From 99cd2b301b95a16376c2dc9e657aac61103efc77 Mon Sep 17 00:00:00 2001 From: Klemek Date: Tue, 1 Jun 2021 09:52:14 +0200 Subject: [PATCH] 1.15.1 bug fix on images --- src/data_types/history.py | 20 +++++++----- src/logs/message_log.py | 18 +++-------- src/main.py | 2 +- src/scanners/first_scanner.py | 4 +-- src/scanners/history_scanner.py | 27 +++++++++++----- src/scanners/last_scanner.py | 6 ++-- src/scanners/random_scanner.py | 4 +-- src/utils/utils.py | 55 ++++++++++++++++++++++++--------- 8 files changed, 86 insertions(+), 50 deletions(-) diff --git a/src/data_types/history.py b/src/data_types/history.py index 8a23925..5a4c023 100644 --- a/src/data_types/history.py +++ b/src/data_types/history.py @@ -11,6 +11,7 @@ from utils import ( SPLIT_TOKEN, FilterLevel, should_allow_spoiler, + is_image_gif, ) MAX_RANDOM_TRIES = 100 @@ -20,7 +21,9 @@ class History: def __init__(self): self.messages = [] - async def to_string_image(self, *, type: str, spoiler: FilterLevel) -> List[str]: + async def to_string_image( + self, *, type: str, spoiler: FilterLevel, gif_only: bool + ) -> List[str]: if len(self.messages) == 0: return ["There was no messages matching your filters"] message = None @@ -32,8 +35,9 @@ class History: while real_message is None and index < len(self.messages): message = self.messages[index] real_message = await message.fetch() - if real_message is not None and not should_allow_spoiler( - real_message, spoiler + if real_message is not None and ( + not should_allow_spoiler(real_message, spoiler) + or (gif_only and not is_image_gif(real_message)) ): real_message = None index += 1 @@ -44,8 +48,9 @@ class History: while real_message is None and index < len(self.messages): message = self.messages[index] real_message = await message.fetch() - if real_message is not None and not should_allow_spoiler( - real_message, spoiler + if real_message is not None and ( + not should_allow_spoiler(real_message, spoiler) + or (gif_only and not is_image_gif(real_message)) ): real_message = None index += 1 @@ -56,8 +61,9 @@ class History: while real_message is None and tries < MAX_RANDOM_TRIES: message = random.choice(self.messages) real_message = await message.fetch() - if real_message is not None and not should_allow_spoiler( - real_message, spoiler + if real_message is not None and ( + not should_allow_spoiler(real_message, spoiler) + or (gif_only and not is_image_gif(real_message)) ): real_message = None tries += 1 diff --git a/src/logs/message_log.py b/src/logs/message_log.py index bd69b4b..da499f7 100644 --- a/src/logs/message_log.py +++ b/src/logs/message_log.py @@ -2,10 +2,10 @@ from typing import Optional, Union, Any import discord from datetime import datetime -from utils import is_extension, serialize - -IMAGE_FORMAT = [".gif", ".gifv", ".png", ".jpg", ".jpeg", ".bmp"] -EMBED_IMAGES = ["image", "gifv"] +from utils import ( + serialize, + has_image, +) class MessageLog: @@ -36,15 +36,7 @@ class MessageLog: self.image = False self.attachment = len(message.attachments) > 0 self.embed = len(message.embeds) > 0 - for attachment in message.attachments: - if is_extension(attachment.filename, IMAGE_FORMAT): - self.image = True - break - else: - for embed in message.embeds: - if embed.type in EMBED_IMAGES: - self.image = True - break + self.image = has_image(message) self.reactions = {} elif isinstance(message, dict): self.id = int(message["id"]) diff --git a/src/main.py b/src/main.py index 3fc6ce9..38eef86 100644 --- a/src/main.py +++ b/src/main.py @@ -18,7 +18,7 @@ emojis.load_emojis() bot = Bot( "Discord Analyst", - "1.15", + "1.15.1", alias="%", ) diff --git a/src/scanners/first_scanner.py b/src/scanners/first_scanner.py index ba7622b..d467486 100644 --- a/src/scanners/first_scanner.py +++ b/src/scanners/first_scanner.py @@ -13,7 +13,7 @@ class FirstScanner(HistoryScanner): "first", "Read first message (add text to filter like %find)", args=[ - "image - pull an image instead of a message", + "image/gif - pull an image instead of a message", "spoiler:allow/only - allow spoiler images", ], ) @@ -24,7 +24,7 @@ class FirstScanner(HistoryScanner): async def get_results(self, intro: str) -> List[str]: if self.images_only: return await self.history.to_string_image( - type="first", spoiler=self.spoiler + type="first", spoiler=self.spoiler, gif_only=self.gif_only ) else: return self.history.to_string(type="first") diff --git a/src/scanners/history_scanner.py b/src/scanners/history_scanner.py index aecf5a5..06853ac 100644 --- a/src/scanners/history_scanner.py +++ b/src/scanners/history_scanner.py @@ -15,7 +15,16 @@ class HistoryScanner(Scanner, ABC): def __init__(self, *, help: str): super().__init__( has_digit_args=True, - valid_args=["all", "everyone", "spoiler", "spoiler:allow", "spoiler:only"], + valid_args=[ + "all", + "everyone", + "spoiler", + "spoiler:allow", + "spoiler:only", + "image", + "img", + "gif", + ], help=help, intro_context="", all_args=True, @@ -24,7 +33,8 @@ class HistoryScanner(Scanner, ABC): async def init(self, message: discord.Message, *args: str) -> bool: self.history = History() self.all_messages = "all" in args or "everyone" in args - self.images_only = "image" in args + self.images_only = "image" in args or "img" in args or "gif" in args + self.gif_only = "gif" in args if "spoiler" in args or "spoiler:allow" in args: self.spoiler = FilterLevel.ALLOW elif "spoiler:only" in args: @@ -80,13 +90,14 @@ class HistoryScanner(Scanner, ABC): and (message.content or message.attachment) and (not images_only or message.image) ): - content = message.content.lower() - for query in queries: - if query[1] is not None: - if not re.match(query[1], message.content): + if not images_only: + content = message.content.lower() + for query in queries: + if query[1] is not None: + if not re.match(query[1], message.content): + return False + elif not query[0] in content: return False - elif not query[0] in content: - return False impacted = True history.messages += [message] return impacted diff --git a/src/scanners/last_scanner.py b/src/scanners/last_scanner.py index 055217e..b17f4f3 100644 --- a/src/scanners/last_scanner.py +++ b/src/scanners/last_scanner.py @@ -13,7 +13,7 @@ class LastScanner(HistoryScanner): "last", "Read last message (add text to filter like %find)", args=[ - "image - pull an image instead of a message", + "image/gif - pull an image instead of a message", "spoiler:allow/only - allow spoiler images", ], ) @@ -23,6 +23,8 @@ class LastScanner(HistoryScanner): async def get_results(self, intro: str) -> List[str]: if self.images_only: - return await self.history.to_string_image(type="last", spoiler=self.spoiler) + return await self.history.to_string_image( + type="last", spoiler=self.spoiler, gif_only=self.gif_only + ) else: return self.history.to_string(type="last") diff --git a/src/scanners/random_scanner.py b/src/scanners/random_scanner.py index 42d4488..851dd00 100644 --- a/src/scanners/random_scanner.py +++ b/src/scanners/random_scanner.py @@ -13,7 +13,7 @@ class RandomScanner(HistoryScanner): "rand", "Read a random message (add text to filter like %find)", args=[ - "image - pull an image instead of a message", + "image/gif - pull an image instead of a message", "spoiler:allow/only - allow spoiler images", ], ) @@ -24,7 +24,7 @@ class RandomScanner(HistoryScanner): async def get_results(self, intro: str) -> List[str]: if self.images_only: return await self.history.to_string_image( - type="random", spoiler=self.spoiler + type="random", spoiler=self.spoiler, gif_only=self.gif_only ) else: return self.history.to_string(type="random") diff --git a/src/utils/utils.py b/src/utils/utils.py index 530a5ff..6627852 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -60,6 +60,26 @@ class FilterLevel(IntEnum): SPLIT_TOKEN = 1152317803 +# FILE + +IMAGE_FORMAT = [".png", ".jpg", ".jpeg", ".bmp"] +EMBED_IMAGES = ["image"] + +GIF_FORMAT = [".gif", ".gifv"] +EMBED_GIF = ["gifv"] + + +def is_extension(filepath: str, ext_list: List[str]) -> bool: + filename, file_extension = os.path.splitext(filepath.lower()) + return file_extension in ext_list + + +def get_resource_path(filename: str) -> str: + return os.path.realpath( + os.path.join(os.path.dirname(__file__), "..", "resources", filename) + ) + + # DISCORD API @@ -100,11 +120,30 @@ class FakeMessage: self.id = id +def has_image(message: discord.Message) -> bool: + for attachment in message.attachments: + if is_extension(attachment.filename, GIF_FORMAT + IMAGE_FORMAT): + return True + for embed in message.embeds: + if embed.type in (EMBED_IMAGES + EMBED_GIF): + return True + return False + + def is_image_spoiler(message: discord.Message) -> bool: if len(message.attachments) > 0: return message.attachments[0].is_spoiler() elif len(message.embeds) > 0: - return re.match(r"||[^|]*http[^|]||", message.content.lower()) is not None + return re.match(r"\|\|[^|]*http[^|]\|\|", message.content.lower()) is not None + else: + return False + + +def is_image_gif(message: discord.Message) -> bool: + if len(message.attachments) > 0: + return is_extension(message.attachments[0].filename, GIF_FORMAT) + elif len(message.embeds) > 0: + return message.embeds[0].type in EMBED_GIF else: return False @@ -119,20 +158,6 @@ def should_allow_spoiler(message: discord.Message, spoiler: FilterLevel) -> bool ) -# FILE - - -def is_extension(filepath: str, ext_list: List[str]) -> bool: - filename, file_extension = os.path.splitext(filepath.lower()) - return file_extension in ext_list - - -def get_resource_path(filename: str) -> str: - return os.path.realpath( - os.path.join(os.path.dirname(__file__), "..", "resources", filename) - ) - - # LISTS