/offlineimap/head: changeset 167

- Modified imaputil.py and folder/Maildir.py to run faster. Eliminated
  many regular expressions; pre-compiled many others.

- Fixed threadutil's exitnotifyloop to always handle threads in the
  order they exited, rather than sometimes in the inverse order. This
  way, make sure to handle thread's exception messages before a thread
  exited.
This commit is contained in:
jgoerzen 2002-07-23 20:55:18 +01:00
parent 674ace5896
commit 9d3298f5a7
4 changed files with 45 additions and 17 deletions

View File

@ -1,3 +1,13 @@
offlineimap (3.1.1) unstable; urgency=low
* Modified imaputil.py and folder/Maildir.py to run faster. Eliminated
many regular expressions; pre-compiled many others.
* Fixed threadutil's exitnotifyloop to always handle threads in the order
they exited, rather than sometimes in the inverse order. This way,
make sure to handle thread's exception messages before a thread exited.
-- John Goerzen <jgoerzen@complete.org> Tue, 23 Jul 2002 06:53:16 -0500
offlineimap (3.1.0) unstable; urgency=low offlineimap (3.1.0) unstable; urgency=low
* When uploading messages from a Maildir, now convert \r\n to \n in case * When uploading messages from a Maildir, now convert \r\n to \n in case

View File

@ -20,6 +20,10 @@ from Base import BaseFolder
from offlineimap import imaputil from offlineimap import imaputil
import os.path, os, re, time, socket, md5 import os.path, os, re, time, socket, md5
foldermatchre = re.compile(',FMD5=([0-9a-f]{32})')
uidmatchre = re.compile(',U=(\d+)')
flagmatchre = re.compile(':.*2,([A-Z]+)')
timeseq = 0 timeseq = 0
lasttime = long(0) lasttime = long(0)
@ -84,7 +88,7 @@ class MaildirFolder(BaseFolder):
filename in os.listdir(fulldirname)]) filename in os.listdir(fulldirname)])
for file in files: for file in files:
messagename = os.path.basename(file) messagename = os.path.basename(file)
foldermatch = re.search(',FMD5=([0-9a-f]{32})', messagename) foldermatch = foldermatchre.search(messagename)
if (not foldermatch) or \ if (not foldermatch) or \
md5.new(self.getvisiblename()).hexdigest() \ md5.new(self.getvisiblename()).hexdigest() \
!= foldermatch.group(1): != foldermatch.group(1):
@ -94,14 +98,14 @@ class MaildirFolder(BaseFolder):
uid = nouidcounter uid = nouidcounter
nouidcounter -= 1 nouidcounter -= 1
else: # It comes from our folder. else: # It comes from our folder.
uidmatch = re.search(',U=(\d+)', messagename) uidmatch = uidmatchre.search(messagename)
uid = None uid = None
if not uidmatch: if not uidmatch:
uid = nouidcounter uid = nouidcounter
nouidcounter -= 1 nouidcounter -= 1
else: else:
uid = long(uidmatch.group(1)) uid = long(uidmatch.group(1))
flagmatch = re.search(':.*2,([A-Z]+)', messagename) flagmatch = flagmatchre.search(messagename)
flags = [] flags = []
if flagmatch: if flagmatch:
flags = [x for x in flagmatch.group(1)] flags = [x for x in flagmatch.group(1)]

View File

@ -16,7 +16,8 @@
# along with this program; if not, write to the Free Software # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import re import re, string
quotere = re.compile('^("(?:[^"]|\\\\")*")')
def dequote(string): def dequote(string):
"""Takes a string which may or may not be quoted and returns it, unquoted. """Takes a string which may or may not be quoted and returns it, unquoted.
@ -46,7 +47,7 @@ def options2hash(list):
def flags2hash(string): def flags2hash(string):
return options2hash(flagsplit(string)) return options2hash(flagsplit(string))
def imapsplit(string): def imapsplit(imapstring):
"""Takes a string from an IMAP conversation and returns a list containing """Takes a string from an IMAP conversation and returns a list containing
its components. One example string is: its components. One example string is:
@ -56,23 +57,36 @@ def imapsplit(string):
['(\\HasNoChildren)', '"."', '"INBOX.Sent"']""" ['(\\HasNoChildren)', '"."', '"INBOX.Sent"']"""
workstr = string workstr = imapstring.strip()
retval = [] retval = []
while len(workstr): while len(workstr):
if re.search('^\s', workstr): if workstr[0] == '(':
workstr = re.search('^\s(.*)$', workstr).group(1) # Needs rindex to properly process eg (FLAGS () UID 123)
elif workstr[0] == '(': rpareni = workstr.rindex(')') + 1
parenlist = re.search('^(\(.*\))', workstr).group(1) parenlist = workstr[0:rpareni]
workstr = workstr[len(parenlist):] workstr = workstr[rpareni:].lstrip()
retval.append(parenlist) retval.append(parenlist)
elif workstr[0] == '"': elif workstr[0] == '"':
quotelist = re.search('^("(?:[^"]|\\\\")*")', workstr).group(1) quotelist = quotere.search(workstr).group(1)
workstr = workstr[len(quotelist):] workstr = workstr[len(quotelist):].lstrip()
retval.append(quotelist) retval.append(quotelist)
else: else:
unq = re.search('^(\S+)', workstr).group(1) splits = string.split(workstr, maxsplit = 1)
workstr = workstr[len(unq):] splitslen = len(splits)
retval.append(unq) # The unquoted word is splits[0]; the remainder is splits[1]
if splitslen == 2:
# There's an unquoted word, and more string follows.
retval.append(splits[0])
workstr = splits[1] # split will have already lstripped it
continue
elif splitslen == 1:
# We got a last unquoted word, but nothing else
retval.append(splits[0])
# Nothing remains. workstr would be ''
break
elif splitslen == 0:
# There was not even an unquoted word.
break
return retval return retval
def flagsimap2maildir(string): def flagsimap2maildir(string):

View File

@ -80,7 +80,7 @@ def exitnotifymonitorloop(callback):
exitcondition.wait(1) exitcondition.wait(1)
while len(exitthreads): while len(exitthreads):
callback(exitthreads.pop()) callback(exitthreads.pop(0)) # Pull off in order added!
exitcondition.release() exitcondition.release()
class ExitNotifyThread(Thread): class ExitNotifyThread(Thread):