Support cached sources.
[zzz-spline-frontpage.git] / splinext / frontpage / controllers / frontpage.py
1 import logging
2
3 from pylons import config, request, response, session, tmpl_context as c, url
4 from pylons.controllers.util import abort, redirect_to
5 from routes import request_config
6 from sqlalchemy.orm.exc import NoResultFound
7
8 from spline.lib import helpers as h
9 from spline.lib.base import BaseController, render
10 from splinext.frontpage.sources import max_age_to_datetime
11
12 log = logging.getLogger(__name__)
13
14 class FrontPageController(BaseController):
15
16 def index(self):
17 """Magicaltastic front page.
18
19 Plugins can register a hook called 'frontpage_updates_<type>' to add
20 updates to the front page. `<type>` is an arbitrary string indicating
21 the sort of update the plugin knows how to handle; for example,
22 spline-forum has a `frontpage_updates_forum` hook for posting news from
23 a specific forum.
24
25 Hook handlers should return a list of FrontPageUpdate objects.
26
27 Standard hook parameters are:
28 `limit`, the maximum number of items that should ever be returned.
29 `max_age`, the number of seconds after which items expire.
30 `title`, a name for the source.
31 `icon`, an icon to show next to its name.
32
33 `limit` and `max_age` are also global options.
34
35 Updates are configured in the .ini like so:
36
37 spline-frontpage.sources.foo = updatetype
38 spline-frontpage.sources.foo.opt1 = val1
39 spline-frontpage.sources.foo.opt2 = val2
40
41 Note that the 'foo' name is completely arbitrary and is only used for
42 grouping options together. This will result in a call to:
43
44 run_hooks('frontpage_updates_updatetype', opt1=val1, opt2=val2)
45
46 Local plugins can override the fairly simple index.mako template to
47 customize the front page layout.
48 """
49
50 updates = []
51 global_limit = config['spline-frontpage.limit']
52 global_max_age = max_age_to_datetime(
53 config['spline-frontpage.max_age'])
54
55 for source in config['spline-frontpage.sources']:
56 new_updates = source.poll(global_limit, global_max_age)
57 updates.extend(new_updates)
58
59 # Little optimization: once there are global_limit items, anything
60 # older than the oldest cannot possibly make it onto the list. So,
61 # bump global_max_age to that oldest time if this is ever the case.
62 updates.sort(key=lambda obj: obj.time, reverse=True)
63 del updates[global_limit:]
64
65 if updates and len(updates) == global_limit:
66 global_max_age = updates[-1].time
67
68 # Done! Feed to template
69 c.updates = updates
70
71 return render('/index.mako')