From 95c1feab1cdb45d331d4ec88c6016d321b8113dc Mon Sep 17 00:00:00 2001 From: Luca Russo Date: Wed, 26 Feb 2025 22:16:53 +0100 Subject: [PATCH] [discord] add single message support --- gallery_dl/extractor/discord.py | 42 ++++++++++++++++++++++++++++++++- test/results/discord.py | 12 ++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/gallery_dl/extractor/discord.py b/gallery_dl/extractor/discord.py index 5a4305f4..6a5fcc9e 100644 --- a/gallery_dl/extractor/discord.py +++ b/gallery_dl/extractor/discord.py @@ -244,6 +244,23 @@ class DiscordChannelExtractor(DiscordExtractor): return self.extract_channel(channel_id) +class DiscordMessageExtractor(DiscordExtractor): + subcategory = "message" + pattern = BASE_PATTERN + r"/channels/(\d+)/(\d+)/(\d+)/?$" + example = "https://discord.com/channels/1234567890/9876543210/2468013579" + + def items(self): + server_id, channel_id, message_id = self.groups + + self.build_server_and_channels(server_id) + + if channel_id not in self.server_channels_metadata: + self.parse_channel(self.api.get_channel(channel_id)) + + return self.extract_message( + self.api.get_message(channel_id, message_id)) + + class DiscordServerExtractor(DiscordExtractor): subcategory = "server" pattern = BASE_PATTERN + r"/channels/(\d+)/?$" @@ -264,13 +281,29 @@ class DiscordDirectMessagesExtractor(DiscordExtractor): subcategory = "direct-messages" directory_fmt = ("{category}", "Direct Messages", "{channel_id}_{recipients:J,}") - pattern = BASE_PATTERN + r"/channels/@me/(\d+)" + pattern = BASE_PATTERN + r"/channels/@me/(\d+)/?$" example = "https://discord.com/channels/@me/1234567890" def items(self): return self.extract_channel(self.groups[0]) +class DiscordDirectMessageExtractor(DiscordExtractor): + subcategory = "direct-message" + directory_fmt = ("{category}", "Direct Messages", + "{channel_id}_{recipients:J,}") + pattern = BASE_PATTERN + r"/channels/@me/(\d+)/(\d+)/?$" + example = "https://discord.com/channels/@me/1234567890/9876543210" + + def items(self): + channel_id, message_id = self.groups + + self.parse_channel(self.api.get_channel(channel_id)) + + return self.extract_message( + self.api.get_message(channel_id, message_id)) + + class DiscordAPI(): """Interface for the Discord API v10 @@ -325,6 +358,13 @@ class DiscordAPI(): return self._pagination(_method, MESSAGES_BATCH) + def get_message(self, channel_id, message_id): + """Get message information""" + return self._call("/channels/" + channel_id + "/messages", { + "limit": 1, + "around": message_id + })[0] + def _call(self, endpoint, params=None): url = self.root + endpoint try: diff --git a/test/results/discord.py b/test/results/discord.py index 90b7c3f4..5b2350db 100644 --- a/test/results/discord.py +++ b/test/results/discord.py @@ -8,6 +8,18 @@ from gallery_dl.extractor import discord __tests__ = ( +{ + "#url" : "https://discord.com/channels/302094807046684672/1306706528786583623/1306706528786583623", + "#category": ("", "discord", "message"), + "#class" : discord.DiscordMessageExtractor, +}, + +{ + "#url" : "https://discord.com/channels/@me/1306706528786583623/1306706528786583623", + "#category": ("", "discord", "direct-message"), + "#class" : discord.DiscordDirectMessageExtractor, +}, + { "#url" : "https://discord.com/channels/302094807046684672/1306705919916249098", "#category": ("", "discord", "channel"),