diff options
| -rw-r--r-- | pysite/views/wiki/delete.py | 2 | ||||
| -rw-r--r-- | pysite/views/wiki/move.py | 86 | ||||
| -rw-r--r-- | templates/wiki/base.html | 14 | ||||
| -rw-r--r-- | templates/wiki/page_delete.html | 33 | ||||
| -rw-r--r-- | templates/wiki/page_move.html | 26 | 
5 files changed, 143 insertions, 18 deletions
| diff --git a/pysite/views/wiki/delete.py b/pysite/views/wiki/delete.py index 0e3bcbbf..47759a87 100644 --- a/pysite/views/wiki/delete.py +++ b/pysite/views/wiki/delete.py @@ -10,7 +10,7 @@ from pysite.decorators import csrf, require_roles  from pysite.mixins import DBMixin -class EditView(RouteView, DBMixin): +class DeleteView(RouteView, DBMixin):      path = "/delete/<path:page>"  # "path" means that it accepts slashes      name = "delete"      table_name = "wiki" diff --git a/pysite/views/wiki/move.py b/pysite/views/wiki/move.py new file mode 100644 index 00000000..081ae56a --- /dev/null +++ b/pysite/views/wiki/move.py @@ -0,0 +1,86 @@ +import datetime + +import requests +from flask import redirect, url_for, request +from werkzeug.exceptions import NotFound, BadRequest + +from pysite.base_route import RouteView +from pysite.constants import EDITOR_ROLES, WIKI_AUDIT_WEBHOOK +from pysite.decorators import csrf, require_roles +from pysite.mixins import DBMixin + + +class MoveView(RouteView, DBMixin): +    path = "/move/<path:page>"  # "path" means that it accepts slashes +    name = "move" +    table_name = "wiki" +    revision_table_name = "wiki_revisions" + +    @require_roles(*EDITOR_ROLES) +    def get(self, page): +        obj = self.db.get(self.table_name, page) + +        if obj: +            title = obj.get("title", "") + +            if obj.get("lock_expiry") and obj.get("lock_user") != self.user_data.get("user_id"): +                lock_time = datetime.datetime.fromtimestamp(obj["lock_expiry"]) +                if datetime.datetime.utcnow() < lock_time: +                    return self.render("wiki/page_in_use.html", page=page) + +            return self.render("wiki/page_move.html", page=page, title=title) +        else: +            raise NotFound() + +    @require_roles(*EDITOR_ROLES) +    @csrf +    def post(self, page): +        location = request.form.get("location") + +        if not location or not location.strip(): +            raise BadRequest() + +        obj = self.db.get(self.table_name, page) + +        if not obj: +            raise NotFound() + +        title = obj.get("title", "") +        other_obj = self.db.get(self.table_name, location) + +        if other_obj: +            return self.render( +                "wiki/page_move.html", page=page, title=title, +                message=f"There's already a page at {location} - please pick a different location" +            ) + +        self.db.delete(self.table_name, page) + +        obj["slug"] = location + +        self.db.insert(self.table_name, obj, conflict="update") + +        self.audit_log(obj) + +        return redirect(url_for("wiki.page", page=location), code=303)  # Redirect, ensuring a GET + +    def audit_log(self, obj): +        if WIKI_AUDIT_WEBHOOK:  # If the audit webhook is not configured there is no point processing it +            audit_payload = { +                "username": "Wiki Updates", +                "embeds": [ +                    { +                        "title": "Page Move", +                        "description": f"**{obj['title']}** was moved by " +                                       f"**{self.user_data.get('username')}** to " +                                       f"**{obj['slug']}**", +                        "color": 4165079, +                        "timestamp": datetime.datetime.utcnow().isoformat(), +                        "thumbnail": { +                            "url": "https://pythondiscord.com/static/logos/logo_discord.png" +                        } +                    } +                ] +            } + +            requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) diff --git a/templates/wiki/base.html b/templates/wiki/base.html index eec0ecb8..a71f09e6 100644 --- a/templates/wiki/base.html +++ b/templates/wiki/base.html @@ -104,6 +104,20 @@                                  </li>                              {% endif %} +                            {% if current_page == "move" %} +                                <li> +                                    <a href="{{ url_for("wiki.page", page=page) }}"> +                                        <i class="uk-icon fas fa-fw fa-arrow-left"></i>  Back +                                    </a> +                                </li> +                            {% else %} +                                <li> +                                    <a href="{{ url_for("wiki.move", page=page) }}"> +                                        <i class="uk-icon fas fa-fw fa-arrow-right"></i>  Move +                                    </a> +                                </li> +                            {% endif %} +                              {% if current_page == "history.show" %}                                  <li>                                      <a href="{{ url_for("wiki.page", page=page) }}"> diff --git a/templates/wiki/page_delete.html b/templates/wiki/page_delete.html index f4d52653..27c4b406 100644 --- a/templates/wiki/page_delete.html +++ b/templates/wiki/page_delete.html @@ -2,25 +2,24 @@  {% block title %}Wiki | Delete: {{ page }}{% endblock %}  {% block og_title %}Wiki | Delete: {{ page }}{% endblock %}  {% block og_description %}{% endblock %} -{% block extra_head %} -<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.3.3/ace.js" type="application/javascript"></script> -{% endblock %}  {% block content %} -    <div uk-alert class="uk-alert-danger"> -        <h3>Delete Page: {{ page }}</h3> -        <p> -            Are you sure you want to delete this page? -        </p> +    <div class="uk-container uk-container-small"> +        <div uk-alert class="uk-alert-danger"> +            <h3>Delete Page: {{ page }}</h3> +            <p> +                Are you sure you want to delete this page? +            </p> -        <form uk-grid class="uk-grid-small" action="{{ url_for("wiki.delete", page=page) }}" method="post"> -            <div class="uk-width-1-2"> -                <a href="{{ url_for("wiki.page", page=page) }}" class="uk-button uk-button-primary uk-width-1-1" type="button" value="Cancel" id="cancel">Cancel</a> -            </div> -            <div class="uk-width-1-2"> -                <input class="uk-button uk-button-secondary uk-width-1-1" type="submit" id="delete" value="Delete" /> -            </div> +            <form uk-grid class="uk-grid-small" action="{{ url_for("wiki.delete", page=page) }}" method="post"> +                <div class="uk-width-1-2"> +                    <a href="{{ url_for("wiki.page", page=page) }}" class="uk-button uk-button-primary uk-width-1-1" type="button" id="cancel">Cancel</a> +                </div> +                <div class="uk-width-1-2"> +                    <input class="uk-button uk-button-secondary uk-width-1-1" type="submit" id="delete" value="Delete" /> +                </div> -            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> -        </form> +                <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> +            </form> +        </div>      </div>  {% endblock %} diff --git a/templates/wiki/page_move.html b/templates/wiki/page_move.html new file mode 100644 index 00000000..e2d52807 --- /dev/null +++ b/templates/wiki/page_move.html @@ -0,0 +1,26 @@ +{% extends "wiki/base.html" %} +{% block title %}Wiki | Move: {{ page }}{% endblock %} +{% block og_title %}Wiki | Move: {{ page }}{% endblock %} +{% block og_description %}{% endblock %} +{% block content %} +    <div class="uk-container uk-container-small"> +        {% if message is defined %} +        <div uk-alert class="uk-alert-danger"> +            <p>{{ message }}</p> +        </div> +        {% endif %} + +        <h3>Move Page: {{ page }}</h3> +        <form uk-grid class="uk-grid-small" action="{{ url_for("wiki.move", page=page) }}" method="post"> +            <input type="text" class="uk-width-1-1 uk-input" placeholder="{{ page }}" id="location" name="location" style="margin-left: 15px;" required> +            <div class="uk-width-1-2"> +                <a href="{{ url_for("wiki.page", page=page) }}" class="uk-button uk-button-primary uk-width-1-1" type="button" id="cancel">Cancel</a> +            </div> +            <div class="uk-width-1-2"> +                <input class="uk-button uk-button-secondary uk-width-1-1" type="submit" id="move" value="Move" /> +            </div> + +            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> +        </form> +    </div> +{% endblock %} | 
