X-Git-Url: http://git.veekun.com/zzz-spline-frontpage.git/blobdiff_plain/4371e472c2c75a12b5e1e499a9df6e62d778c030..9be4bb2b3da075385c748f33488d316ebcbdd9ff:/splinext/frontpage/controllers/frontpage.py diff --git a/splinext/frontpage/controllers/frontpage.py b/splinext/frontpage/controllers/frontpage.py index 478c367..04386fd 100644 --- a/splinext/frontpage/controllers/frontpage.py +++ b/splinext/frontpage/controllers/frontpage.py @@ -1,4 +1,5 @@ from collections import defaultdict +import datetime import logging import re @@ -26,8 +27,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,9 +46,6 @@ 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. """ @@ -60,29 +63,58 @@ class FrontPageController(BaseController): # This is the type declaration; use a special key subkey = '__type__' + if subkey in ('limit', 'max_age'): + val = int(val) update_config[source_name][subkey] = val - - global_config = dict( - limit = 10, - ) + global_limit = int(config.get('spline-frontpage.limit', 10)) + now = datetime.datetime.now() + try: + global_max_age = now - datetime.timedelta( + seconds=int(config['spline-frontpage.max_age'])) + except KeyError: + global_max_age = None # 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']] + hook_name = 'frontpage_updates_' + source_config['__type__'] + + # Merge with the global config + merged_config = source_config.copy() + del merged_config['__type__'] + + merged_config['limit'] = min( + merged_config.get('limit', global_limit), + global_limit, + ) + + try: + local_max_age = now - datetime.timedelta( + seconds=merged_config['max_age']) + except KeyError: + local_max_age = None + + if global_max_age and local_max_age: + merged_config['max_age'] = max(global_max_age, local_max_age) + else: + merged_config['max_age'] = global_max_age or local_max_age + + # XXX bleh + updates_lol = run_hooks(hook_name, **merged_config) + source_obj = updates_lol[0] + updates += source_obj.poll(merged_config['limit'], merged_config['max_age']) + + # Little optimization: maximum age effectively becomes the age of + # the oldest thing that would still appear on the page, as anything + # older would drop off the end no matter what. + # So sort by descending time and crop each iteration... + updates.sort(key=lambda obj: obj.time, reverse=True) + updates = updates[:global_limit] + + if updates and len(updates) == global_limit: + global_max_age = updates[-1].time + + c.updates = updates return render('/index.mako')