]> git.ipfire.org Git - ipfire.org.git/commitdiff
wiki: Add page that diffs revisions of a page
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 2 Dec 2018 15:31:13 +0000 (15:31 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 2 Dec 2018 15:31:13 +0000 (15:31 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/wiki.py
src/templates/wiki/diff.html [new file with mode: 0644]
src/templates/wiki/modules/diff.html [new file with mode: 0644]
src/templates/wiki/modules/list.html
src/web/__init__.py
src/web/wiki.py

index 2cac0644902f9d0652fb3ed56a523ace0d407a49..3e5a059bc5d40270fde39daaca2b31d9ae3d46e9 100644 (file)
@@ -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
 
index 59406da0a3c17cafaf96b86964c6e3d3465e5a0e..dad4a242b9032d4e25ce28a4d87aeab3a70a6ecb 100644 (file)
@@ -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 (file)
index 0000000..4f784c7
--- /dev/null
@@ -0,0 +1,41 @@
+{% extends "page.html" %}
+
+{% block title %}{{ _("Differences in Revisions") }} - {{ page.title }}{% end block %}
+
+{% block main %}
+       <div class="card mb-3">
+               <div class="card-body">
+                       <h4 class="card-title">{{ _("%s: Differences in Revisions") % page.title }}</h4>
+
+                       <div class="row mb-3">
+                               <div class="col col-md-5 text-center">
+                                       <h6 class="mb-0">{{ _("Older Revision") }}</h6>
+
+                                       <a href="{{ a.url }}?revision={{ a.timestamp.isoformat() }}">
+                                               {{ locale.format_date(a.timestamp) }}
+                                       </a>
+                               </div>
+
+                               <div class="col col-md-2 text-center">
+                                       &raquo;
+                               </div>
+
+                               <div class="col col-md-5 text-center">
+                                       <h6 class="mb-0">{{ _("Newer Revision") }}</h6>
+
+                                       <a href="{{ b.url }}?revision={{ b.timestamp.isoformat() }}">
+                                               {{ locale.format_date(b.timestamp) }}
+                                       </a>
+                               </div>
+                       </div>
+
+                       {% if b.changes %}
+                               <div class="alert alert-light">
+                                       {{ b.changes }}
+                               </div>
+                       {% end %}
+
+                       {% module WikiDiff(a, b) %}
+               </div>
+       </div>
+{% end block %}
diff --git a/src/templates/wiki/modules/diff.html b/src/templates/wiki/modules/diff.html
new file mode 100644 (file)
index 0000000..341a5ee
--- /dev/null
@@ -0,0 +1,11 @@
+<table class="table table-sm small text-monospace">
+       <tbody>
+               {% for line in diff %}
+                       {% if not line.startswith("?") %}
+                               <tr class="{% if line.startswith("+") %}table-success{% elif line.startswith("-") %}table-danger{% end %}">
+                                       <td>{% if line[2:] %}{{ line[2:] }}{% else %}&nbsp;{% end %}</td>
+                               </tr>
+                       {% end %}
+               {% end %}
+       </tbody>
+</table>
index f7a67c15854af9b58786e537fdd702979cf8cbdd..16bb15e775113f209c8b0d7f433a0261a613adf8 100644 (file)
                        <a href="/users/{{ page.author.uid }}">{{ page.author }}</a>
                {% end %}
 
+               {% if page.previous_revision %}
+                       <a href="{{ page.url }}?action=diff&a={{ page.previous_revision.timestamp.isoformat() }}&b={{ page.timestamp.isoformat() }}">
+                               <span class="fas fa-exchange-alt"></span>
+                       </a>
+               {% end %}
+
                {% if show_changes and page.changes %}
                        &bull; {{ page.changes }}
                {% end %}
index 7db22f576e71dd645968263364973653a5bcbdb6..99afa5ead246a6a25a70d3131c4430218c7b9f06 100644 (file)
@@ -90,6 +90,7 @@ class Application(tornado.web.Application):
                                                       : fireinfo.DeviceAndGroupsTableModule,
 
                                # Wiki
+                               "WikiDiff"             : wiki.WikiDiffModule,
                                "WikiNavbar"           : wiki.WikiNavbarModule,
                                "WikiList"             : wiki.WikiListModule,
 
index 799536142b4bd17fb453d5021e45742e96b44aaf..7adf37566a005991b95e42111866b14b81443136 100644 (file)
@@ -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,