From 91c6df7457eb62cffc0046bba63f73caacfb5198 Mon Sep 17 00:00:00 2001 From: UNFR Date: Mon, 27 Oct 2025 13:17:09 +0000 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20les=20fichiers=20vers=20?= =?UTF-8?q?"/"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FixEncoding.py | 226 +++++++++++++++++++++++++++++++++++++++++++ QUICKSTART.md | 67 +++++++++++++ README.md | 190 ++++++++++++++++++++++++++++++++++++ test_fix_encoding.py | 105 ++++++++++++++++++++ 4 files changed, 588 insertions(+) create mode 100644 FixEncoding.py create mode 100644 QUICKSTART.md create mode 100644 README.md create mode 100644 test_fix_encoding.py diff --git a/FixEncoding.py b/FixEncoding.py new file mode 100644 index 0000000..fcf3aee --- /dev/null +++ b/FixEncoding.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +############################################################################## +### NZBGET POST-PROCESSING SCRIPT ### +# +# Corrige les problèmes d'encodage dans les noms de fichiers. +# +# Ce script détecte et corrige les noms de fichiers qui ont été mal encodés +# (UTF-8 interprété comme ISO-8859-1/Windows-1252) et les renomme correctement. +# +# NOTE: Ce script utilise Python 3. +# + +############################################################################## +### OPTIONS ### + +# Activer le mode débogage (affiche plus d'informations dans les logs). +# +# yes, no. +#Debug=no + +# Extensions de fichiers à traiter (séparées par des virgules). +# Laisser vide pour traiter tous les fichiers. +# +# Exemples: .flac,.mp3,.mkv,.mp4 +#FileExtensions= + +# Mode de simulation (ne renomme pas les fichiers, affiche seulement ce qui serait fait). +# +# yes, no. +#DryRun=no + +### NZBGET POST-PROCESSING SCRIPT ### +############################################################################## + +import os +import sys +import re + + +# Exit codes utilisés par NZBGet +POSTPROCESS_SUCCESS = 93 +POSTPROCESS_ERROR = 94 +POSTPROCESS_NONE = 95 + + +def is_debug(): + """Vérifie si le mode debug est activé.""" + return os.environ.get('NZBPO_DEBUG', 'no').lower() == 'yes' + + +def is_dry_run(): + """Vérifie si le mode simulation est activé.""" + return os.environ.get('NZBPO_DRYRUN', 'no').lower() == 'yes' + + +def get_file_extensions(): + """Récupère la liste des extensions de fichiers à traiter.""" + extensions = os.environ.get('NZBPO_FILEEXTENSIONS', '') + if not extensions: + return None + return [ext.strip().lower() for ext in extensions.split(',')] + + +def print_log(message, level='INFO'): + """Affiche un message dans les logs NZBGet.""" + print(f'[{level}] {message}') + sys.stdout.flush() + + +def is_encoding_issue(filename): + """ + Détecte si un nom de fichier contient des problèmes d'encodage typiques. + + Recherche des motifs caractéristiques de l'UTF-8 mal interprété comme ISO-8859-1: + - à suivi de caractères accentués (à, â, é, è, ê, ô, etc.) + """ + # Motifs caractéristiques d'un problème d'encodage UTF-8 -> ISO-8859-1 + patterns = [ + 'é', # é mal encodé + 'è', # è mal encodé + 'ê', # ê mal encodé + 'ë', # ë mal encodé + 'à ', # à mal encodé + 'â', # â mal encodé + 'ä', # ä mal encodé + 'ç', # ç mal encodé + 'ô', # ô mal encodé + 'ö', # ö mal encodé + 'ù', # ù mal encodé + 'û', # û mal encodé + 'ü', # ü mal encodé + 'î', # î mal encodé + 'ï', # ï mal encodé + 'Å"', # œ mal encodé + 'É', # É mal encodé + 'À', # À mal encodé + ] + + return any(pattern in filename for pattern in patterns) + + +def fix_encoding(filename): + """ + Corrige le nom de fichier en supposant qu'il a été mal interprété. + + Le problème typique est: UTF-8 -> interprété comme ISO-8859-1 + Solution: encoder en ISO-8859-1 (pour revenir aux octets originaux UTF-8) + puis décoder en UTF-8 + """ + try: + # Tente de corriger l'encodage + # On encode d'abord en ISO-8859-1 pour récupérer les octets originaux + # puis on décode en UTF-8 + fixed = filename.encode('iso-8859-1').decode('utf-8') + return fixed + except (UnicodeDecodeError, UnicodeEncodeError): + # Si la conversion échoue, on retourne le nom original + return None + + +def process_file(filepath, dirname, filename, extensions_filter, dry_run): + """ + Traite un fichier et le renomme si nécessaire. + + Returns: + bool: True si le fichier a été renommé, False sinon + """ + # Vérifie l'extension si un filtre est défini + if extensions_filter: + file_ext = os.path.splitext(filename)[1].lower() + if file_ext not in extensions_filter: + return False + + # Vérifie si le nom contient des problèmes d'encodage + if not is_encoding_issue(filename): + return False + + # Tente de corriger l'encodage + fixed_filename = fix_encoding(filename) + + if not fixed_filename or fixed_filename == filename: + if is_debug(): + print_log(f'Impossible de corriger: {filename}', 'DEBUG') + return False + + # Construit les chemins complets + old_path = os.path.join(dirname, filename) + new_path = os.path.join(dirname, fixed_filename) + + # Vérifie que le nouveau nom n'existe pas déjà + if os.path.exists(new_path): + print_log(f'Le fichier de destination existe déjà: {fixed_filename}', 'WARNING') + return False + + # Affiche l'action + print_log(f'Renommage: {filename}') + print_log(f' -> {fixed_filename}') + + # Renomme le fichier (sauf en mode simulation) + if not dry_run: + try: + os.rename(old_path, new_path) + return True + except OSError as e: + print_log(f'Erreur lors du renommage: {e}', 'ERROR') + return False + else: + print_log('[MODE SIMULATION - Fichier non renommé]', 'INFO') + return True + + +def main(): + """Fonction principale du script.""" + + # Récupère le répertoire de travail depuis les variables d'environnement NZBGet + nzb_directory = os.environ.get('NZBPP_DIRECTORY') + + if not nzb_directory: + print_log('Erreur: NZBPP_DIRECTORY non défini', 'ERROR') + sys.exit(POSTPROCESS_ERROR) + + if not os.path.isdir(nzb_directory): + print_log(f'Erreur: Le répertoire n\'existe pas: {nzb_directory}', 'ERROR') + sys.exit(POSTPROCESS_ERROR) + + print_log('=== Début du traitement de correction d\'encodage ===') + print_log(f'Répertoire: {nzb_directory}') + + # Récupère les options + extensions_filter = get_file_extensions() + dry_run = is_dry_run() + + if dry_run: + print_log('MODE SIMULATION ACTIVÉ - Aucun fichier ne sera modifié', 'WARNING') + + if extensions_filter: + print_log(f'Filtrage par extensions: {", ".join(extensions_filter)}') + + # Parcourt tous les fichiers récursivement + files_renamed = 0 + files_processed = 0 + + for dirpath, dirnames, filenames in os.walk(nzb_directory): + for filename in filenames: + files_processed += 1 + + if process_file(os.path.join(dirpath, filename), dirpath, filename, extensions_filter, dry_run): + files_renamed += 1 + + # Affiche le résumé + print_log('=== Résumé ===') + print_log(f'Fichiers traités: {files_processed}') + print_log(f'Fichiers renommés: {files_renamed}') + + if files_renamed > 0: + print_log('Correction d\'encodage terminée avec succès') + sys.exit(POSTPROCESS_SUCCESS) + else: + print_log('Aucun fichier à corriger') + sys.exit(POSTPROCESS_NONE) + + +if __name__ == '__main__': + main() diff --git a/QUICKSTART.md b/QUICKSTART.md new file mode 100644 index 0000000..e28528c --- /dev/null +++ b/QUICKSTART.md @@ -0,0 +1,67 @@ +# 🚀 DÉMARRAGE RAPIDE + +## Test AVANT installation (recommandé) + +Testez d'abord le script sur vos fichiers existants : + +```bash +# Simulation (ne modifie rien) +python3 test_fix_encoding.py /chemin/vers/vos/fichiers + +# Application réelle des corrections +python3 test_fix_encoding.py /chemin/vers/vos/fichiers --fix +``` + +## Installation dans NZBGet + +### 1. Copiez le script + +**Linux/macOS/Docker :** +```bash +cp FixEncoding.py /path/to/nzbget/scripts/ +chmod +x /path/to/nzbget/scripts/FixEncoding.py +``` + +**Windows :** +Copiez `FixEncoding.py` dans `C:\ProgramData\NZBGet\scripts\` + +### 2. Configurez NZBGet + +1. Ouvrez l'interface web de NZBGet +2. **Settings** → Cliquez **Reload** (en bas à droite) +3. Cherchez **FIXENCODING** dans les paramètres +4. (Optionnel) Activez **DryRun=yes** pour un premier test +5. **Save all changes** + +### 3. Activez le script + +**Pour tous les téléchargements :** +- **Settings** → **Extension Scripts** → Cochez **FixEncoding.py** + +**OU par catégorie :** +- **Settings** → **Categories** → Sélectionnez une catégorie +- **Extensions** → Ajoutez **FixEncoding.py** + +### 4. Testez + +1. **History** → Sélectionnez un téléchargement +2. **Post-Process Again** → Cochez **FixEncoding.py** +3. **Start** +4. Consultez **Messages** pour voir les résultats + +## ✅ C'est tout ! + +Le script corrigera automatiquement : +- `19-La grâce.flac` → `19-La grâce.flac` +- `06-La fièvre dans le sang.flac` → `06-La fièvre dans le sang.flac` +- `02-Géant.flac` → `02-Géant.flac` + +## 📖 Documentation complète + +Consultez **README.md** pour plus de détails et options. + +## ⚙️ Options principales + +- **Debug=yes** : Affiche plus d'informations dans les logs +- **FileExtensions=.flac,.mp3** : Limite aux extensions spécifiées +- **DryRun=yes** : Mode simulation (recommandé pour le premier test) diff --git a/README.md b/README.md new file mode 100644 index 0000000..ec56d48 --- /dev/null +++ b/README.md @@ -0,0 +1,190 @@ +# Script de Correction d'Encodage pour NZBGet + +## Description + +Ce script de post-processing pour NZBGet corrige automatiquement les problèmes d'encodage dans les noms de fichiers. Il est particulièrement utile pour corriger les caractères français mal encodés (UTF-8 interprété comme ISO-8859-1). + +### Problèmes corrigés + +Le script détecte et corrige automatiquement : +- `é` → `é` +- `è` → `è` +- `ê` → `ê` +- `à ` → `à` +- `â` → `â` +- `ç` → `ç` +- `ô` → `ô` +- Et tous les autres caractères accentués français + +**Exemple :** +- `19-La grâce.flac` → `19-La grâce.flac` +- `06-La fièvre dans le sang.flac` → `06-La fièvre dans le sang.flac` +- `02-Géant.flac` → `02-Géant.flac` + +## Installation + +### 1. Prérequis + +- NZBGet installé et fonctionnel +- Python 3.x installé sur votre système + +### 2. Installation du script + +1. **Téléchargez** le fichier `FixEncoding.py` + +2. **Copiez le script** dans le répertoire des scripts de NZBGet : + - **Linux/macOS** : `/path/to/nzbget/scripts/` + - **Windows** : `C:\ProgramData\NZBGet\scripts\` + - **Docker** : montez le script dans `/scripts/` + +3. **Rendez le script exécutable** (Linux/macOS/Docker uniquement) : + ```bash + chmod +x FixEncoding.py + ``` + +### 3. Configuration dans NZBGet + +1. Ouvrez l'interface web de NZBGet +2. Allez dans **Settings** (Paramètres) +3. Cliquez sur **Reload** en bas à droite pour que NZBGet détecte le nouveau script +4. Cherchez la section **FIXENCODING** +5. Configurez les options selon vos besoins (voir ci-dessous) + +### 4. Activation du script + +#### Option A : Global (pour tous les téléchargements) + +1. Allez dans **Settings → Extension Scripts** +2. Activez **FixEncoding.py** + +#### Option B : Par catégorie + +1. Allez dans **Settings → Categories** +2. Sélectionnez une catégorie +3. Dans **Extensions**, ajoutez **FixEncoding.py** + +## Configuration + +Le script propose plusieurs options configurables dans NZBGet : + +### Debug +- **Valeurs** : `yes` / `no` +- **Défaut** : `no` +- **Description** : Active le mode débogage pour afficher plus d'informations dans les logs + +### FileExtensions +- **Valeurs** : Extensions séparées par des virgules (ex: `.flac,.mp3,.mkv`) +- **Défaut** : Vide (tous les fichiers) +- **Description** : Limite le traitement aux fichiers avec ces extensions + +### DryRun +- **Valeurs** : `yes` / `no` +- **Défaut** : `no` +- **Description** : Mode simulation - affiche ce qui serait fait sans modifier les fichiers + +## Utilisation + +### Automatique + +Une fois configuré, le script s'exécute automatiquement après chaque téléchargement et corrige les noms de fichiers si nécessaire. + +### Test manuel + +Pour tester le script sur un téléchargement déjà terminé : + +1. Ouvrez l'interface web de NZBGet +2. Allez dans **History** (Historique) +3. Sélectionnez un téléchargement +4. Cliquez sur **Post-Process Again** +5. Sélectionnez **FixEncoding.py** +6. Cliquez sur **Start** + +### Mode simulation (recommandé pour le premier test) + +1. Dans **Settings**, activez **DryRun=yes** pour FixEncoding +2. Exécutez le script sur un téléchargement de test +3. Vérifiez les logs pour voir ce qui serait modifié +4. Si tout est correct, désactivez DryRun + +## Vérification des logs + +Pour voir ce que le script a fait : + +1. Allez dans **Messages** dans NZBGet +2. Cherchez les messages `[INFO]` de FixEncoding +3. Vous verrez : + - Les fichiers détectés avec des problèmes d'encodage + - Les anciens et nouveaux noms + - Un résumé du nombre de fichiers traités + +## Exemples de logs + +### Succès +``` +[INFO] === Début du traitement de correction d'encodage === +[INFO] Répertoire: /downloads/Music/Album +[INFO] Renommage: 19-La grâce.flac +[INFO] -> 19-La grâce.flac +[INFO] Renommage: 06-La fièvre dans le sang.flac +[INFO] -> 06-La fièvre dans le sang.flac +[INFO] === Résumé === +[INFO] Fichiers traités: 15 +[INFO] Fichiers renommés: 2 +[INFO] Correction d'encodage terminée avec succès +``` + +### Aucun fichier à corriger +``` +[INFO] === Début du traitement de correction d'encodage === +[INFO] Répertoire: /downloads/Music/Album +[INFO] === Résumé === +[INFO] Fichiers traités: 10 +[INFO] Fichiers renommés: 0 +[INFO] Aucun fichier à corriger +``` + +## Compatibilité + +Le script est compatible avec : +- ✅ Linux (toutes distributions) +- ✅ Windows (avec Python installé) +- ✅ macOS +- ✅ Docker (NZBGet en conteneur) +- ✅ NAS Synology, QNAP, etc. (avec Python) + +## Dépannage + +### Le script ne s'exécute pas + +1. Vérifiez que Python 3 est installé : + ```bash + python3 --version + ``` + +2. Vérifiez les permissions du script : + ```bash + ls -l /path/to/scripts/FixEncoding.py + ``` + +3. Activez le mode Debug et consultez les logs + +### Les fichiers ne sont pas renommés + +1. Vérifiez que le script est bien activé dans la configuration +2. Activez DryRun pour voir ce que le script détecte +3. Consultez les logs dans NZBGet + +### Erreur "File exists" + +Le script ne renommera pas un fichier si le nom de destination existe déjà. Vous devrez renommer manuellement l'un des deux fichiers. + +## Support + +Pour toute question ou problème : +- Consultez les logs avec Debug=yes +- Vérifiez que vous utilisez Python 3.x +- Assurez-vous que le script a les bonnes permissions + +## Licence + +Script libre d'utilisation et de modification. diff --git a/test_fix_encoding.py b/test_fix_encoding.py new file mode 100644 index 0000000..93aacb0 --- /dev/null +++ b/test_fix_encoding.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Script de test standalone pour vérifier la correction d'encodage. +Utilisez ce script pour tester la correction AVANT de l'intégrer à NZBGet. + +Usage: + python3 test_fix_encoding.py /chemin/vers/dossier + python3 test_fix_encoding.py /chemin/vers/dossier --fix (pour vraiment renommer) +""" + +import os +import sys + + +def is_encoding_issue(filename): + """Détecte si un nom de fichier contient des problèmes d'encodage.""" + patterns = [ + 'é', 'è', 'ê', 'ë', 'à ', 'â', 'ä', 'ç', + 'ô', 'ö', 'ù', 'û', 'ü', 'î', 'ï', 'Å"', + 'É', 'À' + ] + return any(pattern in filename for pattern in patterns) + + +def fix_encoding(filename): + """Corrige le nom de fichier.""" + try: + fixed = filename.encode('iso-8859-1').decode('utf-8') + return fixed + except (UnicodeDecodeError, UnicodeEncodeError): + return None + + +def main(): + if len(sys.argv) < 2: + print("Usage: python3 test_fix_encoding.py /chemin/vers/dossier [--fix]") + sys.exit(1) + + directory = sys.argv[1] + do_fix = '--fix' in sys.argv + + if not os.path.isdir(directory): + print(f"Erreur: Le répertoire '{directory}' n'existe pas") + sys.exit(1) + + print(f"\n{'='*70}") + print(f"TEST DE CORRECTION D'ENCODAGE") + print(f"{'='*70}") + print(f"Répertoire: {directory}") + print(f"Mode: {'CORRECTION' if do_fix else 'SIMULATION'}") + print(f"{'='*70}\n") + + files_with_issues = 0 + files_corrected = 0 + + for dirpath, dirnames, filenames in os.walk(directory): + for filename in filenames: + if is_encoding_issue(filename): + files_with_issues += 1 + fixed = fix_encoding(filename) + + if fixed and fixed != filename: + rel_path = os.path.relpath(dirpath, directory) + if rel_path == '.': + rel_path = '' + + print(f"\n📁 {rel_path if rel_path else '(racine)'}") + print(f" ❌ Avant : {filename}") + print(f" ✅ Après : {fixed}") + + if do_fix: + old_path = os.path.join(dirpath, filename) + new_path = os.path.join(dirpath, fixed) + + if os.path.exists(new_path): + print(f" ⚠️ ERREUR: Le fichier de destination existe déjà!") + else: + try: + os.rename(old_path, new_path) + print(f" ✔️ Renommé avec succès") + files_corrected += 1 + except OSError as e: + print(f" ❌ ERREUR: {e}") + else: + files_corrected += 1 + + print(f"\n{'='*70}") + print(f"RÉSUMÉ") + print(f"{'='*70}") + print(f"Fichiers avec problèmes d'encodage: {files_with_issues}") + print(f"Fichiers {'corrigés' if do_fix else 'à corriger'}: {files_corrected}") + + if not do_fix and files_corrected > 0: + print(f"\n💡 Pour appliquer les corrections, relancez avec: --fix") + elif do_fix and files_corrected > 0: + print(f"\n✅ Les fichiers ont été corrigés avec succès!") + elif files_corrected == 0: + print(f"\n✅ Aucun problème d'encodage détecté!") + + print(f"{'='*70}\n") + + +if __name__ == '__main__': + main()