Added support for max_age.
authorEevee <git@veekun.com>
Sun, 18 Jul 2010 22:59:42 +0000 (15:59 -0700)
committerEevee <git@veekun.com>
Sun, 18 Jul 2010 22:59:42 +0000 (15:59 -0700)
splinext/frontpage/__init__.py
splinext/frontpage/controllers/frontpage.py

index 2154f6e..e4caec2 100644 (file)
@@ -25,7 +25,7 @@ RSS_SUMMARY_LENGTH = 1000
 FrontPageRSS = namedtuple('FrontPageRSS',
     ['time', 'entry', 'template', 'category', 'content', 'icon'])
 
 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)
 
     """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])
 
             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''
         # 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'])
 
 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."""
     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:]):
 
     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):
         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(
         update = FrontPageGit(
-            time = datetime.datetime.fromtimestamp(int(tag_unixtime)),
+            time = tagged_timestamp,
             gitweb = gitweb,
             log = commits,
             template = '/front_page/git.mako',
             gitweb = gitweb,
             log = commits,
             template = '/front_page/git.mako',
index 478c367..5aba8c5 100644 (file)
@@ -1,4 +1,5 @@
 from collections import defaultdict
 from collections import defaultdict
+import datetime
 import logging
 import re
 
 import logging
 import re
 
@@ -26,8 +27,13 @@ class FrontPageController(BaseController):
 
         Hook handlers should return a list of FrontPageUpdate objects.
 
 
         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:
 
 
         Updates are configured in the .ini like so:
 
@@ -40,9 +46,6 @@ class FrontPageController(BaseController):
 
             run_hooks('frontpage_updates_updatetype', opt1=val1, opt2=val2)
 
 
             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.
         """
         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__'
 
                 # 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
 
             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():
 
         # 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, [])
 
             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')
 
         return render('/index.mako')