]> git.ipfire.org Git - ipfire.org.git/blob - src/web/wiki.py
2afe1ea7c3db502aedc1ec6347bc3b527174ba96
[ipfire.org.git] / src / web / wiki.py
1 #!/usr/bin/python3
2
3 import tornado.web
4
5 from . import auth
6 from . import base
7 from . import ui_modules
8
9 class 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
30 class 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
38 class FileHandler(auth.CacheMixin, base.BaseHandler):
39 def get(self, path):
40 file = self.backend.wiki.get_file_by_path(path)
41 if not file:
42 raise tornado.web.HTTPError(404, "Could not find %s" % path)
43
44 # Set headers
45 self.set_header("Content-Type", file.mimetype or "application/octet-stream")
46 self.set_header("Content-Length", file.size)
47
48 self.finish(file.blob)
49
50
51 class PageHandler(auth.CacheMixin, base.BaseHandler):
52 @property
53 def action(self):
54 return self.get_argument("action", None)
55
56 def write_error(self, status_code, **kwargs):
57 # Render a custom page for 404
58 if status_code == 404:
59 self.render("wiki/404.html", **kwargs)
60 return
61
62 # Otherwise raise this to one layer above
63 super().write_error(status_code, **kwargs)
64
65 @tornado.web.removeslash
66 def get(self, page):
67 # Check if we are asked to render a certain revision
68 revision = self.get_argument("revision", None)
69
70 # Fetch the wiki page
71 page = self.backend.wiki.get_page(page, revision=revision)
72
73 # Edit
74 if self.action == "edit":
75 if not self.current_user:
76 raise tornado.web.HTTPError(401)
77
78 # Empty page if it was deleted
79 if page and page.was_deleted():
80 page = None
81
82 # Render page
83 self.render("wiki/edit.html", page=page)
84 return
85
86 # Revisions
87 elif self.action == "revisions":
88 self.render("wiki/revisions.html", page=page)
89 return
90
91 # If the page does not exist, we send 404
92 if not page or page.was_deleted():
93 raise tornado.web.HTTPError(404)
94
95 # Fetch the latest revision
96 latest_revision = page.get_latest_revision()
97
98 # Render page
99 self.render("wiki/page.html", page=page, latest_revision=latest_revision)
100
101 @tornado.web.authenticated
102 def post(self, page):
103 content = self.get_argument("content", None)
104 changes = self.get_argument("changes")
105
106 # Create a new page in the database
107 with self.db.transaction():
108 page = self.backend.wiki.create_page(page,
109 self.current_user, content, changes=changes, address=self.get_remote_ip())
110
111 # Redirect back
112 if page.was_deleted():
113 self.redirect("/")
114 else:
115 self.redirect(page.url)
116
117 # Update the search index
118 with self.db.transaction():
119 self.backend.wiki.refresh()
120
121
122 class SearchHandler(auth.CacheMixin, base.BaseHandler):
123 @base.blacklisted
124 def get(self):
125 q = self.get_argument("q")
126
127 pages = self.backend.wiki.search(q, limit=50)
128
129 self.render("wiki/search-results.html", q=q, pages=pages)
130
131
132 class RecentChangesHandler(auth.CacheMixin, base.BaseHandler):
133 def get(self):
134 recent_changes = self.backend.wiki.get_recent_changes(limit=50)
135
136 self.render("wiki/recent-changes.html", recent_changes=recent_changes)
137
138
139 class WikiListModule(ui_modules.UIModule):
140 def render(self, pages, link_revision=False, show_breadcrumbs=True, show_changes=False):
141 return self.render_string("wiki/modules/list.html", link_revision=link_revision,
142 pages=pages, show_breadcrumbs=show_breadcrumbs, show_changes=show_changes)
143
144
145 class WikiNavbarModule(ui_modules.UIModule):
146 def render(self, suffix=None):
147 _ = self.locale.translate
148
149 breadcrumbs = self.backend.wiki.make_breadcrumbs(self.request.path)
150
151 # Don't search for a title for the file manager
152 if self.request.path.endswith("/files"):
153 title = _("Files")
154 else:
155 title = self.backend.wiki.get_page_title(self.request.path)
156
157 return self.render_string("wiki/modules/navbar.html",
158 breadcrumbs=breadcrumbs, page_title=title, suffix=suffix)