From 7787331d6f019079ce7515bbee8993dc3f11e4f9 Mon Sep 17 00:00:00 2001 From: UNFR Date: Mon, 27 Oct 2025 13:26:05 +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 --- CHANGELOG.md | 98 ++++++++++++++++++++++++ PROBLEME_FICHIER_NON_CORRIGE.md | 86 +++++++++++++++++++++ README.md | 43 ++++++++++- diagnose_filename.py | 128 ++++++++++++++++++++++++++++++++ 4 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md create mode 100644 PROBLEME_FICHIER_NON_CORRIGE.md create mode 100644 diagnose_filename.py diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ce603aa --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,98 @@ +# Changelog - FixEncoding pour NZBGet + +## Version 1.1 - 2025-10-27 + +### 🐛 Corrections de bugs +- **Correction du bug de l'espace insécable** : Le script détecte maintenant correctement le caractère "à" encodé comme `Ã\xa0` (à + espace insécable U+00A0) +- Amélioration de la détection avec double vérification (pattern + test de conversion) + +### ✨ Améliorations +- Ajout de patterns supplémentaires pour les majuscules accentuées +- Liste étendue de patterns : É, È, Ê, Î, Ô, Ù, Û, Ç, Â, À +- La détection vérifie maintenant que la conversion produit un résultat différent + +### 🔧 Outils ajoutés +- **diagnose_filename.py** : Script de diagnostic pour analyser les noms de fichiers problématiques + - Affiche les octets en hexadécimal + - Détecte les caractères suspects (espaces insécables, etc.) + - Teste la conversion et affiche le résultat + - Analyse des dossiers complets + +### 📚 Documentation +- Ajout de **PROBLEME_FICHIER_NON_CORRIGE.md** : Guide détaillé sur les cas spéciaux +- Amélioration du README avec section de diagnostic +- Exemples de cas d'usage supplémentaires + +### 🔍 Détails techniques + +**Problème corrigé :** +Le caractère UTF-8 "à" (U+00E0) est encodé avec les octets `0xC3 0xA0`. +Quand mal interprété comme ISO-8859-1 : +- `0xC3` → "Ã" (U+00C3) +- `0xA0` → espace insécable (U+00A0, non-breaking space) + +L'espace insécable est invisible mais différent d'un espace normal (U+0020). + +**Solution :** +- Ajout du pattern `'Ã\xa0'` à la liste de détection +- Double vérification : si un pattern est trouvé, on teste si `filename.encode('iso-8859-1').decode('utf-8')` produit un résultat différent +- Si la conversion échoue, le fichier est ignoré (protection contre les faux positifs) + +--- + +## Version 1.0 - 2025-10-27 + +### 🎉 Version initiale + +**Fonctionnalités :** +- Détection et correction automatique des problèmes d'encodage UTF-8 → ISO-8859-1 +- Support des caractères accentués français : é, è, ê, à, â, ç, ô, etc. +- Options configurables via NZBGet : + - Debug : mode verbose pour les logs + - FileExtensions : filtre par extension + - DryRun : mode simulation +- Script de test standalone (test_fix_encoding.py) +- Documentation complète (README.md, QUICKSTART.md) +- Compatible multiplateforme (Linux, Windows, macOS, Docker, NAS) +- Traitement récursif des sous-dossiers +- Gestion sécurisée des erreurs +- Exit codes conformes aux standards NZBGet + +**Patterns supportés (v1.0) :** +- é → é +- è → è +- ê → ê +- ë → ë +- à → à +- â → â +- ä → ä +- ç → ç +- ô → ô +- ö → ö +- ù → ù +- û → û +- ü → ü +- î → î +- ï → ï +- Å" → œ +- É → É +- À → À + +--- + +## Roadmap / Améliorations futures possibles + +### Court terme +- [ ] Support optionnel de ftfy (Fix Text For You) pour les cas complexes +- [ ] Option pour backup automatique avant renommage +- [ ] Rapport détaillé en JSON pour intégration avec d'autres outils + +### Moyen terme +- [ ] Support d'autres types de problèmes d'encodage (UTF-8 → CP1252, etc.) +- [ ] Interface de configuration avancée +- [ ] Statistiques cumulatives dans les logs + +### Long terme +- [ ] Détection automatique du type de problème d'encodage +- [ ] Support des langues autres que le français (allemand, espagnol, etc.) +- [ ] Plugin web pour visualisation dans l'interface NZBGet diff --git a/PROBLEME_FICHIER_NON_CORRIGE.md b/PROBLEME_FICHIER_NON_CORRIGE.md new file mode 100644 index 0000000..292a0bd --- /dev/null +++ b/PROBLEME_FICHIER_NON_CORRIGE.md @@ -0,0 +1,86 @@ +# ⚠️ CAS SPÉCIAL : Fichier non corrigé + +## Problème rencontré + +Le fichier suivant n'a pas été corrigé : +``` +04-Tout s'arrange à la fin.flac +``` + +Alors que d'autres fichiers similaires ont été corrigés avec succès. + +## Cause probable + +Il y a **deux variantes** du problème d'encodage pour la lettre "à" : + +### Variante 1 : à + espace normal (U+0020) +- Moins courant +- Exemple : `à ` (à suivi d'un espace classique) + +### Variante 2 : à + espace insécable (U+00A0) ⬅️ VOTRE CAS +- Plus courant +- Exemple : `Ã\xa0` (à suivi d'un espace insécable invisible) +- **C'est ce qui se passe avec votre fichier !** + +## Explication technique + +En UTF-8, la lettre "à" est encodée avec les octets `0xC3 0xA0`. + +Quand ces octets sont mal interprétés comme ISO-8859-1 : +- `0xC3` → devient le caractère "Ã" +- `0xA0` → devient un **espace insécable** (non-breaking space) + +L'espace insécable est invisible à l'œil nu, mais c'est un caractère différent d'un espace normal ! + +## Solution + +Le script a été **mis à jour** (version corrigée) pour détecter et corriger ce cas spécifique. + +## Comment vérifier votre fichier + +Utilisez le script de diagnostic fourni : + +```bash +python3 diagnose_filename.py "04-Tout s'arrange à la fin.flac" +``` + +Ce script vous montrera : +- Les octets exacts du nom de fichier +- Les caractères suspects (comme l'espace insécable) +- Le résultat de la correction + +## Réexécuter la correction + +Avec la **version mise à jour** du script : + +### Option 1 : Test manuel +```bash +python3 test_fix_encoding.py /chemin/vers/vos/fichiers +python3 test_fix_encoding.py /chemin/vers/vos/fichiers --fix +``` + +### Option 2 : Via NZBGet +1. Remplacez l'ancien `FixEncoding.py` par la version mise à jour +2. Dans NZBGet, allez dans **History** +3. Sélectionnez le téléchargement concerné +4. Cliquez sur **Post-Process Again** +5. Sélectionnez **FixEncoding.py** et lancez + +## Amélioration du script + +La nouvelle version utilise une **double vérification** : + +1. ✅ Recherche les patterns connus (dont `Ã\xa0`) +2. ✅ Teste si la conversion `ISO-8859-1 → UTF-8` fonctionne +3. ✅ Compare le résultat avec l'original + +Cette approche est plus robuste et détecte même les variantes rares du problème. + +## Vérification après correction + +Après avoir réexécuté le script, votre fichier devrait devenir : +``` +04-Tout s'arrange à la fin.flac +``` + +Si le problème persiste, utilisez le script de diagnostic pour obtenir plus d'informations sur la nature exacte du problème d'encodage. diff --git a/README.md b/README.md index ec56d48..d840ea4 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,15 @@ Le script détecte et corrige automatiquement : - `é` → `é` - `è` → `è` - `ê` → `ê` -- `à ` → `à` +- `à ` → `à` (avec espace normal) +- `Ã\xa0` → `à` (avec espace insécable - cas le plus fréquent) - `â` → `â` - `ç` → `ç` - `ô` → `ô` - Et tous les autres caractères accentués français +**Note importante :** Le caractère "à" peut être encodé de deux façons différentes selon les systèmes. Le script gère automatiquement les deux cas. + **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` @@ -152,6 +155,27 @@ Le script est compatible avec : - ✅ Docker (NZBGet en conteneur) - ✅ NAS Synology, QNAP, etc. (avec Python) +## Outils de diagnostic + +### Script de diagnostic +Le package inclut un script de diagnostic pour analyser les noms de fichiers problématiques : + +```bash +# Analyser un fichier spécifique +python3 diagnose_filename.py "nom-du-fichier.ext" + +# Analyser tous les fichiers d'un dossier +python3 diagnose_filename.py /chemin/vers/dossier +``` + +Ce script affiche : +- Les octets exacts du nom de fichier +- Les caractères suspects (espaces insécables, etc.) +- Les patterns d'encodage détectés +- Le résultat de la correction + +**Utilisez-le en cas de problème pour comprendre exactement ce qui se passe !** + ## Dépannage ### Le script ne s'exécute pas @@ -174,6 +198,23 @@ Le script est compatible avec : 2. Activez DryRun pour voir ce que le script détecte 3. Consultez les logs dans NZBGet +### Un fichier spécifique n'est pas corrigé + +Si un fichier contenant "à " n'est pas corrigé, c'est probablement dû à un **espace insécable invisible**. + +**Diagnostic :** +```bash +python3 diagnose_filename.py "nom-du-fichier-problematique.ext" +``` + +Ce script vous montrera exactement quels caractères posent problème. + +**Solution :** +- Assurez-vous d'utiliser la dernière version du script (qui gère les espaces insécables) +- Réexécutez le post-processing sur ce téléchargement + +Consultez `PROBLEME_FICHIER_NON_CORRIGE.md` pour plus de détails. + ### 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. diff --git a/diagnose_filename.py b/diagnose_filename.py new file mode 100644 index 0000000..8643c2a --- /dev/null +++ b/diagnose_filename.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Script de diagnostic pour analyser un nom de fichier problématique. + +Usage: + python3 diagnose_filename.py "04-Tout s'arrange à la fin.flac" + +Ou pour analyser tous les fichiers d'un dossier : + python3 diagnose_filename.py /chemin/vers/dossier +""" + +import os +import sys + + +def analyze_filename(filename): + """Analyse en détail un nom de fichier.""" + print(f"\n{'='*70}") + print(f"ANALYSE DU FICHIER") + print(f"{'='*70}") + print(f"\n📄 Nom affiché : {filename}") + print(f"📊 Longueur : {len(filename)} caractères") + print(f"\n🔍 Représentation Python :") + print(f" {repr(filename)}") + + # Analyse octet par octet + print(f"\n🔢 Octets (hex) :") + try: + encoded = filename.encode('utf-8') + hex_str = ' '.join(f'{b:02x}' for b in encoded) + print(f" {hex_str}") + except: + print(f" ❌ Impossible d'encoder en UTF-8") + + # Recherche de caractères suspects + print(f"\n🔎 Caractères suspects :") + found_issues = False + for i, char in enumerate(filename): + code = ord(char) + if code > 127 or code == 0xA0: # Non-ASCII ou espace insécable + print(f" Position {i:2d}: '{char}' (U+{code:04X} / {code})") + found_issues = True + + if not found_issues: + print(f" ✅ Aucun caractère suspect détecté") + + # Test de conversion + print(f"\n🔄 Test de correction :") + try: + fixed = filename.encode('iso-8859-1').decode('utf-8') + if fixed == filename: + print(f" ℹ️ La conversion ne change rien") + else: + print(f" ✅ Conversion réussie !") + print(f" 📄 Nom corrigé : {fixed}") + print(f" 🔍 Représentation : {repr(fixed)}") + except UnicodeDecodeError as e: + print(f" ❌ Erreur de décodage UTF-8 : {e}") + print(f" 💡 Le fichier contient un mélange d'encodages") + except UnicodeEncodeError as e: + print(f" ❌ Erreur d'encodage ISO-8859-1 : {e}") + print(f" 💡 Le fichier contient des caractères non compatibles ISO-8859-1") + + # Détection des patterns connus + patterns = { + 'é': 'é', 'è': 'è', 'ê': 'ê', 'ë': 'ë', + 'à ': 'à', 'Ã\xa0': 'à (avec espace insécable)', + 'â': 'â', 'ä': 'ä', 'ç': 'ç', + 'ô': 'ô', 'ö': 'ö', 'ù': 'ù', 'û': 'û', 'ü': 'ü', + 'î': 'î', 'ï': 'ï', 'Å"': 'œ' + } + + print(f"\n📋 Patterns d'encodage détectés :") + found_patterns = [] + for pattern, correct in patterns.items(): + if pattern in filename: + found_patterns.append((pattern, correct)) + + if found_patterns: + for pattern, correct in found_patterns: + print(f" • '{pattern}' devrait être '{correct}'") + else: + print(f" ℹ️ Aucun pattern connu détecté") + + print(f"\n{'='*70}\n") + + +def main(): + if len(sys.argv) < 2: + print("Usage:") + print(' python3 diagnose_filename.py "nom-du-fichier.ext"') + print(" python3 diagnose_filename.py /chemin/vers/dossier") + sys.exit(1) + + target = sys.argv[1] + + if os.path.isdir(target): + # Analyse tous les fichiers du dossier + print(f"\n{'#'*70}") + print(f"ANALYSE DU DOSSIER : {target}") + print(f"{'#'*70}") + + files_with_issues = [] + + for dirpath, dirnames, filenames in os.walk(target): + for filename in filenames: + # Cherche des patterns suspects + if any(p in filename for p in ['Ã', 'Å', 'Ã']): + files_with_issues.append((dirpath, filename)) + + if not files_with_issues: + print(f"\n✅ Aucun fichier avec problème d'encodage détecté!") + else: + print(f"\n⚠️ {len(files_with_issues)} fichier(s) avec problème d'encodage détecté(s):\n") + for dirpath, filename in files_with_issues: + rel_path = os.path.relpath(dirpath, target) + if rel_path == '.': + rel_path = '(racine)' + print(f"\n📁 {rel_path}") + analyze_filename(filename) + else: + # Analyse un seul nom de fichier + analyze_filename(target) + + +if __name__ == '__main__': + main()