Liest LANG aus Umgebung oder /etc/locale.conf und liefert deutsche oder englische UI-Strings. Alle hardcoded Strings in greeter.py durch Strings-Dataclass ersetzt. Fallback auf Englisch bei unbekannter Locale.
114 lines
3.8 KiB
Python
114 lines
3.8 KiB
Python
# ABOUTME: Locale detection and string lookup for the greeter UI.
|
|
# ABOUTME: Reads system locale (LANG or /etc/locale.conf) and provides DE or EN strings.
|
|
|
|
import os
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
DEFAULT_LOCALE_CONF = Path("/etc/locale.conf")
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Strings:
|
|
"""All user-visible strings for the greeter UI."""
|
|
|
|
# UI labels
|
|
password_placeholder: str
|
|
reboot_tooltip: str
|
|
shutdown_tooltip: str
|
|
|
|
# Error messages
|
|
no_session_selected: str
|
|
greetd_sock_not_set: str
|
|
greetd_sock_not_absolute: str
|
|
greetd_sock_not_socket: str
|
|
greetd_sock_unreachable: str
|
|
auth_failed: str
|
|
wrong_password: str
|
|
multi_stage_unsupported: str
|
|
invalid_session_command: str
|
|
session_start_failed: str
|
|
reboot_failed: str
|
|
shutdown_failed: str
|
|
|
|
# Templates (use .format())
|
|
connection_error: str
|
|
socket_error: str
|
|
faillock_attempts_remaining: str
|
|
faillock_locked: str
|
|
|
|
|
|
_STRINGS_DE = Strings(
|
|
password_placeholder="Passwort",
|
|
reboot_tooltip="Neustart",
|
|
shutdown_tooltip="Herunterfahren",
|
|
no_session_selected="Keine Session ausgewählt",
|
|
greetd_sock_not_set="GREETD_SOCK nicht gesetzt",
|
|
greetd_sock_not_absolute="GREETD_SOCK ist kein absoluter Pfad",
|
|
greetd_sock_not_socket="GREETD_SOCK zeigt nicht auf einen Socket",
|
|
greetd_sock_unreachable="GREETD_SOCK nicht erreichbar",
|
|
auth_failed="Authentifizierung fehlgeschlagen",
|
|
wrong_password="Falsches Passwort",
|
|
multi_stage_unsupported="Mehrstufige Authentifizierung wird nicht unterstützt",
|
|
invalid_session_command="Ungültiger Session-Befehl",
|
|
session_start_failed="Session konnte nicht gestartet werden",
|
|
reboot_failed="Neustart fehlgeschlagen",
|
|
shutdown_failed="Herunterfahren fehlgeschlagen",
|
|
connection_error="Verbindungsfehler: {error}",
|
|
socket_error="Socket-Fehler: {error}",
|
|
faillock_attempts_remaining="Noch {n} Versuch(e) vor Kontosperrung!",
|
|
faillock_locked="Konto ist möglicherweise gesperrt",
|
|
)
|
|
|
|
_STRINGS_EN = Strings(
|
|
password_placeholder="Password",
|
|
reboot_tooltip="Reboot",
|
|
shutdown_tooltip="Shut down",
|
|
no_session_selected="No session selected",
|
|
greetd_sock_not_set="GREETD_SOCK not set",
|
|
greetd_sock_not_absolute="GREETD_SOCK is not an absolute path",
|
|
greetd_sock_not_socket="GREETD_SOCK does not point to a socket",
|
|
greetd_sock_unreachable="GREETD_SOCK unreachable",
|
|
auth_failed="Authentication failed",
|
|
wrong_password="Wrong password",
|
|
multi_stage_unsupported="Multi-stage authentication is not supported",
|
|
invalid_session_command="Invalid session command",
|
|
session_start_failed="Failed to start session",
|
|
reboot_failed="Reboot failed",
|
|
shutdown_failed="Shutdown failed",
|
|
connection_error="Connection error: {error}",
|
|
socket_error="Socket error: {error}",
|
|
faillock_attempts_remaining="{n} attempt(s) remaining before lockout!",
|
|
faillock_locked="Account may be locked",
|
|
)
|
|
|
|
_LOCALE_MAP: dict[str, Strings] = {
|
|
"de": _STRINGS_DE,
|
|
"en": _STRINGS_EN,
|
|
}
|
|
|
|
|
|
def detect_locale(locale_conf_path: Path = DEFAULT_LOCALE_CONF) -> str:
|
|
"""Determine the system language from LANG env var or /etc/locale.conf."""
|
|
lang = os.environ.get("LANG")
|
|
|
|
if not lang and locale_conf_path.exists():
|
|
for line in locale_conf_path.read_text().splitlines():
|
|
if line.startswith("LANG="):
|
|
lang = line.split("=", 1)[1].strip()
|
|
break
|
|
|
|
if not lang or lang in ("C", "POSIX"):
|
|
return "en"
|
|
|
|
# Extract language prefix: "de_DE.UTF-8" → "de"
|
|
lang = lang.split("_")[0].split(".")[0]
|
|
return lang
|
|
|
|
|
|
def load_strings(locale: str | None = None) -> Strings:
|
|
"""Return the string table for the given locale, defaulting to English."""
|
|
if locale is None:
|
|
locale = detect_locale()
|
|
return _LOCALE_MAP.get(locale, _STRINGS_EN)
|