From: Michael Tremer Date: Mon, 7 Oct 2019 17:18:29 +0000 (+0100) Subject: wiki: Allow uploading newer revisions of a file X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ff14dea337e0330648fb7e668262bda799297f35;p=ipfire.org.git wiki: Allow uploading newer revisions of a file Signed-off-by: Michael Tremer --- diff --git a/src/backend/wiki.py b/src/backend/wiki.py index 4a900693..6647cc9b 100644 --- a/src/backend/wiki.py +++ b/src/backend/wiki.py @@ -208,13 +208,31 @@ class Wiki(misc.Object): return list(files) - def get_file_by_path(self, path): + def get_file_by_path(self, path, revision=None): path, filename = os.path.dirname(path), os.path.basename(path) + if revision: + # Fetch a specific revision + return self._get_file("SELECT * FROM wiki_files \ + WHERE path = %s AND filename = %s AND created_at <= %s \ + ORDER BY created_at DESC LIMIT 1", path, filename, revision) + + # Fetch latest version + return self._get_file("SELECT * FROM wiki_files \ + WHERE path = %s AND filename = %s AND deleted_at IS NULL", + path, filename) + + def get_file_by_path_and_filename(self, path, filename): return self._get_file("SELECT * FROM wiki_files \ - WHERE path = %s AND filename = %s AND deleted_at IS NULL", path, filename) + WHERE path = %s AND filename = %s AND deleted_at IS NULL", + path, filename) def upload(self, path, filename, data, mimetype, author, address): + # Replace any existing files + file = self.get_file_by_path_and_filename(path, filename) + if file: + file.delete(author) + # Upload the blob first blob = self.db.get("INSERT INTO wiki_blobs(data) VALUES(%s) RETURNING id", data) @@ -432,6 +450,10 @@ class File(misc.Object): self.id = id self.data = data + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.id == other.id + @property def url(self): return os.path.join(self.path, self.filename) @@ -461,6 +483,28 @@ class File(misc.Object): def created_at(self): return self.data.created_at + def delete(self, author): + # XXX handle author + self.db.execute("UPDATE wiki_files SET deleted_at = NOW() \ + WHERE id = %s", self.id) + + @property + def deleted_at(self): + return self.data.deleted_at + + def get_latest_revision(self): + revisions = self.get_revisions() + + # Return first object + for rev in revisions: + return rev + + def get_revisions(self): + revisions = self.backend.wiki._get_files("SELECT * FROM wiki_files \ + WHERE path = %s ORDER BY created_at DESC", self.path) + + return list(revisions) + def is_pdf(self): return self.mimetype in ("application/pdf", "application/x-pdf") diff --git a/src/templates/wiki/files/detail.html b/src/templates/wiki/files/detail.html index 1ac3df13..e8a87482 100644 --- a/src/templates/wiki/files/detail.html +++ b/src/templates/wiki/files/detail.html @@ -7,19 +7,19 @@
{% if file.is_image() %}

- {{ file.filename }} + {{ file.filename }}

{% elif file.is_pdf() %} -

{{ _("This PDF attachment could not be displayed.") }} - {{ _("Click here to download") }} + {{ _("Click here to download") }}

{% end %} - + {{ _("Download") }} ({{ format_size(file.size) }}) @@ -37,6 +37,11 @@
{{ _("Uploaded at") }}
{{ locale.format_date(file.created_at) }}
+ + {% if file.deleted_at %} +
{{ _("Deleted at") }}
+
{{ locale.format_date(file.deleted_at) }}
+ {% end %} {% if file.is_image() %} @@ -48,6 +53,39 @@
![](./{{ file.filename }} "{{ _("Caption") }}")
{% end %} + + {% set revisions = file.get_revisions() %} + {% if len(revisions) > 1 %} +
{{ _("Other Revisions") }}
+ + + {% end %} + +
+ {% raw xsrf_form_html() %} + + + + +
+
+ + +
+
+ + +
{% end block %} diff --git a/src/web/wiki.py b/src/web/wiki.py index dfb46a94..6d0600f0 100644 --- a/src/web/wiki.py +++ b/src/web/wiki.py @@ -78,6 +78,9 @@ class ActionUploadHandler(auth.CacheMixin, base.BaseHandler): try: filename, data, mimetype = self.get_file("file") + # Use filename from request if any + filename = self.get_argument("filename", filename) + # XXX check valid mimetypes with self.db.transaction(): @@ -159,8 +162,11 @@ class FileHandler(base.BaseHandler): if not self.backend.wiki.check_acl(path, self.current_user): raise tornado.web.HTTPError(403, "Access to %s not allowed for %s" % (path, self.current_user)) + # Check if we are asked to render a certain revision + revision = self.get_argument("revision", None) + # Fetch the file - file = self.backend.wiki.get_file_by_path(path) + file = self.backend.wiki.get_file_by_path(path, revision=revision) if not file: raise tornado.web.HTTPError(404, "Could not find %s" % path)