Skip to content

Instantly share code, notes, and snippets.

@Rocketeer007
Forked from daverigby/fix_date.py
Last active April 29, 2018 20:09
Show Gist options
  • Save Rocketeer007/e9d31b6e2321de8b2f4183bc2ef990b0 to your computer and use it in GitHub Desktop.
Save Rocketeer007/e9d31b6e2321de8b2f4183bc2ef990b0 to your computer and use it in GitHub Desktop.
fix_date.py - corrects the received date in IMAP folders
#!/usr/bin/python
# fix_date.py - corrects the received date in IMAP folders.
# Description:
# When moving mail between IMAP servers, the received date can become
# reset to the date when the message was added to the new server. This
# script attempts to fix this by setting the received date to the date the
# message was sent.
# Usage:
# Set the 5 variables below to suit your setup, and then run the script.
# If you run the script with the argument '--list', then it will just list
# all the mailboxes on the server. Useful if you don't know the exact name
# of the mailboxes.
# Notes:
# Due to the may IMAP works, you cannot change the recieved date for an
# existing message. To get round this, fix_date.py makes a new copy of the
# message in a different folder. As it has to copy each message, process
# can take some time!
# With some additional work the date could be set to the last received hop
# in the mail's delivery, but I didn't need that accuracy.
import imaplib
import email.Utils
import sys
# Change the following 5 lines as applicable:
source = "INBOX.Source" # The source folder to read the messages to fix.
dest = "INBOX.Dest" # The destination folder to save to new copy.
server = "imap.example.com" # IMAP server address
user = "user" # Username
passwd = "password" # Password
M = imaplib.IMAP4(server)
M.login(user, passwd)
if len(sys.argv) == 2 and sys.argv[1] == '--list':
print "List of mailboxes available on server:"
for mbox in M.list()[1]:
print mbox.split('"."')[1]
else:
M.select(source, readonly=True)
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, date = M.fetch(num, '(BODY.PEEK[HEADER.FIELDS (DATE)])')
typ, received = M.fetch(num, '(BODY.PEEK[HEADER.FIELDS (RECEIVED)])')
typ, body = M.fetch(num, '(RFC822)')
date_str = date[0][1][6:].strip()
received_str = received[0][1].split('\r\n')[0].split(';')[-1].strip()
datetime = email.Utils.parsedate(date_str)
if datetime is None:
datetime = email.Utils.parsedate(received_str)
print "Message (" + num + "), date:" + date_str + " received: " + received_str + " using :" + str(datetime)
M.append(dest, None, imaplib.Time2Internaldate(datetime), body[0][1])
#print body[0][1]
M.logout()
@Rocketeer007
Copy link
Author

Modified from original to support messages (mostly spam, as it happens) that have missing or invalid Date headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment