1 from collections
import namedtuple
4 from sqlalchemy
.orm
import contains_eager
, joinedload
5 from sqlalchemy
.sql
import func
6 from pylons
import tmpl_context
as c
, url
8 from spline
.model
import meta
10 from splinext
.forum
import model
as forum_model
11 from splinext
.frontpage
.sources
import Source
13 FrontPageThread
= namedtuple('FrontPageThread', ['source', 'time', 'post'])
14 class ForumSource(Source
):
15 """Represents a forum whose threads are put on the front page.
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
24 id of the forum to check for new threads.
27 template
= '/forum/front_page.mako'
29 def __init__(self
, forum_id
, **kwargs
):
30 forum
= meta
.Session
.query(forum_model
.Forum
).get(forum_id
)
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
)
39 self
.forum_id
= forum_id
41 def _poll(self
, limit
, max_age
):
44 controller
='forum', action
='threads', forum_id
=self
.forum_id
)
46 thread_q
= meta
.Session
.query(forum_model
.Thread
) \
47 .filter_by(forum_id
=self
.forum_id
) \
48 .join((forum_model
.Post
, forum_model
.Thread
.first_post
)) \
50 contains_eager(forum_model
.Thread
.first_post
, alias
=forum_model
.Post
),
51 contains_eager(forum_model
.Thread
.first_post
, forum_model
.Post
.thread
, alias
=forum_model
.Thread
),
52 joinedload(forum_model
.Thread
.first_post
, forum_model
.Post
.author
),
56 thread_q
= thread_q
.filter(forum_model
.Post
.posted_time
>= max_age
)
59 .order_by(forum_model
.Post
.posted_time
.desc()) \
63 for thread
in threads
:
64 update
= FrontPageThread(
66 time
= thread
.first_post
.posted_time
,
67 post
= thread
.first_post
,
69 updates
.append(update
)
73 FrontPageActivity
= namedtuple('FrontPageActivity', ['template', 'threads'])
74 def forum_activity(*args
, **kwargs
):
75 """Show recently-active threads on the front page.
77 Note that this isn't the most recent X threads; it's threads that are more
78 recent than X, sorted by their activity since X.
80 # XXX this should be configurable probably
81 cutoff
= datetime
.datetime
.now() - datetime
.timedelta(days
=7)
83 # TODO some sort of dropoff here idk
84 active_threads_subq
= meta
.Session
.query(
85 forum_model
.Post
.thread_id
.label('thread_id'),
86 func
.count('*').label('ranking'),
88 .filter(forum_model
.Post
.posted_time
>= cutoff
) \
89 .group_by(forum_model
.Post
.thread_id
) \
92 threads_q
= meta
.Session
.query(forum_model
.Thread
) \
93 .join((active_threads_subq
,
94 active_threads_subq
.c
.thread_id
== forum_model
.Thread
.id)) \
95 .order_by(active_threads_subq
.c
.ranking
.desc()) \
98 return FrontPageActivity(
99 template
='/forum/front_page_activity.mako',
100 threads
=threads_q
.all(),