self.randomgenerator = random.Random()
BaseFolder.__init__(self)
+ def selectro(self, imapobj):
+ """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())
+ except imapobj.readonly:
+ imapobj.select(self.getfullname(), readonly = 1)
+
def getaccountname(self):
return self.accountname
imapobj = self.imapserver.acquireconnection()
try:
# Primes untagged_responses
- imapobj.select(self.getfullname(), readonly = 1)
+ self.selectro(imapobj)
return long(imapobj.untagged_responses['UIDVALIDITY'][0])
finally:
self.imapserver.releaseconnection(imapobj)
+ def quickchanged(self, statusfolder):
+ # An IMAP folder has definitely changed if the number of
+ # messages or the UID of the last message have changed. Otherwise
+ # only flag changes could have occurred.
+ imapobj = self.imapserver.acquireconnection()
+ try:
+ # Primes untagged_responses
+ imapobj.select(self.getfullname(), readonly = 1, force = 1)
+ try:
+ # Some mail servers do not return an EXISTS response if
+ # the folder is empty.
+ maxmsgid = long(imapobj.untagged_responses['EXISTS'][0])
+ except KeyError:
+ return True
+
+ # Different number of messages than last time?
+ if maxmsgid != len(statusfolder.getmessagelist()):
+ return True
+
+ if maxmsgid < 1:
+ # No messages; return
+ return False
+
+ # Now, get the UID for the last message.
+ response = imapobj.fetch('%d' % maxmsgid, '(UID)')[1]
+ finally:
+ self.imapserver.releaseconnection(imapobj)
+
+ # Discard the message number.
+ messagestr = string.split(response[0], maxsplit = 1)[1]
+ options = imaputil.flags2hash(messagestr)
+ if not options.has_key('UID'):
+ return True
+ uid = long(options['UID'])
+ saveduids = statusfolder.getmessagelist().keys()
+ saveduids.sort()
+ if uid != saveduids[-1]:
+ return True
+
+ return False
+
def cachemessagelist(self):
imapobj = self.imapserver.acquireconnection()
self.messagelist = {}
imapobj = self.imapserver.acquireconnection()
try:
+ # Making sure, that we have the necessary rights
+ # ensuring that we access readonly: python's braindead imaplib.py
+ # otherwise might raise an exception during the myrights() call
+ imapobj.select(self.getfullname(),readonly=1)
+ myrights = imapobj.myrights(self.getfullname())[1][0].split()[1]
+ if 'T' in flags and not 'd' in myrights or \
+ 'S' in flags and not 's' in myrights or \
+ filter(lambda x: x not in 'TS', flags) and not 'w' in myrights:
+ # no delete/expunge right, but needed or
+ # no store seen right, but needed or
+ # no write right, but needed
+ UIBase.getglobalui().flagstoreadonly(self, uidlist, flags)
+ return
+
try:
imapobj.select(self.getfullname())
except imapobj.readonly:
- UIBase.getglobalui().flagstoreadonly(self, uidlist, flags)
- return
+ # Above we made sure, we have the necessary rights.
+ # Ugly hack, to prevent an unnecessary exception:
+ # readonly: mailbox status changed to READ-ONLY
+ # imaplib should take care of that itself.
+ # The connection is anyway released below, so we dont need to
+ # undo the hack.
+ imapobj.is_readonly = True
r = imapobj.uid('store',
imaputil.listjoin(uidlist),
operation + 'FLAGS',
self.addmessagesflags_noconvert(uidlist, ['T'])
imapobj = self.imapserver.acquireconnection()
try:
- try:
- imapobj.select(self.getfullname())
- except imapobj.readonly:
+ # Making sure, that we have the necessary rights
+ # ensuring that we access readonly: python's braindead imaplib.py
+ # otherwise might raise an exception during the myrights() call
+ imapobj.select(self.getfullname(),readonly=1)
+ if not 'd' in imapobj.myrights(self.getfullname())[1][0].split()[1]:
+ # no delete/expunge rights
UIBase.getglobalui().deletereadonly(self, uidlist)
return
+
if self.expunge:
+ imapobj.select(self.getfullname())
assert(imapobj.expunge()[0] == 'OK')
finally:
self.imapserver.releaseconnection(imapobj)