Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions GearBot/Cogs/Moderation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,44 @@ async def channel(self, ctx, channel: typing.Union[disnake.TextChannel, disnake.
else:
await ctx.send(f"{Emoji.get_chat_emoji('NO')} {Translator.translate('archive_no_edit_logs', ctx)}")

@archive.command(aliases=['messages','range'])
async def message(self, ctx, first: disnake.PartialMessage, last: disnake.PartialMessage = None):
"""archive_messages_help"""
if not await Configuration.get_var(ctx.guild.id, "MESSAGE_LOGS", "ENABLED"):
await MessageUtils.send_to(ctx, 'NO', 'archive_no_edit_logs')
return
permissions = first.channel.permissions_for(ctx.author)
if not permissions.read_messages:
await MessageUtils.send_to(ctx, 'NO', 'archive_leak_denied')
return
query = LoggedMessage.filter(server=ctx.guild.id, channel=first.channel.id) \
.order_by("-messageid") \
.prefetch_related("attachments")
if last is not None:
if first.channel.id != last.channel.id:
await MessageUtils.send_to(ctx, 'NO', 'archive_message_mismatched_channels', \
first=first.channel.id, last=last.channel.id)
return
if last.id < first.id:
# Last is older than first, swap them
last, first = first, last
query = query.filter(messageid__gte=first.id, messageid__lte=last.id)
# COUNT to see if we are about to request more than 5000 rows
if await query.count() > 5000:
await MessageUtils.send_to(ctx, 'NO', 'archive_too_much')
return
# Even though we are not over 5000, let's be safe about it
query = query.limit(5000)
else:
# Not .first() because we still want to be an iterable
query = query.filter(messageid=first.id).limit(1)
await MessageUtils.send_to(ctx, 'SEARCH', 'searching_archives')
messages = await query
messages += DBUtils.get_messages_in_range(first.channel.id, first.id, last.id if last is not None else None)
await Archive.ship_messages(ctx, messages, "message", plural='yes' if last is not None else 'no')
if first.channel.id == ctx.channel.id and '/' not in ctx.message.content and '-' not in ctx.message.content:
await MessageUtils.send_to(ctx, 'WARNING', 'archive_message_no_channel_id')

@archive.command()
async def user(self, ctx, user: DiscordUser, amount=100):
"""archive_user_help"""
Expand Down
4 changes: 2 additions & 2 deletions GearBot/Util/Archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async def pack_messages(messages, guild_id):
out += f"{timestamp} {message.server} - {message.channel} - {message.messageid} | {name} ({message.author}) | {message.content}{reply} | {(', '.join(Utils.assemble_attachment(message.channel, attachment.id, attachment.name) for attachment in message.attachments))}\r\n"
return out

async def ship_messages(ctx, messages, t, filename="Message archive", filtered=False):
async def ship_messages(ctx, messages, t, filename="Message archive", filtered=False, **kwargs):
addendum = ""
if filtered:
addendum = f"\n{Emoji.get_chat_emoji('WARNING')} {Translator.translate('archive_message_filtered', ctx)}"
Expand All @@ -53,4 +53,4 @@ async def ship_messages(ctx, messages, t, filename="Message archive", filtered=F

await ctx.send(f"{Emoji.get_chat_emoji('YES')} {Translator.translate('archived_count', ctx, count=len(messages))} {addendum}", file=disnake.File(fp=buffer, filename=f"{filename}.txt"))
else:
await ctx.send(f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate(f'archive_empty_{t}', ctx)} {addendum}")
await ctx.send(f"{Emoji.get_chat_emoji('WARNING')} {Translator.translate(f'archive_empty_{t}', ctx, **kwargs)} {addendum}")
8 changes: 7 additions & 1 deletion GearBot/database/DBUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ async def do_flush():
raise e


def get_messages_in_range(channel_id, first_id, last_id=None):
if last_id is not None:
return [message for message in batch.values() if message.channel == channel_id and message.messageid >= first_id and message.messageid <= last_id]
else:
return [message for message in batch.values() if message.channel == channel_id and message.messageid == first_id]

def get_messages_for_channel(channel_id):
return [message for message in batch.values() if message.channel == channel_id]

def get_messages_for_user_in_guild(user_id, guild_id):
return [message for message in batch.values() if message.server == guild_id and message.author == user_id]
return [message for message in batch.values() if message.server == guild_id and message.author == user_id]
6 changes: 5 additions & 1 deletion lang/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,11 @@
"purged_log": "Archived {count, plural, one {1 purged message} other {# purged messages}} from {channel}.",
"archived_count": "Gear minions have returned with {count, plural, one {1 message} other {# messages}}.",
"archive_empty_user": "My gear minions have returned from their quest to the archives with empty hands. It appears they didn't send any messages in the last 6 weeks in this server.",
"archive_empty_channel": "My gear minions have returned from their quest to the archives with empty hands. It appears nobody send any messages in that channel in the last 6 weeks.",
"archive_empty_message": "My gear minions have returned from their quest to the archives with empty hands. It appears the {plural, select, no {message is} yes {messages are}} older than 6 weeks, or {plural, select, no {it is} yes {they are}} in another channel. \n (Try using '`Copy Message Link`' or holding Shift when pressing '`Copy Message ID`')",
"archive_empty_channel": "My gear minions have returned from their quest to the archives with empty hands. It appears nobody sent any messages in that channel in the last 6 weeks.",
"archive_denied_read_perms": "Trying to archive a channel you don't have access to? Sorry, leek denied.",
"archive_message_mismatched_channels": "Both messages must be in the same channel. Received messages from <#{first}> and <#{last}>.",
"archive_message_no_channel_id": "No channel information was provided, so our minions got what they could find. If these messages are incorrect, try including Channel IDs. \n (Use '`Copy Message Link`' or hold Shift when pressing '`Copy Message ID`')",
"archive_no_subcommand": "Instructions unclear, search quest denied. Please read through `{prefix}help archive` and return with a new quest assignment when ready",
"archive_no_edit_logs": "Please enable edit logs to be able to use archiving",
"archive_too_much": "I get it, you like reading old conversations, good for you. But do you really need more than 5000 messages? You might want to try a good book instead.",
Expand Down Expand Up @@ -804,6 +807,7 @@
"cf_help": "Base command to pull mod info from CurseForge, still WIP",
"archive_help": "Base command for archiving, use the subcommands to actually make archives",
"archive_channel_help": "Archive messages from a channel",
"archive_messages_help": "Archive a single message or a range of messages",
"archive_user_help": "Archive messages from a user",
"mban_help": "Bans multiple users with the same reason",
"mwarn_help": "Warns multiple users with the same reason",
Expand Down