def main(): """The main entry point to alot. It parses the command line and prepares for the user interface main loop to run.""" options, command = parser() # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, options.debug_level.upper(), None) logformat = '%(levelname)s:%(module)s:%(message)s' logging.basicConfig(level=numeric_loglevel, filename=options.logfile, filemode='w', format=logformat) # locate alot config files if options.config is None: alotconfig = os.path.join( os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'alot', 'config') if not os.path.exists(alotconfig): alotconfig = None else: alotconfig = options.config try: settings.read_config(alotconfig) settings.read_notmuch_config(options.notmuch_config) except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if options.colour_mode: settings.set('colourmode', options.colour_mode) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = options.mailindex_path or indexpath dbman = DBManager(path=indexpath, ro=options.read_only) # determine what to do if command is None: try: cmdstring = settings.get('initial_command') except CommandParseError as err: sys.exit(err) elif command.subcommand in _SUBCOMMANDS: cmdstring = ' '.join(options.command) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook('exit') if exit_hook is not None: exit_hook()
def main(): """The main entry point to alot. It parses the command line and prepares for the user interface main loop to run.""" options, command = parser() # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, options.debug_level.upper(), None) logformat = '%(levelname)s:%(module)s:%(message)s' logging.basicConfig(level=numeric_loglevel, filename=options.logfile, filemode='w', format=logformat) # locate alot config files if options.config is None: alotconfig = os.path.join( os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'alot', 'config') if os.path.exists(alotconfig): settings.alot_rc_path = alotconfig else: settings.alot_rc_path = options.config settings.notmuch_rc_path = options.notmuch_config try: settings.read_config() settings.read_notmuch_config() except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if options.colour_mode: settings.set('colourmode', options.colour_mode) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = options.mailindex_path or indexpath dbman = DBManager(path=indexpath, ro=options.read_only) # determine what to do if command is None: try: cmdstring = settings.get('initial_command') except CommandParseError as err: sys.exit(err) elif command.subcommand in _SUBCOMMANDS: cmdstring = ' '.join(options.command) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook('exit') if exit_hook is not None: exit_hook()
if os.path.exists(configfilename): alotconfig = configfilename break # use only the first try: settings.read_config(alotconfig) settings.read_notmuch_config(notmuchconfig) except (ConfigError, OSError, IOError), e: sys.exit(e) # store options given by config swiches to the settingsManager: if args['colour-mode']: settings.set('colourmode', args['colour-mode']) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = args['mailindex-path'] or indexpath dbman = DBManager(path=indexpath, ro=args['read-only']) # determine what to do try: if args.subCommand == 'search': query = ' '.join(args.subOptions.args) cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(), query) elif args.subCommand == 'compose': cmdstring = 'compose %s' % args.subOptions.as_argparse_opts() if args.subOptions.rest is not None: cmdstring += ' ' + args.subOptions.rest else: cmdstring = settings.get('initial_command')
def main(): # interpret cml arguments args = Options() try: args.parseOptions() # When given no argument, parses sys.argv[1:] except usage.UsageError as errortext: print "%s" % errortext print "Try --help for usage details." sys.exit(1) # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, args["debug-level"].upper(), None) logfilename = os.path.expanduser(args["logfile"]) logformat = "%(levelname)s:%(module)s:%(message)s" logging.basicConfig(level=numeric_loglevel, filename=logfilename, filemode="w", format=logformat) # locate alot config files configfiles = [os.path.join(os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), "alot", "config")] if args["config"]: expanded_path = os.path.expanduser(args["config"]) if not os.path.exists(expanded_path): msg = 'Config file "%s" does not exist. Goodbye for now.' sys.exit(msg % expanded_path) configfiles.insert(0, expanded_path) # locate notmuch config notmuchpath = os.environ.get("NOTMUCH_CONFIG", "~/.notmuch-config") if args["notmuch-config"]: notmuchpath = args["notmuch-config"] notmuchconfig = os.path.expanduser(notmuchpath) alotconfig = None # read the first alot config file we find for configfilename in configfiles: if os.path.exists(configfilename): alotconfig = configfilename break # use only the first try: settings.read_config(alotconfig) settings.read_notmuch_config(notmuchconfig) except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if args["colour-mode"]: settings.set("colourmode", args["colour-mode"]) # get ourselves a database manager indexpath = settings.get_notmuch_setting("database", "path") indexpath = args["mailindex-path"] or indexpath dbman = DBManager(path=indexpath, ro=args["read-only"]) # determine what to do try: if args.subCommand == "search": query = " ".join(args.subOptions.args) cmdstring = "search %s %s" % (args.subOptions.as_argparse_opts(), query) elif args.subCommand == "compose": cmdstring = "compose %s" % args.subOptions.as_argparse_opts() if args.subOptions.rest is not None: cmdstring += " " + args.subOptions.rest else: cmdstring = settings.get("initial_command") except CommandParseError as e: sys.exit(e) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook("exit") if exit_hook is not None: exit_hook()
def main(): # set up the parser to parse the command line options. parser = argparse.ArgumentParser() parser.add_argument('-v', '--version', action='version', version=alot.__version__) parser.add_argument('-r', '--read-only', action='store_true', help='open db in read only mode') parser.add_argument('-c', '--config', help='config file', type=lambda x: argparse.FileType('r')(x).name) parser.add_argument('-n', '--notmuch-config', default=os.environ.get( 'NOTMUCH_CONFIG', os.path.expanduser('~/.notmuch-config')), type=lambda x: argparse.FileType('r')(x).name, help='notmuch config') parser.add_argument('-C', '--colour-mode', choices=(1, 16, 256), type=int, default=256, help='terminal colour mode [default: %(default)s].') parser.add_argument('-p', '--mailindex-path', #type=directory, help='path to notmuch index') parser.add_argument('-d', '--debug-level', default='info', choices=('debug', 'info', 'warning', 'error'), help='debug log [default: %(default)s]') parser.add_argument('-l', '--logfile', default='/dev/null', type=lambda x: argparse.FileType('w')(x).name, help='logfile [default: %(default)s]') # We will handle the subcommands in a seperate run of argparse as argparse # does not support optional subcommands until now. subcommands = ('search', 'compose', 'bufferlist', 'taglist', 'pyshell') parser.add_argument('command', nargs=argparse.REMAINDER, help='possible subcommands are {}'.format( ', '.join(subcommands))) options = parser.parse_args() if options.command: # We have a command after the initial options so we also parse that. # But we just use the parser that is already defined for the internal # command that will back this subcommand. parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand') for subcommand in subcommands: subparsers.add_parser(subcommand, parents=[COMMANDS['global'][subcommand][1]]) command = parser.parse_args(options.command) else: command = None # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, options.debug_level.upper(), None) logformat = '%(levelname)s:%(module)s:%(message)s' logging.basicConfig(level=numeric_loglevel, filename=options.logfile, filemode='w', format=logformat) # locate alot config files if options.config is None: alotconfig = os.path.join( os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'alot', 'config') if not os.path.exists(alotconfig): alotconfig = None else: alotconfig = options.config try: settings.read_config(alotconfig) settings.read_notmuch_config(options.notmuch_config) except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if options.colour_mode: settings.set('colourmode', options.colour_mode) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = options.mailindex_path or indexpath dbman = DBManager(path=indexpath, ro=options.read_only) # determine what to do if command is None: try: cmdstring = settings.get('initial_command') except CommandParseError as err: sys.exit(err) elif command.subcommand in subcommands: cmdstring = ' '.join(options.command) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook('exit') if exit_hook is not None: exit_hook()
def flush(self): """ write out all queued write-commands in order, each one in a separate :meth:`atomic <notmuch.Database.begin_atomic>` transaction. If this fails the current action is rolled back, stays in the write queue and an exception is raised. You are responsible to retry flushing at a later time if you want to ensure that the cached changes are applied to the database. :exception: :exc:`~errors.DatabaseROError` if db is opened read-only :exception: :exc:`~errors.DatabaseLockedError` if db is locked """ if self.ro: raise DatabaseROError() if self.writequeue: # read notmuch's config regarding imap flag synchronization sync = settings.get_notmuch_setting('maildir', 'synchronize_flags') # go through writequeue entries while self.writequeue: current_item = self.writequeue.popleft() logging.debug('write-out item: %s' % str(current_item)) # watch out for notmuch errors to re-insert current_item # to the queue on errors try: # the first two coordinants are cnmdname and post-callback cmd, afterwards = current_item[:2] logging.debug('cmd created') # aquire a writeable db handler try: mode = Database.MODE.READ_WRITE db = Database(path=self.path, mode=mode) except NotmuchError: raise DatabaseLockedError() logging.debug('got write lock') # make this a transaction db.begin_atomic() logging.debug('got atomic') if cmd == 'add': logging.debug('add') path, tags = current_item[2:] msg, status = db.add_message(path, sync_maildir_flags=sync) logging.debug('added msg') msg.freeze() logging.debug('freeze') for tag in tags: msg.add_tag(tag.encode(DB_ENC), sync_maildir_flags=sync) logging.debug('added tags ') msg.thaw() logging.debug('thaw') elif cmd == 'remove': path = current_item[2] db.remove_message(path) else: # tag/set/untag querystring, tags = current_item[2:] query = db.create_query(querystring) for msg in query.search_messages(): msg.freeze() if cmd == 'tag': for tag in tags: msg.add_tag(tag.encode(DB_ENC), sync_maildir_flags=sync) if cmd == 'set': msg.remove_all_tags() for tag in tags: msg.add_tag(tag.encode(DB_ENC), sync_maildir_flags=sync) elif cmd == 'untag': for tag in tags: msg.remove_tag(tag.encode(DB_ENC), sync_maildir_flags=sync) msg.thaw() logging.debug('ended atomic') # end transaction and reinsert queue item on error if db.end_atomic() != notmuch.STATUS.SUCCESS: raise DatabaseError('end_atomic failed') logging.debug('ended atomic') # close db db.close() logging.debug('closed db') # call post-callback if callable(afterwards): logging.debug(str(afterwards)) afterwards() logging.debug('called callback') # re-insert item to the queue upon Xapian/NotmuchErrors except (XapianError, NotmuchError) as e: logging.exception(e) self.writequeue.appendleft(current_item) raise DatabaseError(unicode(e)) except DatabaseLockedError as e: logging.debug('index temporarily locked') self.writequeue.appendleft(current_item) raise e logging.debug('flush finished')
def main(): # interpret cml arguments args = Options() try: args.parseOptions() # When given no argument, parses sys.argv[1:] except usage.UsageError as errortext: print('%s' % errortext) print('Try --help for usage details.') sys.exit(1) # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, args['debug-level'].upper(), None) logfilename = os.path.expanduser(args['logfile']) logformat = '%(levelname)s:%(module)s:%(message)s' logging.basicConfig(level=numeric_loglevel, filename=logfilename, filemode='w', format=logformat) # locate alot config files configfiles = [ os.path.join(os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'alot', 'config'), ] if args['config']: expanded_path = os.path.expanduser(args['config']) if not os.path.exists(expanded_path): msg = 'Config file "%s" does not exist. Goodbye for now.' sys.exit(msg % expanded_path) configfiles.insert(0, expanded_path) # locate notmuch config notmuchpath = os.environ.get('NOTMUCH_CONFIG', '~/.notmuch-config') if args['notmuch-config']: notmuchpath = args['notmuch-config'] notmuchconfig = os.path.expanduser(notmuchpath) alotconfig = None # read the first alot config file we find for configfilename in configfiles: if os.path.exists(configfilename): alotconfig = configfilename break # use only the first try: settings.read_config(alotconfig) settings.read_notmuch_config(notmuchconfig) except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if args['colour-mode']: settings.set('colourmode', args['colour-mode']) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = args['mailindex-path'] or indexpath dbman = DBManager(path=indexpath, ro=args['read-only']) # determine what to do try: if args.subCommand == 'search': query = ' '.join(args.subOptions.args) cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(), query) elif args.subCommand == 'compose': cmdstring = 'compose %s' % args.subOptions.as_argparse_opts() if args.subOptions.rest is not None: cmdstring += ' ' + args.subOptions.rest else: cmdstring = settings.get('initial_command') except CommandParseError as e: sys.exit(e) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook('exit') if exit_hook is not None: exit_hook()
if os.path.exists(configfilename): alotconfig = configfilename break # use only the first try: settings.read_config(alotconfig) settings.read_notmuch_config(notmuchconfig) except (ConfigError, OSError, IOError), e: sys.exit(e) # store options given by config swiches to the settingsManager: if args['colour-mode']: settings.set('colourmode', args['colour-mode']) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = args['mailindex-path'] or indexpath dbman = DBManager(path=indexpath, ro=args['read-only']) # determine what to do try: if args.subCommand == 'search': query = ' '.join(args.subOptions.args) cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(), query) cmd = commands.commandfactory(cmdstring, 'global') elif args.subCommand == 'compose': cmdstring = 'compose %s' % args.subOptions.as_argparse_opts() cmd = commands.commandfactory(cmdstring, 'global') else: default_commandline = settings.get('initial_command')
def main(): # interpret cml arguments args = Options() try: args.parseOptions() # When given no argument, parses sys.argv[1:] except usage.UsageError as errortext: print('%s' % errortext) print('Try --help for usage details.') sys.exit(1) # logging root_logger = logging.getLogger() for log_handler in root_logger.handlers: root_logger.removeHandler(log_handler) root_logger = None numeric_loglevel = getattr(logging, args['debug-level'].upper(), None) logfilename = os.path.expanduser(args['logfile']) logformat = '%(levelname)s:%(module)s:%(message)s' logging.basicConfig(level=numeric_loglevel, filename=logfilename, filemode='w', format=logformat) # locate alot config files configfiles = [ os.path.join( os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config')), 'alot', 'config'), ] if args['config']: expanded_path = os.path.expanduser(args['config']) if not os.path.exists(expanded_path): msg = 'Config file "%s" does not exist. Goodbye for now.' sys.exit(msg % expanded_path) configfiles.insert(0, expanded_path) # locate notmuch config notmuchpath = os.environ.get('NOTMUCH_CONFIG', '~/.notmuch-config') if args['notmuch-config']: notmuchpath = args['notmuch-config'] notmuchconfig = os.path.expanduser(notmuchpath) alotconfig = None # read the first alot config file we find for configfilename in configfiles: if os.path.exists(configfilename): alotconfig = configfilename break # use only the first try: settings.read_config(alotconfig) settings.read_notmuch_config(notmuchconfig) except (ConfigError, OSError, IOError) as e: sys.exit(e) # store options given by config swiches to the settingsManager: if args['colour-mode']: settings.set('colourmode', args['colour-mode']) # get ourselves a database manager indexpath = settings.get_notmuch_setting('database', 'path') indexpath = args['mailindex-path'] or indexpath dbman = DBManager(path=indexpath, ro=args['read-only']) # determine what to do try: if args.subCommand == 'search': query = ' '.join(args.subOptions.args) cmdstring = 'search %s %s' % (args.subOptions.as_argparse_opts(), query) elif args.subCommand == 'compose': cmdstring = 'compose %s' % args.subOptions.as_argparse_opts() if args.subOptions.rest is not None: cmdstring += ' ' + args.subOptions.rest else: cmdstring = settings.get('initial_command') except CommandParseError as e: sys.exit(e) # set up and start interface UI(dbman, cmdstring) # run the exit hook exit_hook = settings.get_hook('exit') if exit_hook is not None: exit_hook()