mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-03-12 02:31:45 +01:00
fix: add missing translations and fix translation loading/testing
This commit is contained in:
@@ -38,17 +38,20 @@ kleinanzeigen_bot/__init__.py:
|
|||||||
load_ads:
|
load_ads:
|
||||||
"Searching for ad config files...": "Suche nach Anzeigendateien..."
|
"Searching for ad config files...": "Suche nach Anzeigendateien..."
|
||||||
" -> found %s": "-> %s gefunden"
|
" -> found %s": "-> %s gefunden"
|
||||||
|
"ad config file": "Anzeigendatei"
|
||||||
"Start fetch task for the ad(s) with id(s):": "Starte Abrufaufgabe für die Anzeige(n) mit ID(s):"
|
"Start fetch task for the ad(s) with id(s):": "Starte Abrufaufgabe für die Anzeige(n) mit ID(s):"
|
||||||
" -> SKIPPED: inactive ad [%s]": " -> ÜBERSPRUNGEN: inaktive Anzeige [%s]"
|
" -> SKIPPED: inactive ad [%s]": " -> ÜBERSPRUNGEN: inaktive Anzeige [%s]"
|
||||||
" -> SKIPPED: ad [%s] is not in list of given ids.": " -> ÜBERSPRUNGEN: Anzeige [%s] ist nicht in der Liste der angegebenen IDs."
|
" -> SKIPPED: ad [%s] is not in list of given ids.": " -> ÜBERSPRUNGEN: Anzeige [%s] ist nicht in der Liste der angegebenen IDs."
|
||||||
" -> SKIPPED: ad [%s] is not new. already has an id assigned.": " -> ÜBERSPRUNGEN: Anzeige [%s] ist nicht neu. Eine ID wurde bereits zugewiesen."
|
" -> SKIPPED: ad [%s] is not new. already has an id assigned.": " -> ÜBERSPRUNGEN: Anzeige [%s] ist nicht neu. Eine ID wurde bereits zugewiesen."
|
||||||
"Category [%s] unknown. Using category [%s] with ID [%s] instead.": "Kategorie [%s] unbekannt. Verwende stattdessen Kategorie [%s] mit ID [%s]."
|
"Category [%s] unknown. Using category [%s] with ID [%s] instead.": "Kategorie [%s] unbekannt. Verwende stattdessen Kategorie [%s] mit ID [%s]."
|
||||||
"Loaded %s": "%s geladen"
|
"Loaded %s": "%s geladen"
|
||||||
|
"ad": "Anzeige"
|
||||||
|
|
||||||
load_config:
|
load_config:
|
||||||
" -> found %s": "-> %s gefunden"
|
|
||||||
"config": "Konfiguration"
|
|
||||||
"Config file %s does not exist. Creating it with default values...": "Konfigurationsdatei %s existiert nicht. Erstelle sie mit Standardwerten..."
|
"Config file %s does not exist. Creating it with default values...": "Konfigurationsdatei %s existiert nicht. Erstelle sie mit Standardwerten..."
|
||||||
|
"config": "Konfiguration"
|
||||||
|
" -> found %s": "-> %s gefunden"
|
||||||
|
"category": "Kategorie"
|
||||||
|
|
||||||
login:
|
login:
|
||||||
"Checking if already logged in...": "Überprüfe, ob bereits eingeloggt..."
|
"Checking if already logged in...": "Überprüfe, ob bereits eingeloggt..."
|
||||||
@@ -64,6 +67,7 @@ kleinanzeigen_bot/__init__.py:
|
|||||||
delete_ads:
|
delete_ads:
|
||||||
"Processing %s/%s: '%s' from [%s]...": "Verarbeite %s/%s: '%s' von [%s]..."
|
"Processing %s/%s: '%s' from [%s]...": "Verarbeite %s/%s: '%s' von [%s]..."
|
||||||
"DONE: Deleted %s": "FERTIG: %s gelöscht"
|
"DONE: Deleted %s": "FERTIG: %s gelöscht"
|
||||||
|
"ad": "Anzeige"
|
||||||
|
|
||||||
delete_ad:
|
delete_ad:
|
||||||
"Deleting ad '%s' if already present...": "Lösche Anzeige '%s', falls bereits vorhanden..."
|
"Deleting ad '%s' if already present...": "Lösche Anzeige '%s', falls bereits vorhanden..."
|
||||||
@@ -74,6 +78,7 @@ kleinanzeigen_bot/__init__.py:
|
|||||||
"Processing %s/%s: '%s' from [%s]...": "Verarbeite %s/%s: '%s' von [%s]..."
|
"Processing %s/%s: '%s' from [%s]...": "Verarbeite %s/%s: '%s' von [%s]..."
|
||||||
"Skipping because ad is reserved": "Überspringen, da Anzeige reserviert ist"
|
"Skipping because ad is reserved": "Überspringen, da Anzeige reserviert ist"
|
||||||
"DONE: (Re-)published %s": "FERTIG: %s (erneut) veröffentlicht"
|
"DONE: (Re-)published %s": "FERTIG: %s (erneut) veröffentlicht"
|
||||||
|
"ad": "Anzeige"
|
||||||
|
|
||||||
publish_ad:
|
publish_ad:
|
||||||
"Publishing ad '%s'...": "Veröffentliche Anzeige '%s'..."
|
"Publishing ad '%s'...": "Veröffentliche Anzeige '%s'..."
|
||||||
@@ -92,6 +97,7 @@ kleinanzeigen_bot/__init__.py:
|
|||||||
|
|
||||||
__upload_images:
|
__upload_images:
|
||||||
" -> found %s": "-> %s gefunden"
|
" -> found %s": "-> %s gefunden"
|
||||||
|
"image": "Bild"
|
||||||
" -> uploading image [%s]": " -> Lade Bild [%s] hoch"
|
" -> uploading image [%s]": " -> Lade Bild [%s] hoch"
|
||||||
|
|
||||||
__check_ad_republication:
|
__check_ad_republication:
|
||||||
@@ -109,15 +115,17 @@ kleinanzeigen_bot/__init__.py:
|
|||||||
|
|
||||||
download_ads:
|
download_ads:
|
||||||
"Scanning your ad overview...": "Scanne Anzeigenübersicht..."
|
"Scanning your ad overview...": "Scanne Anzeigenübersicht..."
|
||||||
|
"%s found.": "%s gefunden."
|
||||||
|
"ad": "Anzeige"
|
||||||
"Starting download of all ads...": "Starte den Download aller Anzeigen..."
|
"Starting download of all ads...": "Starte den Download aller Anzeigen..."
|
||||||
"%d of %d ads were downloaded from your profile.": "%d von %d Anzeigen wurden aus Ihrem Profil heruntergeladen."
|
"%d of %d ads were downloaded from your profile.": "%d von %d Anzeigen wurden aus Ihrem Profil heruntergeladen."
|
||||||
"Starting download of not yet downloaded ads...": "Starte den Download noch nicht heruntergeladener Anzeigen..."
|
"Starting download of not yet downloaded ads...": "Starte den Download noch nicht heruntergeladener Anzeigen..."
|
||||||
"The ad with id %d has already been saved.": "Die Anzeige mit der ID %d wurde bereits gespeichert."
|
"The ad with id %d has already been saved.": "Die Anzeige mit der ID %d wurde bereits gespeichert."
|
||||||
"%s were downloaded from your profile.": "%s wurden aus Ihrem Profil heruntergeladen."
|
"%s were downloaded from your profile.": "%s wurden aus Ihrem Profil heruntergeladen."
|
||||||
|
"new ad": "neue Anzeige"
|
||||||
"Starting download of ad(s) with the id(s):": "Starte Download der Anzeige(n) mit den ID(s):"
|
"Starting download of ad(s) with the id(s):": "Starte Download der Anzeige(n) mit den ID(s):"
|
||||||
"Downloaded ad with id %d": "Anzeige mit der ID %d heruntergeladen"
|
"Downloaded ad with id %d": "Anzeige mit der ID %d heruntergeladen"
|
||||||
"The page with the id %d does not exist!": "Die Seite mit der ID %d existiert nicht!"
|
"The page with the id %d does not exist!": "Die Seite mit der ID %d existiert nicht!"
|
||||||
"%s found.": "%s gefunden."
|
|
||||||
|
|
||||||
parse_args:
|
parse_args:
|
||||||
"Use --help to display available options.": "Mit --help können die verfügbaren Optionen angezeigt werden."
|
"Use --help to display available options.": "Mit --help können die verfügbaren Optionen angezeigt werden."
|
||||||
@@ -201,6 +209,14 @@ kleinanzeigen_bot/utils/error_handlers.py:
|
|||||||
"%s: %s": "%s: %s"
|
"%s: %s": "%s: %s"
|
||||||
"Unknown exception occurred (missing exception info): ex_type=%s, ex_value=%s": "Unbekannter Fehler aufgetreten (fehlende Fehlerinformation): ex_type=%s, ex_value=%s"
|
"Unknown exception occurred (missing exception info): ex_type=%s, ex_value=%s": "Unbekannter Fehler aufgetreten (fehlende Fehlerinformation): ex_type=%s, ex_value=%s"
|
||||||
|
|
||||||
|
#################################################
|
||||||
|
kleinanzeigen_bot/utils/loggers.py:
|
||||||
|
#################################################
|
||||||
|
format:
|
||||||
|
"CRITICAL": "KRITISCH"
|
||||||
|
"ERROR": "FEHLER"
|
||||||
|
"WARNING": "WARNUNG"
|
||||||
|
|
||||||
#################################################
|
#################################################
|
||||||
kleinanzeigen_bot/utils/dicts.py:
|
kleinanzeigen_bot/utils/dicts.py:
|
||||||
#################################################
|
#################################################
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ def translate(text:object, caller:inspect.FrameInfo | None) -> str:
|
|||||||
file_basename = os.path.splitext(os.path.basename(caller.filename))[0]
|
file_basename = os.path.splitext(os.path.basename(caller.filename))[0]
|
||||||
if module_name and module_name.endswith(f".{file_basename}"):
|
if module_name and module_name.endswith(f".{file_basename}"):
|
||||||
module_name = module_name[:-(len(file_basename) + 1)]
|
module_name = module_name[:-(len(file_basename) + 1)]
|
||||||
|
if module_name:
|
||||||
|
module_name = module_name.replace(".", "/")
|
||||||
file_key = f"{file_basename}.py" if module_name == file_basename else f"{module_name}/{file_basename}.py"
|
file_key = f"{file_basename}.py" if module_name == file_basename else f"{module_name}/{file_basename}.py"
|
||||||
translation = dicts.safe_get(_TRANSLATIONS,
|
translation = dicts.safe_get(_TRANSLATIONS,
|
||||||
file_key,
|
file_key,
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ def _extract_log_messages(file_path:str, exclude_debug:bool = False) -> MessageD
|
|||||||
if msg not in messages[function]:
|
if msg not in messages[function]:
|
||||||
messages[function][msg] = {msg}
|
messages[function][msg] = {msg}
|
||||||
|
|
||||||
def extract_string_value(node:ast.AST) -> str | None:
|
def extract_string_constant(node:ast.AST) -> str | None:
|
||||||
"""Safely extract string value from an AST node."""
|
"""Safely extract string value from an AST node."""
|
||||||
if isinstance(node, ast.Constant):
|
if isinstance(node, ast.Constant):
|
||||||
value = getattr(node, "value", None)
|
value = getattr(node, "value", None)
|
||||||
@@ -125,32 +125,38 @@ def _extract_log_messages(file_path:str, exclude_debug:bool = False) -> MessageD
|
|||||||
function_name = _get_function_name(node)
|
function_name = _get_function_name(node)
|
||||||
|
|
||||||
# Extract messages from various call types
|
# Extract messages from various call types
|
||||||
if (isinstance(node.func, ast.Attribute) and
|
|
||||||
|
# 1) Logging calls: LOG.info(…), logger.warning(…), etc.
|
||||||
|
if (
|
||||||
|
isinstance(node.func, ast.Attribute) and
|
||||||
isinstance(node.func.value, ast.Name) and
|
isinstance(node.func.value, ast.Name) and
|
||||||
node.func.value.id in {"LOG", "logger", "logging"} and
|
node.func.value.id in {"LOG", "logger", "logging"} and
|
||||||
node.func.attr in {None if exclude_debug else "debug", "info", "warning", "error", "exception", "critical"}):
|
node.func.attr in {None if exclude_debug else "debug", "info", "warning", "error", "exception", "critical"}
|
||||||
|
):
|
||||||
if node.args:
|
if node.args:
|
||||||
msg = extract_string_value(node.args[0])
|
msg = extract_string_constant(node.args[0])
|
||||||
if msg:
|
if msg:
|
||||||
add_message(function_name, msg)
|
add_message(function_name, msg)
|
||||||
|
|
||||||
# Handle gettext calls
|
# 2) gettext: _("…") or obj.gettext("…")
|
||||||
elif ((isinstance(node.func, ast.Name) and node.func.id == "_") or
|
elif (
|
||||||
(isinstance(node.func, ast.Attribute) and node.func.attr == "gettext")):
|
(isinstance(node.func, ast.Name) and node.func.id == "_") or
|
||||||
|
(isinstance(node.func, ast.Attribute) and node.func.attr == "gettext")
|
||||||
|
):
|
||||||
if node.args:
|
if node.args:
|
||||||
msg = extract_string_value(node.args[0])
|
msg = extract_string_constant(node.args[0])
|
||||||
if msg:
|
if msg:
|
||||||
add_message(function_name, msg)
|
add_message(function_name, msg)
|
||||||
|
|
||||||
# Handle other translatable function calls
|
# Handle other translatable function calls
|
||||||
elif isinstance(node.func, ast.Name) and node.func.id in {"ainput", "pluralize", "ensure"}:
|
elif isinstance(node.func, ast.Name) and node.func.id in {"ainput", "pluralize", "ensure"}:
|
||||||
arg_index = 0 if node.func.id == "ainput" else 1
|
arg_index = 1 if node.func.id == "ensure" else 0
|
||||||
if len(node.args) > arg_index:
|
if len(node.args) > arg_index:
|
||||||
msg = extract_string_value(node.args[arg_index])
|
msg = extract_string_constant(node.args[arg_index])
|
||||||
if msg:
|
if msg:
|
||||||
add_message(function_name, msg)
|
add_message(function_name, msg)
|
||||||
|
|
||||||
print(f"Messages: {messages}")
|
print(f"Messages: {len(messages)} in {file_path}")
|
||||||
|
|
||||||
return messages
|
return messages
|
||||||
|
|
||||||
@@ -376,6 +382,12 @@ def test_no_obsolete_translations(lang:str) -> None:
|
|||||||
"""
|
"""
|
||||||
messages_by_file = _get_all_log_messages(exclude_debug = False)
|
messages_by_file = _get_all_log_messages(exclude_debug = False)
|
||||||
translations = _get_translations_for_language(lang)
|
translations = _get_translations_for_language(lang)
|
||||||
|
|
||||||
|
# ignore values that are not in code
|
||||||
|
del translations["kleinanzeigen_bot/utils/loggers.py"]["format"]["CRITICAL"]
|
||||||
|
del translations["kleinanzeigen_bot/utils/loggers.py"]["format"]["ERROR"]
|
||||||
|
del translations["kleinanzeigen_bot/utils/loggers.py"]["format"]["WARNING"]
|
||||||
|
|
||||||
obsolete_items:list[tuple[str, str, str]] = []
|
obsolete_items:list[tuple[str, str, str]] = []
|
||||||
|
|
||||||
for module, module_trans in translations.items():
|
for module, module_trans in translations.items():
|
||||||
|
|||||||
Reference in New Issue
Block a user