Possible fix for bug#142

P.H. qikom at free.fr
Fri Sep 11 00:17:15 UTC 2009


Hello to all...

I finally decided to spend some time investigating bug #142, since I've
been suffering from it for some time.
 ( http://software.complete.org/software/issues/show/142 )


Summary: propagating changes to an account on the Zimbra server of some
French Internet provider (Free) crashes offlineimap with

Thread 'Folder sync Com[Junk]' terminated with exception:
...
  File "/usr/lib/pymodules/python2.5/offlineimap/folder/IMAP.py", line 377, in processmessagesflags
    assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])
AssertionError: Error with store: mailbox selected READ-ONLY

Note: I am using offlineimap_6.2.0

Modifying line 126 of IMAP.py (in function "cachemessagelist")
from
-            imapobj.select(self.getfullname(), readonly = 1, force = 1)
to
+            self.selectro(imapobj)
it seems to correct the problem.

If I only remove the 'readonly' flag, it fails for the special folders
'Contacts', 'Emailed Contacts' and 'Chats' which are probably not real
imap folders. (Not a huge problem for me since I filter them in my
offlineimaprc.)


So, in file offlineimap/folders/IMAP.py, is there a reason for using
"selectro" in "getuidvalidity" but not in "cachemessagelist". (nor in
"quickchanged" or "getmessage").

Right now, "selectro" is only used once, so it might be a good thing to
add an optional argument 'force' and use this function whenever
possible.  Pretending that I know what I am doing (I don't), I attach a
tiny patch doing that...
Hopefully, someone more knowledgeable can improve it.


Now, that might or might not fix bug #142, but I'd still like to
understand what is going on.

My first guess is that there is some problem with the Zimbra software.
(This account used to work before the provider switched to using
Zimbra).

My other guess is that this also has something to do with threads...  I
can connect to the account and issue commands using imaplib.IMAP4, or
offlineimap.imapserver.UsefulIMAP4.

More probably, a little bit of both.

Since I am not familiar with threads programming and I don't know how to
debug them, I am in a dead end.

Does anybody have an idea?
Could it be that some 'readonly' flag leaks from one thread (typically
from the one calling "cachemessagelist") to another?


Another very strange things which I encountered trying to fix this is
the following: replacing the call to "selectro" in function
"getuidvalidity" by
   imapobj.select(self.getfullname(), readonly = 1)
I could, "sometimes", propagate changes. I seemed that I had to wait
about 1 minute between calls to offlineimap.
(In the meantime, I could still issue commands via a simple imaplib
script.)
I am confused...


Thanks in advance!


Pierre
--------- 8< ----------------------------------------------------------

-- 
I don't quite hear what you say, but I beg to differ
entirely with you.
    -- Augustus De Morgan

--dTy3Mrz/UPE2dbVg
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch142

--- offlineimap-orig/offlineimap/folder/IMAP.py	2009-08-12 22:25:27.000000000 +0200
+++ offlineimap-work/offlineimap/folder/IMAP.py	2009-09-11 02:11:17.000000000 +0200
@@ -41,15 +41,15 @@
         self.randomgenerator = random.Random()
         BaseFolder.__init__(self)
 
-    def selectro(self, imapobj):
+    def selectro(self, imapobj, force = None):
         """Select this folder when we do not need write access.
         Prefer SELECT to EXAMINE if we can, since some servers
         (Courier) do not stabilize UID validity until the folder is
         selected."""
         try:
-            imapobj.select(self.getfullname())
+            imapobj.select(self.getfullname(), force = force)
         except imapobj.readonly:
-            imapobj.select(self.getfullname(), readonly = 1)
+            imapobj.select(self.getfullname(), readonly = 1, force = force)
 
     def getaccountname(self):
         return self.accountname
@@ -82,7 +82,7 @@
         imapobj = self.imapserver.acquireconnection()
         try:
             # Primes untagged_responses
-            imapobj.select(self.getfullname(), readonly = 1, force = 1)
+            self.selectro(imapobj, force = 1)
             try:
                 # Some mail servers do not return an EXISTS response if
                 # the folder is empty.
@@ -122,7 +122,7 @@
 
         try:
             # Primes untagged_responses
-            imapobj.select(self.getfullname(), readonly = 1, force = 1)
+            self.selectro(imapobj, force = 1)
             try:
                 # Some mail servers do not return an EXISTS response if
                 # the folder is empty.
@@ -160,7 +160,7 @@
         ui = UIBase.getglobalui()
         imapobj = self.imapserver.acquireconnection()
         try:
-            imapobj.select(self.getfullname(), readonly = 1)
+            self.selectro(imapobj)
             initialresult = imapobj.uid('fetch', '%d' % uid, '(BODY.PEEK[])')
             ui.debug('imap', 'Returned object from fetching %d: %s' % \
                      (uid, str(initialresult)))

--dTy3Mrz/UPE2dbVg--



More information about the OfflineIMAP-project mailing list