1# SPDX-License-Identifier: ISC 2# Copyright (c) Justus Winter <4winter@informatik.uni-hamburg.de> 3 4import glob 5import sys 6import logging 7import argparse 8 9from afew.Database import Database 10from afew.main import main as inner_main 11from afew.FilterRegistry import all_filters 12from afew.Settings import user_config_dir, get_filter_chain, \ 13 get_mail_move_rules, get_mail_move_age, get_mail_move_rename 14from afew.NotmuchSettings import read_notmuch_settings, get_notmuch_new_query 15from afew.version import version 16 17parser = argparse.ArgumentParser() 18parser.add_argument('-V', '--version', action='version', version=version) 19 20# the actions 21action_group = parser.add_argument_group( 22 'Actions', 23 'Please specify exactly one action.' 24) 25action_group.add_argument( 26 '-t', '--tag', action='store_true', 27 help='run the tag filters' 28) 29action_group.add_argument( 30 '-w', '--watch', action='store_true', 31 help='continuously monitor the mailbox for new files' 32) 33action_group.add_argument( 34 '-m', '--move-mails', action='store_true', 35 help='move mail files between maildir folders' 36) 37 38# query modifiers 39query_modifier_group = parser.add_argument_group( 40 'Query modifiers', 41 'Please specify either --all or --new or a query string.' 42) 43query_modifier_group.add_argument( 44 '-a', '--all', action='store_true', 45 help='operate on all messages' 46) 47query_modifier_group.add_argument( 48 '-n', '--new', action='store_true', 49 help='operate on all new messages' 50) 51query_modifier_group.add_argument( 52 'query', nargs='*', help='a notmuch query to find messages to work on' 53) 54 55# general options 56options_group = parser.add_argument_group('General options') 57# TODO: get config via notmuch api 58options_group.add_argument( 59 '-C', '--notmuch-config', default=None, 60 help='path to the notmuch configuration file [default: $NOTMUCH_CONFIG or' 61 ' ~/.notmuch-config]' 62) 63options_group.add_argument( 64 '-e', '--enable-filters', 65 help="filter classes to use, separated by ',' [default: filters specified" 66 " in afew's config]" 67) 68options_group.add_argument( 69 '-d', '--dry-run', default=False, action='store_true', 70 help="don't change the db [default: %(default)s]" 71) 72options_group.add_argument( 73 '-R', '--reference-set-size', type=int, default=1000, 74 help='size of the reference set [default: %(default)s]' 75) 76 77options_group.add_argument( 78 '-T', '--reference-set-timeframe', type=int, default=30, metavar='DAYS', 79 help='do not use mails older than DAYS days [default: %(default)s]' 80) 81 82options_group.add_argument( 83 '-v', '--verbose', dest='verbosity', action='count', default=0, 84 help='be more verbose, can be given multiple times' 85) 86 87options_group.add_argument( 88 '-N', '--notmuch-args', default='', 89 help='arguments for notmuch new (in move mode)' 90) 91 92 93def main(): 94 if sys.version_info < (3, 6): 95 sys.exit("Python 3.6 or later is required.") 96 97 args = parser.parse_args() 98 99 no_actions = len(list(filter(None, ( 100 args.tag, 101 args.watch, 102 args.move_mails 103 )))) 104 if no_actions == 0: 105 sys.exit('You need to specify an action') 106 elif no_actions > 1: 107 sys.exit('Please specify exactly one action') 108 109 no_query_modifiers = len(list(filter(None, (args.all, 110 args.new, args.query)))) 111 if no_query_modifiers == 0 and not args.watch \ 112 and not args.move_mails: 113 sys.exit('You need to specify one of --new, --all or a query string') 114 elif no_query_modifiers > 1: 115 sys.exit('Please specify either --all, --new or a query string') 116 117 read_notmuch_settings(args.notmuch_config) 118 119 if args.new: 120 query_string = get_notmuch_new_query() 121 elif args.all: 122 query_string = '' 123 else: 124 query_string = ' '.join(args.query) 125 126 loglevel = { 127 0: logging.WARNING, 128 1: logging.INFO, 129 2: logging.DEBUG, 130 }[min(2, args.verbosity)] 131 logging.basicConfig(level=loglevel) 132 133 sys.path.insert(0, user_config_dir) 134 for file_name in glob.glob1(user_config_dir, '*.py'): 135 logging.info('Importing user filter %r' % (file_name,)) 136 __import__(file_name[:-3], level=0) 137 138 if args.move_mails: 139 args.mail_move_rules = get_mail_move_rules() 140 args.mail_move_age = get_mail_move_age() 141 args.mail_move_rename = get_mail_move_rename() 142 143 with Database() as database: 144 configured_filter_chain = get_filter_chain(database) 145 if args.enable_filters: 146 args.enable_filters = args.enable_filters.split(',') 147 148 all_filters_set = set(all_filters.keys()) 149 enabled_filters_set = set(args.enable_filters) 150 if not all_filters_set.issuperset(enabled_filters_set): 151 sys.exit('Unknown filter(s) selected: %s' % (' '.join( 152 enabled_filters_set.difference(all_filters_set)))) 153 154 args.enable_filters = [all_filters[filter_name](database) 155 for filter_name 156 in args.enable_filters] 157 else: 158 args.enable_filters = configured_filter_chain 159 160 inner_main(args, database, query_string) 161