werkzeug

Форк
0
203 строки · 6.4 Кб
1
"""The per page actions. The actions are defined in the URL with the
2
``action`` parameter and directly dispatched to the functions in this
3
module. In the module the actions are prefixed with '`on_`', so be
4
careful not to name any other objects in the module with the same prefix
5
unless you want to act them as actions.
6
"""
7
from difflib import unified_diff
8

9
from werkzeug.utils import redirect
10

11
from .database import Page
12
from .database import Revision
13
from .database import RevisionedPage
14
from .database import session
15
from .utils import format_datetime
16
from .utils import generate_template
17
from .utils import href
18
from .utils import Response
19

20

21
def on_show(request, page_name):
22
    """Displays the page the user requests."""
23
    revision_id = request.args.get("rev", type=int)
24
    query = RevisionedPage.query.filter_by(name=page_name)
25
    if revision_id:
26
        query = query.filter_by(revision_id=revision_id)
27
        revision_requested = True
28
    else:
29
        query = query.order_by(RevisionedPage.revision_id.desc())
30
        revision_requested = False
31
    page = query.first()
32
    if page is None:
33
        return page_missing(request, page_name, revision_requested)
34
    return Response(generate_template("action_show.html", page=page))
35

36

37
def on_edit(request, page_name):
38
    """Edit the current revision of a page."""
39
    change_note = error = ""
40
    revision = (
41
        Revision.query.filter(
42
            (Page.name == page_name) & (Page.page_id == Revision.page_id)
43
        )
44
        .order_by(Revision.revision_id.desc())
45
        .first()
46
    )
47
    if revision is None:
48
        page = None
49
    else:
50
        page = revision.page
51

52
    if request.method == "POST":
53
        text = request.form.get("text")
54
        if request.form.get("cancel") or revision and revision.text == text:
55
            return redirect(href(page.name))
56
        elif not text:
57
            error = "You cannot save empty revisions."
58
        else:
59
            change_note = request.form.get("change_note", "")
60
            if page is None:
61
                page = Page(page_name)
62
                session.add(page)
63
            session.add(Revision(page, text, change_note))
64
            session.commit()
65
            return redirect(href(page.name))
66

67
    return Response(
68
        generate_template(
69
            "action_edit.html",
70
            revision=revision,
71
            page=page,
72
            new=page is None,
73
            page_name=page_name,
74
            change_note=change_note,
75
            error=error,
76
        )
77
    )
78

79

80
def on_log(request, page_name):
81
    """Show the list of recent changes."""
82
    page = Page.query.filter_by(name=page_name).first()
83
    if page is None:
84
        return page_missing(request, page_name, False)
85
    return Response(generate_template("action_log.html", page=page))
86

87

88
def on_diff(request, page_name):
89
    """Show the diff between two revisions."""
90
    old = request.args.get("old", type=int)
91
    new = request.args.get("new", type=int)
92
    error = ""
93
    diff = page = old_rev = new_rev = None
94

95
    if not (old and new):
96
        error = "No revisions specified."
97
    else:
98
        revisions = {
99
            x.revision_id: x
100
            for x in Revision.query.filter(
101
                (Revision.revision_id.in_((old, new)))
102
                & (Revision.page_id == Page.page_id)
103
                & (Page.name == page_name)
104
            )
105
        }
106
        if len(revisions) != 2:
107
            error = "At least one of the revisions requested does not exist."
108
        else:
109
            new_rev = revisions[new]
110
            old_rev = revisions[old]
111
            page = old_rev.page
112
            diff = unified_diff(
113
                f"{old_rev.text}\n".splitlines(True),
114
                f"{new_rev.text}\n".splitlines(True),
115
                page.name,
116
                page.name,
117
                format_datetime(old_rev.timestamp),
118
                format_datetime(new_rev.timestamp),
119
                3,
120
            )
121

122
    return Response(
123
        generate_template(
124
            "action_diff.html",
125
            error=error,
126
            old_revision=old_rev,
127
            new_revision=new_rev,
128
            page=page,
129
            diff=diff,
130
        )
131
    )
132

133

134
def on_revert(request, page_name):
135
    """Revert an old revision."""
136
    rev_id = request.args.get("rev", type=int)
137

138
    old_revision = page = None
139
    error = "No such revision"
140

141
    if request.method == "POST" and request.form.get("cancel"):
142
        return redirect(href(page_name))
143

144
    if rev_id:
145
        old_revision = Revision.query.filter(
146
            (Revision.revision_id == rev_id)
147
            & (Revision.page_id == Page.page_id)
148
            & (Page.name == page_name)
149
        ).first()
150
        if old_revision:
151
            new_revision = (
152
                Revision.query.filter(
153
                    (Revision.page_id == Page.page_id) & (Page.name == page_name)
154
                )
155
                .order_by(Revision.revision_id.desc())
156
                .first()
157
            )
158
            if old_revision == new_revision:
159
                error = "You tried to revert the current active revision."
160
            elif old_revision.text == new_revision.text:
161
                error = (
162
                    "There are no changes between the current "
163
                    "revision and the revision you want to "
164
                    "restore."
165
                )
166
            else:
167
                error = ""
168
                page = old_revision.page
169
                if request.method == "POST":
170
                    change_note = request.form.get("change_note", "")
171

172
                    if change_note:
173
                        change_note = f"revert: {change_note}"
174
                    else:
175
                        change_note = "revert"
176

177
                    session.add(Revision(page, old_revision.text, change_note))
178
                    session.commit()
179
                    return redirect(href(page_name))
180

181
    return Response(
182
        generate_template(
183
            "action_revert.html", error=error, old_revision=old_revision, page=page
184
        )
185
    )
186

187

188
def page_missing(request, page_name, revision_requested, protected=False):
189
    """Displayed if page or revision does not exist."""
190
    return Response(
191
        generate_template(
192
            "page_missing.html",
193
            page_name=page_name,
194
            revision_requested=revision_requested,
195
            protected=protected,
196
        ),
197
        status=404,
198
    )
199

200

201
def missing_action(request, action):
202
    """Displayed if a user tried to access a action that does not exist."""
203
    return Response(generate_template("missing_action.html", action=action), status=404)
204

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.