Mercurial > public > weighmail
changeset 6:470bfed5411e
First commit where it actually does what it is supposed to.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 19 May 2012 16:43:45 -0500 |
parents | 2c88867c4875 |
children | 1315e39fe059 |
files | weighmail/core.py weighmail/main.py weighmail/observers/__init__.py weighmail/observers/console.py |
diffstat | 4 files changed, 139 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/weighmail/core.py Sat May 19 16:43:45 2012 -0500 @@ -0,0 +1,48 @@ + + +def weighmail(imap, folder, labels, observer=None): + """Applies labels to message that meet size criteria. + + imap - IMAPClient + folder - folder name to operate on + labels - list of Label tuples + observer - will call back to report progress + + """ + imap.select_folder(folder) + + for label in labels: + apply_label(imap, label, observer) + + if observer is not None: + observer.done() + + +def get_criteria(label): + """Returns the RFC 3501 criteria string for the given label""" + + l = 'LARGER %d' % label.min if label.min is not None else '' + s = 'SMALLER %d' % label.max if label.max is not None else '' + + return '{larger} {smaller}'.format(larger=l, smaller=s).strip() + + +def apply_label(imap, label, observer=None): + """Searches for messages that meet the label's criteria and applies the + label to them. + + """ + criteria = get_criteria(label) + + if observer is not None: + observer.searching(label.name) + + msgs = imap.search(criteria) + + if observer is not None: + observer.labeling(label.name, len(msgs)) + + imap.add_gmail_labels(msgs, [label.name]) + + if observer is not None: + observer.done_labeling(label.name, len(msgs))
--- a/weighmail/main.py Sat May 19 13:57:38 2012 -0500 +++ b/weighmail/main.py Sat May 19 16:43:45 2012 -0500 @@ -2,8 +2,12 @@ import getpass import sys +import imapclient + import config from utils import make_label, AppError +from observers.console import ConsoleObserver +from core import weighmail PROG_DESC = "Adds labels to your Gmail according to message size" @@ -65,6 +69,18 @@ return args +def create_imap_client(host, port, ssl, user, password): + """Creates & returns an instance of an IMAPClient""" + + print "Connecting..." + + client = imapclient.IMAPClient(host=host, port=port, ssl=ssl) + client.login(username=user, password=password) + + print "Connected." + return client + + def main(): # Parse command-line arguments args = parse_args() @@ -89,14 +105,26 @@ if opt not in opts or opts[opt] is None: opts[opt] = getpass.getpass(opt + ': ') - print opts - if 'labels' not in opts or not opts['labels']: raise AppError("Please specify some label definitions") + imap_args = opts.copy() + del imap_args['folder'] + del imap_args['labels'] + + client = create_imap_client(**imap_args) + observer = ConsoleObserver() + + weighmail(client, opts['folder'], opts['labels'], observer) + client.logout() + if __name__ == '__main__': try: main() except (IOError, AppError), ex: sys.stderr.write("%s\n" % ex) + except imapclient.IMAPClient.Error, ex: + sys.stderr.write("IMAP Error: %s\n" % ex) + except KeyboardInterrupt: + sys.stderr.write('Interrupted\n')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/weighmail/observers/__init__.py Sat May 19 16:43:45 2012 -0500 @@ -0,0 +1,32 @@ +"""Base observer class for weighmail operations. + +""" + +class BaseObserver(object): + """Base observer class; does nothing.""" + + def searching(self, label): + """Called when the search process has started for a label""" + pass + + def labeling(self, label, count): + """Called when the labelling process has started for a given label + + label - the label we are working on + count - number of messages to label + + """ + pass + + def done_labeling(self, label, count): + """Called when finished labelling for a given label + + label - the label we were working on + count - number of messages that were labelled + + """ + pass + + def done(self): + """Called when completely finished""" + pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/weighmail/observers/console.py Sat May 19 16:43:45 2012 -0500 @@ -0,0 +1,29 @@ +import datetime + +from observers import BaseObserver + +class ConsoleObserver(BaseObserver): + """Console observer class; outputs status to the console.""" + + def __init__(self, *args, **kwargs): + super(BaseObserver, self).__init__(*args, **kwargs) + self.first_callback = True + self.total_messages = 0 + + def searching(self, label): + if self.first_callback: + self.first_callback = False + self.start_time = datetime.datetime.now() + + print "Searching for %s messages..." % label + + def labeling(self, label, count): + print "Applying the label %s to %d messages..." % (label, count) + + def done_labeling(self, label, count): + self.total_messages += count + + def done(self): + duration = datetime.datetime.now() - self.start_time + print "Labeled %d messages in %s" % (self.total_messages, duration) + print "Done."