Clean Cog Rework#1793
Conversation
new name should be more selfexplanatory
The cog is moderation related and all commands are exclusive to moderators.
Between the concurrency check and setting the cleaning flag to True there was an await statement, which could potentially cause race conditions.The setting of the flag was moved to right below the concurrency check.
Added a cog_command_error method that sets cleaning to False when a command ends on an exception. I don't have anything in mind that might cause this, but it will ensure that in any case the cog will still be usable.
Shivansh-007
left a comment
There was a problem hiding this comment.
Works well and looks great!
wookie184
left a comment
There was a problem hiding this comment.
Looks great, love the new interface and look forward to this being merged 👌, just a couple of comments.
I managed to get this error
bot_1 | 2021-09-19 15:44:56 | bot.exts.backend.error_handler | DEBUG | API responded with 400 for command clean bots: {'deletedmessage_set': [{'author': ['Invalid pk "814417186864496711" - object does not exist.']}, {'author': ['Invalid pk "814417186864496711" - object does not exist.']}, {'author': ['Invalid pk "814417186864496711" - object does not exist.']}]}.
When running !clean bots (don't think the fact it was bots is relevant though) on a webhook. I think 814417186864496711 may have been the message ID, but not completely sue.
Also, when "stress testing" by trying to run a bunch of commands at the same time, I managed to get this error
bot_1 | 2021-09-19 12:56:02 | bot.exts.backend.error_handler | DEBUG | API responded with 400 for command clean all: {'deletedmessage_set': [{}, {}, {'id': ['deleted message with this ID already exists.']}, {'id': ['deleted message with this ID already exists.']}, {}, {}, {}, {}, {}, {}]}.
I'm thinking this one could be because I triggered antispam while running clean commands so clean and antispam were both trying to delete the same messages.
I'm not sure if these errors are particularly relevant to this PR, or should be fixed elsewhere.
Yeah I mentioned this kind or error in the PR description. Honestly not sure how to address it But it makes sense that it's related to a race condition with other commands/cogs. Thanks for looking into it. |
|
I see two possible avenues to handle these errors:
|
I haven't looked into modlog too much yet, but i'd guess we could probably get away with changing site to ignore duplicate keys (or getting bot to handle the errors site raises because of this). That would probably be the easiest option anyway, I wouldn't mind a cache but it would be nice not to have to add one, especially since this is something that would probably happen so rarely. I think the webhook-related error I posted is separate though, as webhooks don't have authors it might just be that site just isn't built to handle them at the moment, not sure. |
|
I'll leave handling the 400 errors to a separate PR (probably on the site repo). As far as I can see those are bugs which already exist in prod. |
wookie184
left a comment
There was a problem hiding this comment.
LGTM
Some of the line-breaks make the help command look a bit off

This could be fixed by adding \s to the end of lines we don't want newlines on in the docstring, but I believe this is a greater issue across the bot, and i'm not sure what the current status of #1285 is, so it might be better to decide on a solution across the bot first I guess.
jchristgit
left a comment
There was a problem hiding this comment.
I like this. I have a few comments, but I like it.
|
|
||
| # Reverse the list to have reverse chronological order | ||
| log_messages = reversed(messages) | ||
| log_url = await self.mod_log.upload_log(log_messages, ctx.author.id) |
There was a problem hiding this comment.
Do we have a display for deleted log messages? I think we do, but I don't remember. How does that display deal with multiple channels?
There was a problem hiding this comment.
It doesn't show the channels, this is something that I noticed the anti-spam needs too. I'm leaving it for a separate PR (needs to be on site as far as I can tell).
There was a problem hiding this comment.
Sounds good. Is there an issue open for anti-spam already?
Discussion in the pull request raised some legitimate use cases for supplying a time range for multiple channels (e.g clean the last couple of minutes instead of specifying number of messages to traverse).
This pull request restructures the clean cog and adds additional features to it.
Changes
!clean messagerenamed to!clean until!clean betweenwhich accepts two limits to clean between.!clean message <message>deletes the message specified,!clean untilwill delete the messages and stop at the message specified without deleting it. Same way withbetween.!clean between 5M 15Mwill delete all message in the channel older than 5 minutes but younger than 15 minutes. The order of the two limits doesn't matter.purgeis no longer used, but instead single-message deletion and per-channel deletion are used where possible, with a check for the value ofself.cleaningafter every delete call.user,regex,bots, andallsubcommands, all channels can now be specified for deletion using the*value.*value will make user of the message cache by default. The commands can be forced to not use the cache through an added flag in those commands. It should be noted that when not using all channels, there is no cache usage in any case.The Master Command Usage
An extreme example of the master command being used to delete messages of two users between the specified ISO datetime and creation date of the specified message, but only those messages which contain digits:

Examples of using subcommand functionalities through the master command
!clean all 10=>!clean 10!clean user <user id> 15 <channel1> channel2>=>!clean 15 <user id> <channel1> <channel2>!clean between <limit1> <limit2>=>!clean <limit1> <limit2>Questionable Choices
Greedyis an object, not a type, I was unable to use in a Union to createUnion[Literal["*"], Greedy[TextChannel]]for the channels. As such I created a special converter for it and placed the channels argument as positional only, as discord.py's treats such a command argument as a dump of all the remaining arguments.\d+. This came after some discussion with moderators, and useful anyway as it cancels formatting while trying to write a pattern, but I'm open to alternatives or to more convenient ways to denote a regex pattern. To make it consistent I made the change in theclean regexsubcommand as well.Ageconverter which takes a time delta and returns the date-time of now minues the delta. Meaning, the opposite ofDurationDelta. I placed it inconverters.pyeven though it's not used anywhere else, as because of the added converter annotations, the importedDurationconverter is interpreted by type checkers as atimedelta, and so they can't resolve it as having theconvertermethod.Known Issues
I found a bug which causes logging to fail. It happened after canceling a clean, and the command gave an error that the messages were already added to the DB as deleted. However, reloading the cog made the clean command work properly again. It happened only a couple of times and I was unable to reproduce it by demand.
EDIT: Managed to reproduce a bug, not sure if it's the same one:

Addressed in python-discord/site#585
Special Thanks
To @Senjan21 who made the initiative to improve the cog and implemented some of the functionality and to @ChrisLovering who helped fix some of the issues.