]>
Commit | Line | Data |
---|---|---|
12e5de7e MT |
1 | #!/usr/bin/python |
2 | ||
f0714277 | 3 | import email.utils |
12e5de7e MT |
4 | import tornado.web |
5 | ||
6 | import handlers_base as base | |
7 | ||
f91dfcc7 MT |
8 | from . import ui_modules |
9 | ||
8a897d25 MT |
10 | class IndexHandler(base.BaseHandler): |
11 | def get(self): | |
0a6875dc | 12 | posts = self.backend.blog.get_newest(limit=3) |
8a897d25 MT |
13 | |
14 | self.render("blog/index.html", posts=posts) | |
15 | ||
16 | ||
cfc0823a MT |
17 | class AuthorHandler(base.BaseHandler): |
18 | def get(self, uid): | |
19 | author = self.accounts.get_by_uid(uid) | |
20 | if not author: | |
21 | raise tornado.web.HTTPError(404, "User is unknown") | |
22 | ||
23 | # Get all posts from this author | |
cdf85ee7 | 24 | posts = self.backend.blog.get_by_author(author) |
cfc0823a MT |
25 | if not posts: |
26 | raise tornado.web.HTTPError(404, "User has no posts") | |
27 | ||
28 | self.render("blog/author.html", author=author, posts=posts) | |
29 | ||
30 | ||
f0714277 MT |
31 | class FeedHandler(base.BaseHandler): |
32 | def get(self): | |
33 | cache_key = "%s-%s" % (self.request.host, self.request.path) | |
34 | ||
35 | # Get feed from cache if possible | |
36 | feed = self.memcached.get(cache_key) | |
37 | if not feed: | |
0a6875dc | 38 | posts = self.backend.blog.get_newest(limit=50) |
f0714277 MT |
39 | |
40 | # Render the feed | |
41 | feed = self.render_string("blog/feed.xml", posts=posts, | |
42 | now=email.utils.formatdate()) | |
43 | ||
44 | # Store in cache for 5min | |
45 | self.memcached.set(cache_key, feed, 300) | |
46 | ||
47 | # Set correct content type | |
48 | self.set_header("Content-Type", "application/rss+xml") | |
49 | ||
50 | # Deliver content | |
51 | self.finish(feed) | |
52 | ||
53 | ||
12e5de7e MT |
54 | class PostHandler(base.BaseHandler): |
55 | def get(self, slug): | |
df157ede | 56 | post = self.backend.blog.get_by_slug(slug, published=not self.current_user) |
0a6875dc | 57 | if not post: |
12e5de7e MT |
58 | raise tornado.web.HTTPError(404) |
59 | ||
0a6875dc | 60 | self.render("blog/post.html", post=post) |
f91dfcc7 MT |
61 | |
62 | ||
0b342a05 MT |
63 | class DraftsHandler(base.BaseHandler): |
64 | @tornado.web.authenticated | |
65 | def get(self): | |
66 | drafts = self.backend.blog.get_drafts(author=self.current_user) | |
67 | ||
68 | self.render("blog/drafts.html", drafts=drafts) | |
69 | ||
70 | ||
e6b18dce MT |
71 | class SearchHandler(base.BaseHandler): |
72 | def get(self): | |
73 | q = self.get_argument("q") | |
74 | ||
0a6875dc | 75 | posts = self.backend.blog.search(q, limit=50) |
e6b18dce MT |
76 | if not posts: |
77 | raise tornado.web.HTTPError(404, "Nothing found") | |
78 | ||
79 | self.render("blog/search-results.html", q=q, posts=posts) | |
80 | ||
81 | ||
4bde7f18 MT |
82 | class TagHandler(base.BaseHandler): |
83 | def get(self, tag): | |
84 | posts = self.backend.blog.get_by_tag(tag) | |
85 | if not posts: | |
86 | raise tornado.web.HTTPError(404, "There are no posts with tag: %s" % tag) | |
87 | ||
88 | self.render("blog/tag.html", posts=posts, tag=tag) | |
89 | ||
90 | ||
7e64f6a3 MT |
91 | class YearHandler(base.BaseHandler): |
92 | def get(self, year): | |
93 | posts = self.backend.blog.get_by_year(year) | |
94 | if not posts: | |
95 | raise tornado.web.HTTPError(404, "There are no posts in %s" % year) | |
96 | ||
97 | self.render("blog/year.html", posts=posts, year=year) | |
98 | ||
99 | ||
541c952b MT |
100 | class ComposeHandler(base.BaseHandler): |
101 | @tornado.web.authenticated | |
102 | def get(self): | |
103 | self.render("blog/compose.html", post=None) | |
104 | ||
105 | @tornado.web.authenticated | |
106 | def post(self): | |
107 | title = self.get_argument("title") | |
108 | text = self.get_argument("text") | |
109 | tags = self.get_argument("tags", None) | |
110 | ||
111 | with self.db.transaction(): | |
112 | post = self.backend.blog.create_post(title, text, | |
113 | author=self.current_user, tags=tags) | |
114 | ||
61e0a831 | 115 | self.redirect("/drafts") |
541c952b MT |
116 | |
117 | ||
118 | class EditHandler(base.BaseHandler): | |
119 | @tornado.web.authenticated | |
120 | def get(self, slug): | |
00bf122b | 121 | post = self.backend.blog.get_by_slug(slug, published=False) |
541c952b MT |
122 | if not post: |
123 | raise tornado.web.HTTPError(404) | |
124 | ||
e8a81a70 MT |
125 | # Check if post is editable |
126 | if not post.is_editable(self.current_user): | |
127 | raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post)) | |
541c952b MT |
128 | |
129 | self.render("blog/compose.html", post=post) | |
130 | ||
131 | @tornado.web.authenticated | |
132 | def post(self, slug): | |
00bf122b | 133 | post = self.backend.blog.get_by_slug(slug, published=False) |
541c952b MT |
134 | if not post: |
135 | raise tornado.web.HTTPError(404) | |
136 | ||
e8a81a70 MT |
137 | # Check if post is editable |
138 | if not post.is_editable(self.current_user): | |
139 | raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post)) | |
541c952b MT |
140 | |
141 | with self.db.transaction(): | |
142 | # Update title | |
143 | post.title = self.get_argument("title") | |
144 | ||
145 | # Update text | |
146 | post.text = self.get_argument("text") | |
147 | ||
148 | # Update tags | |
149 | post.tags = (t.strip() for t in self.get_argument("tags", "").split(",")) | |
150 | ||
151 | # Mark post as updated | |
152 | post.updated() | |
153 | ||
154 | # Return to blog if the post is already published | |
155 | if post.is_published(): | |
156 | self.redirect("/post/%s" % post.slug) | |
157 | return | |
158 | ||
61e0a831 MT |
159 | # Otherwise return to drafts |
160 | self.redirect("/drafts") | |
541c952b MT |
161 | |
162 | ||
7e64f6a3 MT |
163 | class HistoryNavigationModule(ui_modules.UIModule): |
164 | def render(self): | |
165 | return self.render_string("blog/modules/history-navigation.html", | |
166 | years=self.backend.blog.years) | |
167 | ||
168 | ||
169 | class ListModule(ui_modules.UIModule): | |
170 | def render(self, posts): | |
171 | return self.render_string("blog/modules/list.html", posts=posts) | |
172 | ||
173 | ||
f91dfcc7 MT |
174 | class PostModule(ui_modules.UIModule): |
175 | def render(self, post): | |
176 | return self.render_string("blog/modules/post.html", post=post) | |
8a897d25 MT |
177 | |
178 | ||
179 | class PostsModule(ui_modules.UIModule): | |
180 | def render(self, posts): | |
0a6875dc | 181 | return self.render_string("blog/modules/posts.html", posts=list(posts)) |