import os block_cipher = None app_dir = 'C:\\Users\\dom\\ai\\anonymisation' datas = [ (os.path.join(app_dir, 'config'), 'config'), (os.path.join(app_dir, 'data', 'bdpm'), os.path.join('data', 'bdpm')), (os.path.join(app_dir, 'data', 'finess'), os.path.join('data', 'finess')), (os.path.join(app_dir, 'data', 'insee'), os.path.join('data', 'insee')), (os.path.join(app_dir, 'models', 'camembert-bio-deid', 'onnx'), os.path.join('models', 'camembert-bio-deid', 'onnx')), (os.path.join(app_dir, 'detectors'), 'detectors'), (os.path.join(app_dir, 'scripts'), 'scripts'), # Assets UI : logo (header + splash), icônes fenêtre, splash image. # Le launcher et la GUI y accèdent via _asset(name) qui résout sous # sys._MEIPASS/assets en mode frozen. (os.path.join(app_dir, 'assets'), 'assets'), ] # Fichiers directs dans data/ — IMPÉRATIF pour fonctionnement correct du core. # Sans eux : stop-words/villes/DPI labels/companion blacklist sont des sets vides, # ce qui dégrade la qualité d'anonymisation et peut masquer/laisser passer des faux-positifs. for data_file in [ 'stopwords_manuels.txt', 'villes_blacklist.txt', 'dpi_labels_blacklist.txt', 'companion_blacklist.txt', ]: src = os.path.join(app_dir, 'data', data_file) if os.path.exists(src): datas.append((src, 'data')) for pyfile in ['anonymizer_core_refactored_onnx.py', 'eds_pseudo_manager.py', 'gliner_manager.py', 'camembert_ner_manager.py', 'Pseudonymisation_Gui_V5.py', 'build_info.py']: datas.append((os.path.join(app_dir, pyfile), '.')) a = Analysis( [os.path.join(app_dir, 'launcher.py')], pathex=[app_dir], datas=datas, hiddenimports=[ 'anonymizer_core_refactored_onnx', 'eds_pseudo_manager', 'gliner_manager', 'camembert_ner_manager', 'Pseudonymisation_Gui_V5', 'edsnlp', 'edsnlp.pipes', 'edsnlp.pipes.ner', 'edsnlp.pipes.ner.pseudo', 'spacy', 'spacy.lang.fr', 'gliner', 'onnxruntime', 'transformers', 'tokenizers', 'torch', 'pdfplumber', 'ahocorasick', 'sklearn', 'scipy', 'pydantic', 'yaml', 'PIL', 'loguru', 'regex', # optimum : utilisé par ner_manager_onnx.py (fallback NER legacy). # Sans ça, la GUI affiche "NER indisponible : optimum.onnxruntime introuvable" # si EDS-Pseudo échoue. Le pipeline principal (CamemBERT-bio ONNX + # EDS-Pseudo + GLiNER) n'en dépend pas — mais l'absence du hiddenimport # crée un message d'erreur cosmétique gênant. 'optimum', 'optimum.onnxruntime', 'optimum.pipelines', 'optimum.modeling_base', 'optimum.exporters.onnx', ], cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) # Splash natif PyInstaller : image affichée AU LANCEMENT DE L'EXE, # avant même que Python démarre. Couvre les ~15-30 s de décompression # du bundle --onefile dans %TEMP% qui laissaient l'écran vide auparavant. # Le launcher ferme le splash via pyi_splash.close() une fois la GUI prête. splash = Splash( os.path.join(app_dir, 'assets', 'splash.png'), binaries=a.binaries, datas=a.datas, # Texte dynamique PyInstaller positionné dans la zone libre du PNG # (y=170-235). text_pos correspond au coin haut-gauche du texte. text_pos=(60, 195), text_size=10, text_color='white', minify_script=True, always_on_top=False, ) exe = EXE( pyz, a.scripts, splash, # image affichée immédiatement splash.binaries, # bootloader splash a.binaries, a.zipfiles, a.datas, [], name='Anonymisation', debug=False, strip=False, upx=False, console=False, # Icône du fichier .exe visible dans l'Explorateur Windows et la taskbar # (dérivée du logo aivanonym, multi-résolution 16→256 dans le .ico). icon=os.path.join(app_dir, 'assets', 'icons', 'app.ico'), )