]> code.delx.au - offlineimap/blobdiff - offlineimap/folder/IMAP.py
Configurable thread status character for ui.Curses.Blinkenlights
[offlineimap] / offlineimap / folder / IMAP.py
index d28825501993c68e09ca75d1dd9b6b702eaf1017..d89059670e2985668192ae793365f467b2369cf4 100644 (file)
@@ -14,7 +14,7 @@
 #
 #    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
+#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
 from Base import BaseFolder
 from offlineimap import imaputil, imaplib
@@ -84,7 +84,7 @@ class IMAPFolder(BaseFolder):
             # Now, get the flags and UIDs for these.
             # We could conceivably get rid of maxmsgid and just say
             # '1:*' here.
-            response = imapobj.fetch('1:%d' % maxmsgid, '(FLAGS UID)')[1]
+            response = imapobj.fetch('1:%d' % maxmsgid, '(FLAGS UID INTERNALDATE)')[1]
         finally:
             self.imapserver.releaseconnection(imapobj)
         for messagestr in response:
@@ -98,7 +98,8 @@ class IMAPFolder(BaseFolder):
             else:
                 uid = long(options['UID'])
                 flags = imaputil.flagsimap2maildir(options['FLAGS'])
-                self.messagelist[uid] = {'uid': uid, 'flags': flags}
+                rtime = imaplib.Internaldate2epoch(messagestr)
+                self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}
 
     def getmessagelist(self):
         return self.messagelist
@@ -115,6 +116,9 @@ class IMAPFolder(BaseFolder):
                 
         finally:
             self.imapserver.releaseconnection(imapobj)
+
+    def getmessagetime(self, uid):
+        return self.messagelist[uid]['time']
     
     def getmessageflags(self, uid):
         return self.messagelist[uid]['flags']
@@ -159,11 +163,16 @@ class IMAPFolder(BaseFolder):
         headervalue = imapobj._quote(headervalue)
         try:
             matchinguids = imapobj.uid('search', 'HEADER', headername, headervalue)[1][0]
-        except imapobj.error:
+        except imapobj.error, err:
             # IMAP server doesn't implement search or had a problem.
+            ui.debug('imap', "savemessage_searchforheader: got IMAP error '%s' while attempting to UID SEARCH for message with header %s" % (err, headername))
             return 0
         ui.debug('imap', 'savemessage_searchforheader got initial matchinguids: ' + repr(matchinguids))
-               
+
+        if matchinguids == '':
+            ui.debug('imap', "savemessage_searchforheader: UID SEARCH for message with header %s yielded no results" % headername)
+            return 0
+
         matchinguids = matchinguids.split(' ')
         ui.debug('imap', 'savemessage_searchforheader: matchinguids now ' + \
                  repr(matchinguids))
@@ -172,7 +181,7 @@ class IMAPFolder(BaseFolder):
         matchinguids.sort()
         return long(matchinguids[0])
 
-    def savemessage(self, uid, content, flags):
+    def savemessage(self, uid, content, flags, rtime):
         imapobj = self.imapserver.acquireconnection()
         ui = UIBase.getglobalui()
         ui.debug('imap', 'savemessage: called')
@@ -189,10 +198,17 @@ class IMAPFolder(BaseFolder):
             # In order to get the new uid, we need to save off the message ID.
 
             message = rfc822.Message(StringIO(content))
-            datetuple = rfc822.parsedate(message.getheader('Date'))
+            datetuple_msg = rfc822.parsedate(message.getheader('Date'))
             # Will be None if missing or not in a valid format.
-            if datetuple == None:
+
+            # If time isn't known
+            if rtime == None and datetuple_msg == None:
                 datetuple = time.localtime()
+            elif rtime == None:
+                datetuple = datetuple_msg
+            else:
+                datetuple = time.localtime(rtime)
+
             try:
                 if datetuple[0] < 1981:
                     raise ValueError
@@ -226,11 +242,11 @@ class IMAPFolder(BaseFolder):
             assert(imapobj.check()[0] == 'OK')
 
             # Keep trying until we get the UID.
-            try:
-                ui.debug('imap', 'savemessage: first attempt to get new UID')
-                uid = self.savemessage_searchforheader(imapobj, headername,
-                                                       headervalue)
-            except ValueError:
+            ui.debug('imap', 'savemessage: first attempt to get new UID')
+            uid = self.savemessage_searchforheader(imapobj, headername,
+                                                   headervalue)
+            # See docs for savemessage in Base.py for explanation of this and other return values
+            if uid <= 0:
                 ui.debug('imap', 'savemessage: first attempt to get new UID failed.  Going to run a NOOP and try again.')
                 assert(imapobj.noop()[0] == 'OK')
                 uid = self.savemessage_searchforheader(imapobj, headername,
@@ -238,7 +254,9 @@ class IMAPFolder(BaseFolder):
         finally:
             self.imapserver.releaseconnection(imapobj)
 
-        self.messagelist[uid] = {'uid': uid, 'flags': flags}
+        if uid: # avoid UID FETCH 0 crash happening later on
+            self.messagelist[uid] = {'uid': uid, 'flags': flags}
+
         ui.debug('imap', 'savemessage: returning %d' % uid)
         return uid