]> git.ipfire.org Git - ipfire.org.git/blame - src/web/wiki.py
release: Cache blog post
[ipfire.org.git] / src / web / wiki.py
CommitLineData
181d08f3
MT
1#!/usr/bin/python3
2
3import tornado.web
4
5from . import auth
6from . import base
6ac7e934 7from . import ui_modules
181d08f3 8
b6e8b28f
MT
9class ActionEditHandler(auth.CacheMixin, base.BaseHandler):
10 @tornado.web.authenticated
11 def post(self):
12 path = self.get_argument("path")
13
14 # Check permissions
15 if not self.backend.wiki.check_acl(path, self.current_user):
16 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user))
17
18 content = self.get_argument("content", None)
19 changes = self.get_argument("changes")
20
21 # Create a new page in the database
22 with self.db.transaction():
23 page = self.backend.wiki.create_page(path,
24 self.current_user, content, changes=changes, address=self.get_remote_ip())
25
26 # Redirect back
27 if page.was_deleted():
28 self.redirect("/")
29 else:
30 self.redirect(page.url)
31
32 def on_finish(self):
33 """
34 Updates the search index after the page has been edited
35 """
36 # This is being executed in the background and after
37 # the response has been set to the client
38 with self.db.transaction():
39 self.backend.wiki.refresh()
40
41
f2cfd873
MT
42class ActionUploadHandler(auth.CacheMixin, base.BaseHandler):
43 @tornado.web.authenticated
44 def post(self):
45 path = self.get_argument("path")
46
11afe905
MT
47 # Check permissions
48 if not self.backend.wiki.check_acl(path, self.current_user):
49 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user))
50
f2cfd873
MT
51 try:
52 filename, data, mimetype = self.get_file("file")
53
54 # XXX check valid mimetypes
55
56 with self.db.transaction():
57 file = self.backend.wiki.upload(path, filename, data,
58 mimetype=mimetype, author=self.current_user,
59 address=self.get_remote_ip())
60
61 except TypeError as e:
62 raise e
63
64 self.redirect("%s/files" % path)
65
66
67class FilesHandler(auth.CacheMixin, base.BaseHandler):
68 @tornado.web.authenticated
69 def get(self, path):
11afe905
MT
70 # Check permissions
71 if not self.backend.wiki.check_acl(path, self.current_user):
72 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user))
73
f2cfd873
MT
74 files = self.backend.wiki.get_files(path)
75
76 self.render("wiki/files/index.html", path=path, files=files)
77
78
568b265b 79class FileHandler(base.BaseHandler):
8cb0bea4
MT
80 @property
81 def action(self):
82 return self.get_argument("action", None)
83
f2cfd873 84 def get(self, path):
11afe905
MT
85 # Check permissions
86 if not self.backend.wiki.check_acl(path, self.current_user):
87 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user))
88
89 # Fetch the file
f2cfd873
MT
90 file = self.backend.wiki.get_file_by_path(path)
91 if not file:
92 raise tornado.web.HTTPError(404, "Could not find %s" % path)
93
8cb0bea4
MT
94 # Render detail page
95 if self.action == "detail":
96 self.render("wiki/files/detail.html", file=file)
97 return
98
79dd9a0f
MT
99 size = self.get_argument_int("s", None)
100
101 # Check if image should be resized
102 if file.is_image() and size:
103 blob = file.get_thumbnail(size)
104 else:
105 blob = file.blob
106
f2cfd873
MT
107 # Set headers
108 self.set_header("Content-Type", file.mimetype or "application/octet-stream")
79dd9a0f 109 self.set_header("Content-Length", len(blob))
f2cfd873 110
568b265b
MT
111 # Set expires
112 self.set_expires(3600)
113
79dd9a0f
MT
114 # Deliver content
115 self.finish(blob)
f2cfd873
MT
116
117
181d08f3 118class PageHandler(auth.CacheMixin, base.BaseHandler):
d398ca08
MT
119 @property
120 def action(self):
121 return self.get_argument("action", None)
122
a446dcb9
MT
123 def write_error(self, status_code, **kwargs):
124 # Render a custom page for 404
125 if status_code == 404:
126 self.render("wiki/404.html", **kwargs)
127 return
128
129 # Otherwise raise this to one layer above
130 super().write_error(status_code, **kwargs)
131
181d08f3
MT
132 @tornado.web.removeslash
133 def get(self, page):
11afe905
MT
134 # Check permissions
135 if not self.backend.wiki.check_acl(page, self.current_user):
136 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (page, self.current_user))
137
7d699684
MT
138 # Check if we are asked to render a certain revision
139 revision = self.get_argument("revision", None)
140
141 # Fetch the wiki page
142 page = self.backend.wiki.get_page(page, revision=revision)
181d08f3 143
d398ca08
MT
144 # Edit
145 if self.action == "edit":
146 if not self.current_user:
147 raise tornado.web.HTTPError(401)
148
149 # Empty page if it was deleted
addc4eb7 150 if page and page.was_deleted():
d398ca08
MT
151 page = None
152
7d699684
MT
153 # Render page
154 self.render("wiki/edit.html", page=page)
155 return
156
157 # Revisions
158 elif self.action == "revisions":
159 self.render("wiki/revisions.html", page=page)
160 return
d398ca08 161
181d08f3
MT
162 # If the page does not exist, we send 404
163 if not page or page.was_deleted():
164 raise tornado.web.HTTPError(404)
165
166 # Fetch the latest revision
167 latest_revision = page.get_latest_revision()
168
169 # Render page
170 self.render("wiki/page.html", page=page, latest_revision=latest_revision)
171
181d08f3
MT
172
173class SearchHandler(auth.CacheMixin, base.BaseHandler):
174 @base.blacklisted
175 def get(self):
176 q = self.get_argument("q")
177
11afe905 178 pages = self.backend.wiki.search(q, account=self.current_user, limit=50)
181d08f3 179
11afe905 180 self.render("wiki/search-results.html", q=q, pages=list(pages))
6ac7e934
MT
181
182
f9db574a
MT
183class RecentChangesHandler(auth.CacheMixin, base.BaseHandler):
184 def get(self):
11afe905 185 recent_changes = self.backend.wiki.get_recent_changes(self.current_user, limit=50)
f9db574a
MT
186
187 self.render("wiki/recent-changes.html", recent_changes=recent_changes)
188
189
190class WikiListModule(ui_modules.UIModule):
7d699684
MT
191 def render(self, pages, link_revision=False, show_breadcrumbs=True, show_changes=False):
192 return self.render_string("wiki/modules/list.html", link_revision=link_revision,
66a814d9 193 pages=pages, show_breadcrumbs=show_breadcrumbs, show_changes=show_changes)
f9db574a
MT
194
195
6ac7e934 196class WikiNavbarModule(ui_modules.UIModule):
67573803 197 def render(self, suffix=None):
f2cfd873
MT
198 _ = self.locale.translate
199
67573803
MT
200 breadcrumbs = self.backend.wiki.make_breadcrumbs(self.request.path)
201
f2cfd873
MT
202 # Don't search for a title for the file manager
203 if self.request.path.endswith("/files"):
204 title = _("Files")
205 else:
206 title = self.backend.wiki.get_page_title(self.request.path)
6ac7e934
MT
207
208 return self.render_string("wiki/modules/navbar.html",
67573803 209 breadcrumbs=breadcrumbs, page_title=title, suffix=suffix)