diff --git a/_batch_i18n.py b/_batch_i18n.py deleted file mode 100644 index a123258..0000000 --- a/_batch_i18n.py +++ /dev/null @@ -1,190 +0,0 @@ -"""Batch i18n: replace all remaining French strings in JS modules with t() calls.""" -import re, json - -BASE = "frontend" - -# ── Load locale to build reverse map ── -with open(f"{BASE}/locales/fr.json", encoding="utf-8") as f: - fr = json.load(f) -text_to_key = {} -for k, v in fr.items(): - if k.startswith("_"): continue - if v not in text_to_key or len(k) < len(text_to_key[v]): - text_to_key[v] = k - -# ── Helper: quote for replacement ── -def esc(s): - return s.replace('\\', '\\\\').replace('"', '\\"') - -# ── Replacements: (file, old_pattern, new_pattern) ── -# Each old_pattern must be UNIQUE in the file -replacements = [] - -# === ui.js === -f = f"{BASE}/js/ui.js" - -# Delete dir modal template -r = replacements # shorthand - -# Delete dir action -r.append((f, - "confirmBtn.disabled = true;\n confirmBtn.textContent = 'Suppression...';\n \n try {\n const result = await api(`/api/directory", - "confirmBtn.disabled = true;\n confirmBtn.textContent = t('modal.creating');\n \n try {\n const result = await api(`/api/directory")) - -r.append((f, - "showToast(`Dossier supprimé (${result.deleted_count} fichiers)`, 'success');", - "showToast(t('toast.dir_deleted', {count: result.deleted_count}), 'success');")) - -r.append((f, - "showToast(err.message || 'Erreur lors de la suppression', 'error');\n confirmBtn.disabled = false;\n confirmBtn.textContent = 'Supprimer définitivement';", - "showToast(err.message || t('toast.delete_error'), 'error');\n confirmBtn.disabled = false;\n confirmBtn.textContent = t('modal.delete_permanently');")) - -# Rename toasts -r.append((f, - "showToast(type === 'directory' ? 'Dossier renommé' : 'Fichier renommé', 'success');", - "showToast(type === 'directory' ? t('toast.dir_renamed') : t('toast.file_renamed'), 'success');")) - -r.append((f, - "showToast(err.message || 'Erreur lors du renommage', 'error');", - "showToast(err.message || t('toast.rename_error'), 'error');")) - -# Copy path toast -r.append((f, - "showToast(`Chemin copié : ${path}`, 'success');", - "showToast(t('toast.path_copied', {path: path}), 'success');")) - -r.append((f, - "showToast('Erreur lors de la copie', 'error');", - "showToast(t('toast.copy_error'), 'error');")) - -# Bookmark toast -r.append((f, - 'showToast(data.bookmarked ? "Ajouté aux bookmarks" : "Retiré des bookmarks", "success");', - 'showToast(data.bookmarked ? t("toast.bookmark_added") : t("toast.bookmark_removed"), "success");')) - -# Dir saved search toast -r.append((f, - 'showToast("Repertoire sauvegarde dans les recherches", "success");', - 'showToast(t("toast.dir_saved_search"), "success");')) - -# Viewer error toast -r.append((f, - 'showToast("Erreur lors du chargement du viewer: " + err.message, "error");', - 'showToast(t("toast.viewer_error") + ": " + err.message, "error");')) - - -# === palette.js === -f = f"{BASE}/js/palette.js" -pal = text_to_key - -# Confirm dialogs -r.append((f, - 'confirm(`Supprimer le fichier \\"${path}\\" ?`)', - 'confirm(t("confirm.delete_file_named", {path: path}))')) - -r.append((f, - 'confirm(`Supprimer \\"${path}\\" et TOUT son contenu ?`)', - 'confirm(t("confirm.delete_dir_named", {path: path}))')) - -# Show toasts -r.append((f, - "showToast('Erreur de création','error')", - "showToast(t('toast.create_error'),'error')")) - -r.append((f, - "showToast('Erreur','error')", - "showToast(t('common.error'),'error')")) - -# === config.js === -f = f"{BASE}/js/config.js" - -# About sections -r.append((f, - 'title: "Application",', - 'title: t("about.section_app"),')) -r.append((f, - 'title: "Environnement",', - 'title: t("about.section_env"),')) -r.append((f, - 'title: "Composants",', - 'title: t("about.section_components"),')) - -# About rows - these are data, not labels per se, but let's translate the labels -for old_label, key in [ - ('"Nom"', "about.name"), ('"Version"', "about.version"), - ('"Version API"', "about.api_version"), ('"Statut"', "about.status"), - ('"Vaults configurés"', "about.vaults_configured"), - ('"Fichiers indexés"', "about.files_indexed"), - ('"Navigateur"', "about.browser"), ('"Plateforme"', "about.platform"), - ('"Langue"', "about.language"), ('"Backend"', "about.backend"), - ('"Rendu Markdown"', "about.markdown_renderer"), - ('"Surveillance fichiers"', "about.file_watcher"), - ('"Frontend"', "about.frontend"), ('"Icônes"', "about.icons"), - ('"Coloration syntaxe"', "about.syntax_highlight"), - ('"Éditeur"', "about.editor"), -]: - r.append((f, f'[{old_label},', f'[t("{key}"),')) - -# Admin-only / no webhooks -r.append((f, - "list.innerHTML = '
Admin uniquement
';", - "list.innerHTML = '
' + t('common.loading') + '
';")) -r.append((f, - "list.innerHTML = '
Aucun webhook configuré.
';", - "list.innerHTML = '
' + t('common.none') + '
';")) - -# === auth.js === -f = f"{BASE}/js/auth.js" -r.append((f, - 'Administration — Utilisateurs', - "' + t('admin.title') + '")) -r.append((f, - '+ Nouvel utilisateur', - "' + t('admin.new_user') + '")) -r.append((f, - "title=\"Fermer\"", - "title=\"' + t('common.close') + '\"")) - -# === viewer.js === -f = f"{BASE}/js/viewer.js" -r.append((f, - "titleInp.placeholder = 'Titre...'", - "titleInp.placeholder = t('forge.title_placeholder')")) -r.append((f, - "title: \"Ouvrir dans une nouvelle fenetre\"", - "title: t('forge.popout')")) -r.append((f, - 'document.createTextNode("pop-out")', - 'document.createTextNode(t("forge.popout_label"))')) - -# === dashboard.js === -f = f"{BASE}/js/dashboard.js" -r.append((f, - '"Copier"', - 't("dashboard.copy_btn")')) -r.append((f, - '"Ouvrir"', - 't("dashboard.open_btn")')) - -# === search.js === -f = f"{BASE}/js/search.js" -r.append((f, - "summaryText.textContent = `${data.total} résultat(s)", - "summaryText.textContent = t('search.results_count', {count: data.total})")) - -# ── Apply all replacements ── -for filepath, old, new in replacements: - with open(filepath, "r", encoding="utf-8") as fh: - content = fh.read() - count = content.count(old) - if count == 0: - print(f"SKIP {filepath}: pattern not found: {old[:60]}...") - continue - if count > 1: - print(f"WARN {filepath}: {count} matches for: {old[:60]}...") - content = content.replace(old, new) - with open(filepath, "w", encoding="utf-8") as fh: - fh.write(content) - print(f"OK {filepath}: {count} replacement(s)") - -print(f"\nTotal replacements applied: {len(replacements)}") diff --git a/_i18n_final.py b/_i18n_final.py deleted file mode 100644 index 23ad980..0000000 --- a/_i18n_final.py +++ /dev/null @@ -1,202 +0,0 @@ -"""One-pass i18n: replace all French strings in all JS modules.""" -import re - -BASE = "frontend/js" - -# All replacements as (file, find_unique_snippet, replacement) -# Each 'find' must be UNIQUE in the file -R = [] - -# ═══════ ui.js ═══════ -F = f"{BASE}/ui.js" - -# Create file modal template -R.append((F, - '

Créer un fichier

', - '

${t(\'modal.create_file\')}

')) -R.append((F, - '', - '')) -R.append((F, - '\n \n \n \n