diff options
Diffstat (limited to 'pysite')
-rw-r--r-- | pysite/constants.py | 8 | ||||
-rw-r--r-- | pysite/views/wiki/delete.py | 32 | ||||
-rw-r--r-- | pysite/views/wiki/edit.py | 97 | ||||
-rw-r--r-- | pysite/views/wiki/move.py | 35 |
4 files changed, 56 insertions, 116 deletions
diff --git a/pysite/constants.py b/pysite/constants.py index 3177fe59..016ab9c5 100644 --- a/pysite/constants.py +++ b/pysite/constants.py @@ -101,14 +101,8 @@ JAM_QUESTION_TYPES = [ # CSRF CSRF = CSRFProtect() -# GitHub Token -GITHUB_TOKEN = environ.get("GITHUB_TOKEN") or None - -# Audit Webhook -WIKI_AUDIT_WEBHOOK = environ.get("WIKI_AUDIT_WEBHOOK") or None - # Bot key -BOT_API_KEY = environ.get("BOT_API_KEY") or None +BOT_API_KEY = environ.get("BOT_API_KEY") # RabbitMQ settings BOT_EVENT_QUEUE = "bot_events" diff --git a/pysite/views/wiki/delete.py b/pysite/views/wiki/delete.py index 38d7d087..d6718f64 100644 --- a/pysite/views/wiki/delete.py +++ b/pysite/views/wiki/delete.py @@ -1,16 +1,15 @@ import datetime -import requests from flask import redirect, url_for from werkzeug.exceptions import NotFound from pysite.base_route import RouteView -from pysite.constants import EDITOR_ROLES, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, EDITOR_ROLES from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin -class DeleteView(RouteView, DBMixin): +class DeleteView(RouteView, DBMixin, RMQMixin): path = "/delete/<path:page>" # "path" means that it accepts slashes name = "delete" table_name = "wiki" @@ -53,20 +52,13 @@ class DeleteView(RouteView, DBMixin): return redirect(url_for("wiki.page", page="home"), 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 Deletion", - "description": f"**{obj['title']}** was deleted by **{self.user_data.get('username')}**", - "color": 4165079, - "timestamp": datetime.datetime.utcnow().isoformat(), - "thumbnail": { - "url": "https://pythondiscord.com/static/logos/logo_discord.png" - } - } - ] + self.rmq_bot_event( + BotEventTypes.send_embed, + { + "target": CHANNEL_MOD_LOG, + "title": f"Page Deletion", + "description": f"**{obj['title']}** was deleted by **{self.user_data.get('username')}**", + "color": 0x3F8DD7, # Light blue + "timestamp": datetime.datetime.now().isoformat() } - - requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) + ) diff --git a/pysite/views/wiki/edit.py b/pysite/views/wiki/edit.py index 5f0129c2..76306cf4 100644 --- a/pysite/views/wiki/edit.py +++ b/pysite/views/wiki/edit.py @@ -1,22 +1,20 @@ import datetime -import difflib import html import re -import requests from flask import redirect, request, url_for from werkzeug.exceptions import BadRequest from pysite.base_route import RouteView -from pysite.constants import DEBUG_MODE, EDITOR_ROLES, GITHUB_TOKEN, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, DEBUG_MODE, EDITOR_ROLES from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin from pysite.rst import render STRIP_REGEX = re.compile(r"<[^<]+?>") -class EditView(RouteView, DBMixin): +class EditView(RouteView, DBMixin, RMQMixin): path = "/edit/<path:page>" # "path" means that it accepts slashes name = "edit" table_name = "wiki" @@ -78,8 +76,6 @@ class EditView(RouteView, DBMixin): "headers": rendered["headers"] } - self.audit_log(page, obj) - self.db.insert( self.table_name, obj, @@ -97,7 +93,17 @@ class EditView(RouteView, DBMixin): del revision_payload["post"]["slug"] - self.db.insert(self.revision_table_name, revision_payload) + current_revisions = self.db.filter(self.revision_table_name, lambda rev: rev["slug"] == page) + sorted_revisions = sorted(current_revisions, lambda rev: rev["date"], reverse=True) + + if len(sorted_revisions) > 0: + old_rev = sorted_revisions[0] + else: + old_rev = None + + new_rev = self.db.insert(self.revision_table_name, revision_payload)["generated_keys"][0] + + self.audit_log(page, new_rev, old_rev) return redirect(url_for("wiki.page", page=page), code=303) # Redirect, ensuring a GET @@ -120,63 +126,20 @@ class EditView(RouteView, DBMixin): }, conflict="update") # Update with new lock time return "", 204 - def audit_log(self, page, obj): - if WIKI_AUDIT_WEBHOOK: # If the audit webhook is not configured there is no point processing the diff - before = self.db.get(self.table_name, page) - if not before: # If this is a new page, before will be None - before = [] - else: - if before.get("rst") is None: - before = [] - else: - before = before["rst"].splitlines(keepends=True) - if len(before) == 0: - pass - else: - if not before[-1].endswith("\n"): - before[-1] += "\n" # difflib sometimes messes up if a newline is missing on last line - - after = obj['rst'].splitlines(keepends=True) or [""] - - if not after[-1].endswith("\n"): - after[-1] += "\n" # Does the same thing as L57 - - diff = difflib.unified_diff(before, after, fromfile="before.rst", tofile="after.rst") - diff = "".join(diff) - - gist_payload = { - "description": f"Changes to: {obj['title']}", - "public": False, - "files": { - "changes.md": { - "content": f"```diff\n{diff}\n```" - } - } - } - - headers = { - "Authorization": f"token {GITHUB_TOKEN}", - "User-Agent": "Discord Python Wiki (https://gitlab.com/python-discord)" - } - - gist = requests.post("https://api.github.com/gists", - json=gist_payload, - headers=headers) - - audit_payload = { - "username": "Wiki Updates", - "embeds": [ - { - "title": "Page Edit", - "description": f"**{obj['title']}** was edited by **{self.user_data.get('username')}**" - f".\n\n[View diff]({gist.json().get('html_url')})", - "color": 4165079, - "timestamp": datetime.datetime.utcnow().isoformat(), - "thumbnail": { - "url": "https://pythondiscord.com/static/logos/logo_discord.png" - } - } - ] + def audit_log(self, page, new, old): + if not old: + link = f"https://wiki.pythondiscord.com/source/{page}" + else: + link = f"https://wiki.pythondiscord.com/history/compare/{old['id']}/{new}" + + self.rmq_bot_event( + BotEventTypes.send_embed, + { + "target": CHANNEL_MOD_LOG, + "title": "Page Edit", + "description": f"**{old['post']['title']}** edited by **{self.user_data.get('username')}**. " + f"[View the diff here]({link})", + "color": 0x3F8DD7, # Light blue + "timestamp": datetime.datetime.now().isoformat() } - - requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) + ) diff --git a/pysite/views/wiki/move.py b/pysite/views/wiki/move.py index 93ce8805..35fc5421 100644 --- a/pysite/views/wiki/move.py +++ b/pysite/views/wiki/move.py @@ -1,16 +1,15 @@ import datetime -import requests from flask import redirect, request, url_for from werkzeug.exceptions import BadRequest, NotFound from pysite.base_route import RouteView -from pysite.constants import EDITOR_ROLES, WIKI_AUDIT_WEBHOOK +from pysite.constants import BotEventTypes, CHANNEL_MOD_LOG, EDITOR_ROLES from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin +from pysite.mixins import DBMixin, RMQMixin -class MoveView(RouteView, DBMixin): +class MoveView(RouteView, DBMixin, RMQMixin): path = "/move/<path:page>" # "path" means that it accepts slashes name = "move" table_name = "wiki" @@ -72,22 +71,14 @@ class MoveView(RouteView, DBMixin): 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" - } - } - ] + self.rmq_bot_event( + BotEventTypes.send_embed, + { + "target": CHANNEL_MOD_LOG, + "title": "Wiki Page Move", + "description": f"**{obj['title']}** was moved by **{self.user_data.get('username')}** to " + f"**{obj['slug']}**", + "color": 0x3F8DD7, # Light blue + "timestamp": datetime.datetime.now().isoformat() } - - requests.post(WIKI_AUDIT_WEBHOOK, json=audit_payload) + ) |