| 1 | ''' |
| 2 | imap_mark_seen.py - Tool to mark all e-mails as seen |
| 3 | |
| 4 | Copyright (c) 2012 Intra2net AG |
| 5 | Author: Plamen Dimitrov |
| 6 | |
| 7 | This program is free software: you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation, either version 3 of the License, or |
| 10 | (at your option) any later version. |
| 11 | |
| 12 | This program is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | ''' |
| 17 | import logging, re |
| 18 | import argparse, getpass |
| 19 | from mail_iterator import MailIterator |
| 20 | from warnings_handler import WarningsHandler |
| 21 | |
| 22 | # logging settings |
| 23 | LOG_FILENAME = "imap_mark_seen.log" |
| 24 | LOG_FILE_LEVEL = logging.DEBUG |
| 25 | LOG_SHELL_LEVEL = logging.INFO |
| 26 | LOG_UNCLEAN_EXIT_LEVEL = logging.WARNING |
| 27 | |
| 28 | def main(): |
| 29 | """Main function.""" |
| 30 | |
| 31 | # prepare configuration |
| 32 | args = configure_args() |
| 33 | warnings_handler = prepare_logger() |
| 34 | logging.info("Marking messages as seen for user \"%s\" in folder \"%s\"", args.user, args.folder) |
| 35 | psw = getpass.getpass() |
| 36 | |
| 37 | # prepare simple mail iterator and iterate throug mailboxes |
| 38 | session = MailIterator(args.server, args.user, psw, args.skip_shared_folders) |
| 39 | total_messages = 0 |
| 40 | for mailbox in session: |
| 41 | delimiter = re.escape(mailbox[1]) |
| 42 | pattern = '^\"?INBOX' + delimiter + re.escape(args.folder) + "[\"?$|" + delimiter + "]" |
| 43 | if args.folder != "all folders" and re.compile(pattern).match(mailbox[2]) == None: |
| 44 | continue |
| 45 | try: |
| 46 | mail_ids = session.fetch_messages() |
| 47 | except UserWarning as ex: |
| 48 | logging.error(ex) |
| 49 | continue |
| 50 | try: |
| 51 | if len(mail_ids) > 0: |
| 52 | mail_id_range = min(mail_ids, key=int).decode('iso-8859-1') + ':' + max(mail_ids, key=int).decode('iso-8859-1') |
| 53 | session.set_seen_messages(mail_id_range) |
| 54 | total_messages += len(mail_ids) |
| 55 | except UserWarning as ex: |
| 56 | logging.error(ex) |
| 57 | |
| 58 | logging.info("Finished marking up to %s messages as seen", total_messages) |
| 59 | logging.info("Exiting with code %s", warnings_handler.detected_problems) |
| 60 | return int(warnings_handler.detected_problems > 0) |
| 61 | |
| 62 | def configure_args(): |
| 63 | """Configure arguments and return them.""" |
| 64 | |
| 65 | # parse arguments |
| 66 | parser = argparse.ArgumentParser(description="Tool to mark messages as seen.") |
| 67 | parser.add_argument('-u', '--user', dest='user', action='store', |
| 68 | required=True, help='mark all messages as seen for a single user') |
| 69 | parser.add_argument('-f', '--folder', dest='folder', action='store', |
| 70 | default="all folders", help='only mark given folder as seen') |
| 71 | parser.add_argument('-s', '--server', dest='server', action='store', |
| 72 | default="localhost", help='imap server name with default localhost') |
| 73 | parser.add_argument('-r', '--shared', dest='skip_shared_folders', action='store_false', |
| 74 | default=True, help='skip shared folders flag') |
| 75 | args = parser.parse_args() |
| 76 | |
| 77 | return args |
| 78 | |
| 79 | def prepare_logger(): |
| 80 | """Sets up the logging functionality""" |
| 81 | |
| 82 | # reset the log |
| 83 | with open(LOG_FILENAME, 'w'): |
| 84 | pass |
| 85 | |
| 86 | # add basic configuration |
| 87 | logging.basicConfig(filename=LOG_FILENAME, |
| 88 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', |
| 89 | level=LOG_FILE_LEVEL) |
| 90 | |
| 91 | # add a handler for a console output |
| 92 | default_logger = logging.getLogger('') |
| 93 | console = logging.StreamHandler() |
| 94 | console.setLevel(LOG_SHELL_LEVEL) |
| 95 | formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') |
| 96 | console.setFormatter(formatter) |
| 97 | default_logger.addHandler(console) |
| 98 | |
| 99 | # add a handler for warnings counting |
| 100 | warnings_handler = WarningsHandler() |
| 101 | warnings_handler.setLevel(LOG_UNCLEAN_EXIT_LEVEL) |
| 102 | default_logger.addHandler(warnings_handler) |
| 103 | |
| 104 | return warnings_handler |
| 105 | |
| 106 | if __name__ == "__main__": |
| 107 | main() |