73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
"""Échange de configuration par fichier JSON (workflow email V5, P1-3).
|
|
|
|
- ``build_export_payload`` : produit le dict V5 (format consommé par
|
|
``scripts/merge_params.merge_params``) à partir des listes du profil courant ;
|
|
- ``import_config_file`` : fusionne un JSON reçu dans le ``dictionnaires.yml``
|
|
utilisateur, sans écraser l'existant.
|
|
|
|
Aucune dépendance à un widget : testable en pur Python.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import Iterable
|
|
|
|
EXPORT_VERSION = "1"
|
|
|
|
|
|
def build_export_payload(
|
|
whitelist: Iterable[str], blacklist: Iterable[str], version: str = EXPORT_VERSION
|
|
) -> dict:
|
|
"""Construit la charge utile d'export au format consommé par merge_params."""
|
|
return {
|
|
"version": version,
|
|
"date_export": datetime.now(timezone.utc).isoformat(),
|
|
"whitelist_phrases": [str(t) for t in whitelist],
|
|
"blacklist_force_mask_terms": [str(t) for t in blacklist],
|
|
}
|
|
|
|
|
|
def _yaml_lists(config_path: Path) -> tuple[set, set]:
|
|
import yaml
|
|
|
|
cfg = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
|
wl = set(cfg.get("whitelist_phrases", []) or [])
|
|
bl = set((cfg.get("blacklist", {}) or {}).get("force_mask_terms", []) or [])
|
|
return wl, bl
|
|
|
|
|
|
def import_config_file(json_path, config_path) -> bool:
|
|
"""Fusionne ``json_path`` dans ``config_path`` (YAML). Retourne True si la
|
|
config a changé, False si rien de nouveau.
|
|
|
|
Fusion autonome (union des listes, jamais d'écrasement) — volontairement
|
|
SANS dépendance à ``scripts/merge_params`` (non bundlé en frozen). Même
|
|
sémantique : ``whitelist_phrases`` et ``blacklist.force_mask_terms``.
|
|
"""
|
|
import json
|
|
import yaml
|
|
|
|
json_path = Path(json_path)
|
|
config_path = Path(config_path)
|
|
before_wl, before_bl = _yaml_lists(config_path)
|
|
|
|
data = json.loads(json_path.read_text(encoding="utf-8"))
|
|
incoming_wl = {str(t).strip() for t in data.get("whitelist_phrases", []) if str(t).strip()}
|
|
incoming_bl = {str(t).strip() for t in data.get("blacklist_force_mask_terms", []) if str(t).strip()}
|
|
|
|
after_wl = before_wl | incoming_wl
|
|
after_bl = before_bl | incoming_bl
|
|
if after_wl == before_wl and after_bl == before_bl:
|
|
return False
|
|
|
|
cfg = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
|
cfg["whitelist_phrases"] = sorted(after_wl)
|
|
cfg.setdefault("blacklist", {})
|
|
cfg["blacklist"]["force_mask_terms"] = sorted(after_bl)
|
|
config_path.write_text(
|
|
yaml.dump(cfg, allow_unicode=True, default_flow_style=False, sort_keys=False),
|
|
encoding="utf-8",
|
|
)
|
|
return True
|