Intégration du logo "aivanonym" (gradient magenta → rose → pêche → noir)
fourni par le propriétaire. Refonte visuelle complète :
• APP_VERSION bump v5.4 → v5.5
• Assets (tous générés depuis assets/icons/logo.png) :
- assets/icons/app.ico multi-résolution 16→256 (icône EXE Windows)
- assets/icons/icon_{16,32,48,64,128,256,512}.png (fallback + taskbar)
- assets/logo_header.png (260×61, intégré dans l'en-tête de la GUI)
- assets/logo_splash.png (335×80, intégré dans le splash)
- assets/splash.png redessiné avec logo + bandeau gradient primary→accent
• Palette dérivée du logo (remplace l'ancien bleu) :
- CLR_PRIMARY #E91E63 magenta logo (CTA, liens)
- CLR_PRIMARY_DARK #C2185B hover / pressed
- CLR_PRIMARY_LIGHT #FCE4EC fond doux (tags, cartes)
- CLR_ACCENT #FFB74D pêche logo (secondaire)
- CLR_ACCENT_LIGHT #FFF3E0
- CLR_TEXT/SECONDARY proches du noir/gris du logo
• Pseudonymisation_Gui_V5.py :
- Helper _asset(name) : résout sous sys._MEIPASS/assets en mode frozen
- _apply_window_icon() : iconbitmap (.ico sur Windows) + iconphoto (PNG)
- _load_image_safe() : charge PIL avec ref persistante (évite GC tkinter)
- Header fixe hors onglets : logo image + baseline "100% local"
- Ligne accent magenta sous le header (inspiration logo)
- Onglets custom uniformes (remplace ttk.Notebook dont les tabs avaient
des tailles variables selon l'état) : tous les boutons identiques,
seule une bordure basse magenta signale l'onglet actif. _switch_tab()
gère l'affichage du contenu et la mise à jour des styles.
- Onglet 1 "Anonymisation" : workflow principal (choix, lancer, résultats)
- Onglet 2 "Paramètres" : 3 listes (whitelist/blacklist/stopwords) +
export/import + save. Plus de section repliable — respiration visuelle.
- Boutons export/import repensés avec les couleurs de la palette
• anonymisation_onefile.spec :
- datas : ajout du dossier assets/ entier
- EXE(icon=assets/icons/app.ico) : le .exe a maintenant le logo dans
l'Explorateur Windows, la barre des tâches, le gestionnaire des tâches
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Demande utilisateur : pouvoir identifier la build au premier coup d'oeil
sans confondre ancien/nouveau exe lors des tests.
Implémentation :
- build_info.py (gitignored, fallback "dev" pour mode développement)
régénéré automatiquement par scripts/rebuild_anon.ps1 avec :
BUILD_DATE = "2026-04-15 18:15"
BUILD_COMMIT = "234137e"
BUILD_BRANCH = "main"
- Pseudonymisation_Gui_V5.py : fonction _version_long() qui construit
"v5.4 · 2026-04-15 18:15 · #234137e" depuis build_info (avec fallback
silencieux si module absent en dev). Affichée dans :
- Titre fenêtre : "Pseudonymisation de vos documents — v5.4 · ..."
- Status bar en bas à droite
- anonymisation_onefile.spec : build_info.py ajouté aux datas bundlées.
- scripts/rebuild_anon.ps1 : STEP 4a génère build_info.py avant le
PyInstaller avec git rev-parse short + branch + date courante.
- .gitignore : build_info.py exclu (volatile, regénéré).
En mode dev (pas frozen) : affichage "v5.4" seul (fallback).
En mode frozen : affichage complet avec date/commit.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Troisième liste paramétrable dans la GUI v5.4, après whitelist_phrases et
blacklist.force_mask_terms : "Mots à ne jamais identifier comme noms".
Cible les sigles, acronymes métier locaux, ou termes ALL-CAPS récurrents
qui ressemblent à des noms propres mais n'en sont pas.
Différence avec la whitelist :
- whitelist_phrases : terme spécifique à protéger même s'il a été masqué
par regex/NER (filtre final sur l'audit + sous-mots de hits multi-mots)
- additional_stopwords : empêche le terme d'être candidat-nom dès l'amont
(intégré à _MEDICAL_STOP_WORDS_SET, filtre toutes les étapes)
Wired dans _load_params, _save_params, _export_params, _import_params.
La nouvelle clé additional_stopwords est incluse dans le JSON d'échange
inter-établissements.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Au premier lancement, la config embarquée est copiée dans config/
à côté de l'exe. Les lancements suivants utilisent cette copie externe.
Workflow de mise à jour :
1. L'établissement exporte ses paramètres (JSON)
2. On fusionne avec merge_params.py
3. On leur envoie le nouveau dictionnaires.yml par email
4. Ils le déposent dans config/ à côté de l'exe
5. Aucune recompilation nécessaire
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GUI :
- Bouton "Exporter pour envoi" → fichier JSON sur le Bureau avec
whitelist + blacklist + version + date, prêt à envoyer par email
- Bouton "Importer" → charge un JSON et fusionne (sans doublons)
Serveur :
- scripts/merge_params.py : fusionne les JSON reçus des établissements
dans la config maîtresse dictionnaires.yml
Usage : python scripts/merge_params.py export1.json export2.json
Workflow :
1. L'établissement ajuste les paramètres dans la GUI
2. Clique "Exporter" → fichier JSON
3. Envoie par email
4. On fusionne avec merge_params.py
5. On reconstruit l'exe avec la config enrichie
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bug critique corrigé : les noms forcés (contexte Dr/Mme) comme "MASSE"
étaient masqués dans le texte mais pas dans le PDF raster car filtrés
par les stop-words médicaux. Nouveau kind "NOM_FORCE" qui bypass le
filtre stop-words dans les fonctions de redaction vector et raster.
GUI : remplacement des zones texte brut par des listes interactives
avec champ de saisie + bouton Ajouter + bouton Supprimer, fond coloré
(vert pour whitelist, rose pour blacklist).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Nouvelle section whitelist_phrases dans dictionnaires.yml : phrases
qui ne doivent jamais être anonymisées (FP récurrents)
- Fonction _apply_whitelist : restaure les phrases whitelistées après
anonymisation, même si des mots ont été remplacés par des placeholders
- GUI : section "Paramètres avancés" repliable avec :
- Zone texte whitelist (phrases à exclure)
- Zone texte blacklist (mots à toujours masquer)
- Bouton sauvegarder → persiste dans le YAML
- Phrases initiales : "classification internationale", "prise en charge",
"bas de contention", "date de naissance", "code postal", etc.
Score évaluation maintenu à 100.0/100 (A+)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Nouveau module format_converter.py : conversion automatique vers PDF
avant anonymisation. Formats supportés :
- PDF (passthrough)
- DOCX (python-docx → texte → PDF)
- ODT (odfpy → texte → PDF)
- RTF (striprtf → texte → PDF)
- TXT (texte brut → PDF via PyMuPDF)
- HTML (BeautifulSoup → texte → PDF)
- JPEG/PNG/TIFF/BMP (image embarquée → OCR docTR en aval)
Nouvelle fonction process_document() : wrapper qui gère la conversion
puis appelle process_pdf(). GUI mise à jour pour chercher tous les
formats supportés (plus seulement *.pdf).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Parseur trackare spécifique (détection par contenu, extraction structurée des PII)
- Support format "Dr X. NOM" et "Mme X. NOM" (initiales + noms composés avec tiret)
- Détection noms personnel médical (Aide, Cadre Infirmier, etc.)
- Masquage RPPS, établissements (EHPAD/SSR/USLD standalone), lieux de naissance
- Stop words médicaux enrichis (~270 entrées : DCI, spécialités, termes contextuels)
- Détection compagnon (noms adjacents à des noms connus dans le texte brut)
- Protection noms composés (JEAN-PIERRE traité comme un tout, pas JEAN + PIERRE)
- Nettoyage codes postaux orphelins, téléphones fragmentés/partiels
- Désactivation masquage dates génériques, AGE avec contexte obligatoire
- GUI : extraction OGC depuis le nom du répertoire parent, incrustation sur les pages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- _app_dir() utilise toujours Path(__file__).parent au lieu de
dir() qui ne détecte pas __compiled__ dans une fonction
- Ajout crash.log + messagebox en cas d'erreur fatale
(même avec --windows-console-mode=disable)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>