]>
Commit | Line | Data |
---|---|---|
0a6875dc MT |
1 | #!/usr/bin/python |
2 | ||
3 | from . import misc | |
4 | ||
5 | class Blog(misc.Object): | |
6 | def _get_post(self, query, *args): | |
7 | res = self.db.get(query, *args) | |
8 | ||
9 | if res: | |
10 | return Post(self.backend, res.id, data=res) | |
11 | ||
12 | def _get_posts(self, query, *args): | |
13 | res = self.db.query(query, *args) | |
14 | ||
15 | for row in res: | |
16 | yield Post(self.backend, row.id, data=row) | |
17 | ||
18 | def get_by_slug(self, slug): | |
19 | return self._get_post("SELECT * FROM blog \ | |
20 | WHERE slug = %s AND published_at <= NOW()", slug) | |
21 | ||
22 | def get_newest(self, limit=None): | |
23 | return self._get_posts("SELECT * FROM blog \ | |
24 | WHERE published_at IS NOT NULL \ | |
25 | AND published_at <= NOW() \ | |
26 | ORDER BY published_at DESC LIMIT %s", limit) | |
27 | ||
28 | def get_by_tag(self, tag, limit=None): | |
29 | return self._get_posts("SELECT * FROM blog \ | |
30 | WHERE published_at IS NOT NULL \ | |
31 | AND published_at <= NOW() \ | |
32 | AND %s = ANY(tags) \ | |
4bde7f18 | 33 | ORDER BY published_at DESC LIMIT %s", tag, limit) |
0a6875dc MT |
34 | |
35 | def get_by_author(self, uid, limit=None): | |
36 | return self._get_posts("SELECT * FROM blog \ | |
37 | WHERE author_uid = %s \ | |
38 | AND published_at IS NOT NULL \ | |
39 | AND published_at <= NOW() \ | |
40 | ORDER BY published_at DESC LIMIT %s", uid, limit) | |
41 | ||
42 | def search(self, query, limit=None): | |
43 | return self._get_posts("SELECT blog.* FROM blog \ | |
44 | LEFT JOIN blog_search_index search_index ON blog.id = search_index.post_id \ | |
45 | WHERE search_index.document @@ to_tsquery('english', %s) \ | |
46 | ORDER BY ts_rank(search_index.document, to_tsquery('english', %s)) DESC \ | |
47 | LIMIT %s", query, query, limit) | |
48 | ||
49 | def refresh(self): | |
50 | """ | |
51 | Needs to be called after a post has been changed | |
52 | and updates the search index. | |
53 | """ | |
54 | self.db.execute("REFRESH MATERIALIZED VIEW blog_search_index") | |
55 | ||
56 | ||
57 | class Post(misc.Object): | |
58 | def init(self, id, data=None): | |
59 | self.id = id | |
60 | self.data = data | |
61 | ||
62 | @property | |
63 | def title(self): | |
64 | return self.data.title | |
65 | ||
66 | @property | |
67 | def slug(self): | |
68 | return self.data.slug | |
69 | ||
70 | # XXX needs caching | |
71 | @property | |
72 | def author(self): | |
73 | if self.data.author_uid: | |
74 | return self.backend.accounts.get_by_uid(self.data.author_uid) | |
75 | ||
76 | @property | |
77 | def created_at(self): | |
78 | return self.data.created_at | |
79 | ||
80 | @property | |
81 | def published_at(self): | |
82 | return self.data.published_at | |
83 | ||
84 | @property | |
85 | def html(self): | |
86 | """ | |
87 | Returns this post as rendered HTML | |
88 | """ | |
89 | return self.data.html | |
8ebc98d4 MT |
90 | |
91 | @property | |
92 | def tags(self): | |
93 | return self.data.tags | |
1e76fec4 MT |
94 | |
95 | @property | |
96 | def link(self): | |
97 | return self.data.link |