From c702337040ac57c452a764212d9f92aa5766fdb9 Mon Sep 17 00:00:00 2001 From: Will Oursler Date: Fri, 13 Oct 2017 19:37:13 -0400 Subject: [PATCH] Reworks how site-specific options work. --- leech.py | 39 ++++++++++++++++++++++++++------------- sites/__init__.py | 4 ++++ sites/xenforo.py | 9 +++++++++ 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/leech.py b/leech.py index da74ffe..2f89753 100755 --- a/leech.py +++ b/leech.py @@ -41,28 +41,41 @@ def uses_session(command): def uses_story(command): """Decorator for click commands that need a story.""" @click.argument('url') - @click.option('--include-index', default=False, help='[Xenforo only] Should the chapter marked as an index be included?') - @click.option('--offset', type=int, default=None, help='[Xenforo only] The chapter to start from.') - @click.option('--limit', type=int, default=None, help='[Xenforo only] The chapter to end with.') - @click.option('--skip-spoilers/--include-spoilers', default=True, help='[Xenforo only] If the story should include content enclosed in spoiler tags.') + @click.option( + '--site-options', + default='{}', + help='JSON object encoding any site specific option.' + ) @uses_session - def wrapper(url, session, include_index, offset, limit, skip_spoilers, **kwargs): + def wrapper(url, session, site_options, **kwargs): site, url = sites.get(url) if not site: raise Exception("No site handler found") - handler = site(session, options={ - 'offset': offset, - 'limit': limit, - 'skip_spoilers': skip_spoilers, - 'include_index': include_index, - }) + default_site_options = site.get_default_options() with open('leech.json') as store_file: store = json.load(store_file) login = store.get('logins', {}).get(site.__name__, False) - if login: - handler.login(login) + configured_site_options = store.get('site_options', {}).get(site.__name__, {}) + + overridden_site_options = json.loads(site_options) + + # The final options dictionary is computed by layering the default, configured, + # and overridden options together in that order. + options = dict( + list(default_site_options.items()) + + list(configured_site_options.items()) + + list(overridden_site_options.items()) + ) + + handler = site( + session, + options=options + ) + + if login: + handler.login(login) story = handler.extract(url) if not story: diff --git a/sites/__init__.py b/sites/__init__.py index efd82df..a1687be 100644 --- a/sites/__init__.py +++ b/sites/__init__.py @@ -64,6 +64,10 @@ class Site: footnotes = attr.ib(default=attr.Factory(list), init=False) options = attr.ib(default=attr.Factory(dict)) + @staticmethod + def get_default_options(): + return {} + @staticmethod def matches(url): raise NotImplementedError() diff --git a/sites/xenforo.py b/sites/xenforo.py index 974b1a9..3b9382b 100644 --- a/sites/xenforo.py +++ b/sites/xenforo.py @@ -10,6 +10,15 @@ class XenForo(Site): domain = False + @staticmethod + def get_default_options(): + return { + 'offset': None, + 'limit': None, + 'skip_spoilers': True, + 'include_index': False, + } + @classmethod def matches(cls, url): match = re.match(r'^(https?://%s/threads/[^/]*\d+)/?.*' % cls.domain, url)