/offlineimap/head: changeset 347

Preparing for 3.99.7
This commit is contained in:
jgoerzen
2003-01-09 03:16:07 +01:00
parent 399f7d9de9
commit 3cb8fb0062
7 changed files with 147 additions and 54 deletions

View File

@ -131,7 +131,7 @@ class BaseFolder:
def addmessagesflags(self, uidlist, flags):
for uid in uidlist:
self.addmessageflags(uid)
self.addmessageflags(uid, flags)
def deletemessageflags(self, uid, flags):
"""Removes each flag given from the message's flag set. If a given
@ -143,6 +143,10 @@ class BaseFolder:
newflags.sort()
self.savemessageflags(uid, newflags)
def deletemessagesflags(self, uidlist, flags):
for uid in uidlist:
self.deletemessageflags(uid, flags)
def deletemessage(self, uid):
raise NotImplementedException
@ -150,6 +154,35 @@ class BaseFolder:
for uid in uidlist:
self.deletemessage(uid)
def syncmessagesto_neguid_msg(self, uid, dest, applyto, register = 1):
if register:
UIBase.getglobalui().registerthread(self.getaccountname())
UIBase.getglobalui().copyingmessage(uid, self, applyto)
successobject = None
successuid = None
message = self.getmessage(uid)
flags = self.getmessageflags(uid)
for tryappend in applyto:
successuid = tryappend.savemessage(uid, message, flags)
if successuid >= 0:
successobject = tryappend
break
# Did we succeed?
if successobject != None:
if successuid: # Only if IMAP actually assigned a UID
# Copy the message to the other remote servers.
for appendserver in \
[x for x in applyto if x != successobject]:
appendserver.savemessage(successuid, message, flags)
# Copy to its new name on the local server and delete
# the one without a UID.
self.savemessage(successuid, message, flags)
self.deletemessage(uid) # It'll be re-downloaded.
else:
# Did not find any server to take this message. Ignore.
pass
def syncmessagesto_neguid(self, dest, applyto):
"""Pass 1 of folder synchronization.
@ -158,33 +191,28 @@ class BaseFolder:
and once that succeeds, get the UID, add it to the others for real,
add it to local for real, and delete the fake one."""
for uid in self.getmessagelist().keys():
if uid >= 0:
continue
UIBase.getglobalui().copyingmessage(uid, self, applyto)
successobject = None
successuid = None
message = self.getmessage(uid)
flags = self.getmessageflags(uid)
for tryappend in applyto:
successuid = tryappend.savemessage(uid, message, flags)
if successuid >= 0:
successobject = tryappend
break
# Did we succeed?
if successobject != None:
if successuid: # Only if IMAP actually assigned a UID
# Copy the message to the other remote servers.
for appendserver in \
[x for x in applyto if x != successobject]:
appendserver.savemessage(successuid, message, flags)
# Copy to its new name on the local server and delete
# the one without a UID.
self.savemessage(successuid, message, flags)
self.deletemessage(uid) # It'll be re-downloaded.
uidlist = [uid for uid in self.getmessagelist().keys() if uid < 0]
threads = []
usethread = None
if applyto != None:
usethread = applyto[0]
for uid in uidlist:
if usethread:
usethread.waitforthread()
thread = InstanceLimitedThread(\
usethread.getcopyinstancelimit(),
target = self.syncmessagesto_neguid_msg,
name = "New msg sync from %s" % self.getvisiblename(),
args = (uid, dest, applyto))
thread.setDaemon(1)
thread.start()
threads.append(thread)
else:
# Did not find any server to take this message. Ignore.
pass
self.syncmessagesto_neguid_msg(uid, dest, applyto, register = 0)
for thread in threads:
thread.join()
def copymessageto(self, uid, applyto, register = 1):
# Sometimes, it could be the case that if a sync takes awhile,
@ -260,6 +288,17 @@ class BaseFolder:
Look for any flag matching issues -- set dest message to have the
same flags that we have."""
# As an optimization over previous versions, we store up which flags
# are being used for an add or a delete. For each flag, we store
# a list of uids to which it should be added. Then, we can call
# addmessagesflags() to apply them in bulk, rather than one
# call per message as before. This should result in some significant
# performance improvements.
addflaglist = {}
delflaglist = {}
for uid in self.getmessagelist().keys():
if uid < 0: # Ignore messages missed by pass 1
continue
@ -267,17 +306,26 @@ class BaseFolder:
destflags = dest.getmessageflags(uid)
addflags = [x for x in selfflags if x not in destflags]
if len(addflags):
UIBase.getglobalui().addingflags(uid, addflags, applyto)
for object in applyto:
object.addmessageflags(uid, addflags)
for flag in addflags:
if not flag in addflaglist:
addflaglist[flag] = []
addflaglist[flag].append(uid)
delflags = [x for x in destflags if x not in selfflags]
if len(delflags):
UIBase.getglobalui().deletingflags(uid, delflags, applyto)
for object in applyto:
object.deletemessageflags(uid, delflags)
for flag in delflags:
if not flag in delflaglist:
delflaglist[flag] = []
delflaglist[flag].append(uid)
for object in applyto:
for flag in addflaglist.keys():
UIBase.getglobalui().addingflags(addflaglist[flag], flag, [object])
object.addmessagesflags(addflaglist[flag], [flag])
for flag in delflaglist.keys():
UIBase.getglobalui().deletingflags(addflaglist[flag], flag, [object])
object.deletemessagesflags(delflaglist[flag], [flag])
def syncmessagesto(self, dest, applyto = None):
"""Syncs messages in this folder to the destination.
If applyto is specified, it should be a list of folders (don't forget

View File

@ -198,6 +198,15 @@ class IMAPFolder(BaseFolder):
self.addmessagesflags([uid], flags)
def addmessagesflags(self, uidlist, flags):
self.processmessagesflags('+', uidlist, flags)
def deletemessageflags(self, uid, flags):
self.deletemessagesflags([uid], flags)
def deletemessagesflags(self, uidlist, flags):
self.processmessagesflags('-', uidlist, flags)
def processmessagesflags(self, operation, uidlist, flags):
imapobj = self.imapserver.acquireconnection()
try:
try:
@ -207,7 +216,7 @@ class IMAPFolder(BaseFolder):
return
r = imapobj.uid('store',
imaputil.listjoin(uidlist),
'+FLAGS',
operation + 'FLAGS',
imaputil.flagsmaildir2imap(flags))
assert r[0] == 'OK', 'Error with store: ' + r[1]
r = r[1]
@ -234,10 +243,15 @@ class IMAPFolder(BaseFolder):
except ValueError: # Let it slide if it's not in the list
pass
for uid in needupdate:
for flag in flags:
if not flag in self.messagelist[uid]['flags']:
self.messagelist[uid]['flags'].append(flag)
self.messagelist[uid]['flags'].sort()
if operation == '+':
for flag in flags:
if not flag in self.messagelist[uid]['flags']:
self.messagelist[uid]['flags'].append(flag)
self.messagelist[uid]['flags'].sort()
elif operation == '-':
for flag in flags:
if flag in self.messagelist[uid]['flags']:
self.messagelist[uid]['flags'].remove(flag)
def deletemessage(self, uid):
self.deletemessages([uid])

View File

@ -170,12 +170,13 @@ class MaildirFolder(BaseFolder):
attempts += 1
else:
break
file = open(os.path.join(tmpdir, messagename), "wt")
tmpmessagename = messagename.split(',')[0]
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
file.write(content)
file.close()
os.link(os.path.join(tmpdir, messagename),
os.link(os.path.join(tmpdir, tmpmessagename),
os.path.join(newdir, messagename))
os.unlink(os.path.join(tmpdir, messagename))
os.unlink(os.path.join(tmpdir, tmpmessagename))
self.messagelist[uid] = {'uid': uid, 'flags': [],
'filename': os.path.join(newdir, messagename)}
self.savemessageflags(uid, flags)

View File

@ -63,13 +63,13 @@ class BlinkenBase:
s.gettf().setcolor('red')
s.__class__.__bases__[-1].deletingmessage(s, uid, destlist)
def addingflags(s, uid, flags, destlist):
def addingflags(s, uidlist, flags, destlist):
s.gettf().setcolor('yellow')
s.__class__.__bases__[-1].addingflags(s, uid, flags, destlist)
s.__class__.__bases__[-1].addingflags(s, uidlist, flags, destlist)
def deletingflags(s, uid, flags, destlist):
def deletingflags(s, uidlist, flags, destlist):
s.gettf().setcolor('pink')
s.__class__.__bases__[-1].deletingflags(s, uid, flags, destlist)
s.__class__.__bases__[-1].deletingflags(s, uidlist, flags, destlist)
def init_banner(s):
s.availablethreadframes = {}

View File

@ -221,17 +221,17 @@ class UIBase:
", ".join([str(u) for u in uidlist]),
ds))
def addingflags(s, uid, flags, destlist):
def addingflags(s, uidlist, flags, destlist):
if s.verbose >= 0:
ds = s.folderlist(destlist)
s._msg("Adding flags %s to message %d on %s" % \
(", ".join(flags), uid, ds))
s._msg("Adding flags %s to %d messages on %s" % \
(", ".join(flags), len(uidlist), ds))
def deletingflags(s, uid, flags, destlist):
def deletingflags(s, uidlist, flags, destlist):
if s.verbose >= 0:
ds = s.folderlist(destlist)
s._msg("Deleting flags %s to message %d on %s" % \
(", ".join(flags), uid, ds))
s._msg("Deleting flags %s to %d messages on %s" % \
(", ".join(flags), len(uidlist), ds))
################################################## Threads