Files
plexamp-lite/tools/strings.py
T
XoséandClaude Opus 5.5 f9050bbac0 Backport from the iOS version: offline downloads, home-first reconnect, stall warning, Close
- Downloads for offline listening: long-press a track, album, artist or
  playlist -> Download; Menu -> Downloads lists them (progress, space used/free,
  play/shuffle, retry, remove). Saved on the SD card (Android/data/com.minamp/
  files/downloads). MP3 originals kept as they are unless above a lower
  download quality; the rest transcoded to MP3 (320 kbps by default). One at a
  time, Range resume for originals, retried when the server is back, Wi-Fi lock.
- Downloaded tracks play from the SD card, offline too; plays made offline
  are reported to Plex when a connection works again.
- Server.pick: when last time's connection was remote, give the plain home
  addresses 2 s first (a hairpinned remote address kept us encrypted and
  capped at home). test/PreferHomeTest.java.
- Playback "playing" but not moving for 12 s: say so instead of staying silent.
- Menu -> Close Minamp: stop the music and close every screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 16:03:46 +02:00

307 lines
18 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Single source of truth for UI text: key -> (English, Galician).
Generates res/values/strings.xml (Galician, the default) and res/values-en/strings.xml (English).
Keys starting with tr_ are looked up by name from the pure-Java layers (com.minamp.util.Tr).
Run: python3 tools/strings.py
"""
import os
S = {
"app_name": ("Minamp", "Minamp"),
# tabs / headers
"tab_home": ("Home", "Inicio"),
"tab_artists": ("Artists", "Artistas"),
"tab_albums": ("Albums", "Álbums"),
"tab_playlists": ("Playlists", "Listas"),
"playing_from": ("PLAYING FROM", "REPRODUCINDO DESDE"),
"see_all": ("SEE ALL ›", "VER TODO ›"),
"album_link": ("Album ›", "Álbum ›"),
# setup
"tagline": ("Your Plex music, anywhere,\non a very small phone.", "A túa música de Plex, onde queiras,\nnun teléfono moi pequeno."),
"sign_in": ("Sign in with Plex", "Iniciar sesión con Plex"),
"connect_address": ("Connect by address", "Conectar por enderezo"),
"connection_log": ("Connection log", "Rexistro de conexión"),
"pin_open": ("On a computer or a newer phone, open", "Nun ordenador ou nun teléfono máis novo, abre"),
"pin_enter": ("and enter this code:", "e escribe este código:"),
"pin_waiting": ("Waiting for you to link…", "Agardando a que vincules a conta…"),
"pin_check_now": ("Check now", "Comprobar agora"),
"cancel": ("Cancel", "Cancelar"),
"server_address": ("Server address", "Enderezo do servidor"),
"server_address_help": ("e.g. 192.168.1.20 or https://plex.example.com. Signing in with Plex is easier and finds remote addresses for you.",
"p. ex. 192.168.1.20 ou https://plex.exemplo.com. Iniciar sesión con Plex é máis doado e atopa por ti os enderezos remotos."),
"address_hint": ("Address", "Enderezo"),
"token_hint": ("X-Plex-Token (optional on your LAN)", "X-Plex-Token (opcional na rede da casa)"),
"connect": ("Connect", "Conectar"),
"back": ("Back", "Volver"),
"contacting_plextv": ("Contacting plex.tv…\n(the first secure connection takes a few seconds on this phone)",
"Contactando con plex.tv…\n(a primeira conexión segura tarda uns segundos neste teléfono)"),
"cant_reach_plextv": ("Couldn't reach plex.tv: %1$s", "Non se puido contactar con plex.tv: %1$s"),
"pin_expired": ("Code expired — press Cancel and sign in again", "O código caducou: preme Cancelar e inicia sesión de novo"),
"pin_not_yet": ("Not linked yet · checked %1$d× · %2$d min left", "Aínda sen vincular · comprobado %1$d× · quedan %2$d min"),
"pin_linked": ("Linked!", "Vinculado!"),
"pin_check_failed": ("Check %1$d failed: %2$s — retrying", "Fallou a comprobación %1$d: %2$s; tentando de novo"),
"signed_in_finding": ("Signed in. Finding your servers…", "Sesión iniciada. Buscando os teus servidores…"),
"finding_servers": ("Finding your servers…", "Buscando os teus servidores…"),
"no_servers": ("No Plex Media Servers on this account", "Esta conta non ten ningún Plex Media Server"),
"choose_server": ("Choose a server", "Escolle un servidor"),
"signed_in_as": ("Signed in as %1$s", "Sesión iniciada como %1$s"),
"you": ("you", "ti"),
"server_yours": ("Yours", "Teu"),
"server_shared": ("Shared with you", "Compartido contigo"),
"server_home_plus": ("home + ", "casa + "),
"server_remote": ("remote", "remoto"),
"server_local_only": ("local only", "só local"),
"cant_list_servers": ("Couldn't list servers: %1$s", "Non se puideron listar os servidores: %1$s"),
"connecting_to": ("Connecting to %1$s…\nTrying home network, then remote, then relay.",
"Conectando con %1$s…\nProbando a rede da casa, despois a remota e despois o relay."),
"enter_address": ("Enter your server's address", "Escribe o enderezo do teu servidor"),
"plex_server": ("Plex server", "Servidor Plex"),
"connecting": ("Connecting…", "Conectando…"),
"server_wants_token": ("The server wants a token (or sign in with Plex instead)", "O servidor pide un token (ou inicia sesión con Plex)"),
"loading_libraries": ("Loading libraries…", "Cargando bibliotecas…"),
"no_music_libraries": ("%1$s has no music libraries", "%1$s non ten bibliotecas de música"),
"choose_library": ("Choose a music library", "Escolle unha biblioteca de música"),
"music": ("Music", "Música"),
# common
"ok": ("OK", "Aceptar"),
"close": ("Close", "Pechar"),
"loading": ("Loading…", "Cargando…"),
"try_again": ("Try again", "Tentar de novo"),
"nothing_here": ("Nothing here", "Non hai nada aquí"),
"nothing_here_yet": ("Nothing here yet", "Aínda non hai nada"),
"cant_load_tap": ("Couldn't load: %1$s (tap to retry)", "Non se puido cargar: %1$s (toca para tentar de novo)"),
"on": ("On", "Activado"),
"off": ("Off", "Desactivado"),
"error_last_time": ("Minamp hit an error last time", "Minamp tivo un erro a última vez"),
"min": ("%1$d min", "%1$d min"),
"h_min": ("%1$d h %2$d min", "%1$d h %2$d min"),
# items / counts
"artist": ("Artist", "Artista"),
"album": ("Album", "Álbum"),
"playlist": ("Playlist", "Lista de reprodución"),
"n_albums_one": ("%1$d album", "%1$d álbum"),
"n_albums": ("%1$d albums", "%1$d álbums"),
"n_tracks_one": ("%1$d track", "%1$d pista"),
"n_tracks": ("%1$d tracks", "%1$d pistas"),
# actions
"play": ("Play", "Reproducir"),
"play_all": ("Play all", "Reproducir"),
"shuffle": ("Shuffle", "Aleatorio"),
"artist_radio": ("Radio", "Radio"),
"artist_radio_shuffle": ("Artist radio (shuffle)", "Radio do artista (aleatorio)"),
"play_next": ("Play next", "Reproducir a continuación"),
"add_to_queue": ("Add to queue", "Engadir á cola"),
"go_to_album": ("Go to album", "Ir ao álbum"),
"go_to_artist": ("Go to artist", "Ir ao artista"),
"love": ("Add to favourites", "Engadir a favoritas"),
"unlove": ("Remove from favourites", "Quitar de favoritas"),
"loved": ("Added to favourites", "Engadida a favoritas"),
"unloved": ("Removed from favourites", "Quitada de favoritas"),
"cant_save_rating": ("Couldn't save rating: %1$s", "Non se puido gardar a valoración: %1$s"),
"nothing_to_play": ("Nothing to play", "Non hai nada que reproducir"),
"shuffling_x": ("Shuffling %1$s", "Reproducindo ao chou %1$s"),
"playing_x": ("Playing %1$s", "Reproducindo %1$s"),
"adding_x": ("Adding %1$s…", "Engadindo %1$s…"),
"no_tracks": ("No tracks", "Non hai pistas"),
"playing_next": ("Playing next", "Soará a continuación"),
"added_to_queue": ("Added to queue", "Engadido á cola"),
"starting_x": ("Starting %1$s…", "Iniciando %1$s…"),
"nothing_found_for": ("Nothing found for %1$s", "Non se atopou nada para %1$s"),
# menu / settings
"now_playing": ("Now playing", "En reprodución"),
"search": ("Search", "Buscar"),
"settings": ("Settings", "Axustes"),
"not_connected_yet": ("not connected yet", "aínda sen conectar"),
"secure": (" (secure)", " (cifrada)"),
"unencrypted": (" (unencrypted)", " (sen cifrar)"),
"set_quality_home": ("Quality at home: %1$s", "Calidade na casa: %1$s"),
"set_quality_away": ("Quality away / mobile data: %1$s", "Calidade fóra / datos móbiles: %1$s"),
"set_download_first": ("Download tracks before playing: %1$s", "Descargar as pistas antes de reproducilas: %1$s"),
"set_secure_home": ("Encrypt at home too (slower): %1$s", "Cifrar tamén na casa (máis lento): %1$s"),
"set_library": ("Library: %1$s", "Biblioteca: %1$s"),
"set_server": ("Server: %1$s", "Servidor: %1$s"),
"set_connection": ("Connection: %1$s", "Conexión: %1$s"),
"set_log": ("Connection log & streaming test", "Rexistro de conexión e proba de reprodución"),
"set_language": ("Language: %1$s", "Idioma: %1$s"),
"set_size": ("Text and button size: %1$s", "Tamaño de texto e botóns: %1$s"),
"size_title": ("Text and button size", "Tamaño de texto e botóns"),
"size_normal": ("Normal", "Normal"),
"size_large": ("Large", "Grande"),
"size_xlarge": ("Extra large", "Moi grande"),
"sign_out": ("Sign out", "Pechar sesión"),
"quality_home_title": ("Quality at home", "Calidade na casa"),
"quality_away_title": ("Quality away / mobile", "Calidade fóra / datos móbiles"),
"quality_original": ("Original", "Orixinal"),
"download_first_toast": ("Download before playing: %1$s", "Descargar antes de reproducir: %1$s"),
"https_home_on": ("Using HTTPS at home (each new connection is slower on this phone)",
"Usando HTTPS na casa (cada conexión nova é máis lenta neste teléfono)"),
"https_home_off": ("Using plain HTTP at home (faster)", "Usando HTTP simple na casa (máis rápido)"),
"reconnecting": ("Reconnecting…", "Reconectando…"),
"connected_x": ("Connected: %1$s", "Conectado: %1$s"),
"applies_next_track": ("Applies from the next track", "Aplícase desde a seguinte pista"),
"sign_out_confirm": ("Sign out and forget this server?", "Pechar sesión e esquecer este servidor?"),
"language_title": ("Language", "Idioma"),
# diagnostics
"log_empty": ("Nothing logged yet.", "Aínda non hai nada no rexistro."),
"save_to_sd": ("Save to SD card", "Gardar na tarxeta SD"),
"test_streaming": ("Test streaming", "Probar reprodución"),
"no_sd": ("No SD card available", "Non hai tarxeta SD dispoñible"),
"saved_log": ("Saved as Minamp-log.txt on the SD card", "Gardado como Minamp-log.txt na tarxeta SD"),
"cant_save": ("Couldn't save: %1$s", "Non se puido gardar: %1$s"),
"testing": ("Testing… (about 30 s)", "Probando… (uns 30 s)"),
# home
"library_radio": ("Library radio", "Radio da biblioteca"),
"library_radio_sub": ("Shuffle everything", "Todo ao chou"),
"loved_radio": ("Favourites radio", "Radio de favoritas"),
"loved_radio_sub": ("Your top rated", "As mellor valoradas"),
"time_travel": ("Time travel", "Viaxe no tempo"),
"time_travel_sub": ("Pick a decade", "Escolle década"),
"random_album": ("Random album", "Álbum ao chou"),
"random_album_sub": ("Feeling lucky", "Proba sorte"),
"recently_added": ("Recently added", "Novidades"),
"recently_played": ("Recently played", "Últimas escoitas"),
"finding_decades": ("Finding decades…", "Buscando décadas…"),
"no_years": ("No release years in this library", "Esta biblioteca non ten anos de publicación"),
"surprise_me": ("Surprise me", "Sorpréndeme"),
"decade_x": ("%1$ds", "Década de %1$d"),
"time_travel_title": ("Time travel radio", "Radio viaxe no tempo"),
"decade_radio_x": ("%1$ds radio", "Radio da década de %1$d"),
"no_albums": ("No albums", "Non hai álbums"),
"loading_artists": ("Loading artists…", "Cargando artistas…"),
"no_artists_library": ("No artists in this library", "Esta biblioteca non ten artistas"),
"loading_albums": ("Loading albums…", "Cargando álbums…"),
"no_albums_library": ("No albums in this library", "Esta biblioteca non ten álbums"),
"loading_playlists": ("Loading playlists…", "Cargando listas…"),
"no_playlists": ("No music playlists yet", "Aínda non hai listas de música"),
"sort_albums": ("Sort albums", "Ordenar álbums"),
"refresh": ("Refresh", "Actualizar"),
"sort_albums_by": ("Sort albums by", "Ordenar álbums por"),
"sort_title": ("Title", "Título"),
"sort_artist": ("Artist", "Artista"),
"sort_added": ("Recently added", "Engadidos recentemente"),
"sort_year": ("Year (newest)", "Ano (máis recentes)"),
"sort_played": ("Most played", "Máis escoitados"),
# now playing
"repeat_queue": ("Repeat queue", "Repetir a cola"),
"repeat_track": ("Repeat track", "Repetir a pista"),
"repeat_off": ("Repeat off", "Sen repetición"),
"nothing_playing": ("Nothing playing", "Non se está a reproducir nada"),
"pick_something": ("Pick something from your library", "Escolle algo da túa biblioteca"),
"end_of_track": ("End of track", "Fin da pista"),
"sleep": ("Sleep", "Durmir"),
"sleep_timer": ("Sleep timer", "Temporizador de apagado"),
"sleep_off": ("Off", "Desactivado"),
"sleep_15": ("15 minutes", "15 minutos"),
"sleep_30": ("30 minutes", "30 minutos"),
"sleep_45": ("45 minutes", "45 minutos"),
"sleep_60": ("1 hour", "1 hora"),
"sleep_90": ("1½ hours", "1½ horas"),
"sleep_eot": ("End of this track", "Ao rematar esta pista"),
"sleep_paused": ("Sleep timer: paused", "Temporizador de apagado: en pausa"),
# playback service
"buffering": ("Buffering…", "Cargando…"),
"downloading_pct": ("Downloading %1$d%%", "Descargando %1$d%%"),
"stream_interrupted": ("Stream interrupted", "Interrompeuse a transmisión"),
"playback_error": ("Playback error (%1$d/%2$d)", "Erro de reprodución (%1$d/%2$d)"),
"paused_dot": ("Paused · ", "En pausa · "),
# queue
"up_next": ("Queue", "Cola"),
"shuffle_on": ("Shuffle on", "Aleatorio activado"),
"shuffle_off": ("Shuffle off", "Aleatorio desactivado"),
"remove_from_queue": ("Remove from queue", "Quitar da cola"),
"queue_empty": ("The queue is empty", "A cola está baleira"),
"clear_upcoming": ("Clear upcoming tracks", "Borrar as pistas seguintes"),
"clear_everything": ("Clear everything", "Borralo todo"),
# search
"search_hint": ("Search music", "Buscar música"),
"search_in": ("Search %1$s", "Buscar en %1$s"),
"searching": ("Searching…", "Buscando…"),
"nothing_found_q": ("Nothing found for “%1$s”", "Non se atopou nada para “%1$s”"),
# downloads (offline listening)
"downloads": ("Downloads", "Descargas"),
"download": ("Download", "Descargar"),
"remove_download": ("Remove download", "Borrar a descarga"),
"downloading_x": ("Downloading %1$s…", "Descargando %1$s…"),
"queued_n": ("%1$d tracks added to downloads", "%1$d pistas engadidas ás descargas"),
"already_downloaded": ("Already downloaded", "Xa está descargado"),
"dl_waiting": ("Waiting", "Agardando"),
"dl_progress": ("Downloading %1$d%%", "Descargando %1$d%%"),
"dl_failed": ("Failed: %1$s (tap to retry)", "Fallou: %1$s (toca para tentar de novo)"),
"dl_retrying": ("Will retry when the server is reachable", "Tentarase de novo cando se poida conectar co servidor"),
"dl_summary": ("%1$d tracks · %2$s · %3$s free", "%1$d pistas · %2$s · %3$s libres"),
"dl_empty": ("Nothing downloaded yet.\nLong-press an album, playlist or track and choose Download.",
"Aínda non descargaches nada.\nMantén premido un álbum, lista ou pista e escolle Descargar."),
"dl_in_progress": ("In progress", "En curso"),
"dl_done_section": ("On this phone", "Neste teléfono"),
"dl_no_space": ("Not enough free space", "Non hai espazo libre abondo"),
"delete_all_downloads": ("Delete all downloads", "Borrar todas as descargas"),
"delete_all_confirm": ("Delete every downloaded track from this phone?", "Borrar deste teléfono todas as pistas descargadas?"),
"cancel_downloads": ("Cancel pending downloads", "Cancelar as descargas pendentes"),
"set_dl_quality": ("Download quality: %1$s", "Calidade das descargas: %1$s"),
"dl_quality_title": ("Download quality", "Calidade das descargas"),
"dl_quality_original": ("Original MP3s, others 320 kbps", "MP3 orixinais, o resto a 320 kbps"),
"set_delete_downloads": ("Delete all downloads (%1$s)", "Borrar todas as descargas (%1$s)"),
"downloaded": ("Downloaded", "Descargada"),
"quit_app": ("Close Minamp", "Pechar Minamp"),
"stalled": ("Playback is stuck. Try pausing and playing again.", "A reprodución quedou parada. Proba a pausar e reproducir de novo."),
# pure-Java layers (looked up by name through com.minamp.util.Tr)
"tr_kind_home": ("Home network", "Rede da casa"),
"tr_kind_direct": ("Direct", "Directa"),
"tr_kind_remote": ("Remote", "Remota"),
"tr_kind_relay": ("Plex Relay", "Plex Relay"),
"tr_cant_reach": ("Can't reach %1$s", "Non se pode conectar con %1$s"),
"tr_server": ("server", "servidor"),
"tr_not_authorized": ("Not authorized (401) on %1$s", "Sen autorización (401) en %1$s"),
"tr_refused": ("Server refused the stream (%1$d)", "O servidor rexeitou a transmisión (%1$d)"),
"tr_file_503": ("Plex couldn't open this file (503). Is the drive or folder with your music available to the server?",
"Plex non puido abrir este ficheiro (503). Está dispoñible para o servidor o disco ou cartafol coa túa música?"),
"tr_cert_mismatch": ("Certificate does not match %1$s", "O certificado non corresponde a %1$s"),
"tr_cert_untrusted": ("Untrusted certificate chain for %1$s", "Cadea de certificados non fiable para %1$s"),
"tr_cert_dates": ("Certificate expired or not yet valid (check the phone's date)",
"Certificado caducado ou aínda non válido (comproba a data do teléfono)"),
"tr_no_media": ("Track has no playable media", "A pista non ten ningún ficheiro reproducible"),
"tr_artist": ("Artist", "Artista"),
"tr_n_tracks_one": ("%1$d track", "%1$d pista"),
"tr_n_tracks": ("%1$d tracks", "%1$d pistas"),
}
def esc(s):
s = s.replace("\\", "\\\\").replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
s = s.replace("'", "\\'").replace('"', '\\"').replace("\n", "\\n")
if s.startswith("@") or s.startswith("?"):
s = "\\" + s
return s
def write(path, idx):
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
f.write('<?xml version="1.0" encoding="utf-8"?>\n<!-- generated by tools/strings.py: edit that file instead -->\n<resources>\n')
for k in sorted(S):
v = S[k][idx]
fmt = ' formatted="false"' if ("%" in v and "%1$" not in v and "%%" not in v) else ""
f.write(' <string name="%s"%s>%s</string>\n' % (k, fmt, esc(v)))
f.write("</resources>\n")
if __name__ == "__main__":
root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "res")
write(os.path.join(root, "values", "strings.xml"), 1) # Galician: default
write(os.path.join(root, "values-en", "strings.xml"), 0) # English
print("%d strings" % len(S))