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