]> git.ipfire.org Git - ipfire.org.git/blob - src/web/docs.py
4f20b5d975241f96b4541b1114b196a0e562e9e1
[ipfire.org.git] / src / web / docs.py
1 #!/usr/bin/python3
2
3 import difflib
4 import tornado.web
5
6 from . import base
7 from . import ui_modules
8
9 class PageHandler(base.BaseHandler):
10 @property
11 def action(self):
12 return self.get_argument("action", None)
13
14 def write_error(self, status_code, **kwargs):
15 # Render a custom page for 404
16 if status_code == 404:
17 self.render("wiki/404.html", **kwargs)
18 return
19
20 # Otherwise raise this to one layer above
21 super().write_error(status_code, **kwargs)
22
23 @tornado.web.removeslash
24 def get(self, path):
25 if path is None:
26 path = "/"
27
28 # Check permissions
29 if not self.backend.wiki.check_acl(path, self.current_user):
30 raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user))
31
32 # Check if we are asked to render a certain revision
33 revision = self.get_argument("revision", None)
34
35 # Fetch the wiki page
36 page = self.backend.wiki.get_page(path, revision=revision)
37
38 # Diff
39 if self.action == "diff":
40 # Get both revisions
41 a = self.get_argument("a")
42 b = self.get_argument("b")
43
44 # Fetch both versions of the page
45 a = self.backend.wiki.get_page(path, revision=a)
46 b = self.backend.wiki.get_page(path, revision=b)
47 if not a or not b:
48 raise tornado.web.HTTPError(404)
49
50 # Cannot render a diff for the identical page
51 if a == b:
52 raise tornado.web.HTTPError(400)
53
54 # Make sure that b is newer than a
55 if a > b:
56 a, b = b, a
57
58 self.render("wiki/diff.html", page=page, a=a, b=b)
59 return
60
61 # Restore
62 elif self.action == "restore":
63 self.render("wiki/confirm-restore.html", page=page)
64 return
65
66 # Revisions
67 elif self.action == "revisions":
68 self.render("wiki/revisions.html", page=page)
69 return
70
71 # If the page does not exist, we send 404
72 if not page or page.was_deleted():
73 # Handle /start links which were in the format of DokuWiki
74 if path.endswith("/start"):
75 # Strip /start from path
76 path = path[:-6] or "/"
77
78 # Redirect user to page if it exists
79 page = self.backend.wiki.page_exists(path)
80 if page:
81 self.redirect(path)
82
83 raise tornado.web.HTTPError(404)
84
85 # Fetch the latest revision
86 latest_revision = page.get_latest_revision()
87
88 # Render page
89 self.render("docs/page.html", page=page, latest_revision=latest_revision)
90
91
92 class HeaderModule(ui_modules.UIModule):
93 @property
94 def page(self):
95 """
96 Returns the path of the page (without any actions)
97 """
98 path = self.request.path.removeprefix("/docs")
99
100 return "/".join((p for p in path.split("/") if not p.startswith("_")))
101
102 def render(self, suffix=None):
103 _ = self.locale.translate
104
105 breadcrumbs = self.backend.wiki.make_breadcrumbs(self.page)
106 title = self.backend.wiki.get_page_title(self.page)
107
108 if self.request.path.endswith("/_edit"):
109 suffix = _("Edit")
110 elif self.request.path.endswith("/_files"):
111 suffix = _("Files")
112
113 return self.render_string("docs/modules/header.html",
114 breadcrumbs=breadcrumbs, page=self.page, page_title=title, suffix=suffix)