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 \
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
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:
@property
def markdown(self):
- return self.data.markdown
+ return self.data.markdown or ""
@property
def html(self):
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
--- /dev/null
+{% 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">
+ »
+ </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 %}
--- /dev/null
+<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 %} {% end %}</td>
+ </tr>
+ {% end %}
+ {% end %}
+ </tbody>
+</table>
<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 %}
• {{ page.changes }}
{% end %}
: fireinfo.DeviceAndGroupsTableModule,
# Wiki
+ "WikiDiff" : wiki.WikiDiffModule,
"WikiNavbar" : wiki.WikiNavbarModule,
"WikiList" : wiki.WikiListModule,
#!/usr/bin/python3
+import difflib
import tornado.web
from . import auth
# 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)
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,