]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/wiki.py
76433dc73dda3d4e6c76e98203f2b77164251baf
8 from . import ui_modules
10 class ActionEditHandler(auth
.CacheMixin
, base
.BaseHandler
):
11 @tornado.web
.authenticated
13 path
= self
.get_argument("path")
16 if not self
.backend
.wiki
.check_acl(path
, self
.current_user
):
17 raise tornado
.web
.HTTPError(403, "Access to %s not allowed for %s" % (path
, self
.current_user
))
19 content
= self
.get_argument("content", None)
20 changes
= self
.get_argument("changes")
22 # Create a new page in the database
23 with self
.db
.transaction():
24 page
= self
.backend
.wiki
.create_page(path
,
25 self
.current_user
, content
, changes
=changes
, address
=self
.get_remote_ip())
27 # Add user as a watcher if wanted
28 watch
= self
.get_argument("watch", False)
30 page
.add_watcher(self
.current_user
)
33 if page
.was_deleted():
36 self
.redirect(page
.url
)
40 Updates the search index after the page has been edited
42 # This is being executed in the background and after
43 # the response has been set to the client
44 with self
.db
.transaction():
45 self
.backend
.wiki
.refresh()
48 class ActionUploadHandler(auth
.CacheMixin
, base
.BaseHandler
):
49 @tornado.web
.authenticated
51 path
= self
.get_argument("path")
54 if not self
.backend
.wiki
.check_acl(path
, self
.current_user
):
55 raise tornado
.web
.HTTPError(403, "Access to %s not allowed for %s" % (path
, self
.current_user
))
58 filename
, data
, mimetype
= self
.get_file("file")
60 # XXX check valid mimetypes
62 with self
.db
.transaction():
63 file = self
.backend
.wiki
.upload(path
, filename
, data
,
64 mimetype
=mimetype
, author
=self
.current_user
,
65 address
=self
.get_remote_ip())
67 except TypeError as e
:
70 self
.redirect("%s/files" % path
)
73 class ActionWatchHandler(auth
.CacheMixin
, base
.BaseHandler
):
74 @tornado.web
.authenticated
75 def get(self
, action
, path
):
76 page
= self
.backend
.wiki
.get_page(path
)
78 raise tornado
.web
.HTTPError(404, "Page does not exist: %s" % path
)
80 with self
.db
.transaction():
82 page
.add_watcher(self
.current_user
)
83 elif action
== "unwatch":
84 page
.remove_watcher(self
.current_user
)
86 # Redirect back to page
87 self
.redirect(page
.url
)
90 class FilesHandler(auth
.CacheMixin
, base
.BaseHandler
):
91 @tornado.web
.authenticated
94 if not self
.backend
.wiki
.check_acl(path
, self
.current_user
):
95 raise tornado
.web
.HTTPError(403, "Access to %s not allowed for %s" % (path
, self
.current_user
))
97 files
= self
.backend
.wiki
.get_files(path
)
99 self
.render("wiki/files/index.html", path
=path
, files
=files
)
102 class FileHandler(base
.BaseHandler
):
105 return self
.get_argument("action", None)
109 if not self
.backend
.wiki
.check_acl(path
, self
.current_user
):
110 raise tornado
.web
.HTTPError(403, "Access to %s not allowed for %s" % (path
, self
.current_user
))
113 file = self
.backend
.wiki
.get_file_by_path(path
)
115 raise tornado
.web
.HTTPError(404, "Could not find %s" % path
)
118 if self
.action
== "detail":
119 for breadcrumb
, title
in self
.backend
.wiki
.make_breadcrumbs(path
):
120 page
= self
.backend
.wiki
.get_page(breadcrumb
)
124 self
.render("wiki/files/detail.html", page
=page
, file=file)
127 size
= self
.get_argument_int("s", None)
129 # Check if image should be resized
130 if file.is_image() and size
:
131 blob
= file.get_thumbnail(size
)
136 self
.set_header("Content-Type", file.mimetype
or "application/octet-stream")
137 self
.set_header("Content-Length", len(blob
))
140 self
.set_expires(3600)
146 class PageHandler(auth
.CacheMixin
, base
.BaseHandler
):
149 return self
.get_argument("action", None)
151 def write_error(self
, status_code
, **kwargs
):
152 # Render a custom page for 404
153 if status_code
== 404:
154 self
.render("wiki/404.html", **kwargs
)
157 # Otherwise raise this to one layer above
158 super().write_error(status_code
, **kwargs
)
160 @tornado.web
.removeslash
163 if not self
.backend
.wiki
.check_acl(path
, self
.current_user
):
164 raise tornado
.web
.HTTPError(403, "Access to %s not allowed for %s" % (path
, self
.current_user
))
166 # Check if we are asked to render a certain revision
167 revision
= self
.get_argument("revision", None)
169 # Fetch the wiki page
170 page
= self
.backend
.wiki
.get_page(path
, revision
=revision
)
173 if self
.action
== "diff":
175 a
= self
.get_argument("a")
176 b
= self
.get_argument("b")
178 # Fetch both versions of the page
179 a
= self
.backend
.wiki
.get_page(path
, revision
=a
)
180 b
= self
.backend
.wiki
.get_page(path
, revision
=b
)
182 raise tornado
.web
.HTTPError(404)
184 # Cannot render a diff for the identical page
186 raise tornado
.web
.HTTPError(400)
188 # Make sure that b is newer than a
192 self
.render("wiki/diff.html", page
=page
, a
=a
, b
=b
)
196 elif self
.action
== "edit":
197 if not self
.current_user
:
198 raise tornado
.web
.HTTPError(401)
200 # Empty page if it was deleted
201 if page
and page
.was_deleted():
205 self
.render("wiki/edit.html", page
=page
)
209 elif self
.action
== "revisions":
210 self
.render("wiki/revisions.html", page
=page
)
213 # If the page does not exist, we send 404
214 if not page
or page
.was_deleted():
215 raise tornado
.web
.HTTPError(404)
217 # Fetch the latest revision
218 latest_revision
= page
.get_latest_revision()
221 self
.render("wiki/page.html", page
=page
, latest_revision
=latest_revision
)
224 class SearchHandler(auth
.CacheMixin
, base
.BaseHandler
):
227 q
= self
.get_argument("q")
229 pages
= self
.backend
.wiki
.search(q
, account
=self
.current_user
, limit
=50)
231 self
.render("wiki/search-results.html", q
=q
, pages
=pages
)
234 class RecentChangesHandler(auth
.CacheMixin
, base
.BaseHandler
):
236 recent_changes
= self
.backend
.wiki
.get_recent_changes(self
.current_user
, limit
=50)
238 self
.render("wiki/recent-changes.html", recent_changes
=recent_changes
)
241 class WatchlistHandler(auth
.CacheMixin
, base
.BaseHandler
):
242 @tornado.web
.authenticated
244 pages
= self
.backend
.wiki
.get_watchlist(self
.current_user
)
246 self
.render("wiki/watchlist.html", pages
=pages
)
249 class WikiDiffModule(ui_modules
.UIModule
):
250 differ
= difflib
.Differ()
252 def render(self
, a
, b
):
253 diff
= self
.differ
.compare(
254 a
.markdown
.splitlines(),
255 b
.markdown
.splitlines(),
258 return self
.render_string("wiki/modules/diff.html", diff
=diff
)
261 class WikiListModule(ui_modules
.UIModule
):
262 def render(self
, pages
, link_revision
=False, show_breadcrumbs
=True,
263 show_author
=True, show_changes
=False):
264 return self
.render_string("wiki/modules/list.html", link_revision
=link_revision
,
265 pages
=pages
, show_breadcrumbs
=show_breadcrumbs
,
266 show_author
=show_author
, show_changes
=show_changes
)
269 class WikiNavbarModule(ui_modules
.UIModule
):
270 def render(self
, suffix
=None):
271 _
= self
.locale
.translate
273 breadcrumbs
= self
.backend
.wiki
.make_breadcrumbs(self
.request
.path
)
275 # Don't search for a title for the file manager
276 if self
.request
.path
.endswith("/files"):
279 title
= self
.backend
.wiki
.get_page_title(self
.request
.path
)
281 return self
.render_string("wiki/modules/navbar.html",
282 breadcrumbs
=breadcrumbs
, page_title
=title
, suffix
=suffix
)