2.6 KiB
2.6 KiB
IMAP Email Migration Pattern
Source-to-destination IMAP migration using Python stdlib (imaplib). Used for migrating email accounts from SiteGround to MXroute.
Known Hosts
| Provider | IMAP Host | Port |
|---|---|---|
| SiteGround | c1113726.sgvps.net | 993 |
| MXroute | heracles.mxrouting.net | 993 |
| germainebrown.com | mail.germainebrown.com | 993 |
| iCloud | imap.mail.me.com | 993 |
Pattern
import imaplib, ssl
ctx = ssl.create_default_context()
# Connect old
old = imaplib.IMAP4_SSL(OLD_HOST, 993, ssl_context=ctx, timeout=15)
old.login(email, old_pw)
# Connect new
new = imaplib.IMAP4_SSL(NEW_HOST, 993, ssl_context=ctx, timeout=15)
new.login(email, new_pw)
# Get folder list
for line in old.list()[1]:
decoded = line.decode()
# IMAP list format: (flags) "." "foldername"
# Extract the last quoted segment
parts = decoded.split('"')
folder = parts[-2] if len(parts) >= 2 else decoded.split()[-1]
# Copy messages
for uid in uids:
r = old.fetch(uid, "(RFC822)")
if r[0] == "OK" and isinstance(r[1][0], tuple):
new.append(target_folder, None, None, r[1][0][1])
Pitfalls
- SiteGround folder list is nonstandard — subfolders show as
INBOX.Trash,INBOX.Sent, etc. but the LIST response uses"."as separator. Parse carefully — there are many redundant.entries. Only folders with actual content (INBOX.Trash, INBOX.Sent, etc.) are real. - Timeout on large folders — 60s is not enough for 100+ messages. Set terminal timeout to 300 for full migration.
- Duplicate on retry — if a migration is interrupted and restarted, messages get appended twice. No built-in dedup during copy. Mapped folders (Trash, Sent) may show 2x expected count after retry. Clean up via MXroute webmail.
- Folder name mapping — SiteGround uses dotted hierarchy (INBOX.Trash), MXroute uses flat names (Trash). Map explicitly per account.
- MXroute folder creation —
new.create("Trash")works for flat names but can fail if the folder already exists (catch and pass). - MXroute LIST response may show 6
.entries with no content — these are cursor entries, not actual folders. Filter them out withif fname == ".": continue. - SiteGround LIST
%pattern may error —list('', 'INBOX.*')returns BAD on SiteGround. Uselist()with no pattern and parse the full response. - List response parsing is provider-specific — the HMXroute format is
(flags) "." Trash(simple), while SiteGround is(flags) "." "INBOX.Trash"(quoted). Usersplit('"', 2)for max compatibility across providers.