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