""" run_filter.py — Frank Outlook Filter (non-interattivo) Versione da eseguire come job schedulato: - Legge le email dall'Inbox dal date_from configurato - Classifica interne/esterne - Sposta nelle cartelle [Frank_Interni] e [Frank_Esterni] - Salva data/outlook_feed.json con le email interne Non chiede conferme. In caso di errore esce con codice 1. """ import sys from pathlib import Path # Assicura che la root del progetto sia nel path sys.path.insert(0, str(Path(__file__).parent.parent.parent)) try: from loguru import logger except ImportError: import logging logger = logging.getLogger(__name__) from modules.outlook.outlook_connector import OutlookConnector from modules.outlook.outlook_filter import OutlookFilter def main(): logger.info("=== Frank Outlook Filter — avvio automatico ===") try: connector = OutlookConnector() connector.connect() except Exception as e: logger.error(f"Connessione Outlook fallita: {e}") sys.exit(1) try: flt = OutlookFilter() except Exception as e: logger.error(f"Caricamento regole fallito: {e}") sys.exit(1) try: emails = flt.get_emails_since(connector) logger.info(f"Email caricate: {len(emails)}") except Exception as e: logger.error(f"Lettura email fallita: {e}") sys.exit(1) classified = flt.classify(emails) n_internal = sum(1 for m in classified if m['category'] == 'internal') n_external = sum(1 for m in classified if m['category'] == 'external') logger.info(f"Classificate: {n_internal} interne, {n_external} esterne") try: counters = flt.execute(classified, connector) logger.info(f"Spostamenti: {counters}") except Exception as e: logger.error(f"Errore durante gli spostamenti: {e}") sys.exit(1) try: internal_only = [m for m in classified if m['category'] == 'internal'] flt.save_feed(internal_only) except Exception as e: logger.warning(f"Salvataggio feed fallito (non critico): {e}") logger.info("=== Frank Outlook Filter — completato ===") if __name__ == '__main__': main()