diff --git a/src/discussion_formatters.py b/src/discussion_formatters.py index 1a6071b..dd4aa81 100644 --- a/src/discussion_formatters.py +++ b/src/discussion_formatters.py @@ -4,7 +4,7 @@ import gettext from urllib.parse import quote_plus from src.configloader import settings -from src.misc import link_formatter, create_article_path, DiscordMessage, send_to_discord, escape_formatting +from src.misc import link_formatter, create_article_path, DiscordMessage, send_to_discord, escape_formatting, DiscordMessageMetadata from src.i18n import discussion_formatters _ = discussion_formatters.gettext @@ -67,7 +67,7 @@ def compact_formatter(post_type, post, article_paths): else: message = "❓ "+_("Unknown event `{event}` by [{author}]({author_url}), report it on the [support server](<{support}>).").format( event=post_type, author=author, author_url=author_url, support=settings["support"]) - send_to_discord(DiscordMessage("compact", "discussion", settings["fandom_discussions"]["webhookURL"], content=message), meta={"request_type": "POST"}) + send_to_discord(DiscordMessage("compact", "discussion", settings["fandom_discussions"]["webhookURL"], content=message), meta=DiscordMessageMetadata("POST")) def embed_formatter(post_type, post, article_paths): @@ -168,7 +168,7 @@ def embed_formatter(post_type, post, article_paths): else: embed.add_field(_("Report this on the support server"), change_params) embed.finish_embed() - send_to_discord(embed, meta={"request_type": "POST"}) + send_to_discord(embed, meta=DiscordMessageMetadata("POST")) class DiscussionsFromHellParser: diff --git a/src/message_redaction.py b/src/message_redaction.py index b27a338..df6e157 100644 --- a/src/message_redaction.py +++ b/src/message_redaction.py @@ -1,5 +1,5 @@ from src.configloader import settings -from src.misc import send_to_discord +from src.misc import send_to_discord, DiscordMessageMetadata import logging logger = logging.getLogger("rcgcdw.message_redaction") import sqlite3 @@ -44,10 +44,12 @@ def add_entry(pageid: int, revid: int, logid: int, message): def delete_messages(pageid: int): to_delete = db_cursor.execute("SELECT msg_id FROM event WHERE pageid = ?", (pageid)) + msg_to_remove = [] for message in to_delete: webhook_url = "{main_webhook}/messages/{message_id}".format(main_webhook=settings["webhookURL"], message_id=message[0]) - send_to_discord(None, {"request_type": "DELETE", "webhook_url": webhook_url}) - db_cursor.executemany("DELETE FROM messages WHERE message_id = ?", list_of_messageids) + msg_to_remove.append(message[0]) + send_to_discord(None, DiscordMessageMetadata("DELETE", webhook_url=webhook_url)) + db_cursor.executemany("DELETE FROM messages WHERE message_id = ?", msg_to_remove) def redact_messages(rev_ids: list, to_censor: dict): diff --git a/src/misc.py b/src/misc.py index b8ddf63..041c795 100644 --- a/src/misc.py +++ b/src/misc.py @@ -25,6 +25,10 @@ from src.configloader import settings from src.i18n import misc from typing import Optional +AUTO_SUPPRESSION_ENABLED = settings.get("auto_suppression", {"enabled": True}).get("enabled") +if AUTO_SUPPRESSION_ENABLED: + from src.message_redaction import add_entry as add_message_redaction_entry + _ = misc.gettext # Create a custom logger @@ -326,7 +330,7 @@ def send_simple(msgtype, message, name, avatar): discord_msg.set_avatar(avatar) discord_msg.set_name(name) messagequeue.resend_msgs() - send_to_discord(discord_msg, meta={"request_type": "POST"}) + send_to_discord(discord_msg, meta=DiscordMessageMetadata("POST")) def update_ratelimit(request): @@ -413,23 +417,41 @@ def profile_field_name(name, embed): return _("unknown") -def send_to_discord_webhook(data: Optional[DiscordMessage], metadata: dict = None): +class DiscordMessageMetadata: + def __init__(self, method, log_id = None, page_id = None, rev_id = None, webhook_url = None, new_data = None): + self.method = method + self.page_id = page_id + self.log_id = log_id + self.rev_id = rev_id + self.webhook_url = webhook_url + self.new_data = new_data + + def dump_ids(self): + return self.page_id, self.rev_id, self.log_id + +def send_to_discord_webhook(data: Optional[DiscordMessage], metadata: DiscordMessageMetadata): global rate_limit header = settings["header"] header['Content-Type'] = 'application/json' standard_args = dict(headers=header, timeout=10) - if metadata["request_type"] == "POST": - req = requests.Request("POST", data.webhook_url+"?wait=" + "true" if settings.get("auto_suppression", {"enabled": True}).get("enabled") else "false", data=repr(data), **standard_args) - elif metadata["request_type"] == "DELETE": - req = requests.Request("DELETE", metadata["webhook_url"], **standard_args) - elif metadata["request_type"] == "PATCH": - req = requests.Request("PATCH", metadata["webhook_url"], data=metadata["new_data"], **standard_args) + if metadata.method == "POST": + req = requests.Request("POST", data.webhook_url+"?wait=" + "true" if AUTO_SUPPRESSION_ENABLED else "false", data=repr(data), **standard_args) + elif metadata.method == "DELETE": + req = requests.Request("DELETE", metadata.webhook_url, **standard_args) + elif metadata.method == "PATCH": + req = requests.Request("PATCH", metadata.webhook_url, data=metadata.new_data, **standard_args) try: time.sleep(rate_limit) rate_limit = 0 req = req.prepare() result = req.send() update_ratelimit(result) + if AUTO_SUPPRESSION_ENABLED: + # TODO Prepare request with all of safety checks + try: + add_message_redaction_entry(*metadata.dump_ids(), result.json()) + except ValueError: + misc_logger.error("Couldn't get json of result of sending Discord message.") except requests.exceptions.Timeout: misc_logger.warning("Timeouted while sending data to the webhook.") return 3 @@ -440,7 +462,7 @@ def send_to_discord_webhook(data: Optional[DiscordMessage], metadata: dict = Non return handle_discord_http(result.status_code, data, result) -def send_to_discord(data: Optional[DiscordMessage], meta: dict): +def send_to_discord(data: Optional[DiscordMessage], meta: DiscordMessageMetadata): if data is not None: for regex in settings["disallow_regexes"]: if data.webhook_object.get("content", None): diff --git a/src/rc_formatters.py b/src/rc_formatters.py index f952c56..fa68065 100644 --- a/src/rc_formatters.py +++ b/src/rc_formatters.py @@ -11,7 +11,7 @@ from bs4 import BeautifulSoup from src.configloader import settings from src.misc import link_formatter, create_article_path, WIKI_SCRIPT_PATH, send_to_discord, DiscordMessage, safe_read, \ - WIKI_API_PATH, ContentParser, profile_field_name, LinkParser + WIKI_API_PATH, ContentParser, profile_field_name, LinkParser, DiscordMessageMetadata from src.message_redaction import delete_messages, redact_messages from src.i18n import rc_formatters #from src.rc import recent_changes, pull_comment @@ -63,10 +63,11 @@ def compact_abuselog_formatter(change, recent_changes): action=abusefilter_actions.get(change["action"], _("Unknown")), target=change.get("title", _("Unknown")), target_url=create_article_path(change.get("title", _("Unknown"))), result=abusefilter_results.get(change["result"], _("Unknown"))) - send_to_discord(DiscordMessage("compact", action, settings["webhookURL"], content=message), meta={"request_type": "POST"}) + send_to_discord(DiscordMessage("compact", action, settings["webhookURL"], content=message), meta=DiscordMessageMetadata("POST")) def compact_formatter(action, change, parsed_comment, categories, recent_changes): + request_metadata = DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None), page_id=change.get("pageid", None)) if action != "suppressed": author_url = link_formatter(create_article_path("User:{user}".format(user=change["user"]))) author = change["user"] @@ -404,7 +405,7 @@ def compact_formatter(action, change, parsed_comment, categories, recent_changes content = "❓ "+_( "Unknown event `{event}` by [{author}]({author_url}), report it on the [support server](<{support}>).").format( event=action, author=author, author_url=author_url, support=settings["support"]) - send_to_discord(DiscordMessage("compact", action, settings["webhookURL"], content=content), meta={"request_type": "POST"}) + send_to_discord(DiscordMessage("compact", action, settings["webhookURL"], content=content), meta=request_metadata) def embed_abuselog_formatter(change, recent_changes): action = "abuselog/{}".format(change["result"]) @@ -416,11 +417,12 @@ def embed_abuselog_formatter(change, recent_changes): embed.add_field(_("Action taken"), abusefilter_results.get(change["result"], _("Unknown"))) embed.add_field(_("Title"), change.get("title", _("Unknown"))) embed.finish_embed() - send_to_discord(embed, meta={"request_type": "POST"}) + send_to_discord(embed, meta=DiscordMessageMetadata("POST")) def embed_formatter(action, change, parsed_comment, categories, recent_changes): embed = DiscordMessage("embed", action, settings["webhookURL"]) + request_metadata = DiscordMessageMetadata("POST", rev_id=change.get("revid", None), log_id=change.get("logid", None), page_id=change.get("pageid", None)) if parsed_comment is None: parsed_comment = _("No description provided") if action != "suppressed": @@ -890,4 +892,4 @@ def embed_formatter(action, change, parsed_comment, categories, recent_changes): del_cat = (_("**Removed**: ") + ", ".join(list(categories["removed"])[0:16]) + ("" if len(categories["removed"])<=15 else _(" and {} more").format(len(categories["removed"])-15))) if categories["removed"] else "" embed.add_field(_("Changed categories"), new_cat + del_cat) embed.finish_embed() - send_to_discord(embed, meta={"request_type": "POST"}) + send_to_discord(embed, meta=request_metadata) diff --git a/src/rcgcdw.py b/src/rcgcdw.py index 2a52d33..1b6025e 100644 --- a/src/rcgcdw.py +++ b/src/rcgcdw.py @@ -27,7 +27,7 @@ from collections import defaultdict, Counter from src.configloader import settings from src.misc import add_to_dict, datafile, \ WIKI_API_PATH, create_article_path, send_to_discord, \ - DiscordMessage + DiscordMessage, DiscordMessageMetadata from src.rc import recent_changes from src.exceptions import MWError from src.i18n import rcgcdw @@ -202,7 +202,7 @@ def day_overview(): for name, value in fields: embed.add_field(name, value, inline=True) embed.finish_embed() - send_to_discord(embed, meta={"request_type": "POST"}) + send_to_discord(embed, meta=DiscordMessageMetadata("POST")) else: logger.debug("function requesting changes for day overview returned with error code")