Paging for threads and posts! #314
[zzz-spline-forum.git] / splinext / forum / frontpage_sources.py
1 from collections import namedtuple
2
3 from pylons import url
4
5 from spline.model import meta
6
7 from splinext.forum import model as forum_model
8 from splinext.frontpage.sources import Source
9
10 def frontpage_hook(limit, max_age, forum_id):
11 """Hook to return recent news for the front page."""
12
13 FrontPageThread = namedtuple('FrontPageThread', ['source', 'time', 'post'])
14 class ForumSource(Source):
15 """Represents a forum whose threads are put on the front page.
16
17 ``link``, ``title``, and ``icon`` are all optional; the link and title
18 default to the forum's thread list and name, and the icon defaults to a
19 newspaper.
20
21 Extra properties:
22
23 ``forum_id``
24 id of the forum to check for new threads.
25 """
26
27 template = '/forum/front_page.mako'
28
29 def __init__(self, forum_id, **kwargs):
30 forum = meta.Session.query(forum_model.Forum).get(forum_id)
31
32 # Link is tricky. Needs url(), which doesn't exist when this class is
33 # loaded. Lazy-load it in poll() below, instead
34 kwargs.setdefault('link', None)
35 kwargs.setdefault('title', forum.name)
36 kwargs.setdefault('icon', 'newspapers')
37 super(ForumSource, self).__init__(**kwargs)
38
39 self.forum_id = forum_id
40
41 def _poll(self, limit, max_age):
42 if not self.link:
43 self.link = url(
44 controller='forum', action='threads', forum_id=self.forum_id)
45
46 thread_q = meta.Session.query(forum_model.Thread) \
47 .filter_by(forum_id=self.forum_id) \
48 .join(forum_model.Thread.first_post)
49
50 if max_age:
51 thread_q = thread_q.filter(forum_model.Post.posted_time >= max_age)
52
53 threads = thread_q \
54 .order_by(forum_model.Post.posted_time.desc()) \
55 [:limit]
56
57 updates = []
58 for thread in threads:
59 update = FrontPageThread(
60 source = self,
61 time = thread.first_post.posted_time,
62 post = thread.first_post,
63 )
64 updates.append(update)
65
66 return updates