diff --git a/ArchiviazioneMail.py b/ArchiviazioneMail.py index b416581..895bba9 100644 --- a/ArchiviazioneMail.py +++ b/ArchiviazioneMail.py @@ -2,105 +2,121 @@ import win32com.client from datetime import datetime, timedelta from tqdm import tqdm import time +import locale # --- CONFIGURAZIONE --- ARCHIVE_NAME = "Archivio online - alessandro.battilani@intesasanpaolo.com" -MONTHS_LIMIT = 3 +# MONTHS_LIMIT = 3 # ---------------------- -def mostra_cartelle(folder_object, indent=""): - for folder in folder_object.Folders: - print(f"{indent}{folder.Name}") - # Richiama se stessa per cercare sottocartelle - mostra_cartelle(folder, indent + " ") +# Imposta la localizzazione in italiano +try: + locale.setlocale(locale.LC_TIME, "it_IT.UTF-8") +except: + try: + locale.setlocale(locale.LC_TIME, "ita_ita") + except: + print("Locale italiano non impostato, uso nomi manuali.") def main(): print("Connessione a Outlook in corso...") try: outlook = win32com.client.Dispatch("Outlook.Application") namespace = outlook.GetNamespace("MAPI") - - # Partendo dalla radice dell'account predefinito - # root = namespace.GetDefaultFolder(6).Parent - # mostra_cartelle(root) - email_sent = namespace.GetDefaultFolder() - inbox = namespace.GetDefaultFolder(6) archive_root = namespace.Folders.Item(ARCHIVE_NAME) + + # 6 = Inbox (ReceivedTime), 5 = Sent Items (SentOn) + folders_to_process = [ + (namespace.GetDefaultFolder(6), "[ReceivedTime]", "ReceivedTime"), + (namespace.GetDefaultFolder(5), "[SentOn]", "SentOn") + ] except Exception as e: - print(f"Errore di connessione: {e}") + print(f"Errore connessione: {e}") return + stringa_mounths_limit = input("\n Quanti mesi vuoi tenere in linea? ") + + # Convertiamo la stringa in un numero intero + MONTHS_LIMIT = int(stringa_mounths_limit) + cutoff_date = datetime.now() - timedelta(days=MONTHS_LIMIT * 30) filter_date_str = cutoff_date.strftime("%d/%m/%Y %H:%M") - - - - filter_str = f"[ReceivedTime] < '{filter_date_str}'" - items = inbox.Items.Restrict(filter_str) - items.Sort("[ReceivedTime]", True) - - total_items = items.Count - if total_items == 0: - print("Nessuna email da archiviare.") - return - - print(f"Trovate {total_items} email vecchie. Inizio archiviazione...") - - archived_count = 0 mesi_it = {1: "Gennaio", 2: "Febbraio", 3: "Marzo", 4: "Aprile", 5: "Maggio", 6: "Giugno", 7: "Luglio", 8: "Agosto", 9: "Settembre", 10: "Ottobre", 11: "Novembre", 12: "Dicembre"} - with tqdm(total=total_items, desc="Archiviazione", unit="mail", colour='green') as pbar: - for i in range(total_items, 0, -1): - try: - item = items.Item(i) + for source_folder, filter_attr, time_attr in folders_to_process: + print(f"\n--- Analisi cartella: {source_folder.Name} ---") + + filter_str = f"{filter_attr} < '{filter_date_str}'" + items = source_folder.Items.Restrict(filter_str) + items.Sort(filter_attr, True) + + total_items = items.Count + if total_items == 0: + print(f"Nessuna mail più vecchia di {MONTHS_LIMIT} mesi in {source_folder.Name}.") + continue + + archived_count = 0 + # tqdm posizionato esternamente per monitorare il progresso reale + with tqdm(total=total_items, desc=f"Archiviazione {source_folder.Name}", unit="mail", colour='green') as pbar: + for i in range(total_items, 0, -1): + try: + item = items.Item(i) + + if not hasattr(item, time_attr): + pbar.update(1) + continue + + # Recupero data dinamico + rt = getattr(item, time_attr) + received_time = datetime(rt.year, rt.month, rt.day, rt.hour, rt.minute) + anno_str = str(received_time.year) + nome_mese = mesi_it[received_time.month] + pbar.set_description(f"Archiviazione {source_folder.Name} - Mese: {nome_mese} {anno_str}") + + # Gestione struttura cartelle (Source -> Anno -> Mese) + try: + arch_type = archive_root.Folders.Item(source_folder.Name) + except: + arch_type = archive_root.Folders.Add(source_folder.Name) + + try: + y_f = arch_type.Folders.Item(anno_str) + except: + y_f = arch_type.Folders.Add(anno_str) + + month_folder_name = f"{received_time.month:02d}-{nome_mese}" + try: + target_folder = y_f.Folders.Item(month_folder_name) + except: + target_folder = y_f.Folders.Add(month_folder_name) + + # --- TENTA LO SPOSTAMENTO CON RETRY (Reintegrato) --- + archived_item = None + for tentativo in range(3): + try: + archived_item = item.Move(target_folder) + if archived_item: + archived_item.Save() + time.sleep(0.4) # Pausa vitale + break + except: + time.sleep(1) # Attesa per server busy + + if archived_item: + archived_count += 1 + pbar.set_postfix(successo=archived_count) + else: + pbar.set_postfix(error="Move fallito") + + except Exception as e: + pbar.set_postfix(err=str(e)[:15]) + + # Update della barra sempre alla fine del ciclo i pbar.update(1) - if not hasattr(item, 'ReceivedTime'): - continue - - rt = item.ReceivedTime - received_time = datetime(rt.year, rt.month, rt.day, rt.hour, rt.minute) - anno_str = str(received_time.year) - nome_mese = mesi_it[received_time.month] - pbar.set_description(f"Mese: {nome_mese} {anno_str}") - - # Cartelle - month_folder_name = f"{received_time.month:02d}-{nome_mese}" - try: - y_f = archive_root.Folders.Item(anno_str) - except: # noqa: E722 - y_f = archive_root.Folders.Add(anno_str) - try: - target_folder = y_f.Folders.Item(month_folder_name) - except: # noqa: E722 - target_folder = y_f.Folders.Add(month_folder_name) - - # --- TENTA LO SPOSTAMENTO CON RETRY --- - archived_item = None - for tentativo in range(3): - try: - archived_item = item.Move(target_folder) - if archived_item: - archived_item.Save() - time.sleep(0.5) # Pausa vitale per il server - break - except: # noqa: E722 - time.sleep(1) # Aspetta se il server è occupato - - if not archived_item: - pbar.set_postfix(error="Move fallito") - continue - - archived_count += 1 - pbar.set_postfix(archiviate=archived_count) - - except Exception as e: - pbar.set_postfix(last_err=str(e)[:15]) - continue - - print(f"\nCompletato. Archiviate: {archived_count}") + print(f"\nOperazione conclusa con successo.") if __name__ == "__main__": main() \ No newline at end of file