Skip to content

Instantly share code, notes, and snippets.

@michelbl
Last active February 3, 2019 10:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michelbl/a44def020c2ba14a8bf4ed4281d44109 to your computer and use it in GitHub Desktop.
Save michelbl/a44def020c2ba14a8bf4ed4281d44109 to your computer and use it in GitHub Desktop.
Backup emails using IMAP
"""
Inspired from http://stackp.online.fr/?p=25s
Create a file named "mail_config.py" containing :
HOST = 'mail.gandi.net'
PORT = 993
USER = 'test@mydomain.net'
PASSWORD = '***'
"""
import imaplib
import ssl
import re
import pickle
import time
import datetime
import os
import mail_config
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
def backup_mails():
context = ssl.create_default_context()
with imaplib.IMAP4_SSL(host=mail_config.HOST, port=mail_config.PORT, ssl_context=context) as imap:
response_login_code, _ = imap.login(
user=mail_config.USER,
password=mail_config.PASSWORD
)
assert response_login_code == 'OK'
response_list_code, response_list_message = imap.list()
assert response_list_code == 'OK'
folder_names = [
re.match(r'^\([^\)]*\) "[^"]*" (.*)$', folder_line.decode()).groups()[0]
for folder_line in response_list_message
]
# You could see weird codes, like '&AOk-', '&AOg-'... See http://forums.4d.com/Code4D/EN/2/1/15512564/
# Warning : folder_names[i] could be either SomeName (without quotes) or "Some W&AOk-ird Name" (with quotes)
folders_content = {}
for folder_name in folder_names:
response_select_code, _ = imap.select(folder_name)
assert response_select_code == 'OK'
response_search_code, response_search_message = imap.search(None, "ALL")
assert response_search_code == 'OK'
folders_content[folder_name] = []
message_ids = response_search_message[0].split()
for message_id in message_ids:
response_fetch_code, response_fetch_message = imap.fetch(message_id, "(BODY.PEEK[])")
assert response_fetch_code == 'OK'
folders_content[folder_name].append(response_fetch_message)
timestamp = time.time()
time_str = datetime.datetime.fromtimestamp(timestamp).strftime('%Y_%m_%d_%H_%M_%S')
dump_name = '{}-{}-{}.pickle'.format(mail_config.HOST, mail_config.USER, time_str)
dump_path = os.path.join(ROOT_DIR, dump_name)
with open(dump_path, 'wb') as file_handle:
pickle.dump(folders_content, file_handle)
if __name__ == '__main__':
backup_mails()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment