From b14c850cf33213550e194ca76c9a695b945473df Mon Sep 17 00:00:00 2001 From: ajax146 <31014239+ajax146@users.noreply.github.com> Date: Wed, 17 Apr 2024 09:34:36 -0400 Subject: [PATCH 1/3] Fix all flake8 ANN003 issues --- techsupport_bot/botlogging/delayed.py | 5 ++- techsupport_bot/commands/dumpdbg.py | 17 +++------ techsupport_bot/commands/gate.py | 22 ++++------- techsupport_bot/commands/google.py | 26 ++++--------- techsupport_bot/commands/hangman.py | 4 +- techsupport_bot/commands/kanye.py | 39 ++++++++++--------- techsupport_bot/commands/listen.py | 54 +++++++++++---------------- techsupport_bot/commands/poll.py | 18 +++------ techsupport_bot/commands/protect.py | 21 +++++------ techsupport_bot/commands/rules.py | 11 +----- techsupport_bot/commands/wolfram.py | 17 +++------ techsupport_bot/core/auxiliary.py | 4 +- techsupport_bot/core/cogs.py | 4 +- techsupport_bot/core/http.py | 6 ++- techsupport_bot/functions/events.py | 2 +- 15 files changed, 102 insertions(+), 148 deletions(-) diff --git a/techsupport_bot/botlogging/delayed.py b/techsupport_bot/botlogging/delayed.py index 8312828b5..009b48f36 100644 --- a/techsupport_bot/botlogging/delayed.py +++ b/techsupport_bot/botlogging/delayed.py @@ -2,6 +2,7 @@ import asyncio import os +from typing import Any from botlogging import logger @@ -17,13 +18,13 @@ class DelayedLogger(logger.BotLogger): queue_size (int): the max number of queue events """ - def __init__(self, *args, **kwargs): + def __init__(self, *args: tuple, **kwargs: dict[str, Any]) -> None: self.wait_time = kwargs.pop("wait_time", 1) self.queue_size = kwargs.pop("queue_size", 1000) self.__send_queue = None super().__init__(*args, **kwargs) - async def send_log(self, *args, **kwargs): + async def send_log(self, *args: tuple, **kwargs: dict[str, Any]) -> None: """Adds a log to the queue Does nothing different than the Logger send_log function() Will disregard debug logs if debug is off diff --git a/techsupport_bot/commands/dumpdbg.py b/techsupport_bot/commands/dumpdbg.py index 18af50f4a..54c0a5a4f 100644 --- a/techsupport_bot/commands/dumpdbg.py +++ b/techsupport_bot/commands/dumpdbg.py @@ -31,14 +31,6 @@ async def setup(bot): bot.add_extension_config("dumpdbg", config) -class DumpdbgEmbed(discord.Embed): - """Class to set up the dumpdbg embed.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.green() - - class Dumpdbg(cogs.BaseCog): """Class for the dump debugger on the discord bot.""" @@ -148,17 +140,19 @@ async def debug_dump(self, ctx): # Formatting for several files because it looks prettier if len(result_urls) == 1: await ctx.send( - embed=DumpdbgEmbed( + embed=auxiliary.generate_basic_embed( title="Dump succesfully debugged! \nResult links:", description="\n".join(result_urls), + color=discord.Color.green(), ), content=auxiliary.construct_mention_string([ctx.author]), ) else: await ctx.send( - embed=DumpdbgEmbed( + embed=auxiliary.generate_basic_embed( title="Dumps succesfully debugged! \nResult links:", description="\n".join(result_urls), + color=discord.Color.green(), ) ) @@ -188,9 +182,10 @@ async def get_files(self, ctx): # Disregards any empty dumps if attachment.size == 0: await ctx.send( - embed=DumpdbgEmbed( + embed=auxiliary.generate_basic_embed( title="Invalid dump detected (Size 0)", description=f"Skipping dump number {dump_no}...", + color=discord.Color.green(), ) ) continue diff --git a/techsupport_bot/commands/gate.py b/techsupport_bot/commands/gate.py index b3851d38e..b35f8a645 100644 --- a/techsupport_bot/commands/gate.py +++ b/techsupport_bot/commands/gate.py @@ -64,19 +64,6 @@ async def setup(bot): bot.add_extension_config("gate", config) -class WelcomeEmbed(discord.Embed): - """Class to welcome a user to the discord, then delete the message.""" - - def __init__(self, *args, **kwargs): - welcome_message = kwargs.pop("welcome_message") - delete_wait = kwargs.pop("delete_wait") - super().__init__(*args, **kwargs) - self.title = "Server Gate" - self.description = welcome_message - self.set_footer(text=f"This message will be deleted in {delete_wait} seconds") - self.color = discord.Color.green() - - class ServerGate(cogs.MatchCog): """Class to get the server gate from config.""" @@ -117,8 +104,13 @@ async def response(self, config, ctx: commands.Context, content, _): welcome_message = config.extensions.gate.welcome_message.value delete_wait = config.extensions.gate.delete_wait.value - embed = WelcomeEmbed( - welcome_message=welcome_message, delete_wait=delete_wait + embed = auxiliary.generate_basic_embed( + title="Server Gate", + description=welcome_message, + color=discord.Color.green(), + ) + embed.set_footer( + text=f"This message will be deleted in {delete_wait} seconds" ) await ctx.send( embed=embed, diff --git a/techsupport_bot/commands/google.py b/techsupport_bot/commands/google.py index 5bd8eb2d8..65903435d 100644 --- a/techsupport_bot/commands/google.py +++ b/techsupport_bot/commands/google.py @@ -31,24 +31,14 @@ async def setup(bot): bot.add_extension_config("google", config) -class GoogleEmbed(discord.Embed): - """Class for the google embed for discord.""" - - ICON_URL = ( - "https://cdn.icon-icons.com/icons2/673/PNG/512/Google_icon-icons.com_60497.png" - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.blurple() - self.set_thumbnail(url=self.ICON_URL) - - class Googler(cogs.BaseCog): """Class for the google extension for the discord bot.""" GOOGLE_URL = "https://www.googleapis.com/customsearch/v1" YOUTUBE_URL = "https://www.googleapis.com/youtube/v3/search?part=id&maxResults=10" + ICON_URL = ( + "https://cdn.icon-icons.com/icons2/673/PNG/512/Google_icon-icons.com_60497.png" + ) async def get_items(self, url, data): """Method to get an item from google's api.""" @@ -101,11 +91,11 @@ async def search(self, ctx, *, query: str): for index, item in enumerate(items): link = item.get("link") snippet = item.get("snippet", "
").replace("\n", "") - embed = ( - GoogleEmbed(title=f"Results for {query}") - if field_counter == 1 - else embed - ) + if field_counter == 1: + embed = auxiliary.generate_basic_embed( + title=f"Results for {query}", url=self.ICON_URL + ) + embed.add_field(name=link, value=snippet, inline=False) if ( field_counter == config.extensions.google.max_responses.value diff --git a/techsupport_bot/commands/hangman.py b/techsupport_bot/commands/hangman.py index 0d735c52e..e31c1b203 100644 --- a/techsupport_bot/commands/hangman.py +++ b/techsupport_bot/commands/hangman.py @@ -2,6 +2,7 @@ import datetime import uuid +from typing import Any import discord import ui @@ -87,8 +88,7 @@ class HangmanGame: ] FINAL_STEP = len(HANG_PICS) - 1 - def __init__(self, **kwargs): - word = kwargs.pop("word") + def __init__(self, word: str) -> None: if not word or "_" in word or not word.isalpha(): raise ValueError("valid word must be provided") self.word = word diff --git a/techsupport_bot/commands/kanye.py b/techsupport_bot/commands/kanye.py index 5a143a2aa..4e105a114 100644 --- a/techsupport_bot/commands/kanye.py +++ b/techsupport_bot/commands/kanye.py @@ -37,9 +37,10 @@ async def setup(bot): bot.add_extension_config("kanye", config) -class KanyeEmbed(discord.Embed): - """Class for the Kanye embed for discord.""" +class KanyeQuotes(cogs.LoopCog): + """Class to get the Kanye quotes from the api.""" + API_URL = "https://api.kanye.rest" KANYE_PICS = [ "https://i.imgur.com/ITmTXGz.jpg", "https://i.imgur.com/o8BkPrL.jpg", @@ -48,19 +49,23 @@ class KanyeEmbed(discord.Embed): "https://i.imgur.com/g1o2Gro.jpg", ] - def __init__(self, *args, **kwargs): - quote = kwargs.pop("quote") - super().__init__(*args, **kwargs) - self.set_thumbnail(url=random.choice(self.KANYE_PICS)) - self.color = discord.Color.dark_gold() - self.title = f'"{quote}"' - self.description = "Kanye West" - - -class KanyeQuotes(cogs.LoopCog): - """Class to get the Kanye quotes from the api.""" - - API_URL = "https://api.kanye.rest" + def generate_themed_embed(self, quote: str) -> discord.Embed: + """Generates a themed embed for the kayne plugin + Includes adding the quote, changing the color, and adding an icon + + Args: + quote (str): The quote to put in the embed + + Returns: + discord.Embed: The formatted embed, ready to be sent + """ + embed = auxiliary.generate_basic_embed( + title=f'"{quote}"', + description="Kanye West", + color=discord.Color.dark_gold(), + url=random.choice(self.KANYE_PICS), + ) + return embed async def get_quote(self): """Method to get the quote from the api.""" @@ -70,7 +75,7 @@ async def get_quote(self): async def execute(self, config, guild): """Method to execute and give the quote to discord.""" quote = await self.get_quote() - embed = KanyeEmbed(quote=quote) + embed = self.generate_themed_embed(quote=quote) channel = guild.get_channel(int(config.extensions.kanye.channel.value)) if not channel: @@ -95,6 +100,6 @@ async def wait(self, config, _): async def kanye(self, ctx): """Method to call the command on discord.""" quote = await self.get_quote() - embed = KanyeEmbed(quote=quote) + embed = self.generate_themed_embed(quote=quote) await ctx.send(embed=embed) diff --git a/techsupport_bot/commands/listen.py b/techsupport_bot/commands/listen.py index fb7c7cdf8..7ee759217 100644 --- a/techsupport_bot/commands/listen.py +++ b/techsupport_bot/commands/listen.py @@ -36,50 +36,39 @@ async def convert(self, ctx, argument: int): return channel -class ListenEmbed(discord.Embed): - """Base embed for listen events.""" +class Listener(cogs.BaseCog): + """Cog object for listening to channels.""" - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.blurple() - self.timestamp = datetime.datetime.utcnow() + MAX_DESTINATIONS = 10 + CACHE_TIME = 60 + def format_message_in_embed(self, message: discord.Message) -> discord.Embed: + """Formats a listened message into a pretty embed -class MessageEmbed(ListenEmbed): - """Embed for message events.""" + Args: + message (discord.Message): The raw message to format - def __init__(self, *args, **kwargs): - message = kwargs.pop("message") - super().__init__(*args, **kwargs) - self.set_author( + Returns: + discord.Embed: The stylized embed ready to be sent + """ + embed = auxiliary.generate_basic_embed(description=message.clean_content) + + embed.timestamp = datetime.datetime.utcnow() + embed.set_author( name=message.author.name, icon_url=message.author.display_avatar.url ) - self.description = message.clean_content if message.embeds: - self.description = f"{self.description} (includes embed)" + embed.description = f"{embed.description} (includes embed)" if message.attachments: - self.add_field( + embed.add_field( name="Attachments", value=" ".join(a.url for a in message.attachments) ) - self.set_footer(text=f"#{message.channel.name} - {message.guild}") + embed.set_footer(text=f"#{message.channel.name} - {message.guild}") - -class InfoEmbed(discord.Embed): - """Embed for providing info about listener jobs.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.green() - - -class Listener(cogs.BaseCog): - """Cog object for listening to channels.""" - - MAX_DESTINATIONS = 10 - CACHE_TIME = 60 + return embed async def preconfig(self): """Preconfigures the listener cog.""" @@ -356,8 +345,9 @@ async def jobs(self, ctx): ) return - embed = InfoEmbed( + embed = auxiliary.generate_basic_embed( title="Listener Registrations", + color=discord.Color.green(), ) for source_obj in source_objects: src_ch = source_obj.get("source") @@ -390,7 +380,7 @@ async def on_message(self, message: discord.Message): if not destinations: return for dst in destinations: - embed = MessageEmbed(message=message) + embed = self.format_message_in_embed(message=message) await dst.send(embed=embed) @commands.Cog.listener() diff --git a/techsupport_bot/commands/poll.py b/techsupport_bot/commands/poll.py index d15eb90ac..faca333ca 100644 --- a/techsupport_bot/commands/poll.py +++ b/techsupport_bot/commands/poll.py @@ -16,16 +16,6 @@ async def setup(bot): await bot.add_cog(StrawPoller(bot=bot)) -class PollEmbed(discord.Embed): - """Class for the poll embed for discord.""" - - def __init__(self, *args, **kwargs): - thumbnail_url = kwargs.pop("thumbnail_url") - super().__init__(*args, **kwargs) - self.set_thumbnail(url=thumbnail_url) - self.color = discord.Color.gold() - - class PollGenerator(cogs.BaseCog): """Class to make the poll generator for the extension.""" @@ -157,10 +147,11 @@ async def generate(self, ctx): ) display_timeout_units = "seconds" if request_body.timeout <= 60 else "minutes" - embed = PollEmbed( + embed = auxiliary.generate_basic_embed( title=request_body.question, description=f"Poll timeout: {display_timeout} {display_timeout_units}", - thumbnail_url=request_body.image_url, + color=discord.Color.gold(), + url=request_body.image_url, ) for index, option in enumerate(request_body.options): @@ -201,9 +192,10 @@ async def generate(self, ctx): ) return - embed = PollEmbed( + embed = auxiliary.generate_basic_embed( title=f"Poll results for `{request_body.question}`", description=f"Votes: {total}", + color=discord.Color.gold(), thumbnail_url=request_body.image_url, ) diff --git a/techsupport_bot/commands/protect.py b/techsupport_bot/commands/protect.py index 48eaa7750..d223bdd25 100644 --- a/techsupport_bot/commands/protect.py +++ b/techsupport_bot/commands/protect.py @@ -134,15 +134,6 @@ async def setup(bot): bot.add_extension_config("protect", config) -class ProtectEmbed(discord.Embed): - """Class to make the embed for the protect command.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.title = "Chat Protection" - self.color = discord.Color.gold() - - class Protector(cogs.MatchCog): """Class for the protector command.""" @@ -357,7 +348,11 @@ async def handle_string_alert(self, config, ctx, content, filter_config): return self.string_alert_cache[cache_key] = True - embed = ProtectEmbed(description=filter_config.message) + embed = auxiliary.generate_basic_embed( + title="Chat Protection", + description=filter_config.message, + color=discord.Color.gold(), + ) await ctx.send(ctx.message.author.mention, embed=embed) await self.send_alert( @@ -625,7 +620,11 @@ async def send_alert(self, config, ctx, message): async def send_default_delete_response(self, config, ctx, content, reason): """Method for the default delete of a message.""" - embed = ProtectEmbed(description=f"Message deleted. Reason: *{reason}*") + embed = auxiliary.generate_basic_embed( + title="Chat Protection", + description=f"Message deleted. Reason: *{reason}*", + color=discord.Color.gold(), + ) await ctx.send(ctx.message.author.mention, embed=embed) await ctx.author.send(f"Deleted message: ```{content[:1994]}```") diff --git a/techsupport_bot/commands/rules.py b/techsupport_bot/commands/rules.py index ab8945198..022e75171 100644 --- a/techsupport_bot/commands/rules.py +++ b/techsupport_bot/commands/rules.py @@ -21,14 +21,6 @@ async def setup(bot: bot.TechSupportBot): await bot.add_cog(Rules(bot=bot)) -class RuleEmbed(discord.Embed): - """Class for setting up the rules embed.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.gold() - - class Rules(cogs.BaseCog): """Class to define the rules for the extension.""" @@ -193,9 +185,10 @@ async def get_all_rules(self, ctx: commands.Context): ) return - embed = RuleEmbed( + embed = auxiliary.generate_basic_embed( title="Server Rules", description="By talking on this server, you agree to the following rules", + color=discord.Color.gold(), ) for index, rule in enumerate(rules_data.get("rules")): diff --git a/techsupport_bot/commands/wolfram.py b/techsupport_bot/commands/wolfram.py index 0ee7f9065..a3d989c6b 100644 --- a/techsupport_bot/commands/wolfram.py +++ b/techsupport_bot/commands/wolfram.py @@ -18,21 +18,11 @@ async def setup(bot): await bot.add_cog(Wolfram(bot=bot)) -class WolframEmbed(discord.Embed): - """Class to set up the wolfram embed.""" - - ICON_URL = "https://cdn.icon-icons.com/icons2/2107/PNG/512/file_type_wolfram_icon_130071.png" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.color = discord.Color.orange() - self.set_thumbnail(url=self.ICON_URL) - - class Wolfram(cogs.BaseCog): """Class to set up the wolfram extension.""" API_URL = "http://api.wolframalpha.com/v1/result?appid={}&i={}" + ICON_URL = "https://cdn.icon-icons.com/icons2/2107/PNG/512/file_type_wolfram_icon_130071.png" @auxiliary.with_typing @commands.command( @@ -64,4 +54,7 @@ async def simple_search(self, ctx, *, query: str): return answer = response["text"] - await ctx.send(embed=WolframEmbed(description=answer)) + embed = auxiliary.generate_basic_embed( + description=answer, color=discord.Color.orange(), url=self.ICON_URL + ) + await ctx.send(embed=embed) diff --git a/techsupport_bot/core/auxiliary.py b/techsupport_bot/core/auxiliary.py index ebe6cd43f..fa9a435b0 100644 --- a/techsupport_bot/core/auxiliary.py +++ b/techsupport_bot/core/auxiliary.py @@ -5,6 +5,7 @@ import json from functools import wraps +from typing import Any import discord import munch @@ -274,7 +275,8 @@ def with_typing(command: commands.Command) -> commands.Command: original_callback = command.callback @wraps(original_callback) - async def typing_wrapper(*args, **kwargs): + async def typing_wrapper(*args: tuple, **kwargs: dict[str, Any]) -> None: + """The wrapper to add typing to any given function and call the original function""" context = args[1] typing_func = getattr(context, "typing", None) diff --git a/techsupport_bot/core/cogs.py b/techsupport_bot/core/cogs.py index 56cb04564..7cef9ed21 100644 --- a/techsupport_bot/core/cogs.py +++ b/techsupport_bot/core/cogs.py @@ -3,7 +3,7 @@ from __future__ import annotations import asyncio -from typing import TYPE_CHECKING, List +from typing import TYPE_CHECKING, Any, List import discord import gino @@ -176,7 +176,7 @@ class LoopCog(BaseCog): ON_START: bool = False CHANNELS_KEY: str = "channels" - def __init__(self, *args, **kwargs): + def __init__(self, *args: tuple, **kwargs: dict[str, Any]): super().__init__(*args, **kwargs) asyncio.create_task(self._loop_preconfig()) self.channels = {} diff --git a/techsupport_bot/core/http.py b/techsupport_bot/core/http.py index cc26592ca..5c634f851 100644 --- a/techsupport_bot/core/http.py +++ b/techsupport_bot/core/http.py @@ -9,7 +9,7 @@ import urllib from collections import deque from json import JSONDecodeError -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from urllib.parse import urlparse import aiohttp @@ -79,7 +79,9 @@ def __init__(self, bot: bot.TechSupportBot) -> None: except AttributeError: print("No linx API URL found. Not rate limiting linx") - async def http_call(self, method: str, url: str, *args, **kwargs): + async def http_call( + self, method: str, url: str, *args: tuple, **kwargs: dict[str, Any] + ): """Makes an HTTP request. By default this returns JSON/dict with the status code injected. diff --git a/techsupport_bot/functions/events.py b/techsupport_bot/functions/events.py index b923f3be1..b7db5353e 100644 --- a/techsupport_bot/functions/events.py +++ b/techsupport_bot/functions/events.py @@ -699,7 +699,7 @@ async def on_command(self, ctx: commands.Context): ) @commands.Cog.listener() - async def on_error(self, event_method, *_args, **_kwargs): + async def on_error(self, event_method): """Catches non-command errors and sends them to the error logger for processing. parameters: From 76d2a1ab9d0d6c639337757b1a50dedd0970e47d Mon Sep 17 00:00:00 2001 From: ajax146 <31014239+ajax146@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:18:32 -0400 Subject: [PATCH 2/3] Formatting --- techsupport_bot/commands/google.py | 1 - techsupport_bot/commands/hangman.py | 1 - 2 files changed, 2 deletions(-) diff --git a/techsupport_bot/commands/google.py b/techsupport_bot/commands/google.py index 65903435d..f7133294e 100644 --- a/techsupport_bot/commands/google.py +++ b/techsupport_bot/commands/google.py @@ -1,6 +1,5 @@ """Module for the google extension for the discord bot.""" -import discord import ui from core import auxiliary, cogs, extensionconfig from discord.ext import commands diff --git a/techsupport_bot/commands/hangman.py b/techsupport_bot/commands/hangman.py index e31c1b203..870e8d712 100644 --- a/techsupport_bot/commands/hangman.py +++ b/techsupport_bot/commands/hangman.py @@ -2,7 +2,6 @@ import datetime import uuid -from typing import Any import discord import ui From cf4a7d2086b2dc08be4827107454b7299a482bf7 Mon Sep 17 00:00:00 2001 From: ajax146 <31014239+ajax146@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:37:12 -0400 Subject: [PATCH 3/3] Formatting --- techsupport_bot/botlogging/delayed.py | 1 - 1 file changed, 1 deletion(-) diff --git a/techsupport_bot/botlogging/delayed.py b/techsupport_bot/botlogging/delayed.py index 408bcdc4e..81258dd50 100644 --- a/techsupport_bot/botlogging/delayed.py +++ b/techsupport_bot/botlogging/delayed.py @@ -25,7 +25,6 @@ def __init__(self, *args: tuple, **kwargs: dict[str, Any]) -> None: super().__init__(*args, **kwargs) async def send_log(self, *args: tuple, **kwargs: dict[str, Any]) -> None: - """Adds a log to the queue Does nothing different than the Logger send_log function() Will disregard debug logs if debug is off