Mercurial > silorider
view silorider/main.py @ 65:412ff72ba091
Add utility command to forget parts of the cache.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 26 Dec 2023 16:26:35 -0800 |
parents | d76063c61c6d |
children |
line wrap: on
line source
import os import os.path import logging import argparse import configparser import coloredlogs logger = logging.getLogger(__name__) class ExecutionContext: def __init__(self, args, config, cache, silos): self.args = args self.config = config self.cache = cache self.silos = silos def _setup_auth(parser): def _run(ctx): from .commands.auth import auth_silo auth_silo(ctx) parser.add_argument( 'silo', action='append', help=("The name of the silo to authenticate. " "Use 'all' to authenticate all declared silos.")) parser.add_argument( '-f', '--force', action='store_true', help="Force re-authenticate even silos with valid access.") parser.add_argument( '--console', action='store_true', help=("Use the current terminal to enter credentials. This is " "useful if you're not in an environment where silorider can " "launch a browser.")) parser.set_defaults(func=_run) def _setup_process(parser): def _run(ctx): from .commands.process import process_urls process_urls(ctx) parser.add_argument( '-u', '--url', action='append', help="Only parse the given URL name(s).") parser.add_argument( '-s', '--silo', action='append', help="Only use the given silo(s).") parser.add_argument( '--no-cache', action='store_true', help="Ignore the cache, post all entries that qualify.") parser.add_argument( '--since', help="Post entries since the specified date/time only.") parser.add_argument( '--until', help="Post entries until the specified date/time only.") parser.add_argument( '--dry-run', action='store_true', help="Only report what would be posted, but don't post anything.") parser.set_defaults(func=_run) def _setup_populate(parser): def _run(ctx): from .commands.utils import populate_cache populate_cache(ctx) parser.add_argument( '-u', '--url', action='append', help="Only populate from the given URL name(s).") parser.add_argument( '-s', '--silo', action='append', help="Only populate the given silo(s).") parser.add_argument( '--until', help="The date until which to populate the cache (excluded).") parser.add_argument( '--dry-run', action='store_true', help="Only report what would be populated, but don't populate anything.") parser.set_defaults(func=_run) def _setup_forget(parser): def _run(ctx): from .commands.utils import forget_cache forget_cache(ctx) parser.add_argument( '-s', '--silo', action='append', help="Only froget entries from the given silo(s).") parser.add_argument( '--since', help="The date after which to forget entries from the cache (excluded).") parser.add_argument( '--until', help="The date until which to forget entries from the cache (excluded).") parser.add_argument( '--dry-run', action='store_true', help="Only report what would be forgotten, but don't forget anything.") parser.set_defaults(func=_run) commands = { 'auth': { 'help': "Authenticate with a silo service.", 'setup': _setup_auth, }, 'process': { 'help': "Post a website's latest articles to silo services.", 'setup': _setup_process, }, 'populate': { 'help': "Populates the cache with the latest entries from a feed.", 'setup': _setup_populate, }, 'forget': { 'help': "Forget entries from the cache, so they can be reposted.", 'setup': _setup_forget, } } has_debug_logging = False pre_exec_hook = None post_exec_hook = None def _unsafe_main(args=None): parser = argparse.ArgumentParser('SiloRider') parser.add_argument( '-v', '--verbose', action='store_true', help="Print debug messages.") parser.add_argument( '--no-color', action='store_true', help="Don't use pretty colors.") parser.add_argument( '-c', '--config', help="Configuration file to load.") subparsers = parser.add_subparsers() for cn, cd in commands.items(): cp = subparsers.add_parser(cn, help=cd.get('help')) cd['setup'](cp) args = parser.parse_args(args) global has_debug_logging has_debug_logging = args.verbose if not args.no_color: coloredlogs.install() loglvl = logging.DEBUG if args.verbose else logging.INFO root_logger = logging.getLogger() root_logger.setLevel(loglvl) for handler in root_logger.handlers: handler.setLevel(loglvl) if args.verbose: # Specifically don't enable debug logging for requests' OAuth # lib because it prints out large chunks of binary payloads. req_logger = logging.getLogger('requests_oauthlib') req_logger.setLevel(logging.INFO) for handler in req_logger.handlers: handler.setLevel(logging.INFO) if not getattr(args, 'func', None): parser.print_help() return logger.debug("Loading configuration.") xdg_config_home = os.getenv('XDG_CONFIG_HOME', os.path.expanduser('~/.config')) config = configparser.ConfigParser(interpolation=None) config_paths = [ os.path.join(os.path.dirname(__file__), 'default.cfg'), os.path.join(xdg_config_home, 'silorider/silorider.cfg') ] if args.config: config_paths.append(args.config) config.read(config_paths) from .silos.base import has_any_silo if not has_any_silo(config): logger.warning("No silos defined in the configuration file. " "Nothing to do!") return if not config.has_section('urls') or not config.items('urls'): logger.warning("No URLs defined in the configuration file. " "Nothing to do!") return logger.debug("Initializing cache.") from .cache.base import load_cache cfg_dir = os.path.dirname(args.config) if args.config else None cache = load_cache(config, cfg_dir) logger.debug("Initializing silo riders.") from .silos.base import load_silos silos = load_silos(config, cache) ctx = ExecutionContext(args, config, cache, silos) if pre_exec_hook: pre_exec_hook(ctx) res = args.func(ctx) if post_exec_hook: post_exec_hook(ctx, res) if isinstance(res, int): return res return 0 def main(): try: res = _unsafe_main() except Exception as ex: if has_debug_logging: raise logger.error(ex) res = 1 import sys sys.exit(res) if __name__ == '__main__': main()