aerc sendmail wip

This commit is contained in:
Tim Bendt
2025-08-11 09:44:47 -05:00
parent 5eddddc8ec
commit c64fbbb072
6 changed files with 561 additions and 13 deletions

View File

@@ -18,6 +18,7 @@ from src.services.microsoft_graph.mail import (
archive_mail_async,
delete_mail_async,
synchronize_maildir_async,
process_outbox_async,
)
from src.services.microsoft_graph.auth import get_access_token
@@ -38,6 +39,11 @@ def create_maildir_structure(base_path):
ensure_directory_exists(os.path.join(base_path, "tmp"))
ensure_directory_exists(os.path.join(base_path, ".Archives"))
ensure_directory_exists(os.path.join(base_path, ".Trash", "cur"))
# Create outbox structure for sending emails
ensure_directory_exists(os.path.join(base_path, "outbox", "new"))
ensure_directory_exists(os.path.join(base_path, "outbox", "cur"))
ensure_directory_exists(os.path.join(base_path, "outbox", "tmp"))
ensure_directory_exists(os.path.join(base_path, "outbox", "failed"))
async def fetch_calendar_async(
@@ -228,7 +234,8 @@ async def _sync_outlook_data(
vdir = os.path.expanduser(vdir)
# Save emails to Maildir
maildir_path = os.getenv("MAILDIR_PATH", os.path.expanduser("~/Mail")) + f"/{org}"
base_maildir_path = os.getenv("MAILDIR_PATH", os.path.expanduser("~/Mail"))
maildir_path = base_maildir_path + f"/{org}"
attachments_dir = os.path.join(maildir_path, "attachments")
ensure_directory_exists(attachments_dir)
create_maildir_structure(maildir_path)
@@ -256,6 +263,9 @@ async def _sync_outlook_data(
task_read = progress.add_task("[blue]Marking as read...", total=0)
task_archive = progress.add_task("[yellow]Archiving mail...", total=0)
task_delete = progress.add_task("[red]Deleting mail...", total=0)
task_outbox = progress.add_task(
"[bright_green]Sending outbound mail...", total=0
)
# Stage 1: Synchronize local changes (read, archive, delete, calendar) to the server
progress.console.print(
@@ -273,13 +283,16 @@ async def _sync_outlook_data(
headers, org_vdir_path, progress, task_local_calendar, dry_run
)
# Handle mail changes in parallel
# Handle mail changes and outbound email in parallel
await asyncio.gather(
synchronize_maildir_async(
maildir_path, headers, progress, task_read, dry_run
),
archive_mail_async(maildir_path, headers, progress, task_archive, dry_run),
delete_mail_async(maildir_path, headers, progress, task_delete, dry_run),
process_outbox_async(
base_maildir_path, org, headers, progress, task_outbox, dry_run
),
)
progress.console.print("[bold green]Step 1: Local changes synced.[/bold green]")
@@ -628,14 +641,50 @@ async def daemon_mode(
vdir, org
)
# Check for outbound emails in outbox
base_maildir_path = os.getenv(
"MAILDIR_PATH", os.path.expanduser("~/Mail")
)
outbox_new_dir = os.path.join(base_maildir_path, org, "outbox", "new")
outbox_changes = False
pending_email_count = 0
if os.path.exists(outbox_new_dir):
pending_emails = [
f for f in os.listdir(outbox_new_dir) if not f.startswith(".")
]
pending_email_count = len(pending_emails)
outbox_changes = pending_email_count > 0
# Determine what changed and show appropriate status
if mail_changes and calendar_changes:
if mail_changes and calendar_changes and outbox_changes:
console.print(
create_status_display(
f"Changes detected! Mail: Remote {remote_message_count}, Local {local_message_count} | Calendar: {calendar_change_desc} | Outbox: {pending_email_count} pending. Starting sync...",
"yellow",
)
)
elif mail_changes and calendar_changes:
console.print(
create_status_display(
f"Changes detected! Mail: Remote {remote_message_count}, Local {local_message_count} | Calendar: {calendar_change_desc}. Starting sync...",
"yellow",
)
)
elif mail_changes and outbox_changes:
console.print(
create_status_display(
f"Changes detected! Mail: Remote {remote_message_count}, Local {local_message_count} | Outbox: {pending_email_count} pending. Starting sync...",
"yellow",
)
)
elif calendar_changes and outbox_changes:
console.print(
create_status_display(
f"Changes detected! Calendar: {calendar_change_desc} | Outbox: {pending_email_count} pending. Starting sync...",
"yellow",
)
)
elif mail_changes:
console.print(
create_status_display(
@@ -650,9 +699,16 @@ async def daemon_mode(
"yellow",
)
)
elif outbox_changes:
console.print(
create_status_display(
f"Outbound emails detected! {pending_email_count} emails pending. Starting sync...",
"yellow",
)
)
# Sync if any changes detected
if mail_changes or calendar_changes:
if mail_changes or calendar_changes or outbox_changes:
await _sync_outlook_data(
dry_run,
vdir,
@@ -674,6 +730,8 @@ async def daemon_mode(
if two_way_calendar:
status_parts.append(f"Calendar: {calendar_change_desc}")
status_parts.append(f"Outbox: {pending_email_count} pending")
console.print(
create_status_display(
f"No changes detected ({', '.join(status_parts)})",