From 69e763a9763c70b88ccfbbd2ab126212b5754f63 Mon Sep 17 00:00:00 2001 From: Eevee Date: Sun, 18 Jul 2010 15:59:42 -0700 Subject: [PATCH] Added support for max_age. --- splinext/frontpage/__init__.py | 38 +++++++++------ splinext/frontpage/controllers/frontpage.py | 74 +++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/splinext/frontpage/__init__.py b/splinext/frontpage/__init__.py index 2154f6e..e4caec2 100644 --- a/splinext/frontpage/__init__.py +++ b/splinext/frontpage/__init__.py @@ -25,7 +25,7 @@ RSS_SUMMARY_LENGTH = 1000 FrontPageRSS = namedtuple('FrontPageRSS', ['time', 'entry', 'template', 'category', 'content', 'icon']) -def rss_hook(limit, url, title=None, icon=None): +def rss_hook(limit, max_age, url, title=None, icon=None): """Front page handler for news feeds.""" feed = feedparser.parse(url) @@ -42,6 +42,11 @@ def rss_hook(limit, url, title=None, icon=None): timestamp_tuple = entry.updated_parsed timestamp = datetime.datetime(*timestamp_tuple[:6]) + if max_age and timestamp < max_age: + # Entries should be oldest-first, so we can bail after the first + # expired entry + break + # Try to find something to show! Default to the summary, if there is # one, or try to generate one otherwise content = u'' @@ -97,7 +102,7 @@ FrontPageGit = namedtuple('FrontPageGit', FrontPageGitCommit = namedtuple('FrontPageGitCommit', ['hash', 'author', 'time', 'subject', 'repo']) -def git_hook(limit, title, gitweb, repo_paths, repo_names, +def git_hook(limit, max_age, title, gitweb, repo_paths, repo_names, tag_pattern=None, icon=None): """Front page handler for repository history.""" @@ -127,6 +132,22 @@ def git_hook(limit, title, gitweb, repo_paths, repo_names, updates = [] for tag, since_tag in zip(interesting_tags, tags[1:]): + # Get the date when this tag was actually created + args = [ + 'git', + '--git-dir=' + repo_paths[0], + 'for-each-ref', + '--format=%(taggerdate:raw)', + 'refs/tags/' + tag, + ] + tag_timestamp, _ = subprocess.Popen(args, stdout=subprocess.PIPE) \ + .communicate() + tag_unixtime, tag_timezone = tag_timestamp.split(None, 1) + tagged_timestamp = datetime.datetime.fromtimestamp(int(tag_unixtime)) + + if max_age and tagged_timestamp < max_age: + break + commits = [] for repo_path, repo_name in zip(repo_paths, repo_names): @@ -152,19 +173,8 @@ def git_hook(limit, title, gitweb, repo_paths, repo_names, ) ) - # LASTLY, get the date when this tag was actually created - args = [ - 'git', - 'for-each-ref', - '--format=%(taggerdate:raw)', - 'refs/tags/' + tag, - ] - tag_timestamp, _ = subprocess.Popen(args, stdout=subprocess.PIPE) \ - .communicate() - tag_unixtime, tag_timezone = tag_timestamp.split(None, 1) - update = FrontPageGit( - time = datetime.datetime.fromtimestamp(int(tag_unixtime)), + time = tagged_timestamp, gitweb = gitweb, log = commits, template = '/front_page/git.mako', diff --git a/splinext/frontpage/controllers/frontpage.py b/splinext/frontpage/controllers/frontpage.py index 478c367..5aba8c5 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) + 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 + + # Hooks should return a list of FrontPageUpdate-like objects, + # making this return value a list of lists + updates_lol = run_hooks(hook_name, **merged_config) 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']] + # 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: + global_max_age = updates[-1].time + + c.updates = updates return render('/index.mako') -- 2.7.4