]> git.ipfire.org Git - ipfire.org.git/blame - src/web/blog.py
web: Drop unused CacheMixin
[ipfire.org.git] / src / web / blog.py
CommitLineData
12e5de7e
MT
1#!/usr/bin/python
2
9ea64cef 3import datetime
9fa06206 4import dateutil
f0714277 5import email.utils
12e5de7e
MT
6import tornado.web
7
124a8404 8from . import base
f91dfcc7
MT
9from . import ui_modules
10
da24ac0a 11class IndexHandler(base.BaseHandler):
8a897d25 12 def get(self):
feb245e0 13 posts = self.backend.blog.get_newest(limit=10)
8a897d25 14
9d020f28 15 # Allow this to be cached for 5 minutes
9b8ff27d
MT
16 if not self.current_user:
17 self.set_expires(300)
9d020f28 18
54b9fef8
RH
19 # Extract the latest post
20 latest_post = posts.pop(0)
21
22 self.render("blog/index.html", posts=posts, latest_post=latest_post)
8a897d25
MT
23
24
da24ac0a 25class AuthorHandler(base.BaseHandler):
cfc0823a
MT
26 def get(self, uid):
27 author = self.accounts.get_by_uid(uid)
28 if not author:
29 raise tornado.web.HTTPError(404, "User is unknown")
30
31 # Get all posts from this author
cdf85ee7 32 posts = self.backend.blog.get_by_author(author)
cfc0823a
MT
33 if not posts:
34 raise tornado.web.HTTPError(404, "User has no posts")
35
9d020f28 36 # Allow this to be cached for 10 minutes
9b8ff27d
MT
37 if not self.current_user:
38 self.set_expires(600)
9d020f28 39
cfc0823a
MT
40 self.render("blog/author.html", author=author, posts=posts)
41
42
f0714277
MT
43class FeedHandler(base.BaseHandler):
44 def get(self):
bc586673 45 posts = self.backend.blog.get_newest(limit=10)
b2ed0760
MT
46 if not posts:
47 raise tornado.web.HTTPError(404)
f0714277 48
9d020f28
MT
49 # Allow this to be cached for 10 minutes
50 self.set_expires(600)
f0714277
MT
51
52 # Set correct content type
a7d34bc5 53 self.set_header("Content-Type", "application/atom+xml")
f0714277 54
b2ed0760
MT
55 # Render the feed
56 self.render("blog/feed.xml", posts=posts,
a7d34bc5 57 now=datetime.datetime.now())
f0714277
MT
58
59
da24ac0a 60class PostHandler(base.BaseHandler):
12e5de7e 61 def get(self, slug):
df157ede 62 post = self.backend.blog.get_by_slug(slug, published=not self.current_user)
0a6875dc 63 if not post:
12e5de7e
MT
64 raise tornado.web.HTTPError(404)
65
9d020f28 66 # Allow this to be cached for 10 minutes
a864e694
MT
67 if post.is_published():
68 self.set_expires(600)
9d020f28 69
0a6875dc 70 self.render("blog/post.html", post=post)
f91dfcc7
MT
71
72
da24ac0a 73class PublishHandler(base.BaseHandler):
9fa06206
MT
74 @tornado.web.authenticated
75 def get(self, slug):
76 post = self.backend.blog.get_by_slug(slug, published=False)
77 if not post:
78 raise tornado.web.HTTPError(404)
79
80 # Check if current_user is allowed to edit the post
81 if not post.is_editable(self.current_user):
82 raise tornado.web.HTTPError(403)
83
84 # Is the post already published?
85 if post.is_published():
86 raise tornado.web.HTTPError(400, "Post is already published")
87
88 self.render("blog/publish.html", post=post)
89
9ea64cef
MT
90 @tornado.web.authenticated
91 def post(self, slug):
9fa06206 92 post = self.backend.blog.get_by_slug(slug, published=False)
9ea64cef
MT
93 if not post:
94 raise tornado.web.HTTPError(404)
95
9fa06206
MT
96 # Check if current_user is allowed to edit the post
97 if not post.is_editable(self.current_user):
98 raise tornado.web.HTTPError(403)
99
9ea64cef
MT
100 # Is the post already published?
101 if post.is_published():
102 raise tornado.web.HTTPError(400, "Post is already published")
103
9fa06206
MT
104 when = self.get_argument("when", None)
105 if when:
106 when = dateutil.parser.parse(when)
fe40c0fa 107
9ea64cef
MT
108 # Publish the post
109 with self.db.transaction():
9fa06206 110 post.publish(when)
9ea64cef
MT
111
112 self.redirect("/post/%s" % post.slug)
113
114
da24ac0a 115class DraftsHandler(base.BaseHandler):
0b342a05
MT
116 @tornado.web.authenticated
117 def get(self):
118 drafts = self.backend.blog.get_drafts(author=self.current_user)
119
120 self.render("blog/drafts.html", drafts=drafts)
121
122
da24ac0a 123class SearchHandler(base.BaseHandler):
53a15fe0 124 @base.ratelimit(minutes=5, requests=25)
e6b18dce
MT
125 def get(self):
126 q = self.get_argument("q")
127
0a6875dc 128 posts = self.backend.blog.search(q, limit=50)
e6b18dce
MT
129 if not posts:
130 raise tornado.web.HTTPError(404, "Nothing found")
131
132 self.render("blog/search-results.html", q=q, posts=posts)
133
134
da24ac0a 135class TagHandler(base.BaseHandler):
4bde7f18
MT
136 def get(self, tag):
137 posts = self.backend.blog.get_by_tag(tag)
138 if not posts:
139 raise tornado.web.HTTPError(404, "There are no posts with tag: %s" % tag)
140
9d020f28
MT
141 # Allow this to be cached for 10 minutes
142 self.set_expires(600)
143
f0dc2fc1 144 self.render("blog/tag.html", posts=list(posts), tag=tag)
4bde7f18
MT
145
146
da24ac0a 147class YearHandler(base.BaseHandler):
7e64f6a3
MT
148 def get(self, year):
149 posts = self.backend.blog.get_by_year(year)
150 if not posts:
151 raise tornado.web.HTTPError(404, "There are no posts in %s" % year)
152
9d020f28
MT
153 # Allow this to be cached for 10 minutes
154 self.set_expires(600)
155
7e64f6a3
MT
156 self.render("blog/year.html", posts=posts, year=year)
157
158
da24ac0a 159class ComposeHandler(base.BaseHandler):
541c952b
MT
160 @tornado.web.authenticated
161 def get(self):
162 self.render("blog/compose.html", post=None)
163
164 @tornado.web.authenticated
165 def post(self):
166 title = self.get_argument("title")
167 text = self.get_argument("text")
dc035dce 168 tags = self.get_argument("tags", "").split(" ")
541c952b
MT
169
170 with self.db.transaction():
171 post = self.backend.blog.create_post(title, text,
172 author=self.current_user, tags=tags)
173
61e0a831 174 self.redirect("/drafts")
541c952b
MT
175
176
da24ac0a 177class EditHandler(base.BaseHandler):
541c952b
MT
178 @tornado.web.authenticated
179 def get(self, slug):
00bf122b 180 post = self.backend.blog.get_by_slug(slug, published=False)
541c952b
MT
181 if not post:
182 raise tornado.web.HTTPError(404)
183
e8a81a70
MT
184 # Check if post is editable
185 if not post.is_editable(self.current_user):
186 raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post))
541c952b
MT
187
188 self.render("blog/compose.html", post=post)
189
190 @tornado.web.authenticated
191 def post(self, slug):
00bf122b 192 post = self.backend.blog.get_by_slug(slug, published=False)
541c952b
MT
193 if not post:
194 raise tornado.web.HTTPError(404)
195
e8a81a70
MT
196 # Check if post is editable
197 if not post.is_editable(self.current_user):
198 raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post))
541c952b 199
93725180 200 # Save updated content
541c952b 201 with self.db.transaction():
93725180
MT
202 post.update(
203 title = self.get_argument("title"),
204 text = self.get_argument("text"),
dc035dce 205 tags = self.get_argument("tags", "").split(" "),
93725180 206 )
541c952b
MT
207
208 # Return to blog if the post is already published
209 if post.is_published():
210 self.redirect("/post/%s" % post.slug)
211 return
212
61e0a831
MT
213 # Otherwise return to drafts
214 self.redirect("/drafts")
541c952b
MT
215
216
da24ac0a 217class DeleteHandler(base.BaseHandler):
914238a5
MT
218 @tornado.web.authenticated
219 def get(self, slug):
220 post = self.backend.blog.get_by_slug(slug, published=False)
221 if not post:
222 raise tornado.web.HTTPError(404)
223
224 # Check if post is editable
225 if not post.is_editable(self.current_user):
226 raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post))
227
228 self.render("blog/delete.html", post=post)
229
230 @tornado.web.authenticated
231 def post(self, slug):
232 post = self.backend.blog.get_by_slug(slug, published=False)
233 if not post:
234 raise tornado.web.HTTPError(404)
235
236 # Check if post is editable
237 if not post.is_editable(self.current_user):
238 raise tornado.web.HTTPError(403, "%s cannot edit %s" % (self.current_user, post))
239
240 with self.db.transaction():
241 post.delete()
242
243 # Return to drafts
244 self.redirect("/drafts")
245
246
7e64f6a3
MT
247class HistoryNavigationModule(ui_modules.UIModule):
248 def render(self):
249 return self.render_string("blog/modules/history-navigation.html",
feb245e0 250 authors=self.backend.blog.authors, years=self.backend.blog.years)
7e64f6a3
MT
251
252
253class ListModule(ui_modules.UIModule):
feb245e0
MT
254 def render(self, posts, relative=False, show_author=True):
255 return self.render_string("blog/modules/list.html",
256 posts=posts, relative=relative, show_author=show_author)
7e64f6a3
MT
257
258
f91dfcc7
MT
259class PostModule(ui_modules.UIModule):
260 def render(self, post):
261 return self.render_string("blog/modules/post.html", post=post)