Config-driven delivery of emails from MS Live POP3 to named IMAP folders on gravlax (mail.critchley.biz, port 993, TLS). Emails are delivered idempotently and deleted from POP3 on success.
imap_deliver.py — delivery logic and route loaderimap_folders.yml — config mapping To: address → IMAP folder nameSimple key/value YAML. Key is the To: address (matched by process_emails dispatcher), value is the IMAP folder name. Folder is created and subscribed automatically on first delivery if it does not exist.
load_routes(config_path=None) -> list — reads imap_folders.yml and returns a list of (address, handler) pairs suitable for the process_emails map. Each handler is a closure over the folder name.process_to_folder(mails, folder) -> set — connects to IMAP, ensures folder exists, appends each message, returns set of UIDLs to delete from POP3. Idempotent: checks Message-ID before appending.move_to_inbox(folder) -> int — copies all messages from folder to INBOX then expunges them. Used to stage emails for POP3 re-processing via gravlax (see todo — Jobserve re-processing). Runnable as python3 imap_deliver.py move-to-inbox <folder>._connect() -> imaplib.IMAP4_SSL — opens an authenticated IMAP connection using credentials from ~/.netrc (machine mail.critchley.biz)._ensure_folder(conn, folder) — selects folder; creates and subscribes it if it does not exist._exists(conn, folder, msg_id) -> bool — searches folder for a message with the given Message-ID header.