diff --git a/head/offlineimap.py b/head/offlineimap.py index 5c08570..9257658 100644 --- a/head/offlineimap.py +++ b/head/offlineimap.py @@ -84,6 +84,7 @@ for accountname in accounts: # Load status folder. statusfolder = statusrepos.getfolder(remotefolder.getname()) + statusfolder.cachemessagelist() if statusfolder.isnewfolder(): print "Local status folder is new; ignoring." @@ -93,7 +94,7 @@ for accountname in accounts: # Synchronize remote changes. print "Synchronizing remote to local..." - remotefolder.syncmessagesto(localfolder, [localfolder, statusfolder]) + remotefolder.syncmessagesto(localfolder) # Make sure the status folder is up-to-date. print "Updating local status cache..." diff --git a/head/offlineimap/folder/Base.py b/head/offlineimap/folder/Base.py index 4af65dd..c6afcad 100644 --- a/head/offlineimap/folder/Base.py +++ b/head/offlineimap/folder/Base.py @@ -193,11 +193,11 @@ class BaseFolder: addflags = [x for x in selfflags if x not in destflags] if len(addflags): for object in applyto: - object.addmessageflags(addflags) + object.addmessageflags(uid, addflags) delflags = [x for x in destflags if x not in selfflags] if len(delflags): for object in applyto: - object.deletemessageflags(delflags) + object.deletemessageflags(uid, delflags) diff --git a/head/offlineimap/folder/IMAP.py b/head/offlineimap/folder/IMAP.py index 8f19778..52e6c04 100644 --- a/head/offlineimap/folder/IMAP.py +++ b/head/offlineimap/folder/IMAP.py @@ -92,7 +92,7 @@ class IMAPFolder(BaseFolder): assert(self.imapobj.select(self.getfullname())[0] == 'OK') result = self.imapobj.uid('store', '%d' % uid, 'FLAGS', imaputil.flagsmaildir2imap(flags))[1][0] - flags = imaputil.flags2hash(imaputil.imapsplit(result)[1]){'FLAGS'} + flags = imaputil.flags2hash(imaputil.imapsplit(result)[1])['FLAGS'] self.messagelist[uid]['flags'] = imaputil.flagsimap2maildir(flags) def deletemessage(self, uid): diff --git a/head/offlineimap/folder/LocalStatus.py b/head/offlineimap/folder/LocalStatus.py new file mode 100644 index 0000000..f9b275a --- /dev/null +++ b/head/offlineimap/folder/LocalStatus.py @@ -0,0 +1,95 @@ +# Local status cache virtual folder +# Copyright (C) 2002 John Goerzen +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from Base import BaseFolder +import os + +magicline = "IMAPSYNC LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1" + +class LocalStatusFolder(BaseFolder): + def __init__(self, root, name): + self.name = name + self.root = root + self.sep = '.' + self.filename = os.path.join(root, name) + self.messagelist = None + + def isnewfolder(self): + return not os.path.exists(self.filename) + + def getname(self): + return self.name + + def getroot(self): + return self.root + + def getsep(self): + return self.sep + + def getfullname(self): + return self.filename + + def cachemessagelist(self): + if self.isnewfolder(): + self.messagelist = {} + return + file = open(self.filename, "rt") + self.messagelist = {} + line = file.readline().strip() + assert(line == magicline) + for line in file.xreadlines(): + uid, flags = line.split(':') + uid = long(uid) + flags = [x for x in flags] + self.messagelist[uid] = {'uid': uid, 'flags': flags} + file.close() + + def save(self): + file = open(self.filename, "wt") + file.write(magicline + "\n") + for msg in self.messagelist.values(): + flags = msg['flags'] + flags.sort() + flags = ''.join(flags) + file.write("%s:%s\n" % (msg['uid'], flags)) + file.close() + + def getmessagelist(self): + return self.messagelist + + def savemessage(self, uid, content, flags): + if uid < 0: + # We cannot assign a uid. + return uid + + if uid in self.messagelist: # already have it + self.savemessageflags(uid, flags) + return uid + + self.messagelist[uid] = {'uid': uid, 'flags': flags} + return uid + + def getmessageflags(self, uid): + return self.messagelist[uid]['flags'] + + def savemessageflags(self, uid, flags): + self.messagelist[uid]['flags'] = flags + + def deletemessage(self, uid): + del(self.messagelist[uid]) + diff --git a/head/offlineimap/folder/Maildir.py b/head/offlineimap/folder/Maildir.py index b27cdc1..c870578 100644 --- a/head/offlineimap/folder/Maildir.py +++ b/head/offlineimap/folder/Maildir.py @@ -41,7 +41,7 @@ class MaildirFolder(BaseFolder): def saveuidvalidity(self, newval): file = open(self.uidfilename, "wt") - file.write("%d\n", newval) + file.write("%d\n" % newval) file.close() def isuidvalidityok(self, remotefolder): @@ -50,6 +50,7 @@ class MaildirFolder(BaseFolder): return myval == remotefolder.getuidvalidity() else: self.saveuidvalidity(remotefolder.getuidvalidity()) + return 1 def cachemessagelist(self): """Cache the message list. Maildir flags are: @@ -142,7 +143,7 @@ class MaildirFolder(BaseFolder): if infomatch: # If the info string is present.. infostr = infomatch.group(1) newname = newname.split(':')[0] # Strip off the info string. - re.sub('2,[A-Z]*', '', infostr) + infostr = re.sub('2,[A-Z]*', '', infostr) flags.sort() infostr += '2,' + ''.join(flags) newname += infostr @@ -151,6 +152,7 @@ class MaildirFolder(BaseFolder): if (newfilename != oldfilename): os.rename(oldfilename, newfilename) self.getmessagelist()[uid]['flags'] = flags + self.getmessagelist()[uid]['filename'] = newfilename def getmessageflags(self, uid): return self.getmessagelist()[uid]['flags']