X-Git-Url: http://git.veekun.com/zzz-spline-frontpage.git/blobdiff_plain/475ce71bfb57fba45376c568d603007a5e52f54a..f3fc85523d8288c4eb352bf9836660fe4a67781b:/splinext/frontpage/__init__.py diff --git a/splinext/frontpage/__init__.py b/splinext/frontpage/__init__.py index ceb606c..9661906 100644 --- a/splinext/frontpage/__init__.py +++ b/splinext/frontpage/__init__.py @@ -1,14 +1,77 @@ +from collections import defaultdict, namedtuple from pkg_resources import resource_filename +import re +import subprocess -from spline.lib.plugin import PluginBase +from pylons import config + +from spline.lib import helpers from spline.lib.plugin import PluginBase, PluginLink, Priority +from spline.lib.plugin.load import run_hooks import splinext.frontpage.controllers.frontpage +from splinext.frontpage.sources import FeedSource, GitSource def add_routes_hook(map, *args, **kwargs): """Hook to inject some of our behavior into the routes configuration.""" map.connect('/', controller='frontpage', action='index') +def load_sources_hook(*args, **kwargs): + """Hook to load all the known sources and stuff them in config. Run once, + on server startup. + """ + # Extract source definitions from config and store as source_name => config + update_config = defaultdict(dict) + key_rx = re.compile( + '(?x) ^ spline-frontpage [.] sources [.] (\w+) (?: [.] (\w+) )? $') + for key, val in config.iteritems(): + # Match against spline-frontpage.source.(source).(key) + match = key_rx.match(key) + if not match: + continue + + source_name, subkey = match.groups() + if not subkey: + # This is the type declaration; use a special key + subkey = '__type__' + + update_config[source_name][subkey] = val + + # Figure out the global limit and expiration time, with reasonable + # defaults. Make sure they're integers. + global_limit = int(config.get('spline-frontpage.limit', 10)) + # max_age is optional and can be None + try: + global_max_age = int(config['spline-frontpage.max_age']) + except KeyError: + global_max_age = None + + config['spline-frontpage.limit'] = global_limit + config['spline-frontpage.max_age'] = global_max_age + + # Ask plugins to turn configuration into source objects + sources = [] + for source, source_config in update_config.iteritems(): + hook_name = 'frontpage_updates_' + source_config['__type__'] + del source_config['__type__'] # don't feed this to constructor! + + # Default to global limit and max age. Source takes care of making + # integers and whatnot + source_config.setdefault('limit', global_limit) + source_config.setdefault('max_age', global_max_age) + + # Hooks return a list of sources; combine with running list + sources += run_hooks(hook_name, **source_config) + + # Save the list of sources, and done + config['spline-frontpage.sources'] = sources + +def source_cron_hook(*args, **kwargs): + """Hook to pass on cron tics to all sources, should they need it for e.g. + caching. + """ + for source in config['spline-frontpage.sources']: + source.do_cron(*args, **kwargs) class FrontPagePlugin(PluginBase): def controllers(self): @@ -23,5 +86,9 @@ class FrontPagePlugin(PluginBase): def hooks(self): return [ - ('routes_mapping', Priority.NORMAL, add_routes_hook), + ('routes_mapping', Priority.NORMAL, add_routes_hook), + ('after_setup', Priority.NORMAL, load_sources_hook), + ('cron', Priority.NORMAL, source_cron_hook), + ('frontpage_updates_rss', Priority.NORMAL, FeedSource), + ('frontpage_updates_git', Priority.NORMAL, GitSource), ]