diff options
| -rw-r--r-- | pysite/decorators.py | 2 | ||||
| -rw-r--r-- | pysite/views/wiki/edit.py | 14 | ||||
| -rw-r--r-- | pysite/views/wiki/page.py | 2 | ||||
| -rw-r--r-- | pysite/views/wiki/render.py | 34 | ||||
| -rw-r--r-- | templates/wiki/page_edit.html | 46 | 
5 files changed, 91 insertions, 7 deletions
| diff --git a/pysite/decorators.py b/pysite/decorators.py index 653489b4..426d4846 100644 --- a/pysite/decorators.py +++ b/pysite/decorators.py @@ -34,7 +34,7 @@ def require_roles(*roles: int):              if data:                  for role in roles: -                    if role in data["roles"]: +                    if role in data.get("roles", []):                          return f(self, *args, **kwargs)                  if isinstance(self, APIView): diff --git a/pysite/views/wiki/edit.py b/pysite/views/wiki/edit.py index 8f6c22e3..23a281dc 100644 --- a/pysite/views/wiki/edit.py +++ b/pysite/views/wiki/edit.py @@ -1,5 +1,5 @@  # coding=utf-8 -from flask import url_for +from flask import url_for, request  from werkzeug.utils import redirect  from pysite.base_route import RouteView @@ -17,9 +17,19 @@ class EditView(RouteView, DBMixin):      @require_roles(*ALL_STAFF_ROLES)      def get(self, page): -        return self.render("wiki/page_edit.html", page=page) +        rst = "" +        title = "" + +        obj = self.db.get(self.table_name, page) + +        if obj: +            rst = obj["rst"] +            title = obj["title"] + +        return self.render("wiki/page_edit.html", page=page, rst=rst, title=title)      @require_roles(*ALL_STAFF_ROLES)      @csrf      def post(self, page): +        rst = request.form["rst"]          return redirect(url_for("wiki.page", page=page), code=303)  # Redirect, ensuring a GET diff --git a/pysite/views/wiki/page.py b/pysite/views/wiki/page.py index eb4c2429..01c8fa8a 100644 --- a/pysite/views/wiki/page.py +++ b/pysite/views/wiki/page.py @@ -27,7 +27,7 @@ class PageView(RouteView, DBMixin):          if not self.logged_in:              return False -        roles = self.user_data["roles"] +        roles = self.user_data.get("roles", [])          for role in roles:              if role in ALL_STAFF_ROLES: diff --git a/pysite/views/wiki/render.py b/pysite/views/wiki/render.py new file mode 100644 index 00000000..01b5e6fa --- /dev/null +++ b/pysite/views/wiki/render.py @@ -0,0 +1,34 @@ +# coding=utf-8 +from docutils.core import publish_parts +from flask import jsonify +from schema import Schema + +from pysite.base_route import APIView +from pysite.constants import ALL_STAFF_ROLES, ValidationTypes +from pysite.decorators import csrf, require_roles, api_params + +SCHEMA = Schema([{ +    "data": str +}]) + + +class RenderView(APIView): +    path = "/render"  # "path" means that it accepts slashes +    name = "render" + +    @csrf +    @require_roles(*ALL_STAFF_ROLES) +    @api_params(schema=SCHEMA, validation_type=ValidationTypes.json) +    def post(self, data): +        if not len(data): +            return jsonify({"error": "No data!"}) + +        data = data[0]["data"] +        try: +            html = publish_parts( +                source=data, writer_name="html5", settings_overrides={"traceback": True, "halt_level": 2} +            )["html_body"] + +            return jsonify({"data": html}) +        except Exception as e: +            return jsonify({"error": str(e)}) diff --git a/templates/wiki/page_edit.html b/templates/wiki/page_edit.html index 5601cbbf..97a5161c 100644 --- a/templates/wiki/page_edit.html +++ b/templates/wiki/page_edit.html @@ -4,8 +4,48 @@  {% block og_description %}Landing page for the wiki{% endblock %}  {% block content %}      <div class="uk-container uk-section"> -    <h1 class="uk-title uk-text-center"> -        Placeholder text. -    </h1> +        <form action="{{ url_for("wiki.edit", page=page) }}" method="post"> +            <label for="title">Title: </label> +            <input name="title" id="title" value="{{ title }}" class="uk-input" /> +            <label for="rst">Document: </label> +            <textarea name="rst" id="rst" class="uk-textarea">{{ rst }}</textarea> +            <button value="Preview" id="preview">Preview</button> +            <button type="submit" value="Save">Save</button> +            <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> +        </form> + +        <div id="preview-div" style="border: 1px solid grey;"> +            <p>Preview will appear here.</p> +        </div>      </div> + +    <script type="application/javascript"> +        "use strict"; + +        let csrf_token = "{{ csrf_token() }}"; + +        document.getElementById("preview").onclick = function(event) { +            let oReq = new XMLHttpRequest(); +            let data = document.getElementById("rst").value; + +            oReq.addEventListener("load", function() { +                let response = JSON.parse(this.responseText); + +                if (response.error !== undefined) { +                    console.log("Error: " + response.error) +                } else { +                    document.getElementById("preview-div").innerHTML = response.data; +                } +            }); + +            oReq.open("POST", "/render"); + +            oReq.setRequestHeader("Content-type", "application/json"); +            oReq.setRequestHeader("X-CSRFToken", csrf_token); + +            oReq.send(JSON.stringify({"data": data})); + +            return false; +        } +    </script>  {% endblock %}
\ No newline at end of file | 
