diff --git a/head/offlineimap/folder/Base.py b/head/offlineimap/folder/Base.py index f80c78f..9f39848 100644 --- a/head/offlineimap/folder/Base.py +++ b/head/offlineimap/folder/Base.py @@ -32,3 +32,24 @@ class BaseFolder: def getfullname(self): return self.getroot() + self.getsep() + self.getname() + def isuidvalidityok(self, remotefolder): + raise NotImplementedException + + def getuidvalidity(self): + raise NotImplementedException + + def saveuidvalidity(self, newval): + raise NotImplementedException + + def cachemessagelist(self): + """Reads the message list from disk or network and stores it in + memory for later use. This list will not be re-read from disk or + memory unless this function is called again.""" + raise NotImplementedException + + def getmessagelist(self): + """Gets the current message list. If cachemessagelist has not yet + been called, it will be called.""" + raise NotImplementedException + + diff --git a/head/offlineimap/folder/Maildir.py b/head/offlineimap/folder/Maildir.py index ada77d6..46b5b47 100644 --- a/head/offlineimap/folder/Maildir.py +++ b/head/offlineimap/folder/Maildir.py @@ -18,11 +18,64 @@ from Base import BaseFolder from imapsync import imaputil +import os.path, os, re class MaildirFolder(BaseFolder): def __init__(self, root, name): self.name = name self.root = root self.sep = '.' + self.uidfilename = os.path.join(self.getfullname(), "imapsync.uidvalidity") + self.messagelist = None + + def getuidvalidity(self): + if not os.path.exists(self.uidfilename): + return None + file = open(self.uidfilename, "rt") + retval = int(file.readline().strip()) + file.close() + return retval + + def saveuidvalidity(self, newval): + file = open(self.uidfilename, "wt") + file.write("%d\n", newval) + file.close() + + def isuidvalidityok(self, remotefolder): + myval = self.getuidvalidity() + if myval != None: + return myval == remotefolder.getuidvalidity() + else: + self.saveuidvalidity(remotefolder.getuidvalidity()) + + def cachemessagelist(self): + """Cache the message list. Maildir flags are: + R (replied) + S (seen) + T (trashed) + D (draft) + F (flagged) + and must occur in ASCII order.""" + self.messagelist = {} + files = [] + for dirannex in ['new', 'cur']: + fulldirname = os.path.join(self.getfullname(), dirannex) + files.append([os.path.join(fulldirname, filename) for + filename in os.listdir(fulldirname)]) + for file in files: + messagename = os.path.basename(file) + uid = int(re.search(',U=(\d+)', messagename).group(1)) + flagmatch = re.search(':.*2,([A-Z]+)') + flags = [] + if flagmatch: + flags = [f for x in flagmatch.group(1)] + self.messagelist[uid] = {'uid': uid, + 'flags': flags, + 'filename': messagename} + + def getmessagelist(self): + if self.messagelist == None: + self.cachemessagelist() + return self.messagelist