|
8 | 8 | from itertools import takewhile |
9 | 9 | from typing import Literal, TYPE_CHECKING |
10 | 10 |
|
| 11 | +import arrow |
11 | 12 | from discord import Colour, Message, NotFound, TextChannel, Thread, User, errors |
12 | 13 | from discord.ext.commands import Cog, Context, Converter, Greedy, command, group, has_any_role |
13 | 14 | from discord.ext.commands.converter import TextChannelConverter |
@@ -221,9 +222,17 @@ async def _delete_invocation(self, ctx: Context) -> None: |
221 | 222 | # Invocation message has already been deleted |
222 | 223 | log.info("Tried to delete invocation message, but it was already deleted.") |
223 | 224 |
|
224 | | - def _use_cache(self, limit: datetime) -> bool: |
225 | | - """Tell whether all messages to be cleaned can be found in the cache.""" |
226 | | - return self.bot.cached_messages[0].created_at <= limit |
| 225 | + def _earliest_cache_datetime(self) -> datetime: |
| 226 | + """Return the datetime of the earliest message cached, or now if the cache is empty.""" |
| 227 | + return self.bot.cached_messages[0].created_at if self.bot.cached_messages else arrow.utcnow().datetime |
| 228 | + |
| 229 | + def _use_cache(self, most_recent_limit: datetime | None) -> bool: |
| 230 | + """Return whether there are messages to clean that can be found in the cache.""" |
| 231 | + return most_recent_limit is None or self._earliest_cache_datetime() <= most_recent_limit |
| 232 | + |
| 233 | + def _use_api(self, oldest_limit: datetime) -> bool: |
| 234 | + """Return whether there might be messages to clean that won't be found in the cache.""" |
| 235 | + return self._earliest_cache_datetime() >= oldest_limit |
227 | 236 |
|
228 | 237 | def _get_messages_from_cache( |
229 | 238 | self, |
@@ -430,27 +439,33 @@ async def _clean_messages( |
430 | 439 | # Delete the invocation first |
431 | 440 | executor.submit(self._delete_invocation(ctx)) |
432 | 441 |
|
433 | | - if self._use_cache(first_limit): |
| 442 | + deleted_messages = [] |
| 443 | + |
| 444 | + if self._use_cache(second_limit): |
434 | 445 | log.trace(f"Messages for cleaning by {ctx.author.id} will be searched in the cache.") |
435 | 446 | message_mappings, message_ids = self._get_messages_from_cache( |
436 | 447 | channels=deletion_channels, to_delete=predicate, lower_limit=first_limit |
437 | 448 | ) |
438 | | - else: |
| 449 | + self.mod_log.ignore(Event.message_delete, *message_ids) |
| 450 | + deleted_messages = await self._delete_found(message_mappings, executor) |
| 451 | + second_limit = self._earliest_cache_datetime() |
| 452 | + |
| 453 | + if self._use_api(first_limit): |
439 | 454 | log.trace(f"Messages for cleaning by {ctx.author.id} will be searched in channel histories.") |
440 | 455 | message_mappings, message_ids = await self._get_messages_from_channels( |
441 | 456 | channels=deletion_channels, |
442 | 457 | to_delete=predicate, |
443 | 458 | after=first_limit, # Remember first is the earlier datetime (the "older" time). |
444 | 459 | before=second_limit |
445 | 460 | ) |
| 461 | + self.mod_log.ignore(Event.message_delete, *message_ids) |
| 462 | + api_deleted_messages = await self._delete_found(message_mappings, executor) |
| 463 | + deleted_messages.extend(api_deleted_messages) |
446 | 464 |
|
447 | 465 | if not self.cleaning: |
448 | 466 | # Means that the cleaning was canceled |
449 | 467 | return None |
450 | 468 |
|
451 | | - # Now let's delete the actual messages with purge. |
452 | | - self.mod_log.ignore(Event.message_delete, *message_ids) |
453 | | - deleted_messages = await self._delete_found(message_mappings, executor) |
454 | 469 | self.cleaning = False |
455 | 470 | log.trace("Cleaning completed, wrapping up") |
456 | 471 |
|
|
0 commit comments