From 419f27418ec4a8b27ac2c98bb6f3bb2169bafa28 Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Fri, 4 Mar 2011 17:34:20 +0100 Subject: [PATCH] Simplify & document savemessage_getnewheader savemessage_getnewheader was an undocmented, cryptic and overengineered function. It generates a new unique value that can be used as a mail header to be inserted. For this it used LOTS of randomness sources: hash of the mail content, hash of the folder name, hash of the repository name, the current time, a random() value, and the offlineimap version string. All we need is something random. So reduce this to hash of content appended by a random integer. Sufficient and somewhat faster to calculate. Rename the function to actually describe accurately what it does or would you have guessed that savemessage_getnewheader() did nothing more than returning ('X-OfflineIMAP', )? Rename to generate_randomheader() to make it clearer what this is all about. Also document the function, describing what it does, and what it returns. Signed-off-by: Sebastian Spaeth Signed-off-by: Nicolas Sebrecht --- offlineimap/folder/IMAP.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index b1c343b..8dd9ee6 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -25,7 +25,7 @@ import time from StringIO import StringIO from copy import copy from Base import BaseFolder -from offlineimap import imaputil, imaplibutil, __version__ +from offlineimap import imaputil, imaplibutil class IMAPFolder(BaseFolder): def __init__(self, imapserver, name, visiblename, accountname, repository): @@ -226,14 +226,30 @@ class IMAPFolder(BaseFolder): def getmessageflags(self, uid): return self.messagelist[uid]['flags'] - def savemessage_getnewheader(self, content): + def generate_randomheader(self, content): + """Returns a unique X-OfflineIMAP header + + Generate an 'X-OfflineIMAP' mail header which contains a random + unique value (which is based on the mail content, and a random + number). This header allows us to fetch a mail after APPENDing + it to an IMAP server and thus find out the UID that the server + assigned it. + + :returns: (headername, headervalue) tuple, consisting of strings + headername == 'X-OfflineIMAP' and headervalue will be a + random string + """ headername = 'X-OfflineIMAP' - headervalue = '%s-' % str(binascii.crc32(content)).replace('-', 'x') - headervalue += binascii.hexlify(self.repository.getname()) + '-' - headervalue += binascii.hexlify(self.getname()) - headervalue += '-%d-' % long(time.time()) - headervalue += str(self.randomgenerator.random()).replace('.', '') - headervalue += '-v' + __version__ + # We need a random component too. If we ever upload the same + # mail twice (e.g. in different folders), we would still need to + # get the UID for the correct one. As we won't have too many + # mails with identical content, the randomness requirements are + # not extremly critial though. + + # compute unsigned crc32 of 'content' as unique hash + # NB: crc32 returns unsigned only starting with python 3.0 + headervalue = str( binascii.crc32(content) & 0xffffffff ) + '-' + headervalue += str(self.randomgenerator.randint(0,9999999999)) return (headername, headervalue) def savemessage_addheader(self, content, headername, headervalue): @@ -332,8 +348,8 @@ class IMAPFolder(BaseFolder): content = re.sub("(?