]> git.ipfire.org Git - ipfire.org.git/blame - src/web/blog.py
blog: Only allow to edit own posts
[ipfire.org.git] / src / web / blog.py
CommitLineData
12e5de7e
MT
1#!/usr/bin/python
2
f0714277 3import email.utils
12e5de7e
MT
4import tornado.web
5
6import handlers_base as base
7
f91dfcc7
MT
8from . import ui_modules
9
8a897d25
MT
10class 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
17class 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
31class 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
54class 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
63class 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
71class 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
82class 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
91class 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
100class 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
118class 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
163class 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
169class ListModule(ui_modules.UIModule):
170 def render(self, posts):
171 return self.render_string("blog/modules/list.html", posts=posts)
172
173
f91dfcc7
MT
174class PostModule(ui_modules.UIModule):
175 def render(self, post):
176 return self.render_string("blog/modules/post.html", post=post)
8a897d25
MT
177
178
179class PostsModule(ui_modules.UIModule):
180 def render(self, posts):
0a6875dc 181 return self.render_string("blog/modules/posts.html", posts=list(posts))