Prevent modifications on a folder level to occur in dry-run

Prevent savemessage(), and savemessageflags() to occur in dryrun mode in
all backends. Still need to protect against deletemessage().

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2011-09-16 11:44:50 +02:00
parent b6807355b5
commit 5ef69e95c0
7 changed files with 81 additions and 7 deletions

View File

@ -208,6 +208,10 @@ class BaseFolder(object):
If the uid is > 0, the backend should set the uid to this, if it can.
If it cannot set the uid to that, it will save it anyway.
It will return the uid assigned in any case.
Note that savemessage() does not check against dryrun settings,
so you need to ensure that savemessage is never called in a
dryrun mode.
"""
raise NotImplementedException
@ -220,27 +224,48 @@ class BaseFolder(object):
raise NotImplementedException
def savemessageflags(self, uid, flags):
"""Sets the specified message's flags to the given set."""
"""Sets the specified message's flags to the given set.
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
raise NotImplementedException
def addmessageflags(self, uid, flags):
"""Adds the specified flags to the message's flag set. If a given
flag is already present, it will not be duplicated.
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode.
:param flags: A set() of flags"""
newflags = self.getmessageflags(uid) | flags
self.savemessageflags(uid, newflags)
def addmessagesflags(self, uidlist, flags):
"""
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
for uid in uidlist:
self.addmessageflags(uid, flags)
def deletemessageflags(self, uid, flags):
"""Removes each flag given from the message's flag set. If a given
flag is already removed, no action will be taken for that flag."""
flag is already removed, no action will be taken for that flag.
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
newflags = self.getmessageflags(uid) - flags
self.savemessageflags(uid, newflags)
def deletemessagesflags(self, uidlist, flags):
"""
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
for uid in uidlist:
self.deletemessageflags(uid, flags)
@ -345,6 +370,10 @@ class BaseFolder(object):
statusfolder.uidexists(uid),
self.getmessageuidlist())
num_to_copy = len(copylist)
if num_to_copy and self.repository.account.dryrun:
self.ui.info("[DRYRUN] Copy {} messages from {}[{}] to {}".format(
num_to_copy, self, self.repository, dstfolder.repository))
return
for num, uid in enumerate(copylist):
# bail out on CTRL-C or SIGTERM
if offlineimap.accounts.Account.abort_NOW_signal.is_set():
@ -422,11 +451,15 @@ class BaseFolder(object):
for flag, uids in addflaglist.items():
self.ui.addingflags(uids, flag, dstfolder)
if self.repository.account.dryrun:
continue #don't actually add in a dryrun
dstfolder.addmessagesflags(uids, set(flag))
statusfolder.addmessagesflags(uids, set(flag))
for flag,uids in delflaglist.items():
self.ui.deletingflags(uids, flag, dstfolder)
if self.repository.account.dryrun:
continue #don't actually remove in a dryrun
dstfolder.deletemessagesflags(uids, set(flag))
statusfolder.deletemessagesflags(uids, set(flag))

View File

@ -488,12 +488,16 @@ class IMAPFolder(BaseFolder):
This function will update the self.messagelist dict to contain
the new message after sucessfully saving it.
See folder/Base for details. Note that savemessage() does not
check against dryrun settings, so you need to ensure that
savemessage is never called in a dryrun mode.
:param rtime: A timestamp to be used as the mail date
:returns: the UID of the new message as assigned by the server. If the
message is saved, but it's UID can not be found, it will
return 0. If the message can't be written (folder is
read-only for example) it will return -1."""
self.ui.debug('imap', 'savemessage: called')
self.ui.savemessage('imap', uid, flags, self)
# already have it, just save modified flags
if uid > 0 and self.uidexists(uid):
@ -611,7 +615,11 @@ class IMAPFolder(BaseFolder):
return uid
def savemessageflags(self, uid, flags):
"""Change a message's flags to `flags`."""
"""Change a message's flags to `flags`.
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:
try:

View File

@ -111,6 +111,11 @@ class LocalStatusFolder(BaseFolder):
return self.messagelist
def savemessage(self, uid, content, flags, rtime):
"""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."""
if uid < 0:
# We cannot assign a uid.
return uid

View File

@ -216,6 +216,11 @@ class LocalStatusSQLiteFolder(LocalStatusFolder):
# assert False,"getmessageflags() called on non-existing message"
def savemessage(self, uid, content, flags, rtime):
"""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."""
if uid < 0:
# We cannot assign a uid.
return uid

View File

@ -237,13 +237,18 @@ class MaildirFolder(BaseFolder):
uid, self._foldermd5, self.infosep, ''.join(sorted(flags)))
def savemessage(self, uid, content, flags, rtime):
"""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."""
# This function only ever saves to tmp/,
# but it calls savemessageflags() to actually save to cur/ or new/.
self.ui.debug('maildir', 'savemessage: called to write with flags %s '
'and content %s' % (repr(flags), repr(content)))
self.ui.savemessage('maildir', uid, flags, self)
if uid < 0:
# We cannot assign a new uid.
return uid
if uid in self.messagelist:
# We already have it, just update flags.
self.savemessageflags(uid, flags)
@ -291,8 +296,11 @@ class MaildirFolder(BaseFolder):
"""Sets the specified message's flags to the given set.
This function moves the message to the cur or new subdir,
depending on the 'S'een flag."""
depending on the 'S'een flag.
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
oldfilename = self.messagelist[uid]['filename']
dir_prefix, filename = os.path.split(oldfilename)
# If a message has been seen, it goes into 'cur'

View File

@ -184,7 +184,12 @@ class MappedIMAPFolder(IMAPFolder):
If the uid is > 0, the backend should set the uid to this, if it can.
If it cannot set the uid to that, it will save it anyway.
It will return the uid assigned in any case.
See folder/Base for details. Note that savemessage() does not
check against dryrun settings, so you need to ensure that
savemessage is never called in a dryrun mode.
"""
self.ui.savemessage('imap', uid, flags, self)
# Mapped UID instances require the source to already have a
# positive UID, so simply return here.
if uid < 0:
@ -217,6 +222,11 @@ class MappedIMAPFolder(IMAPFolder):
return None
def savemessageflags(self, uid, flags):
"""
Note that this function does not check against dryrun settings,
so you need to ensure that it is never called in a
dryrun mode."""
self._mb.savemessageflags(self.r2l[uid], flags)
def addmessageflags(self, uid, flags):

View File

@ -408,6 +408,11 @@ class UIBase(object):
if conn: #release any existing IMAP connection
repository.imapserver.close()
def savemessage(self, debugtype, uid, flags, folder):
"""Output a log line stating that we save a msg"""
self.debug(debugtype, "Write mail '%s:%d' with flags %s" %
(folder, uid, repr(flags)))
################################################## Threads
def getThreadDebugLog(self, thread):