Initial commit: 25 scripts Python sauvegardés
Date: 2026-08-28 11:43:34 EDT
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# Python script: add i18n keys to both locale files
|
||||
|
||||
# Usage:
|
||||
# cd /c/dev/git/python/obsigate
|
||||
# python3 << 'PYEOF' ... PYEOF
|
||||
#
|
||||
# The script below adds new keys to both fr.json and en.json, keeping them
|
||||
# alphabetically sorted. Adjust the `new_keys` dict as needed.
|
||||
|
||||
import json
|
||||
|
||||
with open('frontend/locales/fr.json', encoding='utf-8') as f:
|
||||
fr = json.load(f)
|
||||
with open('frontend/locales/en.json', encoding='utf-8') as f:
|
||||
en = json.load(f)
|
||||
|
||||
# Keys to add: key -> {fr: "texte français", en: "english text"}
|
||||
new_keys = {
|
||||
"vaulthome.loading": {"fr": "Chargement des fichiers...", "en": "Loading files..."},
|
||||
"vaulthome.empty": {"fr": "Aucun fichier dans ce repertoire", "en": "No files in this directory"},
|
||||
"vaulthome.file_count": {"fr": "{count} fichier", "en": "{count} file"},
|
||||
"vaulthome.file_count_plural": {"fr": "{count} fichiers", "en": "{count} files"},
|
||||
"vaulthome.error_loading": {"fr": "Erreur de chargement:", "en": "Loading error:"},
|
||||
"vaulthome.size_bytes": {"fr": "o", "en": "B"},
|
||||
"vaulthome.size_kb": {"fr": "Ko", "en": "KB"},
|
||||
"vaulthome.size_mb": {"fr": "Mo", "en": "MB"},
|
||||
"common.root": {"fr": "(racine)", "en": "(root)"},
|
||||
"common.unknown": {"fr": "Inconnue", "en": "Unknown"},
|
||||
}
|
||||
|
||||
for k, v in new_keys.items():
|
||||
fr[k] = v["fr"]
|
||||
en[k] = v["en"]
|
||||
|
||||
fr = dict(sorted(fr.items()))
|
||||
en = dict(sorted(en.items()))
|
||||
|
||||
with open('frontend/locales/fr.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(fr, f, ensure_ascii=False, indent=2)
|
||||
f.write('\n')
|
||||
with open('frontend/locales/en.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(en, f, ensure_ascii=False, indent=2)
|
||||
f.write('\n')
|
||||
|
||||
print(f"OK: Added {len(new_keys)} keys. FR={len(fr)} EN={len(en)}")
|
||||
@@ -0,0 +1,82 @@
|
||||
# Hardcoded string scanner for ObsiGate frontend JS files
|
||||
# Finds user-visible strings that should be i18n'd but aren't.
|
||||
# Also checks EN locale for French contamination.
|
||||
#
|
||||
# Usage:
|
||||
# cd /c/dev/git/python/obsigate
|
||||
# python3 << 'PYEOF' ... PYEOF
|
||||
|
||||
import re, os, json
|
||||
|
||||
js_dir = 'frontend/js'
|
||||
|
||||
# ── Part 1: Find hardcoded user-visible strings in JS ──
|
||||
noise_patterns = [
|
||||
r'\.css', r'data-', r'console\.', r'getElementById', r'querySelector',
|
||||
r'\.json', r'/api/', r'CSS\.escape', r'encodeURI', r'font-size',
|
||||
r'background:', r'padding:', r'border', r'SSE parse', r'\[Offline',
|
||||
r'Failed to', r'Error ', r'Soft vault', r'\[Forge\]', r'CodeMirror',
|
||||
r'\[PWA\]', r'\[SW\]', r'DragDrop', r'Dashboard:',
|
||||
]
|
||||
|
||||
french_chars = re.compile(r'[àâäéèêëîïôöùûüçÀÂÄÉÈÊËÎÏÔÖÙÛÜÇ]')
|
||||
ui_words = ['loading', 'error', 'search', 'save', 'delete', 'create',
|
||||
'cancel', 'download', 'upload', 'share', 'copy', 'rename',
|
||||
'open', 'close', 'file', 'folder', 'vault']
|
||||
|
||||
for fname in sorted(os.listdir(js_dir)):
|
||||
if not fname.endswith('.js') or fname == 'i18n.js':
|
||||
continue
|
||||
fpath = os.path.join(js_dir, fname)
|
||||
with open(fpath, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
hardcoded = []
|
||||
for i, line in enumerate(lines, 1):
|
||||
strings = re.findall(r"'([^']+)'|\"([^\"]+)\"|`([^`]+)`", line)
|
||||
for s_tuple in strings:
|
||||
s = s_tuple[0] or s_tuple[1] or s_tuple[2]
|
||||
if len(s) < 4: continue
|
||||
if not re.search(r'[A-Za-zÀ-ÿ]', s): continue
|
||||
if any(re.search(p, s) for p in noise_patterns): continue
|
||||
if s.startswith('#') or s.startswith('.') or s.startswith('http'): continue
|
||||
|
||||
context = ''.join(lines[max(0,i-2):i+1])
|
||||
if 't(' in context or 'data-i18n' in context or 'tr(' in context:
|
||||
continue
|
||||
|
||||
has_fr = bool(french_chars.search(s))
|
||||
is_ui = has_fr or any(w in s.lower() for w in ui_words)
|
||||
if is_ui:
|
||||
hardcoded.append((i, s.strip()[:120]))
|
||||
|
||||
if hardcoded:
|
||||
print(f"\n=== {fname} ({len(hardcoded)}) ===")
|
||||
for ln, s in hardcoded:
|
||||
print(f" L{ln}: {s}")
|
||||
|
||||
# ── Part 2: Check EN locale for French contamination ──
|
||||
with open('frontend/locales/fr.json', encoding='utf-8') as f:
|
||||
fr = json.load(f)
|
||||
with open('frontend/locales/en.json', encoding='utf-8') as f:
|
||||
en = json.load(f)
|
||||
|
||||
print(f"\n=== Locale alignment: FR={len(fr)} EN={len(en)} ===")
|
||||
|
||||
only_fr = set(fr.keys()) - set(en.keys())
|
||||
only_en = set(en.keys()) - set(fr.keys())
|
||||
if only_fr: print(f"Keys in FR only: {sorted(only_fr)}")
|
||||
if only_en: print(f"Keys in EN only: {sorted(only_en)}")
|
||||
|
||||
# EN values with French chars
|
||||
fr_in_en = []
|
||||
for k in sorted(fr.keys()):
|
||||
if k in en and isinstance(en[k], str):
|
||||
if french_chars.search(en[k]):
|
||||
fr_in_en.append(k)
|
||||
|
||||
if fr_in_en:
|
||||
print(f"\n=== EN keys with French text ({len(fr_in_en)}) ===")
|
||||
for k in fr_in_en:
|
||||
if not k.startswith('auto.') and not k.startswith('help.desc_'):
|
||||
print(f" {k}: {en[k][:80]}")
|
||||
Reference in New Issue
Block a user