Merge pull request #6 from thekix/master
Solves issue #4 and some cleanup
This commit is contained in:
commit
941d69c7b4
@ -524,13 +524,21 @@ class BaseFolder:
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
def savemessagelabels(self, uid, labels, ignorelabels=set(), mtime=0):
|
||||
def savemessagelabels(self, uid, labels, ignorelabels=None, mtime=0):
|
||||
"""Sets the specified message's labels to the given set.
|
||||
|
||||
Note that this function does not check against dryrun settings,
|
||||
so you need to ensure that it is never called in a
|
||||
dryrun mode."""
|
||||
|
||||
"""
|
||||
If this function is implemented,
|
||||
then it should include this code:
|
||||
|
||||
if ignorelabels is None:
|
||||
ignorelabels = set()
|
||||
"""
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
def addmessagelabels(self, uid, labels):
|
||||
|
@ -56,7 +56,7 @@ class GmailFolder(IMAPFolder):
|
||||
|
||||
# Labels to be left alone
|
||||
ignorelabels = self.repository.account.getconf('ignorelabels', '')
|
||||
self.ignorelabels = set([l for l in re.split(r'\s*,\s*', ignorelabels) if len(l)])
|
||||
self.ignorelabels = set([v for v in re.split(r'\s*,\s*', ignorelabels) if len(v)])
|
||||
|
||||
def getmessage(self, uid):
|
||||
"""Retrieve message with UID from the IMAP server (incl body). Also
|
||||
|
@ -133,12 +133,15 @@ class GmailMaildirFolder(MaildirFolder):
|
||||
self.messagelist[uid]['labels'] = labels
|
||||
return ret
|
||||
|
||||
def savemessagelabels(self, uid, labels, ignorelabels=set()):
|
||||
def savemessagelabels(self, uid, labels, ignorelabels=None):
|
||||
"""Change a message's labels to `labels`.
|
||||
|
||||
Note that this function does not check against dryrun settings,
|
||||
so you need to ensure that it is never called in a dryrun mode."""
|
||||
|
||||
if ignorelabels is None:
|
||||
ignorelabels = set()
|
||||
|
||||
filename = self.messagelist[uid]['filename']
|
||||
filepath = os.path.join(self.getfullname(), filename)
|
||||
|
||||
|
@ -91,7 +91,7 @@ class IMAPFolder(BaseFolder):
|
||||
name = self.getfullname()
|
||||
if self.repository.account.utf_8_support:
|
||||
name = imaputil.utf8_IMAP(name)
|
||||
return name
|
||||
return imaputil.foldername_to_imapname(name)
|
||||
|
||||
# Interface from BaseFolder
|
||||
def suggeststhreads(self):
|
||||
|
@ -190,13 +190,16 @@ class LocalStatusFolder(BaseFolder):
|
||||
os.close(fd)
|
||||
|
||||
# Interface from BaseFolder
|
||||
def savemessage(self, uid, content, flags, rtime, mtime=0, labels=set()):
|
||||
def savemessage(self, uid, content, flags, rtime, mtime=0, labels=None):
|
||||
"""Writes a new message, with the specified uid.
|
||||
|
||||
See folder/Base for detail. Note that savemessage() does not
|
||||
check against dryrun settings, so you need to ensure that
|
||||
savemessage is never called in a dryrun mode."""
|
||||
|
||||
if labels is None:
|
||||
labels = set()
|
||||
|
||||
if uid < 0:
|
||||
# We cannot assign a uid.
|
||||
return uid
|
||||
|
@ -323,13 +323,16 @@ class LocalStatusSQLiteFolder(BaseFolder):
|
||||
# assert False,"getmessageflags() called on non-existing message"
|
||||
|
||||
# Interface from BaseFolder
|
||||
def savemessage(self, uid, content, flags, rtime, mtime=0, labels=set()):
|
||||
def savemessage(self, uid, content, flags, rtime, mtime=0, labels=None):
|
||||
"""Writes a new message, with the specified uid.
|
||||
|
||||
See folder/Base for detail. Note that savemessage() does not
|
||||
check against dryrun settings, so you need to ensure that
|
||||
savemessage is never called in a dryrun mode."""
|
||||
|
||||
if labels is None:
|
||||
labels = set()
|
||||
|
||||
if uid < 0:
|
||||
# We cannot assign a uid.
|
||||
return uid
|
||||
|
@ -270,7 +270,7 @@ class MaildirFolder(BaseFolder):
|
||||
filepath = os.path.join(self.getfullname(), filename)
|
||||
return os.path.getmtime(filepath)
|
||||
|
||||
def new_message_filename(self, uid, flags=set(), date=None):
|
||||
def new_message_filename(self, uid, flags=None, date=None):
|
||||
"""Creates a new unique Maildir filename
|
||||
|
||||
:param uid: The UID`None`, or a set of maildir flags
|
||||
@ -278,6 +278,9 @@ class MaildirFolder(BaseFolder):
|
||||
:param flags: (optional) Date
|
||||
:returns: String containing unique message filename"""
|
||||
|
||||
if flags is None:
|
||||
flags = set()
|
||||
|
||||
timeval, timeseq = _gettimeseq(date)
|
||||
uniq_name = '%d_%d.%d.%s,U=%d,FMD5=%s%s2,%s' % \
|
||||
(timeval, timeseq, os.getpid(), socket.gethostname(),
|
||||
|
@ -73,16 +73,16 @@ def flagsplit(s):
|
||||
return imapsplit(s[1:-1])
|
||||
|
||||
|
||||
def __options2hash(list):
|
||||
"""convert list [1,2,3,4,5,6] to {1:2, 3:4, 5:6}"""
|
||||
def __options2hash(l_list):
|
||||
"""convert l_list [1,2,3,4,5,6] to {1:2, 3:4, 5:6}"""
|
||||
|
||||
# effectively this does dict(zip(l[::2],l[1::2])), however
|
||||
# measurements seemed to have indicated that the manual variant is
|
||||
# faster for mosly small lists.
|
||||
retval = {}
|
||||
counter = 0
|
||||
while counter < len(list):
|
||||
retval[list[counter]] = list[counter + 1]
|
||||
while counter < len(l_list):
|
||||
retval[l_list[counter]] = l_list[counter + 1]
|
||||
counter += 2
|
||||
__debug("__options2hash returning:", retval)
|
||||
return retval
|
||||
@ -435,3 +435,23 @@ def imap4_utf_7(name):
|
||||
|
||||
|
||||
codecs.register(imap4_utf_7)
|
||||
|
||||
|
||||
def foldername_to_imapname(folder_name):
|
||||
"""
|
||||
This function returns the folder_name ready to send to the
|
||||
IMAP server. It tests if the folder_name has special characters
|
||||
Then, quote it.
|
||||
Args:
|
||||
folder_name: Folder's name
|
||||
|
||||
Returns: The folder_name quoted if needed
|
||||
|
||||
"""
|
||||
# If name includes some of these characters, quote it
|
||||
atom_specials = [' ', '/', '(', ')', '{', '}']
|
||||
|
||||
if any((c in atom_specials) for c in folder_name):
|
||||
folder_name = '"' + folder_name + '"'
|
||||
|
||||
return folder_name
|
@ -32,7 +32,7 @@ class Repository:
|
||||
def __new__(cls, account, reqtype):
|
||||
"""
|
||||
:param account: :class:`Account`
|
||||
:param regtype: 'remote', 'local', or 'status'"""
|
||||
:param reqtype: 'remote', 'local', or 'status'"""
|
||||
|
||||
if reqtype == 'remote':
|
||||
name = account.getconf('remoterepository')
|
||||
@ -81,6 +81,6 @@ class Repository:
|
||||
executed instead of this stub
|
||||
|
||||
:param account: :class:`Account`
|
||||
:param regtype: 'remote', 'local', or 'status'
|
||||
:param reqtype: 'remote', 'local', or 'status'
|
||||
"""
|
||||
pass
|
||||
|
@ -78,17 +78,6 @@ def monitor():
|
||||
"""An infinite "monitoring" loop watching for finished ExitNotifyThread's.
|
||||
|
||||
This one is supposed to run in the main thread.
|
||||
:param callback: the function to call when a thread terminated. That
|
||||
function is called with a single argument -- the
|
||||
ExitNotifyThread that has terminated. The monitor will
|
||||
not continue to monitor for other threads until
|
||||
'callback' returns, so if it intends to perform long
|
||||
calculations, it should start a new thread itself -- but
|
||||
NOT an ExitNotifyThread, or else an infinite loop
|
||||
may result.
|
||||
Furthermore, the monitor will hold the lock all the
|
||||
while the other thread is waiting.
|
||||
:type callback: a callable function
|
||||
"""
|
||||
|
||||
global exitedThreads
|
||||
|
Loading…
Reference in New Issue
Block a user