From: Michael Tremer Date: Sun, 2 Dec 2018 15:31:13 +0000 (+0000) Subject: wiki: Add page that diffs revisions of a page X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c21ffadb8452cc840c58a766e294b5f5b99965e3;p=ipfire.org.git wiki: Add page that diffs revisions of a page Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 2cac0644..3e5a059b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -260,6 +260,7 @@ templates_staticdir = $(templatesdir)/static templates_wiki_DATA = \ src/templates/wiki/404.html \ src/templates/wiki/base.html \ + src/templates/wiki/diff.html \ src/templates/wiki/edit.html \ src/templates/wiki/page.html \ src/templates/wiki/recent-changes.html \ @@ -275,6 +276,7 @@ templates_wiki_files_DATA = \ templates_wiki_filesdir = $(templates_wikidir)/files templates_wiki_modules_DATA = \ + src/templates/wiki/modules/diff.html \ src/templates/wiki/modules/list.html \ src/templates/wiki/modules/navbar.html diff --git a/src/backend/wiki.py b/src/backend/wiki.py index 59406da0..dad4a242 100644 --- a/src/backend/wiki.py +++ b/src/backend/wiki.py @@ -181,6 +181,10 @@ class Page(misc.Object): def __repr__(self): return "<%s %s %s>" % (self.__class__.__name__, self.page, self.timestamp) + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.id == other.id + def __lt__(self, other): if isinstance(other, self.__class__): if self.page == other.page: @@ -298,7 +302,7 @@ class Page(misc.Object): @property def markdown(self): - return self.data.markdown + return self.data.markdown or "" @property def html(self): @@ -326,6 +330,12 @@ class Page(misc.Object): return self.backend.wiki._get_pages("SELECT * FROM wiki \ WHERE page = %s ORDER BY timestamp DESC", self.page) + @lazy_property + def previous_revision(self): + return self.backend.wiki._get_page("SELECT * FROM wiki \ + WHERE page = %s AND timestamp < %s ORDER BY timestamp DESC \ + LIMIT 1", self.page, self.timestamp) + @property def changes(self): return self.data.changes diff --git a/src/templates/wiki/diff.html b/src/templates/wiki/diff.html new file mode 100644 index 00000000..4f784c70 --- /dev/null +++ b/src/templates/wiki/diff.html @@ -0,0 +1,41 @@ +{% extends "page.html" %} + +{% block title %}{{ _("Differences in Revisions") }} - {{ page.title }}{% end block %} + +{% block main %} +
+
+

{{ _("%s: Differences in Revisions") % page.title }}

+ +
+
+
{{ _("Older Revision") }}
+ + + {{ locale.format_date(a.timestamp) }} + +
+ +
+ » +
+ +
+
{{ _("Newer Revision") }}
+ + + {{ locale.format_date(b.timestamp) }} + +
+
+ + {% if b.changes %} +
+ {{ b.changes }} +
+ {% end %} + + {% module WikiDiff(a, b) %} +
+
+{% end block %} diff --git a/src/templates/wiki/modules/diff.html b/src/templates/wiki/modules/diff.html new file mode 100644 index 00000000..341a5ee9 --- /dev/null +++ b/src/templates/wiki/modules/diff.html @@ -0,0 +1,11 @@ + + + {% for line in diff %} + {% if not line.startswith("?") %} + + + + {% end %} + {% end %} + +
{% if line[2:] %}{{ line[2:] }}{% else %} {% end %}
diff --git a/src/templates/wiki/modules/list.html b/src/templates/wiki/modules/list.html index f7a67c15..16bb15e7 100644 --- a/src/templates/wiki/modules/list.html +++ b/src/templates/wiki/modules/list.html @@ -17,6 +17,12 @@ {{ page.author }} {% end %} + {% if page.previous_revision %} + + + + {% end %} + {% if show_changes and page.changes %} • {{ page.changes }} {% end %} diff --git a/src/web/__init__.py b/src/web/__init__.py index 7db22f57..99afa5ea 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -90,6 +90,7 @@ class Application(tornado.web.Application): : fireinfo.DeviceAndGroupsTableModule, # Wiki + "WikiDiff" : wiki.WikiDiffModule, "WikiNavbar" : wiki.WikiNavbarModule, "WikiList" : wiki.WikiListModule, diff --git a/src/web/wiki.py b/src/web/wiki.py index 79953614..7adf3756 100644 --- a/src/web/wiki.py +++ b/src/web/wiki.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 +import difflib import tornado.web from . import auth @@ -141,8 +142,31 @@ class PageHandler(auth.CacheMixin, base.BaseHandler): # Fetch the wiki page page = self.backend.wiki.get_page(page, revision=revision) + # Diff + if self.action == "diff": + # Get both revisions + a = self.get_argument("a") + b = self.get_argument("b") + + # Fetch both versions of the page + a = self.backend.wiki.get_page(page.page, revision=a) + b = self.backend.wiki.get_page(page.page, revision=b) + if not a or not b: + raise tornado.web.HTTPError(404) + + # Cannot render a diff for the identical page + if a == b: + raise tornado.web.HTTPError(400) + + # Make sure that b is newer than a + if a > b: + a, b = b, a + + self.render("wiki/diff.html", page=page, a=a, b=b) + return + # Edit - if self.action == "edit": + elif self.action == "edit": if not self.current_user: raise tornado.web.HTTPError(401) @@ -187,6 +211,18 @@ class RecentChangesHandler(auth.CacheMixin, base.BaseHandler): self.render("wiki/recent-changes.html", recent_changes=recent_changes) +class WikiDiffModule(ui_modules.UIModule): + differ = difflib.Differ() + + def render(self, a, b): + diff = self.differ.compare( + a.markdown.splitlines(), + b.markdown.splitlines(), + ) + + return self.render_string("wiki/modules/diff.html", diff=diff) + + class WikiListModule(ui_modules.UIModule): def render(self, pages, link_revision=False, show_breadcrumbs=True, show_changes=False): return self.render_string("wiki/modules/list.html", link_revision=link_revision,