Update archive_emails.py

This commit is contained in:
Jan Kocoń
2025-02-26 20:30:19 +01:00
committed by GitHub
parent 80dfe73f07
commit d7f4a7848d

View File

@@ -2,7 +2,6 @@ import win32com.client
import sys
import datetime
def list_outlook_mailboxes():
"""Returns a list of available mailboxes in Outlook."""
outlook = win32com.client.Dispatch("Outlook.Application")
@@ -34,9 +33,10 @@ def list_main_folders(mailbox_name):
return [folder.Name for folder in mailbox.Folders]
def main_archive():
"""Main function to select a mailbox and folders for archiving."""
total_emails_moved = 0
total_size_moved_kb = 0
"""Main function to select a mailbox and folders for archiving."""
mailboxes = list_outlook_mailboxes()
if not mailboxes:
print("No mailboxes found in Outlook.")
@@ -61,7 +61,6 @@ def main_archive():
print("No corresponding Online Archive found. Exiting.")
sys.exit(1)
# ✅ Sprawdźmy, czy wybrana skrzynka jest poprawna
print(f"Selected mailbox: {mailbox_name}")
main_folders = list_main_folders(mailbox_name)
@@ -86,67 +85,96 @@ def main_archive():
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
# Referencja do wybranego mailboxa i archiwum
mailbox = namespace.Folders[mailbox_name]
archive_root = namespace.Folders[archive_mailbox]
for folder_name in selected_folder_names:
try:
print(f"Accessing folder: {folder_name}")
folder = mailbox.Folders[folder_name]
try:
archive_folder = namespace.Folders[archive_mailbox].Folders[folder_name]
except Exception:
print(f"Archive folder '{folder_name}' does not exist. Attempting to create it...")
try:
archive_folder = namespace.Folders[archive_mailbox].Folders.Add(folder_name)
except Exception as e:
print(f"Failed to create archive folder '{folder_name}'. Skipping. Error: {e}")
continue
# [ZMIANA] - Tworzymy (lub pobieramy) identyczny folder w archiwum
archive_folder = get_or_create_subfolder(archive_root, folder_name)
emails_moved, size_moved_kb = process_folder(folder, archive_folder, run_type)
total_emails_moved += emails_moved
total_size_moved_kb += size_moved_kb
except Exception as e:
print(f"Error accessing folder {folder_name}: {e}")
print("Dry-run complete. No emails were moved." if run_type == 'dry-run' else "Email move completed.")
print(f"Total emails processed: {total_emails_moved}")
print(f"Total size processed: {total_size_moved_kb / 1024:.2f} MB")
except (ValueError, IndexError):
print("Invalid folder selection.")
sys.exit(1)
def get_or_create_subfolder(parent_folder, subfolder_name):
"""
Sprawdza, czy w folderze 'parent_folder' istnieje podfolder 'subfolder_name'.
Jeśli nie istnieje — tworzy go. Zwraca referencję do podfolderu.
"""
try:
return parent_folder.Folders[subfolder_name]
except:
print(f"Archive folder '{subfolder_name}' does not exist in '{parent_folder.Name}'. Attempting to create it...")
try:
new_folder = parent_folder.Folders.Add(subfolder_name)
return new_folder
except Exception as e:
print(f"Failed to create subfolder '{subfolder_name}' in '{parent_folder.Name}'. Error: {e}")
# Jeśli nie możemy utworzyć podfolderu, zwracamy sam parent_folder,
# ale w praktyce powinniśmy przerywać, bo maile nie trafią tam, gdzie chcemy.
return parent_folder
def process_folder(folder, archive_folder, run_type, depth=0):
old_email_count = 0
total_size_kb = 0
"""Processes a folder and its subfolders, counting and optionally moving emails."""
"""
Processes a folder and its subfolders, moving or counting old emails.
Zwraca liczbę przeniesionych maili i sumaryczny rozmiar w KB.
"""
old_email_count = 0
total_size_kb = 0
try:
# print(f"{' ' * depth}Processing folder: {folder.Name}")
#print(f"{' ' * depth}Processing folder: {folder.Name}")
# Dla debugowania, możemy podejrzeć obie ścieżki:
#print(f"{' ' * depth}Source folder path: {folder.FolderPath}")
#print(f"{' ' * depth}Archive folder path: {archive_folder.FolderPath}")
for item in folder.Items:
# Sprawdzamy np. 12 miesięcy wstecz
if hasattr(item, 'ReceivedTime') and item.ReceivedTime < (datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=365)):
old_email_count += 1
total_size_kb += item.Size / 1024
#print(item.Subject)
if run_type == 'move':
try:
item.Move(archive_folder)
except Exception as move_err:
print(f"Error moving item: {move_err}")
print(f"{' ' * depth}Source folder path: {folder.FolderPath}")
print(f"{' ' * depth}Archive folder path: {archive_folder.FolderPath}")
if old_email_count > 0:
status_text = "would be moved" if run_type == "dry-run" else "moved"
print(f"{' ' * depth}Folder '{folder.Name}': {old_email_count} emails "
f"({total_size_kb / 1024:.2f} MB) {status_text}.")
except Exception as e:
print(f"Error processing folder {folder.Name}: {e}")
# ✅ PRZENIESIONE POZA EXCEPT → teraz zawsze przetwarza podfoldery
if old_email_count > 0 :
print(f"{' ' * depth}Folder '{folder.Name}': {old_email_count} emails ({total_size_kb / 1024:.2f} MB) would be moved.")
# [ZMIANA] Dla każdego podfolderu w skrzynce źródłowej odtwarzamy podfolder w archiwum
for subfolder in folder.Folders:
sub_emails, sub_size = process_folder(subfolder, archive_folder, run_type, depth + 1)
sub_archive_folder = get_or_create_subfolder(archive_folder, subfolder.Name)
sub_emails, sub_size = process_folder(subfolder, sub_archive_folder, run_type, depth + 1)
old_email_count += sub_emails
total_size_kb += sub_size
return old_email_count, total_size_kb
process_folder(subfolder, archive_folder, run_type, depth + 1)
if __name__ == "__main__":
main_archive()