""" test_filter.py — Script interattivo di verifica Layer 2 Lancia dalla root di Frank: python modules\outlook\test_filter.py Requisiti: - Outlook aperto e loggato - Step 1 completato (outlook_connector.py funzionante) """ import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) from modules.outlook.outlook_connector import OutlookConnector from modules.outlook.outlook_filter import OutlookFilter SEP = "─" * 60 RULES_PATH = 'config/outlook_rules.json' FEED_PATH = 'data/outlook_feed.json' def main(): print(SEP) print(" Frank — Outlook Filter — Layer 2 Test") print(SEP) # --- Connessione --- print("\n[1/5] Connessione a Outlook...") connector = OutlookConnector() if not connector.connect(): print("✗ Connessione fallita. Assicurati che Outlook sia aperto e loggato.") sys.exit(1) account_email = connector.namespace.CurrentUser.Address print(f"✓ Connesso — {account_email}") # --- Carica regole --- print("\n[2/5] Caricamento regole...") try: fltr = OutlookFilter(rules_path=RULES_PATH) print(f"✓ Regole caricate — domini interni: {fltr.internal_domains}") print(f" Periodo: dal {fltr.date_from} ad oggi") except FileNotFoundError: print(f"✗ File regole non trovato: {RULES_PATH}") sys.exit(1) # --- Lettura email con filtro data --- print(f"\n[3/5] Lettura email (dal {fltr.date_from})...") print(" (potrebbe richiedere qualche secondo sulla mailbox Mediaset...)") emails = fltr.get_emails_since(connector, n=1000) if not emails: print(f" Nessuna email trovata dal {fltr.date_from}.") sys.exit(0) print(f" Caricate {len(emails)} email.") # --- Classificazione --- print(f"\n[4/5] Classificazione interno/esterno...") classified = fltr.classify(emails) internal = [m for m in classified if m['category'] == 'internal'] external = [m for m in classified if m['category'] == 'external'] print(SEP) print(f" Analizzate {len(classified)} email:") print(f" Interne: {len(internal)}") if internal: for m in internal[:3]: print(f" [{m['received']}] {m['sender']:<25} — \"{m['subject'][:50]}\"") if len(internal) > 3: print(f" ... e altre {len(internal) - 3}") print(f" Esterne: {len(external)}") if external: for m in external[:3]: print(f" [{m['received']}] {m['sender']:<25} — \"{m['subject'][:50]}\"") if len(external) > 3: print(f" ... e altre {len(external) - 3}") print(SEP) # --- Conferma spostamenti --- print(f"\n[5/5] Spostamento email nelle cartelle:") print(f" Interne → [Frank_Interni]") print(f" Esterne → [Frank_Esterni]") print(f" ⚠️ Le operazioni sono reversibili — nessuna email viene eliminata") print() try: risposta = input(" Procedo con gli spostamenti? [s/N]: ").strip().lower() except (KeyboardInterrupt, EOFError): risposta = 'n' if risposta != 's': print("\n Spostamenti annullati.") print(" (Il feed JSON non verrà salvato)") sys.exit(0) # --- Esecuzione spostamenti --- print() counters = fltr.execute(classified, connector) print(f" ✓ {counters['internal']} email spostate in [Frank_Interni]") print(f" ✓ {counters['external']} email spostate in [Frank_Esterni]") if counters['errors'] > 0: print(f" ⚠️ {counters['errors']} errori — controlla i log") # --- Salva feed JSON (solo interne) --- fltr.save_feed(internal, path=FEED_PATH) print(f" ✓ Feed salvato in {FEED_PATH} ({len(internal)} email interne)") # --- Riepilogo --- print() print(SEP) print(" Layer 2 completato.") print(f" Feed pronto per Albert: {FEED_PATH}") print(SEP) if __name__ == '__main__': main()