fix inaccurate UI messages when some messages are excluded from the cached lists

Some messages were excluded from the copy/delete list after the UI message said
they were copied/deleted.
Also fix Internaldate2epoch(), which was wrong.

Signed-off-by: Janna Martl <janna.martl109@gmail.com>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Janna Martl 2015-03-21 02:15:25 -04:00 committed by Nicolas Sebrecht
parent 03114b1867
commit 428349e3f4
4 changed files with 28 additions and 20 deletions

View File

@ -365,6 +365,7 @@ class BaseFolder(object):
dryrun mode.""" dryrun mode."""
for uid in uidlist: for uid in uidlist:
if self.uidexists(uid):
self.addmessageflags(uid, flags) self.addmessageflags(uid, flags)
def deletemessageflags(self, uid, flags): def deletemessageflags(self, uid, flags):
@ -695,11 +696,6 @@ class BaseFolder(object):
content = self.getmessage(uid) content = self.getmessage(uid)
rtime = emailutil.get_message_date(content, 'Date') rtime = emailutil.get_message_date(content, 'Date')
if uid > 0 and dstfolder.uidexists(uid):
# dst has message with that UID already, only update status
statusfolder.savemessage(uid, None, flags, rtime)
return
# If any of the destinations actually stores the message body, # If any of the destinations actually stores the message body,
# load it up. # load it up.
if dstfolder.storesmessages(): if dstfolder.storesmessages():
@ -766,6 +762,16 @@ class BaseFolder(object):
# bail out on CTRL-C or SIGTERM # bail out on CTRL-C or SIGTERM
if offlineimap.accounts.Account.abort_NOW_signal.is_set(): if offlineimap.accounts.Account.abort_NOW_signal.is_set():
break break
if uid > 0 and dstfolder.uidexists(uid):
# dst has message with that UID already, only update status
flags = self.getmessageflags(uid)
rtime = self.getmessagetime(uid)
if dstfolder.utime_from_message:
content = self.getmessage(uid)
rtime = emailutil.get_message_date(content, 'Date')
statusfolder.savemessage(uid, None, flags, rtime)
copylist.remove(uid)
self.ui.copyingmessage(uid, num+1, num_to_copy, self, dstfolder) self.ui.copyingmessage(uid, num+1, num_to_copy, self, dstfolder)
# exceptions are caught in copymessageto() # exceptions are caught in copymessageto()
if self.suggeststhreads() and not globals.options.singlethreading: if self.suggeststhreads() and not globals.options.singlethreading:
@ -790,19 +796,24 @@ class BaseFolder(object):
that were deleted in 'self'. Delete those from dstfolder and that were deleted in 'self'. Delete those from dstfolder and
statusfolder. statusfolder.
This function checks and protects us from action in ryrun mode. This function checks and protects us from action in dryrun mode.
""" """
deletelist = filter(lambda uid: uid >= 0 and not deletelist = filter(lambda uid: uid >= 0 and not
self.uidexists(uid), statusfolder.getmessageuidlist()) self.uidexists(uid), statusfolder.getmessageuidlist())
if len(deletelist):
# Delete in statusfolder first to play safe. In case of abort, we
# won't lose message, we will just unneccessarily retransmit some.
# Delete messages from statusfolder that were either deleted by the
# user, or not being tracked (e.g. because of maxage).
statusfolder.deletemessages(deletelist)
# Filter out untracked messages
deletelist = filter(lambda uid: dstfolder.uidexists(uid), deletelist)
if len(deletelist): if len(deletelist):
self.ui.deletingmessages(deletelist, [dstfolder]) self.ui.deletingmessages(deletelist, [dstfolder])
if self.repository.account.dryrun: if self.repository.account.dryrun:
return #don't delete messages in dry-run mode return #don't delete messages in dry-run mode
# delete in statusfolder first to play safe. In case of abort, we dstfolder.deletemessages(deletelist)
# won't lose message, we will just retransmit some unneccessary.
for folder in [statusfolder, dstfolder]:
folder.deletemessages(deletelist)
def __syncmessagesto_flags(self, dstfolder, statusfolder): def __syncmessagesto_flags(self, dstfolder, statusfolder):
"""Pass 3: Flag synchronization. """Pass 3: Flag synchronization.

View File

@ -836,8 +836,6 @@ class IMAPFolder(BaseFolder):
self.__deletemessages_noconvert(uidlist) self.__deletemessages_noconvert(uidlist)
def __deletemessages_noconvert(self, uidlist): def __deletemessages_noconvert(self, uidlist):
# Weed out ones not in self.messagelist
uidlist = [uid for uid in uidlist if self.uidexists(uid)]
if not len(uidlist): if not len(uidlist):
return return

View File

@ -439,9 +439,6 @@ class MaildirFolder(BaseFolder):
:return: Nothing, or an Exception if UID but no corresponding file :return: Nothing, or an Exception if UID but no corresponding file
found. found.
""" """
if not self.uidexists(uid):
return
filename = self.messagelist[uid]['filename'] filename = self.messagelist[uid]['filename']
filepath = os.path.join(self.getfullname(), filename) filepath = os.path.join(self.getfullname(), filename)
try: try:

View File

@ -222,6 +222,8 @@ def Internaldate2epoch(resp):
Returns seconds since the epoch.""" Returns seconds since the epoch."""
from calendar import timegm
mo = InternalDate.match(resp) mo = InternalDate.match(resp)
if not mo: if not mo:
return None return None
@ -245,4 +247,4 @@ def Internaldate2epoch(resp):
tt = (year, mon, day, hour, min, sec, -1, -1, -1) tt = (year, mon, day, hour, min, sec, -1, -1, -1)
return time.mktime(tt) return timegm(tt) - zone