diff --git a/src/wiki.py b/src/wiki.py index 350e178..852886e 100644 --- a/src/wiki.py +++ b/src/wiki.py @@ -110,8 +110,9 @@ class MessageHistory: dbmanager.add(("INSERT INTO rcgcdb_msg_history(message_id, webhook, message_object) VALUES ($1, $2, $3) ON CONFLICT (message_id) DO UPDATE SET message_object = $3;", (stacked_message.discord_callback_message_id, stacked_message.webhook, pickle.dumps(stacked_message)))) for stack_id, message in enumerate(stacked_message): - dbmanager.add(("INSERT INTO rcgcdb_msg_metadata(message_id, log_id, page_id, rev_id, message_display, stacked_index) VALUES ($1, $2, $3, $4, $5, $6);", - (stacked_message.discord_callback_message_id, *message.metadata.dump_ids(), stack_id))) + dbmanager.add(("INSERT INTO rcgcdb_msg_metadata(message_id, log_id, page_id, rev_id, message_display, timestamp, stacked_index) VALUES ($1, $2, $3, $4, $5, $6, $7);", + (stacked_message.discord_callback_message_id, *message.metadata.dump_ids(), + message.metadata.time_of_change.strftime('%Y%m%d%H%M%S') if message.metadata.time_of_change is not None else None, stack_id))) class Wiki: @@ -232,6 +233,35 @@ class Wiki: else: messagequeue.add_message(QueueEntry(stacked_message, [webhook], self, method="PATCH")) + async def redact_images(self, context: Context, ids: list[int] | set[int], censored_properties: dict, page_id=None): + async with db.pool().acquire() as connection: + async with connection.transaction(): + for event_id in ids: + async for db_record in connection.cursor( + f"SELECT rcgcdb_msg_history.message_id, rcgcdb_msg_history.webhook, message_object FROM rcgcdb_msg_history INNER JOIN rcgcdb_msg_metadata ON rcgcdb_msg_metadata.message_id = rcgcdb_msg_history.message_id INNER JOIN rcgcdb ON rcgcdb_msg_history.webhook = rcgcdb.webhook WHERE rcgcdb_msg_metadata.timestamp < $1 AND rcgcdb_msg_metadata.page_id = $2", event_id, page_id): + try: + stacked_message: StackedDiscordMessage = pickle.loads(db_record["message_object"]) + except ValueError: + logger.error("Couldn't loads JSON for message data. What happened? Data: {}".format(row[0])) + return + except TypeError: + logger.error( + "Couldn't find entry in the database for RevDel to censor information. This is probably because the script has been recently restarted or cache cleared.") + return + for message in [message for message in stacked_message.message_list if + message.metadata.matches({"page_id": page_id, "message_display": [2, 3]})]: + if "user" in censored_properties and "url" in message["author"]: + message["author"]["name"] = context._("hidden") + message["author"].pop("url") + if "content" in censored_properties and "image" in message: + message.embed.pop("image") + if "comment" in censored_properties: + message["description"] = context._("~~hidden~~") + logger.debug( + f"Rev-deleting contents of message {stacked_message.discord_callback_message_id} due to being in list of ids {ids}.") + messagequeue.add_message( + QueueEntry(stacked_message, [stacked_message.webhook], self, method="PATCH")) + async def redact_messages(self, context: Context, ids: list[int] | set[int], mode: str, censored_properties: dict, page_id=None): # ids can refer to multiple events, and search does not support additive mode, so we have to loop it for all ids async for stacked_message, webhook in self.message_history.fetch_stacked_from_db({mode: ids, "message_display": [1, 2, 3]}): @@ -528,6 +558,13 @@ class Wiki: await send_to_discord_webhook(dc_msg, webhook, "POST") except: logger.exception("Webhook removal send_reason failure.") + header = settings["header"] + header["X-Audit-Log-Reason"] = reason if reason else "Unknown reason" + async with aiohttp.ClientSession(headers=header, timeout=aiohttp.ClientTimeout(total=6)) as session: + for combination, webhooks in rc_targets_long_lived.items(): + for webhook in webhooks: + async with session.delete(f"https://discord.com/api/webhooks/{webhook}") as resp: + pass async def fetch_discussions(self, params: dict) -> tuple[aiohttp.ClientResponse, dict]: @@ -649,7 +686,10 @@ async def rc_processor(wiki: Wiki, change: dict, changed_categories: dict, displ await wiki.delete_messages(dict(log_id=[int(x) for x in logparams.get("ids", [])], message_display=0)) elif identification_string == "delete/revision": logparams = change.get('logparams', {"ids": []}) - await wiki.redact_messages(context, logparams.get("ids", []), "rev_id", logparams.get("new", {}), page_id=change.get("pageid", -1)) + if logparams.get("type", "") == "oldimage": + await wiki.redact_images(context, logparams.get("ids", []), logparams.get("new", {}), page_id=change.get("pageid", -1)) + else: + await wiki.redact_messages(context, logparams.get("ids", []), "rev_id", logparams.get("new", {}), page_id=change.get("pageid", -1)) await wiki.delete_messages(dict(rev_id=[int(x) for x in logparams.get("ids", [])], message_display=0)) run_hooks(post_hooks, discord_message, metadata, context, change) await asyncio.sleep(wiki.request_cost*0.5) # Await amount of time due to additional requests made in the formatters