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', <randomstring> )? 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 <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Sebastian Spaeth 2011-03-04 17:34:20 +01:00 committed by Nicolas Sebrecht
parent a271f90271
commit 419f27418e

View File

@ -25,7 +25,7 @@ import time
from StringIO import StringIO from StringIO import StringIO
from copy import copy from copy import copy
from Base import BaseFolder from Base import BaseFolder
from offlineimap import imaputil, imaplibutil, __version__ from offlineimap import imaputil, imaplibutil
class IMAPFolder(BaseFolder): class IMAPFolder(BaseFolder):
def __init__(self, imapserver, name, visiblename, accountname, repository): def __init__(self, imapserver, name, visiblename, accountname, repository):
@ -226,14 +226,30 @@ class IMAPFolder(BaseFolder):
def getmessageflags(self, uid): def getmessageflags(self, uid):
return self.messagelist[uid]['flags'] 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' headername = 'X-OfflineIMAP'
headervalue = '%s-' % str(binascii.crc32(content)).replace('-', 'x') # We need a random component too. If we ever upload the same
headervalue += binascii.hexlify(self.repository.getname()) + '-' # mail twice (e.g. in different folders), we would still need to
headervalue += binascii.hexlify(self.getname()) # get the UID for the correct one. As we won't have too many
headervalue += '-%d-' % long(time.time()) # mails with identical content, the randomness requirements are
headervalue += str(self.randomgenerator.random()).replace('.', '') # not extremly critial though.
headervalue += '-v' + __version__
# 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) return (headername, headervalue)
def savemessage_addheader(self, content, headername, headervalue): def savemessage_addheader(self, content, headername, headervalue):
@ -332,8 +348,8 @@ class IMAPFolder(BaseFolder):
content = re.sub("(?<!\r)\n", "\r\n", content) content = re.sub("(?<!\r)\n", "\r\n", content)
self.ui.debug('imap', 'savemessage: initial content is: ' + repr(content)) self.ui.debug('imap', 'savemessage: initial content is: ' + repr(content))
(headername, headervalue) = self.savemessage_getnewheader(content) (headername, headervalue) = self.generate_randomheader(content)
self.ui.debug('imap', 'savemessage: new headers are: %s: %s' % \ ui.debug('imap', 'savemessage: new headers are: %s: %s' % \
(headername, headervalue)) (headername, headervalue))
content = self.savemessage_addheader(content, headername, content = self.savemessage_addheader(content, headername,
headervalue) headervalue)