diff options
-rwxr-xr-x | archive_folder.py | 69 | ||||
-rwxr-xr-x | purgeObsolete.py | 16 |
2 files changed, 42 insertions, 43 deletions
diff --git a/archive_folder.py b/archive_folder.py index 37eba50..2ac91fd 100755 --- a/archive_folder.py +++ b/archive_folder.py @@ -19,14 +19,6 @@ logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', stream=sys.stdout, level=logging.INFO) log = logging.getLogger('imapArch') -class ServerError(IOError): - pass - -class FolderError(IOError): - pass - -class MessageError(IOError): - pass Capas = collections.namedtuple('Capas', ['MOVE', 'UIDPLUS']) SEP_RE = re.compile(r'\s+"([/.])"\s+') @@ -35,6 +27,7 @@ FOLDER_RE = re.compile(r'\s+"[/.]"\s+') class Message(object): """Abstraction over one email message.""" + def __init__(self, folder, uid): self.folder = folder self.box = self.folder.box @@ -43,7 +36,7 @@ class Message(object): date_header = self.msg['Date'] try: self.date = email.utils.parsedate_to_datetime(date_header) - except TypeError: + except (TypeError, ValueError): log.warning('Cannot parse date string %s', date_header) self.date = None self.subject = self.__get_subject() @@ -53,8 +46,8 @@ class Message(object): if typ == 'OK': return email.message_from_bytes(data[0][1]) else: - raise MessageError('Cannot parse message %s:\n%s!' % - (self.uid, data[0][1])) + raise IOError('Cannot parse message %s:\n%s!' % + (self.uid, data[0][1])) def __get_subject(self): out_str = '' @@ -90,14 +83,15 @@ class Folder(object): self.folder_sep = self.__get_separator() log.debug('self.__create_missing = %s, fld_name = %s, exists %s', - self.__create_missing, fld_name, fld_name not in self.server.all_folders) + self.__create_missing, fld_name, + fld_name not in self.server.all_folders) if self.__create_missing and (fld_name not in self.server.all_folders): self.__create_folder() def select(self): ok, _ = self.box.select(mailbox=self.fld_name) if ok != 'OK': - raise FolderError('Cannot select folder %s' % self.fld_name) + raise IOError('Cannot select folder %s' % self.fld_name) self.selected = True return self @@ -122,7 +116,7 @@ class Folder(object): name = '{}/'.format(self.fld_name) ok, data = self.box.list(name, wildcards) if ok != 'OK': - raise ServerError('Cannot list folder %s' % self.fld_name) + raise IOError('Cannot list folder %s' % self.fld_name) log.debug('data = %s', data) return data[0] @@ -141,13 +135,14 @@ class Folder(object): if parse_data is not None: return parse_data.group(1) else: - raise ServerError('Cannot find folder separator from %s' % data) + raise IOError('Cannot find folder separator from %s' % data) def __emails_search(self, search_type, date_str): - ok, res = self.box.uid('SEARCH', '%s %s' % (search_type.upper(), date_str)) + ok, res = self.box.uid('SEARCH', + '%s %s' % (search_type.upper(), date_str)) if ok != 'OK': - raise MessageError('SEARCH %s %s failed!' % - (search_type.lower(), date_str)) + raise IOError('SEARCH %s %s failed!' % + (search_type.lower(), date_str)) msgs = [] uids = res[0].decode().split() @@ -164,44 +159,44 @@ class Folder(object): return raw_name.strip('/') def move_messages(self, messages): - assert self.selected == False, 'Target folder should not be selected.' + assert self.selected is False, 'Target folder should not be selected.' if self.box.features_present.MOVE: # We cannot move self.box.uid('MOVE', messages, self.fld_name) # because IMAP4_SSL.uid has a protection against unknown # commands. https://bugs.python.org/issue33336 typ, dat = self.box._simple_command('UID', 'MOVE', - messages, self.fld_name) + messages, self.fld_name) ok, data = self.box._untagged_response(typ, dat, 'MOVE') log.debug('MOVE ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot move messages to folder %s' % - self.fld_name) + raise IOError('Cannot move messages to folder %s' % + self.fld_name) elif self.box.features_present.UIDPLUS: ok, data = self.box.uid('COPY', messages, self.fld_name) log.debug('COPY ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot copy messages to folder %s' % - self.fld_name) + raise IOError('Cannot copy messages to folder %s' % + self.fld_name) ok, data = self.box.uid('STORE', r'+FLAGS.SILENT (\DELETED)', messages) log.debug('STORE ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot delete messages-') + raise IOError('Cannot delete messages-') ok, data = self.box.uid('EXPUNGE', messages) log.debug('EXPUNGE ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot expunge messages.') + raise IOError('Cannot expunge messages.') else: ok, data = self.box.uid('COPY', messages, self.fld_name) log.debug('COPY ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot copy messages to folder %s' % - self.fld_name) + raise IOError('Cannot copy messages to folder %s' % + self.fld_name) ok, data = self.box.uid('STORE', r'+FLAGS.SILENT (\DELETED)', messages) log.debug('STORE ok = %s, data = %s', ok, data) if ok != 'OK': - raise FolderError('Cannot delete messages-') + raise IOError('Cannot delete messages-') class EmailServer(object): @@ -215,17 +210,19 @@ class EmailServer(object): if verbosity > 1: self.box.debug = 4 - def __login(self, host='localhost', username=None, password=None, ssl=None): + def __login(self, host='localhost', username=None, password=None, + ssl=None): box = imaplib.IMAP4_SSL(host=host) ok, data = box.login(username, password) if ok != 'OK': - raise ServerError('Cannot login with credentials %s' % - str((host, username, password,))) + raise IOError('Cannot login with credentials %s' % + str((host, username, password,))) ok, data = box.capability() capas = data[0].decode() log.debug('capas = %s', capas) - box.features_present = Capas._make(['MOVE' in capas, 'UIDPLUS' in capas]) + box.features_present = Capas._make( + ['MOVE' in capas, 'UIDPLUS' in capas]) ok, data = box.list() if ok != 'OK': @@ -294,7 +291,8 @@ if __name__ == '__main__': locale.setlocale(locale.LC_ALL, 'en_US') argp = argparse.ArgumentParser() subps = argp.add_subparsers(dest='cmd') - subp_servers = subps.add_parser('servers', help='List available servers (by keywords)') + subp_servers = subps.add_parser('servers', + help='List available servers (by keywords)') subp_list = subps.add_parser('list', help='List all folders') subp_arc = subps.add_parser('archive', help='Archive folder[s]') subp_arc.add_argument('-d', type=int, default=14, dest='days', @@ -302,7 +300,8 @@ if __name__ == '__main__': subp_arc.add_argument('-s', '--server', help='Symbolic name of the server to be used') subp_arc.add_argument('folder', help='Folder which should be archived') - subp_arc.add_argument('archive', help='Root folder to store annual archives to') + subp_arc.add_argument('archive', + help='Root folder to store annual archives to') argp.add_argument('-v', action='count', dest='verbosity', default=0, help='Verbosity of the operation (-vv shows IMAP chatter)') diff --git a/purgeObsolete.py b/purgeObsolete.py index 4491eec..48173ec 100755 --- a/purgeObsolete.py +++ b/purgeObsolete.py @@ -19,10 +19,10 @@ debug=False class SimpleDate(GregorianCalendar): def __init__(self): pass - + def getDate(): return self.getTime() - + def decrease(self,howMuch,unit="m"): pass @@ -42,7 +42,7 @@ class ArchivedFolder(object): def __init__(self,store,name): self.folder = store.store.getDefaultFolder().getFolder(name) self.folder.open(Folder.READ_WRITE) - + def purgeOld(self,dateLimit): toBeDeleted = [] for msg in self.folder.getMessages(): @@ -59,7 +59,7 @@ class ArchivedStore(object): >>> len(folderList)>0 1 >>> myStore.store.close() - + and >>> myStore = ArchivedStore(paramServer="zimbra") >>> folder = ArchivedFolder(myStore,"INBOX/bugzilla/xgl") @@ -81,7 +81,7 @@ class ArchivedStore(object): print >> sys.stderr, "Cannot get Store" raise - conffile = os.path.expanduser("~/.bugzillarc") + conffile = os.path.expanduser("~/.bugzillarc") if paramServer: config = ConfigParser.ConfigParser() config.read([conffile]) @@ -109,7 +109,7 @@ class ArchivedStore(object): (host,user,password) self.__login(host,user,password) - + def __login(self,server,user,password): try: self.store.connect(server,user,password) @@ -138,12 +138,12 @@ def main(): myStore = ArchivedStore(paramServer="zimbra") folder = ArchivedFolder(myStore,"INBOX/bugzilla/xgl") - + unreadTerm = FlagTerm(Flags(Flags.Flag.SEEN),True) dateTerm = ReceivedDateTerm(ComparisonTerm.LT,JD3MAgo) searchTerm = AndTerm(unreadTerm,dateTerm) msgsFound = folder.folder.search(searchTerm) - + print len(msgsFound) myStore.store.close() |