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