Add 7 languages (EN/PL/DE/ES/FR/UK/ZH), first-run lang prompt, --reset-lang
Users are asked to choose language on first run, saved to ~/.config/systats/. L key toggles language live. --reset-lang clears saved preference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
226
systats.py
226
systats.py
@@ -28,87 +28,96 @@ REFRESH_INTERVAL = 1.0
|
|||||||
|
|
||||||
# ─── i18n ───────────────────────────────────────────────────────────
|
# ─── i18n ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
LANGS = ["en", "pl"]
|
LANGS = ["en", "pl", "de", "es", "fr", "uk", "zh"]
|
||||||
|
LANG_NAMES = {
|
||||||
|
"en": "English",
|
||||||
|
"pl": "Polski",
|
||||||
|
"de": "Deutsch",
|
||||||
|
"es": "Espanol",
|
||||||
|
"fr": "Francais",
|
||||||
|
"uk": "Ukrainska",
|
||||||
|
"zh": "Zhongwen",
|
||||||
|
}
|
||||||
current_lang = "en"
|
current_lang = "en"
|
||||||
|
|
||||||
TRANSLATIONS = {
|
TRANSLATIONS = {
|
||||||
# Header
|
# Header
|
||||||
"up": {"en": "Up", "pl": "Czas"},
|
"up": {"en": "Up", "pl": "Czas", "de": "Up", "es": "Arr", "fr": "Up", "uk": "Chas", "zh": "Yunxing"},
|
||||||
"load": {"en": "Load", "pl": "Obc."},
|
"load": {"en": "Load", "pl": "Obc.", "de": "Last", "es": "Carga", "fr": "Charge", "uk": "Nav.", "zh": "Fuzai"},
|
||||||
"procs": {"en": "Procs", "pl": "Proc"},
|
"procs": {"en": "Procs", "pl": "Proc", "de": "Proz", "es": "Proc", "fr": "Proc", "uk": "Proc", "zh": "Jinch"},
|
||||||
"run": {"en": "run", "pl": "dzia."},
|
"run": {"en": "run", "pl": "dzia.", "de": "lauf", "es": "ejec", "fr": "exec", "uk": "prac", "zh": "yunx"},
|
||||||
# Sections
|
# Sections
|
||||||
"memory": {"en": "MEMORY", "pl": "PAMIEC"},
|
"memory": {"en": "MEMORY", "pl": "PAMIEC", "de": "SPEICHER", "es": "MEMORIA", "fr": "MEMOIRE", "uk": "PAM'YAT", "zh": "NEICUN"},
|
||||||
"network": {"en": "NETWORK", "pl": "SIEC"},
|
"network": {"en": "NETWORK", "pl": "SIEC", "de": "NETZWERK", "es": "RED", "fr": "RESEAU", "uk": "MEREZHA", "zh": "WANGLUO"},
|
||||||
"disk": {"en": "DISK", "pl": "DYSK"},
|
"disk": {"en": "DISK", "pl": "DYSK", "de": "PLATTE", "es": "DISCO", "fr": "DISQUE", "uk": "DYSK", "zh": "CIPAN"},
|
||||||
"gpu": {"en": "GPU", "pl": "GPU"},
|
"gpu": {"en": "GPU", "pl": "GPU", "de": "GPU", "es": "GPU", "fr": "GPU", "uk": "GPU", "zh": "GPU"},
|
||||||
"temps": {"en": "TEMPS", "pl": "TEMP"},
|
"temps": {"en": "TEMPS", "pl": "TEMP", "de": "TEMP", "es": "TEMP", "fr": "TEMP", "uk": "TEMP", "zh": "WENDU"},
|
||||||
"processes": {"en": "PROCESSES", "pl": "PROCESY"},
|
"processes": {"en": "PROCESSES", "pl": "PROCESY", "de": "PROZESSE", "es": "PROCESOS", "fr": "PROCESSUS", "uk": "PROCESY", "zh": "JINCHENG"},
|
||||||
# Disk
|
# Disk
|
||||||
"read": {"en": "Read", "pl": "Odczyt"},
|
"read": {"en": "Read", "pl": "Odczyt", "de": "Lesen", "es": "Leer", "fr": "Lire", "uk": "Chyt.", "zh": "Du"},
|
||||||
"write": {"en": "Write", "pl": "Zapis"},
|
"write": {"en": "Write", "pl": "Zapis", "de": "Schreib", "es": "Escrib", "fr": "Ecrir", "uk": "Zapys", "zh": "Xie"},
|
||||||
# Network
|
# Network
|
||||||
"total": {"en": "Total", "pl": "Suma"},
|
"total": {"en": "Total", "pl": "Suma", "de": "Gesamt", "es": "Total", "fr": "Total", "uk": "Vsogo", "zh": "Zongji"},
|
||||||
# Process table
|
# Process table
|
||||||
"filter": {"en": "filter", "pl": "filtr"},
|
"filter": {"en": "filter", "pl": "filtr", "de": "Filter", "es": "filtro", "fr": "filtre", "uk": "filtr", "zh": "guolv"},
|
||||||
"name": {"en": "NAME", "pl": "NAZWA"},
|
"name": {"en": "NAME", "pl": "NAZWA", "de": "NAME", "es": "NOMBRE", "fr": "NOM", "uk": "NAZVA", "zh": "MINGCH"},
|
||||||
# Process hints
|
# Process hints
|
||||||
"hint_sort": {"en": "sort", "pl": "sort."},
|
"hint_sort": {"en": "sort", "pl": "sort.", "de": "sort.", "es": "orden", "fr": "tri", "uk": "sort.", "zh": "paixu"},
|
||||||
"hint_reverse": {"en": "reverse", "pl": "odwroc"},
|
"hint_reverse": {"en": "reverse", "pl": "odwroc", "de": "umkehr", "es": "invert", "fr": "invers", "uk": "zvorot", "zh": "fanzhuan"},
|
||||||
"hint_filter": {"en": "filter", "pl": "filtr"},
|
"hint_filter": {"en": "filter", "pl": "filtr", "de": "Filter", "es": "filtro", "fr": "filtre", "uk": "filtr", "zh": "guolv"},
|
||||||
"hint_signals": {"en": "signals", "pl": "sygnaly"},
|
"hint_signals": {"en": "signals", "pl": "sygnaly", "de": "Signale", "es": "senales", "fr": "signaux", "uk": "sygnaly", "zh": "xinhao"},
|
||||||
"hint_details": {"en": "details", "pl": "szczeg."},
|
"hint_details": {"en": "details", "pl": "szczeg.", "de": "Details", "es": "detalle", "fr": "details", "uk": "detal.", "zh": "xiangxi"},
|
||||||
"hint_nice": {"en": "nice", "pl": "priorytet"},
|
"hint_nice": {"en": "nice", "pl": "priorytet", "de": "Priorit.", "es": "prior.", "fr": "prior.", "uk": "prior.", "zh": "youxian"},
|
||||||
"hint_quit": {"en": "quit", "pl": "wyjscie"},
|
"hint_quit": {"en": "quit", "pl": "wyjscie", "de": "Ende", "es": "salir", "fr": "quitter", "uk": "vyhid", "zh": "tuichu"},
|
||||||
# Kill menu
|
# Kill menu
|
||||||
"send_signal_to": {"en": "Send signal to", "pl": "Wyslij sygnal do"},
|
"send_signal_to": {"en": "Send signal to", "pl": "Wyslij sygnal do", "de": "Signal senden an", "es": "Enviar senal a", "fr": "Envoyer signal a", "uk": "Nadislaty sygnal", "zh": "Fasong xinhao"},
|
||||||
"send": {"en": "send", "pl": "wyslij"},
|
"send": {"en": "send", "pl": "wyslij", "de": "senden", "es": "enviar", "fr": "envoyer", "uk": "nadis.", "zh": "fasong"},
|
||||||
"cancel": {"en": "cancel", "pl": "anuluj"},
|
"cancel": {"en": "cancel", "pl": "anuluj", "de": "abbrech", "es": "cancel", "fr": "annuler", "uk": "skasuv.", "zh": "quxiao"},
|
||||||
"apply": {"en": "apply", "pl": "zastosuj"},
|
"apply": {"en": "apply", "pl": "zastosuj", "de": "anwend", "es": "aplicar", "fr": "appliqu", "uk": "zastos.", "zh": "yingyong"},
|
||||||
# Details
|
# Details
|
||||||
"proc_details": {"en": "Process Details", "pl": "Szczegoly procesu"},
|
"proc_details": {"en": "Process Details", "pl": "Szczegoly procesu", "de": "Prozessdetails", "es": "Detalles proceso", "fr": "Details processus", "uk": "Detali procesu", "zh": "Jincheng xiangxi"},
|
||||||
"created": {"en": "Created", "pl": "Utworzony"},
|
"created": {"en": "Created", "pl": "Utworzony", "de": "Erstellt", "es": "Creado", "fr": "Cree", "uk": "Stvoreno", "zh": "Chuangjian"},
|
||||||
"connections": {"en": "Connections", "pl": "Polaczenia"},
|
"connections": {"en": "Connections", "pl": "Polaczenia", "de": "Verbindungen", "es": "Conexiones", "fr": "Connexions", "uk": "Z'yednannya", "zh": "Lianjie"},
|
||||||
"close": {"en": "close", "pl": "zamknij"},
|
"close": {"en": "close", "pl": "zamknij", "de": "schlies", "es": "cerrar", "fr": "fermer", "uk": "zakryty", "zh": "guanbi"},
|
||||||
# Renice
|
# Renice
|
||||||
"nice_value": {"en": "Nice value (-20..19)", "pl": "Priorytet (-20..19)"},
|
"nice_value": {"en": "Nice value (-20..19)", "pl": "Priorytet (-20..19)", "de": "Nice-Wert (-20..19)", "es": "Valor nice (-20..19)", "fr": "Valeur nice (-20..19)", "uk": "Priorytet (-20..19)", "zh": "Nice zhi (-20..19)"},
|
||||||
# Filter bar
|
# Filter bar
|
||||||
"filter_label": {"en": "Filter", "pl": "Filtr"},
|
"filter_label": {"en": "Filter", "pl": "Filtr", "de": "Filter", "es": "Filtro", "fr": "Filtre", "uk": "Filtr", "zh": "Guolv"},
|
||||||
# Status messages
|
# Status messages
|
||||||
"no_proc_selected": {"en": "No process selected", "pl": "Nie wybrano procesu"},
|
"no_proc_selected": {"en": "No process selected", "pl": "Nie wybrano procesu", "de": "Kein Prozess gewaehlt", "es": "Ningun proceso seleccionado", "fr": "Aucun processus selectionne", "uk": "Proces ne obrano", "zh": "Wei xuanze jincheng"},
|
||||||
"sent_to": {"en": "Sent {sig} to {name} (PID {pid})", "pl": "Wyslano {sig} do {name} (PID {pid})"},
|
"sent_to": {"en": "Sent {sig} to {name} (PID {pid})", "pl": "Wyslano {sig} do {name} (PID {pid})", "de": "{sig} an {name} gesendet (PID {pid})", "es": "{sig} enviado a {name} (PID {pid})", "fr": "{sig} envoye a {name} (PID {pid})", "uk": "Nadislano {sig} do {name} (PID {pid})", "zh": "Yi fasong {sig} dao {name} (PID {pid})"},
|
||||||
"proc_not_found": {"en": "Process {pid} not found", "pl": "Proces {pid} nie znaleziony"},
|
"proc_not_found": {"en": "Process {pid} not found", "pl": "Proces {pid} nie znaleziony", "de": "Prozess {pid} nicht gefunden", "es": "Proceso {pid} no encontrado", "fr": "Processus {pid} introuvable", "uk": "Proces {pid} ne znajdeno", "zh": "Jincheng {pid} wei zhaodao"},
|
||||||
"perm_denied": {"en": "Permission denied: {name} (PID {pid})", "pl": "Brak uprawnien: {name} (PID {pid})"},
|
"perm_denied": {"en": "Permission denied: {name} (PID {pid})", "pl": "Brak uprawnien: {name} (PID {pid})", "de": "Zugriff verweigert: {name} (PID {pid})", "es": "Permiso denegado: {name} (PID {pid})", "fr": "Permission refusee: {name} (PID {pid})", "uk": "Dostup zaboroneno: {name} (PID {pid})", "zh": "Quanxian jujue: {name} (PID {pid})"},
|
||||||
"set_nice": {"en": "Set nice {val} for {name} (PID {pid})", "pl": "Ustawiono priorytet {val} dla {name} (PID {pid})"},
|
"set_nice": {"en": "Set nice {val} for {name} (PID {pid})", "pl": "Ustawiono priorytet {val} dla {name} (PID {pid})", "de": "Nice {val} fuer {name} gesetzt (PID {pid})", "es": "Nice {val} para {name} (PID {pid})", "fr": "Nice {val} pour {name} (PID {pid})", "uk": "Vstanovleno priorytet {val} dlya {name} (PID {pid})", "zh": "Yi shezhi nice {val} {name} (PID {pid})"},
|
||||||
"invalid_nice": {"en": "Invalid nice value", "pl": "Nieprawidlowy priorytet"},
|
"invalid_nice": {"en": "Invalid nice value", "pl": "Nieprawidlowy priorytet", "de": "Ungueltiger Nice-Wert", "es": "Valor nice invalido", "fr": "Valeur nice invalide", "uk": "Nepravyl'nyj priorytet", "zh": "Wuxiao nice zhi"},
|
||||||
# Help
|
# Help
|
||||||
"help_title": {"en": "SYSTATS - Keyboard Shortcuts", "pl": "SYSTATS - Skroty klawiszowe"},
|
"help_title": {"en": "SYSTATS - Keyboard Shortcuts", "pl": "SYSTATS - Skroty klawiszowe", "de": "SYSTATS - Tastenkuerzel", "es": "SYSTATS - Atajos de teclado", "fr": "SYSTATS - Raccourcis clavier", "uk": "SYSTATS - Klavishni skroty", "zh": "SYSTATS - Jianpan kuaijiejian"},
|
||||||
"help_close": {"en": "Press h, F1 or ? to close", "pl": "Nacisnij h, F1 lub ? aby zamknac"},
|
"help_close": {"en": "Press h, F1 or ? to close", "pl": "Nacisnij h, F1 lub ? aby zamknac", "de": "h, F1 oder ? zum Schliessen", "es": "Pulsa h, F1 o ? para cerrar", "fr": "Appuyez h, F1 ou ? pour fermer", "uk": "Natysnit' h, F1 abo ? shchob zakryty", "zh": "An h, F1 huo ? guanbi"},
|
||||||
"help_nav": {"en": "NAVIGATION", "pl": "NAWIGACJA"},
|
"help_nav": {"en": "NAVIGATION", "pl": "NAWIGACJA", "de": "NAVIGATION", "es": "NAVEGACION", "fr": "NAVIGATION", "uk": "NAVIGACIYA", "zh": "DAOHANG"},
|
||||||
"help_down": {"en": "Move cursor down", "pl": "Kursor w dol"},
|
"help_down": {"en": "Move cursor down", "pl": "Kursor w dol", "de": "Cursor nach unten", "es": "Mover cursor abajo", "fr": "Curseur vers le bas", "uk": "Kursor vnyz", "zh": "Guangbiao xia yi"},
|
||||||
"help_up": {"en": "Move cursor up", "pl": "Kursor w gore"},
|
"help_up": {"en": "Move cursor up", "pl": "Kursor w gore", "de": "Cursor nach oben", "es": "Mover cursor arriba", "fr": "Curseur vers le haut", "uk": "Kursor vgoru", "zh": "Guangbiao shang yi"},
|
||||||
"help_pgdn": {"en": "Scroll down 20", "pl": "Przewin 20 w dol"},
|
"help_pgdn": {"en": "Scroll down 20", "pl": "Przewin 20 w dol", "de": "20 nach unten", "es": "Bajar 20", "fr": "Defiler 20 bas", "uk": "Prokrutyty 20 vnyz", "zh": "Xiang xia gundon 20"},
|
||||||
"help_pgup": {"en": "Scroll up 20", "pl": "Przewin 20 w gore"},
|
"help_pgup": {"en": "Scroll up 20", "pl": "Przewin 20 w gore", "de": "20 nach oben", "es": "Subir 20", "fr": "Defiler 20 haut", "uk": "Prokrutyty 20 vgoru", "zh": "Xiang shang gundon 20"},
|
||||||
"help_home": {"en": "Go to top", "pl": "Na poczatek"},
|
"help_home": {"en": "Go to top", "pl": "Na poczatek", "de": "Zum Anfang", "es": "Ir al inicio", "fr": "Aller en haut", "uk": "Na pochatok", "zh": "Dao dingbu"},
|
||||||
"help_end": {"en": "Go to bottom", "pl": "Na koniec"},
|
"help_end": {"en": "Go to bottom", "pl": "Na koniec", "de": "Zum Ende", "es": "Ir al final", "fr": "Aller en bas", "uk": "Na kinec'", "zh": "Dao dibu"},
|
||||||
"help_sorting": {"en": "SORTING", "pl": "SORTOWANIE"},
|
"help_sorting": {"en": "SORTING", "pl": "SORTOWANIE", "de": "SORTIERUNG", "es": "ORDENAR", "fr": "TRI", "uk": "SORTUVANNYA", "zh": "PAIXU"},
|
||||||
"help_sort_cpu": {"en": "Sort by CPU%", "pl": "Sortuj wg CPU%"},
|
"help_sort_cpu": {"en": "Sort by CPU%", "pl": "Sortuj wg CPU%", "de": "Nach CPU% sortieren", "es": "Ordenar por CPU%", "fr": "Trier par CPU%", "uk": "Sort. za CPU%", "zh": "An CPU% paixu"},
|
||||||
"help_sort_mem": {"en": "Sort by MEM%", "pl": "Sortuj wg MEM%"},
|
"help_sort_mem": {"en": "Sort by MEM%", "pl": "Sortuj wg MEM%", "de": "Nach MEM% sortieren", "es": "Ordenar por MEM%", "fr": "Trier par MEM%", "uk": "Sort. za MEM%", "zh": "An MEM% paixu"},
|
||||||
"help_sort_pid": {"en": "Sort by PID", "pl": "Sortuj wg PID"},
|
"help_sort_pid": {"en": "Sort by PID", "pl": "Sortuj wg PID", "de": "Nach PID sortieren", "es": "Ordenar por PID", "fr": "Trier par PID", "uk": "Sort. za PID", "zh": "An PID paixu"},
|
||||||
"help_sort_name": {"en": "Sort by name", "pl": "Sortuj wg nazwy"},
|
"help_sort_name": {"en": "Sort by name", "pl": "Sortuj wg nazwy", "de": "Nach Name sortieren", "es": "Ordenar por nombre", "fr": "Trier par nom", "uk": "Sort. za nazvoyu", "zh": "An mingcheng paixu"},
|
||||||
"help_reverse": {"en": "Reverse sort order", "pl": "Odwroc sortowanie"},
|
"help_reverse": {"en": "Reverse sort order", "pl": "Odwroc sortowanie", "de": "Sortierung umkehren", "es": "Invertir orden", "fr": "Inverser le tri", "uk": "Zvorotne sortuvannya", "zh": "Fanzhuan paixu"},
|
||||||
"help_proc": {"en": "PROCESS MGMT", "pl": "ZARZ. PROCESAMI"},
|
"help_proc": {"en": "PROCESS MGMT", "pl": "ZARZ. PROCESAMI", "de": "PROZESSVERWALT.", "es": "GEST. PROCESOS", "fr": "GEST. PROCESSUS", "uk": "KER. PROCESAMY", "zh": "JINCHENG GUANLI"},
|
||||||
"help_sigterm": {"en": "Send SIGTERM to process", "pl": "Wyslij SIGTERM"},
|
"help_sigterm": {"en": "Send SIGTERM to process", "pl": "Wyslij SIGTERM", "de": "SIGTERM senden", "es": "Enviar SIGTERM", "fr": "Envoyer SIGTERM", "uk": "Nadislaty SIGTERM", "zh": "Fasong SIGTERM"},
|
||||||
"help_sigkill": {"en": "Send SIGKILL to process", "pl": "Wyslij SIGKILL"},
|
"help_sigkill": {"en": "Send SIGKILL to process", "pl": "Wyslij SIGKILL", "de": "SIGKILL senden", "es": "Enviar SIGKILL", "fr": "Envoyer SIGKILL", "uk": "Nadislaty SIGKILL", "zh": "Fasong SIGKILL"},
|
||||||
"help_sigmenu": {"en": "Signal menu (choose signal)", "pl": "Menu sygnalow"},
|
"help_sigmenu": {"en": "Signal menu (choose signal)", "pl": "Menu sygnalow", "de": "Signalmenue", "es": "Menu de senales", "fr": "Menu signaux", "uk": "Menyu sygnaliv", "zh": "Xinhao caidan"},
|
||||||
"help_nice_pos": {"en": "Renice process", "pl": "Zmien priorytet"},
|
"help_nice_pos": {"en": "Renice process", "pl": "Zmien priorytet", "de": "Prioritaet aendern", "es": "Cambiar prioridad", "fr": "Changer priorite", "uk": "Zminyty priorytet", "zh": "Gaibian youxianji"},
|
||||||
"help_nice_neg": {"en": "Renice process (negative)", "pl": "Zmien priorytet (ujemny)"},
|
"help_nice_neg": {"en": "Renice process (negative)", "pl": "Zmien priorytet (ujemny)", "de": "Prioritaet aendern (neg)", "es": "Cambiar prioridad (neg)", "fr": "Changer priorite (neg)", "uk": "Zminyty priorytet (vid'yem.)", "zh": "Gaibian youxianji (fu)"},
|
||||||
"help_details": {"en": "Process details", "pl": "Szczegoly procesu"},
|
"help_details": {"en": "Process details", "pl": "Szczegoly procesu", "de": "Prozessdetails", "es": "Detalles proceso", "fr": "Details processus", "uk": "Detali procesu", "zh": "Jincheng xiangxi"},
|
||||||
"help_filter": {"en": "Filter processes", "pl": "Filtruj procesy"},
|
"help_filter": {"en": "Filter processes", "pl": "Filtruj procesy", "de": "Prozesse filtern", "es": "Filtrar procesos", "fr": "Filtrer processus", "uk": "Filtruvannya procesiv", "zh": "Guolv jincheng"},
|
||||||
"help_general": {"en": "GENERAL", "pl": "OGOLNE"},
|
"help_general": {"en": "GENERAL", "pl": "OGOLNE", "de": "ALLGEMEIN", "es": "GENERAL", "fr": "GENERAL", "uk": "ZAGAL'NE", "zh": "TONGYONG"},
|
||||||
"help_help": {"en": "Toggle this help", "pl": "Pokaz/ukryj pomoc"},
|
"help_help": {"en": "Toggle this help", "pl": "Pokaz/ukryj pomoc", "de": "Hilfe ein/aus", "es": "Mostrar/ocultar ayuda", "fr": "Afficher/masquer aide", "uk": "Pokaz./skhov. dovidku", "zh": "Xianshi/yincang bangzhu"},
|
||||||
"help_lang": {"en": "Switch language (EN/PL)", "pl": "Zmien jezyk (EN/PL)"},
|
"help_lang": {"en": "Switch language", "pl": "Zmien jezyk", "de": "Sprache wechseln", "es": "Cambiar idioma", "fr": "Changer langue", "uk": "Zminyty movu", "zh": "Qiehuan yuyan"},
|
||||||
"help_quit": {"en": "Quit", "pl": "Wyjscie"},
|
"help_quit": {"en": "Quit", "pl": "Wyjscie", "de": "Beenden", "es": "Salir", "fr": "Quitter", "uk": "Vyhid", "zh": "Tuichu"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1303,6 +1312,7 @@ def main(stdscr):
|
|||||||
global current_lang
|
global current_lang
|
||||||
idx = LANGS.index(current_lang)
|
idx = LANGS.index(current_lang)
|
||||||
current_lang = LANGS[(idx + 1) % len(LANGS)]
|
current_lang = LANGS[(idx + 1) % len(LANGS)]
|
||||||
|
save_lang(current_lang)
|
||||||
elif key == ord("c"):
|
elif key == ord("c"):
|
||||||
data.process_sort = "cpu"
|
data.process_sort = "cpu"
|
||||||
data.process_sort_reverse = True
|
data.process_sort_reverse = True
|
||||||
@@ -1361,13 +1371,93 @@ def main(stdscr):
|
|||||||
pm.show_details = True
|
pm.show_details = True
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_path():
|
||||||
|
config_dir = os.path.join(os.path.expanduser("~"), ".config", "systats")
|
||||||
|
os.makedirs(config_dir, exist_ok=True)
|
||||||
|
return os.path.join(config_dir, "config")
|
||||||
|
|
||||||
|
|
||||||
|
def load_saved_lang():
|
||||||
|
path = get_config_path()
|
||||||
|
try:
|
||||||
|
with open(path) as f:
|
||||||
|
for line in f:
|
||||||
|
if line.startswith("lang="):
|
||||||
|
lang = line.strip().split("=", 1)[1]
|
||||||
|
if lang in LANGS:
|
||||||
|
return lang
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def save_lang(lang):
|
||||||
|
path = get_config_path()
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.write(f"lang={lang}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def ask_lang():
|
||||||
|
print(" \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510")
|
||||||
|
print(" \u2502 SYSTATS - Electric Entropy Lab \u2502")
|
||||||
|
print(" \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524")
|
||||||
|
print(" \u2502 Choose your language: \u2502")
|
||||||
|
print(" \u2502 \u2502")
|
||||||
|
for i, code in enumerate(LANGS, 1):
|
||||||
|
name = LANG_NAMES.get(code, code)
|
||||||
|
print(f" \u2502 {i}) {name:<28s} \u2502")
|
||||||
|
print(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518")
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
choice = input(" > ").strip().lower()
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
print()
|
||||||
|
sys.exit(0)
|
||||||
|
# Accept number
|
||||||
|
if choice.isdigit() and 1 <= int(choice) <= len(LANGS):
|
||||||
|
return LANGS[int(choice) - 1]
|
||||||
|
# Accept lang code
|
||||||
|
if choice in LANGS:
|
||||||
|
return choice
|
||||||
|
print(f" 1-{len(LANGS)} or lang code ({'/'.join(LANGS)})")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import argparse
|
import argparse
|
||||||
parser = argparse.ArgumentParser(description="systats - Terminal system monitor | Electric Entropy Lab")
|
parser = argparse.ArgumentParser(description="systats - Terminal system monitor | Electric Entropy Lab")
|
||||||
parser.add_argument("--lang", choices=LANGS, default="en",
|
lang_help = ", ".join(f"{c} ({n})" for c, n in LANG_NAMES.items())
|
||||||
help="UI language: en (English) or pl (Polski)")
|
parser.add_argument("--lang", choices=LANGS, default=None,
|
||||||
|
help=f"UI language: {lang_help}")
|
||||||
|
parser.add_argument("--reset-lang", action="store_true",
|
||||||
|
help="Reset saved language preference and ask again")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.reset_lang:
|
||||||
|
path = get_config_path()
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
print("Language preference reset.")
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("No saved preference found.")
|
||||||
|
if not args.lang:
|
||||||
|
lang = ask_lang()
|
||||||
|
save_lang(lang)
|
||||||
|
current_lang = lang
|
||||||
|
else:
|
||||||
|
save_lang(args.lang)
|
||||||
current_lang = args.lang
|
current_lang = args.lang
|
||||||
|
elif args.lang:
|
||||||
|
save_lang(args.lang)
|
||||||
|
current_lang = args.lang
|
||||||
|
else:
|
||||||
|
saved = load_saved_lang()
|
||||||
|
if saved:
|
||||||
|
current_lang = saved
|
||||||
|
else:
|
||||||
|
lang = ask_lang()
|
||||||
|
save_lang(lang)
|
||||||
|
current_lang = lang
|
||||||
|
|
||||||
try:
|
try:
|
||||||
curses.wrapper(main)
|
curses.wrapper(main)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|||||||
Reference in New Issue
Block a user