X-Git-Url: http://git.veekun.com/zzz-spline-frontpage.git/blobdiff_plain/4371e472c2c75a12b5e1e499a9df6e62d778c030..16a2995a38feb21c3477a474a752efd9005e6b4f:/splinext/frontpage/controllers/frontpage.py diff --git a/splinext/frontpage/controllers/frontpage.py b/splinext/frontpage/controllers/frontpage.py index 478c367..0990e81 100644 --- a/splinext/frontpage/controllers/frontpage.py +++ b/splinext/frontpage/controllers/frontpage.py @@ -1,6 +1,4 @@ -from collections import defaultdict import logging -import re from pylons import config, request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect_to @@ -9,7 +7,7 @@ from sqlalchemy.orm.exc import NoResultFound from spline.lib import helpers as h from spline.lib.base import BaseController, render -from spline.lib.plugin.load import run_hooks +from splinext.frontpage.sources import max_age_to_datetime log = logging.getLogger(__name__) @@ -26,8 +24,13 @@ class FrontPageController(BaseController): Hook handlers should return a list of FrontPageUpdate objects. - Standard hook parameters are `limit`, the maximum number of items that - should ever be returned. + Standard hook parameters are: + `limit`, the maximum number of items that should ever be returned. + `max_age`, the number of seconds after which items expire. + `title`, a name for the source. + `icon`, an icon to show next to its name. + + `limit` and `max_age` are also global options. Updates are configured in the .ini like so: @@ -40,49 +43,30 @@ class FrontPageController(BaseController): run_hooks('frontpage_updates_updatetype', opt1=val1, opt2=val2) - Standard options are not shown and take precedence over whatever's in - the config file. - Local plugins can override the fairly simple index.mako template to customize the front page layout. """ - # XXX no reason to do this on the fly; cache it on server startup - update_config = defaultdict(dict) # source_name => config - key_rx = re.compile( - '(?x) ^ spline-frontpage [.] sources [.] (\w+) (?: [.] (\w+) )? $') - for key, val in config.iteritems(): - 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 - - - global_config = dict( - limit = 10, - ) - # Ask plugins to deal with this stuff for us! updates = [] - for source, source_config in update_config.iteritems(): - source_config2 = source_config.copy() - hook_name = 'frontpage_updates_' + source_config2.pop('__type__') - source_config2.update(global_config) - - # Hooks should return a list of FrontPageUpdate objects, making this - # return value a list of lists - updates_lol = run_hooks(hook_name, **source_config2) - updates += sum(updates_lol, []) - - # Sort everything by descending time, then crop to the right number of - # items - updates.sort(key=lambda obj: obj.time) - updates.reverse() - c.updates = updates[:global_config['limit']] + global_limit = config['spline-frontpage.limit'] + global_max_age = max_age_to_datetime( + config['spline-frontpage.max_age']) + + c.sources = config['spline-frontpage.sources'] + for source in c.sources: + new_updates = source.poll(global_limit, global_max_age) + updates.extend(new_updates) + + # Little optimization: once there are global_limit items, anything + # older than the oldest cannot possibly make it onto the list. So, + # bump global_max_age to that oldest time if this is ever the case. + updates.sort(key=lambda obj: obj.time, reverse=True) + del updates[global_limit:] + + if updates and len(updates) == global_limit: + global_max_age = updates[-1].time + + # Done! Feed to template + c.updates = updates return render('/index.mako')