feat(gui): apply WIP profils+masques+build-windows from stash (2026-04-27)

Application du stash@{0} resté en WIP depuis le 27/04 :
  "On main: wip-gui-profils-masque-manuel-build-windows-2026-04-27"

## Apport

- Pseudonymisation_Gui_V5.py (+1208 lignes) : profils, panneau paramètres
  avancés, éditeur de masques intégré, gestion whitelist/blacklist
- launcher.py (+315) : splash natif PyInstaller, single-instance,
  téléchargement modèles
- anonymisation_onefile.spec : config PyInstaller mise à jour
- pdf_mask_designer.py (+114) : éditeur de masques amélioré
- config_defaults.py (+23) : constantes nouvelles
- tests/unit/test_config_externalization.py (+12) : tests config
- .gitignore (+5)

## Pourquoi

La version courante de la GUI sur la branche feature manquait :
- L'éditeur de masques
- Les profils
- Le panneau paramètres avancés
- Le splash natif au démarrage

Aucun conflit avec mes 10 commits Q-1 (pas de chevauchement de fichiers).

## Validation

75 passed, 10 xfailed sur pytest tests/unit/.

## Note

Le stash reste disponible dans `git stash list` jusqu'à drop explicite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 11:09:46 +02:00
parent 055a31c298
commit 3c9d68b49e
7 changed files with 1664 additions and 179 deletions

View File

@@ -153,6 +153,29 @@ def load_effective_dictionaries_dict(path: Path | None = None) -> Dict[str, Any]
)
def _normalize_string_list(values: Any) -> list[str]:
if not isinstance(values, list):
return []
normalized: list[str] = []
for value in values:
text = str(value).strip()
if text:
normalized.append(text)
return normalized
def load_effective_param_lists(path: Path | None = None) -> Dict[str, list[str]]:
"""Return the effective parameter lists shown in the GUI."""
data = load_effective_dictionaries_dict(path)
return {
"whitelist_phrases": _normalize_string_list(data.get("whitelist_phrases", [])),
"blacklist_force_mask_terms": _normalize_string_list(
data.get("blacklist", {}).get("force_mask_terms", [])
),
"additional_stopwords": _normalize_string_list(data.get("additional_stopwords", [])),
}
def deep_merge_dict(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
merged = deepcopy(base)
for key, value in (override or {}).items():