[PATCH 10/17] Automatically cache messages if needed
Sebastian Spaeth
Sebastian at SSpaeth.de
Mon Nov 29 16:02:18 GMT 2010
Rather than forcing the user to cachemessagelist() before getmessagelist()
do it automatically.
Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
offlineimap/folder/Base.py | 26 +++++++++++++++----
offlineimap/folder/IMAP.py | 7 ++++-
offlineimap/folder/LocalStatus.py | 24 ++++++++++--------
offlineimap/folder/Maildir.py | 49 +++++++++++++++++-------------------
offlineimap/folder/UIDMaps.py | 5 ++++
5 files changed, 66 insertions(+), 45 deletions(-)
diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py
index 35ab450..e7ad22d 100644
--- a/offlineimap/folder/Base.py
+++ b/offlineimap/folder/Base.py
@@ -26,7 +26,10 @@ import sys
class BaseFolder:
def __init__(self):
self.uidlock = Lock()
-
+ self.cachedMessageList = False
+ """whether we already got and cached the message list"""
+ self.messagelist = {}
+
def getname(self):
"""Returns name"""
return self.name
@@ -122,12 +125,20 @@ class BaseFolder:
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."""
+ memory unless this function is called again.
+
+ Your implementation MUST set self.cachedMessageList = True
+ after successfull caching. Usually this function will be
+ automatically invoked by either method:`getmessagelist` or
+ method: `getmessageuidlist`"""
raise NotImplementedException
def getmessagelist(self):
"""Gets the current message list.
- You must call cachemessagelist() before calling this function!"""
+
+ Your implementation MUST call cachemessagelist() if
+ self.cachedMessageList = False and set
+ self.cachedMessageList = True afterwards."""
raise NotImplementedException
def uidexists(self,uid):
@@ -140,13 +151,16 @@ class BaseFolder:
return 0
def getmessageuidlist(self):
- """Gets a list of UIDs.
- You may have to call cachemessagelist() before calling this function!"""
+ """Returns a list of UIDs.
+
+ Caches the list in if needed."""
+ if not self.cachedMessageList:
+ self.cachemessagelist()
return self.getmessagelist().keys()
def getmessagecount(self):
"""Gets the number of messages."""
- return len(self.getmessagelist().keys())
+ return len(self.getmessagelist())
def getmessage(self, uid):
"""Returns the content of the specified message."""
diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py
index 7569781..b4fa791 100644
--- a/offlineimap/folder/IMAP.py
+++ b/offlineimap/folder/IMAP.py
@@ -35,7 +35,6 @@ class IMAPFolder(BaseFolder):
self.root = None # imapserver.root
self.sep = imapserver.delim
self.imapserver = imapserver
- self.messagelist = None
self.visiblename = visiblename
self.accountname = accountname
self.repository = repository
@@ -117,7 +116,8 @@ class IMAPFolder(BaseFolder):
return False
- # TODO: Make this so that it can define a date that would be the oldest messages etc.
+ # TODO: Make this so that it can define a date that would be
+ # the oldest messages etc.
def cachemessagelist(self):
imapobj = self.imapserver.acquireconnection()
self.messagelist = {}
@@ -196,8 +196,11 @@ class IMAPFolder(BaseFolder):
flags = imaputil.flagsimap2maildir(options['FLAGS'])
rtime = imaplibutil.Internaldate2epoch(messagestr)
self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}
+ self.cachedMessageList = True
def getmessagelist(self):
+ if not self.cachedMessageList:
+ self.cachemessagelist()
return self.messagelist
def getmessage(self, uid):
diff --git a/offlineimap/folder/LocalStatus.py b/offlineimap/folder/LocalStatus.py
index 0972a36..1c0a840 100644
--- a/offlineimap/folder/LocalStatus.py
+++ b/offlineimap/folder/LocalStatus.py
@@ -38,7 +38,6 @@ class LocalStatusFolder(BaseFolder):
self.dofsync = config.getdefaultboolean("general", "fsync", True)
self.filename = os.path.join(root, name)
self.filename = repository.getfolderfilename(name)
- self.messagelist = {}
self.repository = repository
self.savelock = threading.Lock()
self.doautosave = 1
@@ -112,16 +111,6 @@ class LocalStatusFolder(BaseFolder):
os.unlink(self.dbfilename)
def cachemessagelist(self):
- return
-
- def autosave(self):
- if self.doautosave:
- self.save()
-
- def save(self):
- self.connection.commit()
-
- def getmessagelist(self):
if self.isnewfolder():
self.messagelist = {}
return
@@ -132,6 +121,19 @@ class LocalStatusFolder(BaseFolder):
flags = [x for x in row[1]]
self.messagelist[row[0]] = {'uid': row[0], 'flags': flags}
+ self.cachedMessageList = True
+ return self.messagelist
+
+ def autosave(self):
+ if self.doautosave:
+ self.save()
+
+ def save(self):
+ self.connection.commit()
+
+ def getmessagelist(self):
+ if not self.cachedMessageList:
+ self.cachemessagelist()
return self.messagelist
def uidexists(self,uid):
diff --git a/offlineimap/folder/Maildir.py b/offlineimap/folder/Maildir.py
index 49d4dae..c93fcc1 100644
--- a/offlineimap/folder/Maildir.py
+++ b/offlineimap/folder/Maildir.py
@@ -57,7 +57,6 @@ class MaildirFolder(BaseFolder):
self.dofsync = config.getdefaultboolean("general", "fsync", True)
self.root = root
self.sep = sep
- self.messagelist = None
self.repository = repository
self.accountname = accountname
BaseFolder.__init__(self)
@@ -94,8 +93,20 @@ class MaildirFolder(BaseFolder):
else:
return True
+ def quickchanged(self, statusfolder):
+ if not self.cachedMessageList:
+ self.cachemessagelist()
+ savedmessages = statusfolder.getmessagelist()
+ if len(self.messagelist) != len(savedmessages):
+ return True
+ for uid in self.messagelist.keys():
+ if uid not in savedmessages:
+ return True
+ if self.messagelist[uid]['flags'] != savedmessages[uid]['flags']:
+ return True
+ return False
- def _scanfolder(self):
+ def cachemessagelist(self):
"""Cache the message list. Maildir flags are:
R (replied)
S (seen)
@@ -103,7 +114,7 @@ class MaildirFolder(BaseFolder):
D (draft)
F (flagged)
and must occur in ASCII order."""
- retval = {}
+ self.messagelist = {}
files = []
nouidcounter = -1 # Messages without UIDs get
# negative UID numbers.
@@ -154,28 +165,15 @@ class MaildirFolder(BaseFolder):
if flagmatch:
flags = [x for x in flagmatch.group(1)]
flags.sort()
- retval[uid] = {'uid': uid,
+ self.messagelist[uid] = {'uid': uid,
'flags': flags,
'filename': file}
- return retval
-
- def quickchanged(self, statusfolder):
- self.cachemessagelist()
- savedmessages = statusfolder.getmessagelist()
- if len(self.messagelist) != len(savedmessages):
- return True
- for uid in self.messagelist.keys():
- if uid not in savedmessages:
- return True
- if self.messagelist[uid]['flags'] != savedmessages[uid]['flags']:
- return True
- return False
- def cachemessagelist(self):
- if self.messagelist is None:
- self.messagelist = self._scanfolder()
+ self.cachedMessageList = True
def getmessagelist(self):
+ if not self.cachedMessageList:
+ self.cachemessagelist()
return self.messagelist
def getmessage(self, uid):
@@ -299,10 +297,9 @@ class MaildirFolder(BaseFolder):
try:
os.unlink(filename)
except OSError:
- # Can't find the file -- maybe already deleted?
- newmsglist = self._scanfolder()
- if uid in newmsglist: # Nope, try new filename.
- os.unlink(newmsglist[uid]['filename'])
- # Yep -- return.
+ # Can't find the file -- maybe already deleted? Update cache.
+ self.cachemessagelist()
+ if self.uidexists(uid): # Nope, try new filename.
+ os.unlink(self.messagelist[uid]['filename'])
+ # Yep -- return.
del(self.messagelist[uid])
-
diff --git a/offlineimap/folder/UIDMaps.py b/offlineimap/folder/UIDMaps.py
index 946f1f5..59fe570 100644
--- a/offlineimap/folder/UIDMaps.py
+++ b/offlineimap/folder/UIDMaps.py
@@ -102,10 +102,15 @@ class MappingFolderMixIn:
finally:
self.maplock.release()
+ self.cachedMessageList = True
+
def getmessagelist(self):
"""Gets the current message list.
You must call cachemessagelist() before calling this function!"""
+ if not self.cachedMessageList:
+ self.cachemessagelist()
+
retval = {}
localhash = self._mb.getmessagelist(self)
self.maplock.acquire()
--
1.7.1
More information about the OfflineIMAP-project
mailing list