more style consistency

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht
2015-01-14 22:58:25 +01:00
parent 5318af606e
commit 461554b7b1
20 changed files with 343 additions and 297 deletions

View File

@ -48,13 +48,11 @@ class BaseFolder(object):
self.visiblename = ''
self.config = repository.getconfig()
utime_from_message_global = \
self.config.getdefaultboolean("general",
"utime_from_message", False)
utime_from_message_global = self.config.getdefaultboolean(
"general", "utime_from_message", False)
repo = "Repository " + repository.name
self._utime_from_message = \
self.config.getdefaultboolean(repo,
"utime_from_message", utime_from_message_global)
self._utime_from_message = self.config.getdefaultboolean(repo,
"utime_from_message", utime_from_message_global)
# Determine if we're running static or dynamic folder filtering
# and check filtering status
@ -78,16 +76,19 @@ class BaseFolder(object):
return self.name
def __str__(self):
# FIMXE: remove calls of this. We have getname().
return self.name
@property
def accountname(self):
"""Account name as string"""
return self.repository.accountname
@property
def sync_this(self):
"""Should this folder be synced or is it e.g. filtered out?"""
if not self._dynamic_folderfilter:
return self._sync_this
else:
@ -144,7 +145,7 @@ class BaseFolder(object):
if self.name == self.visiblename:
return self.name
else:
return "%s [remote name %s]" % (self.visiblename, self.name)
return "%s [remote name %s]"% (self.visiblename, self.name)
def getrepository(self):
"""Returns the repository object that this folder is within."""
@ -172,9 +173,9 @@ class BaseFolder(object):
if not self.name:
basename = '.'
else: #avoid directory hierarchies and file names such as '/'
else: # Avoid directory hierarchies and file names such as '/'.
basename = self.name.replace('/', '.')
# replace with literal 'dot' if final path name is '.' as '.' is
# Replace with literal 'dot' if final path name is '.' as '.' is
# an invalid file name.
basename = re.sub('(^|\/)\.$','\\1dot', basename)
return basename
@ -196,7 +197,7 @@ class BaseFolder(object):
return True
def _getuidfilename(self):
"""provides UIDVALIDITY cache filename for class internal purposes"""
"""provides UIDVALIDITY cache filename for class internal purposes.
return os.path.join(self.repository.getuiddir(),
self.getfolderbasename())
@ -228,7 +229,7 @@ class BaseFolder(object):
uidfilename = self._getuidfilename()
with open(uidfilename + ".tmp", "wt") as file:
file.write("%d\n" % newval)
file.write("%d\n"% newval)
os.rename(uidfilename + ".tmp", uidfilename)
self._base_saved_uidvalidity = newval
@ -252,6 +253,7 @@ class BaseFolder(object):
def getmessagelist(self):
"""Gets the current message list.
You must call cachemessagelist() before calling this function!"""
raise NotImplementedError
@ -272,6 +274,7 @@ class BaseFolder(object):
def getmessageuidlist(self):
"""Gets a list of UIDs.
You may have to call cachemessagelist() before calling this function!"""
return self.getmessagelist().keys()
@ -377,6 +380,7 @@ class BaseFolder(object):
def getmessagelabels(self, uid):
"""Returns the labels for the specified message."""
raise NotImplementedError
def savemessagelabels(self, uid, labels, ignorelabels=set(), mtime=0):
@ -691,10 +695,10 @@ class BaseFolder(object):
# load it up.
if dstfolder.storesmessages():
message = self.getmessage(uid)
#Succeeded? -> IMAP actually assigned a UID. If newid
#remained negative, no server was willing to assign us an
#UID. If newid is 0, saving succeeded, but we could not
#retrieve the new UID. Ignore message in this case.
# Succeeded? -> IMAP actually assigned a UID. If newid
# remained negative, no server was willing to assign us an
# UID. If newid is 0, saving succeeded, but we could not
# retrieve the new UID. Ignore message in this case.
new_uid = dstfolder.savemessage(uid, message, flags, rtime)
if new_uid > 0:
if new_uid != uid:
@ -728,7 +732,7 @@ class BaseFolder(object):
raise #raise on unknown errors, so we can fix those
def __syncmessagesto_copy(self, dstfolder, statusfolder):
"""Pass1: Copy locally existing messages not on the other side
"""Pass1: Copy locally existing messages not on the other side.
This will copy messages to dstfolder that exist locally but are
not in the statusfolder yet. The strategy is:
@ -738,18 +742,16 @@ class BaseFolder(object):
- If dstfolder doesn't have it yet, add them to dstfolder.
- Update statusfolder
This function checks and protects us from action in ryrun mode.
"""
This function checks and protects us from action in dryrun mode."""
threads = []
copylist = filter(lambda uid: not \
statusfolder.uidexists(uid),
self.getmessageuidlist())
copylist = filter(lambda uid: not statusfolder.uidexists(uid),
self.getmessageuidlist())
num_to_copy = len(copylist)
if num_to_copy and self.repository.account.dryrun:
self.ui.info("[DRYRUN] Copy {0} messages from {1}[{2}] to {3}".format(
num_to_copy, self, self.repository, dstfolder.repository))
num_to_copy, self, self.repository, dstfolder.repository))
return
for num, uid in enumerate(copylist):
# bail out on CTRL-C or SIGTERM
@ -773,7 +775,7 @@ class BaseFolder(object):
thread.join()
def __syncmessagesto_delete(self, dstfolder, statusfolder):
"""Pass 2: Remove locally deleted messages on dst
"""Pass 2: Remove locally deleted messages on dst.
Get all UIDS in statusfolder but not self. These are messages
that were deleted in 'self'. Delete those from dstfolder and
@ -782,9 +784,8 @@ class BaseFolder(object):
This function checks and protects us from action in ryrun mode.
"""
deletelist = filter(lambda uid: uid>=0 \
and not self.uidexists(uid),
statusfolder.getmessageuidlist())
deletelist = filter(lambda uid: uid >= 0 and not
self.uidexists(uid), statusfolder.getmessageuidlist())
if len(deletelist):
self.ui.deletingmessages(deletelist, [dstfolder])
if self.repository.account.dryrun:
@ -795,7 +796,7 @@ class BaseFolder(object):
folder.deletemessages(deletelist)
def __syncmessagesto_flags(self, dstfolder, statusfolder):
"""Pass 3: Flag synchronization
"""Pass 3: Flag synchronization.
Compare flag mismatches in self with those in statusfolder. If
msg has a valid UID and exists on dstfolder (has not e.g. been
@ -904,7 +905,7 @@ class BaseFolder(object):
def __eq__(self, other):
"""Comparisons work either on string comparing folder names or
on the same instance
on the same instance.
MailDirFolder('foo') == 'foo' --> True
a = MailDirFolder('foo'); a == b --> True

View File

@ -22,11 +22,10 @@ from sys import exc_info
from offlineimap import imaputil, OfflineImapError
from offlineimap import imaplibutil
import offlineimap.accounts
"""Folder implementation to support features of the Gmail IMAP server.
"""
from .IMAP import IMAPFolder
"""Folder implementation to support features of the Gmail IMAP server."""
class GmailFolder(IMAPFolder):
"""Folder implementation to support features of the Gmail IMAP server.
@ -101,11 +100,11 @@ class GmailFolder(IMAPFolder):
body = self.addmessageheader(body, '\n', self.labelsheader, labels_str)
if len(body)>200:
dbg_output = "%s...%s" % (str(body)[:150], str(body)[-50:])
dbg_output = "%s...%s"% (str(body)[:150], str(body)[-50:])
else:
dbg_output = body
self.ui.debug('imap', "Returned object from fetching %d: '%s'" %
self.ui.debug('imap', "Returned object from fetching %d: '%s'"%
(uid, dbg_output))
return body
@ -139,7 +138,7 @@ class GmailFolder(IMAPFolder):
# imaplib2 from quoting the sequence.
#
# NB: msgsToFetch are sequential numbers, not UID's
res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
res_type, response = imapobj.fetch("'%s'"% msgsToFetch,
'(FLAGS X-GM-LABELS UID)')
if res_type != 'OK':
raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. " % \

View File

@ -164,10 +164,10 @@ class IMAPFolder(BaseFolder):
# By default examine all messages in this folder
msgsToFetch = '1:*'
maxage = self.config.getdefaultint("Account %s"% self.accountname,
"maxage", -1)
maxsize = self.config.getdefaultint("Account %s"% self.accountname,
"maxsize", -1)
maxage = self.config.getdefaultint(
"Account %s"% self.accountname, "maxage", -1)
maxsize = self.config.getdefaultint(
"Account %s"% self.accountname, "maxsize", -1)
# Build search condition
if (maxage != -1) | (maxsize != -1):
@ -178,9 +178,9 @@ class IMAPFolder(BaseFolder):
oldest_struct = time.gmtime(time.time() - (60*60*24*maxage))
if oldest_struct[0] < 1900:
raise OfflineImapError("maxage setting led to year %d. "
"Abort syncing." % oldest_struct[0],
OfflineImapError.ERROR.REPO)
search_cond += "SINCE %02d-%s-%d" % (
"Abort syncing."% oldest_struct[0],
OfflineImapError.ERROR.REPO)
search_cond += "SINCE %02d-%s-%d"% (
oldest_struct[2],
MonthNames[oldest_struct[1]],
oldest_struct[0])
@ -188,7 +188,7 @@ class IMAPFolder(BaseFolder):
if(maxsize != -1):
if(maxage != -1): # There are two conditions, add space
search_cond += " "
search_cond += "SMALLER %d" % maxsize
search_cond += "SMALLER %d"% maxsize
search_cond += ")"
@ -225,10 +225,8 @@ class IMAPFolder(BaseFolder):
msgsToFetch, '(FLAGS UID)')
if res_type != 'OK':
raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. "
"Server responded '[%s] %s'"% (
self.getrepository(), self,
res_type, response),
OfflineImapError.ERROR.FOLDER)
"Server responded '[%s] %s'"% (self.getrepository(), self,
res_type, response), OfflineImapError.ERROR.FOLDER)
finally:
self.imapserver.releaseconnection(imapobj)
@ -259,7 +257,7 @@ class IMAPFolder(BaseFolder):
# Interface from BaseFolder
def getmessage(self, uid):
"""Retrieve message with UID from the IMAP server (incl body)
"""Retrieve message with UID from the IMAP server (incl body).
After this function all CRLFs will be transformed to '\n'.
@ -280,7 +278,7 @@ class IMAPFolder(BaseFolder):
data = data[0][1].replace(CRLF, "\n")
if len(data)>200:
dbg_output = "%s...%s" % (str(data)[:150], str(data)[-50:])
dbg_output = "%s...%s"% (str(data)[:150], str(data)[-50:])
else:
dbg_output = data
@ -331,7 +329,8 @@ class IMAPFolder(BaseFolder):
# Now find the UID it got.
headervalue = imapobj._quote(headervalue)
try:
matchinguids = imapobj.uid('search', 'HEADER', headername, headervalue)[1][0]
matchinguids = imapobj.uid('search', 'HEADER',
headername, headervalue)[1][0]
except imapobj.error as err:
# IMAP server doesn't implement search or had a problem.
self.ui.debug('imap', "__savemessage_searchforheader: got IMAP error '%s' while attempting to UID SEARCH for message with header %s"% (err, headername))
@ -396,8 +395,8 @@ class IMAPFolder(BaseFolder):
result = imapobj.uid('FETCH', bytearray('%d:*'% start), 'rfc822.header')
if result[0] != 'OK':
raise OfflineImapError('Error fetching mail headers: ' + '. '.join(result[1]),
OfflineImapError.ERROR.MESSAGE)
raise OfflineImapError('Error fetching mail headers: %s'%
'. '.join(result[1]), OfflineImapError.ERROR.MESSAGE)
result = result[1]
@ -423,7 +422,8 @@ class IMAPFolder(BaseFolder):
def __getmessageinternaldate(self, content, rtime=None):
"""Parses mail and returns an INTERNALDATE string
It will use information in the following order, falling back as an attempt fails:
It will use information in the following order, falling back as an
attempt fails:
- rtime parameter
- Date header of email
@ -475,21 +475,22 @@ class IMAPFolder(BaseFolder):
"Server will use local time."% datetuple)
return None
#produce a string representation of datetuple that works as
#INTERNALDATE
# Produce a string representation of datetuple that works as
# INTERNALDATE.
num2mon = {1:'Jan', 2:'Feb', 3:'Mar', 4:'Apr', 5:'May', 6:'Jun',
7:'Jul', 8:'Aug', 9:'Sep', 10:'Oct', 11:'Nov', 12:'Dec'}
#tm_isdst coming from email.parsedate is not usable, we still use it here, mhh
# tm_isdst coming from email.parsedate is not usable, we still use it
# here, mhh.
if datetuple.tm_isdst == '1':
zone = -time.altzone
else:
zone = -time.timezone
offset_h, offset_m = divmod(zone//60, 60)
internaldate = '"%02d-%s-%04d %02d:%02d:%02d %+03d%02d"' \
% (datetuple.tm_mday, num2mon[datetuple.tm_mon], datetuple.tm_year, \
datetuple.tm_hour, datetuple.tm_min, datetuple.tm_sec, offset_h, offset_m)
internaldate = '"%02d-%s-%04d %02d:%02d:%02d %+03d%02d"'% \
(datetuple.tm_mday, num2mon[datetuple.tm_mon], datetuple.tm_year, \
datetuple.tm_hour, datetuple.tm_min, datetuple.tm_sec, offset_h, offset_m)
return internaldate
@ -554,7 +555,7 @@ class IMAPFolder(BaseFolder):
content = self.addmessageheader(content, CRLF, headername, headervalue)
if len(content)>200:
dbg_output = "%s...%s" % (content[:150], content[-50:])
dbg_output = "%s...%s"% (content[:150], content[-50:])
else:
dbg_output = content
self.ui.debug('imap', "savemessage: date: %s, content: '%s'"%
@ -726,6 +727,7 @@ class IMAPFolder(BaseFolder):
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
imapobj = self.imapserver.acquireconnection()
try:
result = self._store_to_imap(imapobj, str(uid), 'FLAGS',

View File

@ -21,8 +21,9 @@ import threading
from .Base import BaseFolder
class LocalStatusFolder(BaseFolder):
"""LocalStatus backend implemented as a plain text file"""
"""LocalStatus backend implemented as a plain text file."""
cur_version = 2
magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT %d"
@ -53,12 +54,10 @@ class LocalStatusFolder(BaseFolder):
if not self.isnewfolder():
os.unlink(self.filename)
# Interface from BaseFolder
def msglist_item_initializer(self, uid):
return {'uid': uid, 'flags': set(), 'labels': set(), 'time': 0, 'mtime': 0}
def readstatus_v1(self, fp):
"""Read status folder in format version 1.
@ -80,7 +79,6 @@ class LocalStatusFolder(BaseFolder):
self.messagelist[uid] = self.msglist_item_initializer(uid)
self.messagelist[uid]['flags'] = flags
def readstatus(self, fp):
"""Read status file in the current format.
@ -97,7 +95,7 @@ class LocalStatusFolder(BaseFolder):
mtime = long(mtime)
labels = set([lb.strip() for lb in labels.split(',') if len(lb.strip()) > 0])
except ValueError as e:
errstr = "Corrupt line '%s' in cache file '%s'" % \
errstr = "Corrupt line '%s' in cache file '%s'"% \
(line, self.filename)
self.ui.warn(errstr)
raise ValueError(errstr), None, exc_info()[2]
@ -227,7 +225,6 @@ class LocalStatusFolder(BaseFolder):
self.messagelist[uid]['flags'] = flags
self.save()
def savemessagelabels(self, uid, labels, mtime=None):
self.messagelist[uid]['labels'] = labels
if mtime: self.messagelist[uid]['mtime'] = mtime
@ -263,7 +260,6 @@ class LocalStatusFolder(BaseFolder):
def getmessagemtime(self, uid):
return self.messagelist[uid]['mtime']
# Interface from BaseFolder
def deletemessage(self, uid):
self.deletemessages([uid])

View File

@ -64,7 +64,7 @@ class LocalStatusSQLiteFolder(BaseFolder):
#Try to establish connection, no need for threadsafety in __init__
try:
self.connection = sqlite.connect(self.filename, check_same_thread = False)
self.connection = sqlite.connect(self.filename, check_same_thread=False)
except NameError:
# sqlite import had failed
raise UserWarning('SQLite backend chosen, but no sqlite python '
@ -93,7 +93,6 @@ class LocalStatusSQLiteFolder(BaseFolder):
def getfullname(self):
return self.filename
# Interface from LocalStatusFolder
def isnewfolder(self):
return self._newfolder
@ -101,7 +100,8 @@ class LocalStatusSQLiteFolder(BaseFolder):
# Interface from LocalStatusFolder
def deletemessagelist(self):
"""delete all messages in the db"""
"""Delete all messages in the db."""
self.__sql_write('DELETE FROM status')
@ -114,6 +114,7 @@ class LocalStatusSQLiteFolder(BaseFolder):
:param executemany: bool indicating whether we want to
perform conn.executemany() or conn.execute().
:returns: the Cursor() or raises an Exception"""
success = False
while not success:
self._dblock.acquire()
@ -153,8 +154,8 @@ class LocalStatusSQLiteFolder(BaseFolder):
# Upgrade from database version 1 to version 2
# This change adds labels and mtime columns, to be used by Gmail IMAP and Maildir folders.
if from_ver <= 1:
self.ui._msg('Upgrading LocalStatus cache from version 1 to version 2 for %s:%s' %\
(self.repository, self))
self.ui._msg('Upgrading LocalStatus cache from version 1 to version 2 for %s:%s'%
(self.repository, self))
self.connection.executescript("""ALTER TABLE status ADD mtime INTEGER DEFAULT 0;
ALTER TABLE status ADD labels VARCHAR(256) DEFAULT '';
UPDATE metadata SET value='2' WHERE key='db_version';
@ -167,12 +168,10 @@ class LocalStatusSQLiteFolder(BaseFolder):
def __create_db(self):
"""
Create a new db file.
"""Create a new db file.
self.connection must point to the opened and valid SQlite
database connection.
"""
database connection."""
self.ui._msg('Creating new Local Status db for %s:%s' \
% (self.repository, self))
self.connection.executescript("""
@ -212,6 +211,7 @@ class LocalStatusSQLiteFolder(BaseFolder):
def saveall(self):
"""Saves the entire messagelist to the database."""
data = []
for uid, msg in self.messagelist.items():
mtime = msg['mtime']
@ -219,8 +219,9 @@ class LocalStatusSQLiteFolder(BaseFolder):
labels = ', '.join(sorted(msg['labels']))
data.append((uid, flags, mtime, labels))
self.__sql_write('INSERT OR REPLACE INTO status (id,flags,mtime,labels) VALUES (?,?,?,?)',
data, executemany=True)
self.__sql_write('INSERT OR REPLACE INTO status '
'(id,flags,mtime,labels) VALUES (?,?,?,?)',
data, executemany=True)
# Following some pure SQLite functions, where we chose to use
@ -267,14 +268,12 @@ class LocalStatusSQLiteFolder(BaseFolder):
# Interface from BaseFolder
def savemessage(self, uid, content, flags, rtime, mtime=0, labels=set()):
"""
Writes a new message, with the specified uid.
"""Writes a new message, with the specified uid.
See folder/Base for detail. Note that savemessage() does not
check against dryrun settings, so you need to ensure that
savemessage is never called in a dryrun mode.
"""
savemessage is never called in a dryrun mode."""
if uid < 0:
# We cannot assign a uid.
return uid
@ -352,6 +351,7 @@ class LocalStatusSQLiteFolder(BaseFolder):
def savemessagesmtimebulk(self, mtimes):
"""Saves mtimes from the mtimes dictionary in a single database operation."""
data = [(mt, uid) for uid, mt in mtimes.items()]
self.__sql_write('UPDATE status SET mtime=? WHERE id=?', data, executemany=True)
for uid, mt in mtimes.items():
@ -376,6 +376,7 @@ class LocalStatusSQLiteFolder(BaseFolder):
This function uses sqlites executemany() function which is
much faster than iterating through deletemessage() when we have
many messages to delete."""
# Weed out ones not in self.messagelist
uidlist = [uid for uid in uidlist if uid in self.messagelist]
if not len(uidlist):

View File

@ -69,7 +69,7 @@ class MaildirFolder(BaseFolder):
"Account "+self.accountname, "maildir-windows-compatible", False)
self.infosep = '!' if self.wincompatible else ':'
"""infosep is the separator between maildir name and flag appendix"""
self.re_flagmatch = re.compile('%s2,(\w*)' % self.infosep)
self.re_flagmatch = re.compile('%s2,(\w*)'% self.infosep)
#self.ui is set in BaseFolder.init()
# Everything up to the first comma or colon (or ! if Windows):
self.re_prefixmatch = re.compile('([^'+ self.infosep + ',]*)')
@ -128,13 +128,14 @@ class MaildirFolder(BaseFolder):
detected, we return an empty flags list.
:returns: (prefix, UID, FMD5, flags). UID is a numeric "long"
type. flags is a set() of Maildir flags"""
type. flags is a set() of Maildir flags.
"""
prefix, uid, fmd5, flags = None, None, None, set()
prefixmatch = self.re_prefixmatch.match(filename)
if prefixmatch:
prefix = prefixmatch.group(1)
folderstr = ',FMD5=%s' % self._foldermd5
folderstr = ',FMD5=%s'% self._foldermd5
foldermatch = folderstr in filename
# If there was no folder MD5 specified, or if it mismatches,
# assume it is a foreign (new) message and ret: uid, fmd5 = None, None
@ -154,7 +155,9 @@ class MaildirFolder(BaseFolder):
Maildir flags are: R (replied) S (seen) T (trashed) D (draft) F
(flagged).
:returns: dict that can be used as self.messagelist"""
:returns: dict that can be used as self.messagelist.
"""
maxage = self.config.getdefaultint("Account " + self.accountname,
"maxage", None)
maxsize = self.config.getdefaultint("Account " + self.accountname,
@ -254,9 +257,9 @@ class MaildirFolder(BaseFolder):
:returns: String containing unique message filename"""
timeval, timeseq = _gettimeseq()
return '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s' % \
return '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s'% \
(timeval, timeseq, os.getpid(), socket.gethostname(),
uid, self._foldermd5, self.infosep, ''.join(sorted(flags)))
uid, self._foldermd5, self.infosep, ''.join(sorted(flags)))
def save_to_tmp_file(self, filename, content):
@ -393,7 +396,7 @@ class MaildirFolder(BaseFolder):
"""
if not uid in self.messagelist:
raise OfflineImapError("Cannot change unknown Maildir UID %s" % uid)
raise OfflineImapError("Cannot change unknown Maildir UID %s"% uid)
if uid == new_uid: return
oldfilename = self.messagelist[uid]['filename']

View File

@ -78,7 +78,7 @@ class MappedIMAPFolder(IMAPFolder):
try:
file = open(mapfilename + ".tmp", 'wt')
for (key, value) in self.diskl2r.iteritems():
file.write("%d:%d\n" % (key, value))
file.write("%d:%d\n"% (key, value))
file.close()
os.rename(mapfilename + '.tmp', mapfilename)
finally:
@ -91,7 +91,7 @@ class MappedIMAPFolder(IMAPFolder):
raise OfflineImapError("Could not find UID for msg '{0}' (f:'{1}'."
" This is usually a bad thing and should be reported on the ma"
"iling list.".format(e.args[0], self),
OfflineImapError.ERROR.MESSAGE), None, exc_info()[2]
OfflineImapError.ERROR.MESSAGE), None, exc_info()[2]
# Interface from BaseFolder
def cachemessagelist(self):
@ -215,8 +215,8 @@ class MappedIMAPFolder(IMAPFolder):
newluid = self._mb.savemessage(-1, content, flags, rtime)
if newluid < 1:
raise ValueError("Backend could not find uid for message, returned "
"%s" % newluid)
raise ValueError("Backend could not find uid for message, "
"returned %s"% newluid)
self.maplock.acquire()
try:
self.diskl2r[newluid] = uid
@ -262,8 +262,8 @@ class MappedIMAPFolder(IMAPFolder):
UID. The UIDMaps case handles this efficiently by simply
changing the mappings file."""
if ruid not in self.r2l:
raise OfflineImapError("Cannot change unknown Maildir UID %s" % ruid,
OfflineImapError.ERROR.MESSAGE)
raise OfflineImapError("Cannot change unknown Maildir UID %s"%
ruid, OfflineImapError.ERROR.MESSAGE)
if ruid == new_ruid: return # sanity check shortcut
self.maplock.acquire()
try:
@ -271,10 +271,10 @@ class MappedIMAPFolder(IMAPFolder):
self.l2r[luid] = new_ruid
del self.r2l[ruid]
self.r2l[new_ruid] = luid
#TODO: diskl2r|r2l are a pain to sync and should be done away with
#diskl2r only contains positive UIDs, so wrap in ifs
if luid>0: self.diskl2r[luid] = new_ruid
if ruid>0: del self.diskr2l[ruid]
# TODO: diskl2r|r2l are a pain to sync and should be done away with
# diskl2r only contains positive UIDs, so wrap in ifs.
if luid > 0: self.diskl2r[luid] = new_ruid
if ruid > 0: del self.diskr2l[ruid]
if new_ruid > 0: self.diskr2l[new_ruid] = luid
self._savemaps(dolock = 0)
finally: