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