aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/views/wiki/history/compare.py
blob: 6296f73424b90602d632ca4e41bdab3ad5227f2b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import difflib

from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import DiffLexer
from werkzeug.exceptions import BadRequest, NotFound

from pysite.base_route import RouteView
from pysite.constants import DEBUG_MODE, EDITOR_ROLES
from pysite.mixins import DBMixin


class CompareView(RouteView, DBMixin):
    path = "/history/compare/<string:first_rev>/<string:second_rev>"
    name = "history.compare"

    table_name = "wiki_revisions"
    table_primary_key = "id"

    def get(self, first_rev, second_rev):
        before = self.db.get(self.table_name, first_rev)
        after = self.db.get(self.table_name, second_rev)

        if not (before and after):
            raise NotFound()

        if before["date"] > after["date"]:  # Check whether the before was created after the after
            raise BadRequest()

        if before["id"] == after["id"]:  # The same revision has been requested
            raise BadRequest()

        before_text = before["post"]["rst"]
        after_text = after["post"]["rst"]

        if not before_text.endswith("\n"):
            before_text += "\n"

        if not after_text.endswith("\n"):
            after_text += "\n"

        before_text = before_text.splitlines(keepends=True)
        after_text = after_text.splitlines(keepends=True)

        if not before["slug"] == after["slug"]:
            raise BadRequest()  # The revisions are not from the same post

        diff = difflib.unified_diff(before_text, after_text, fromfile=f"{first_rev}.rst", tofile=f"{second_rev}.rst")
        diff = "".join(diff)
        diff = highlight(diff, DiffLexer(), HtmlFormatter())
        return self.render("wiki/compare_revision.html",
                           title=after["post"]["title"],
                           diff=diff, slug=before["slug"],
                           can_edit=self.is_staff())

    def is_staff(self):
        if DEBUG_MODE:
            return True
        if not self.logged_in:
            return False

        roles = self.user_data.get("roles", [])

        for role in roles:
            if role in EDITOR_ROLES:
                return True

        return False