diff --git a/.flake8 b/.flake8 index c24d03d63..48b31fad5 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,4 @@ [flake8] -ignore = DCO010, DCO023, E203, E501, E712, F401, F403, F821, W503 +ignore = DCO010, DCO023, DOC602, DOC603, E203, E501, E712, F401, F403, F821, W503 style = google skip-checking-short-docstrings = False \ No newline at end of file diff --git a/Pipfile b/Pipfile index 244835203..f42392224 100644 --- a/Pipfile +++ b/Pipfile @@ -29,7 +29,7 @@ typing_extensions = "==4.8.0" pip = "==24.1.2" pipenv = "==2024.0.1" pydantic = "==2.8.2" -pydoclint = "==0.4.1" +pydoclint = "==0.5.6" pylint = "==3.2.6" pynacl = "==1.5.0" pytest = "==8.3.1" diff --git a/Pipfile.lock b/Pipfile.lock index 399ee8bed..91bbbfbd3 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "9e8ec7097b35f17e7f9113affa151956360bcbd62640faf7cde844b24850c4fe" + "sha256": "cdf8a57383490b0e566fe0673f6461e15d33f09daac68c5599b5971cf70ece1e" }, "pipfile-spec": 6, "requires": { @@ -364,11 +364,11 @@ }, "docstring-parser-fork": { "hashes": [ - "sha256:59d3b00d42ba9f4e229a7df7e1f6fc742845f88a1190973cc33ba336a5405425", - "sha256:88098ae01b0909b241954ad2c50c0c29ec2292223366a540bfd68332be8fd595" + "sha256:0be85ad00cb25bf5beeb673e46e777facf0f47552fa3a7570d120ef7e3374401", + "sha256:95b23cc5092af85080c716a6da68360f5ae4fcffa75f4a3aca5e539783cbcc3d" ], "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==0.0.8" + "version": "==0.0.9" }, "emoji": { "hashes": [ @@ -967,12 +967,12 @@ }, "pydoclint": { "hashes": [ - "sha256:4e32fdf0a47a2199377617f09af0a82a2157f80543026f919a17112a396e752f", - "sha256:d39ed26a793203afadb1917011710fbf258ac3dddcd79b53212e0a2107221643" + "sha256:903a33a25504df85b200d3a3f1207688de208890b79730ceb6045978864ba7c9", + "sha256:991d336a8058d482e581f55e0b140c5757ce11d2baa2d2fca94b8f678c03831b" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==0.4.1" + "version": "==0.5.6" }, "pyflakes": { "hashes": [ diff --git a/techsupport_bot/bot.py b/techsupport_bot/bot.py index 9909e9edb..b4413f4b5 100644 --- a/techsupport_bot/bot.py +++ b/techsupport_bot/bot.py @@ -39,7 +39,7 @@ class TechSupportBot(commands.Bot): allowed_mentions (discord.AllowedMentions): What the bot is, or is not, allowed to mention - Attrs: + Attributes: CONFIG_PATH (str): The hard coded path to the yaml config file EXTENSIONS_DIR_NAME (str): The hardcoded folder for commands EXTENSIONS_DIR (str): The list of all files in the EXTENSIONS_DIR_NAME folder diff --git a/techsupport_bot/botlogging/common.py b/techsupport_bot/botlogging/common.py index 3e4e25b9c..bc2317162 100644 --- a/techsupport_bot/botlogging/common.py +++ b/techsupport_bot/botlogging/common.py @@ -12,17 +12,17 @@ class LogLevel(Enum): """This is a way to map log levels to strings, and have the easy ability to dynamically add or remove log levels - Attrs: + Attributes: DEBUG (str): Representation of debug INFO (str): Representation of info WARNING (str): Representation of warning ERROR (str): Representation of error """ - DEBUG = "debug" - INFO = "info" - WARNING = "warning" - ERROR = "error" + DEBUG: str = "debug" + INFO: str = "info" + WARNING: str = "warning" + ERROR: str = "error" @dataclass @@ -30,9 +30,9 @@ class LogContext: """A very simple class to store a few contextual items about the log This is used to determine if some guild settings means the log shouldn't be logged - Attrs: + Attributes: guild (discord.Guild | None): The guild the log occured with. Optional - channel (discord.abc.Messageble | None): The channel, DM, thread, + channel (discord.abc.Messageable | None): The channel, DM, thread, or other messagable the log occured in """ diff --git a/techsupport_bot/botlogging/embed.py b/techsupport_bot/botlogging/embed.py index c24122bc7..c941eb93d 100644 --- a/techsupport_bot/botlogging/embed.py +++ b/techsupport_bot/botlogging/embed.py @@ -15,13 +15,13 @@ class LogEmbed(discord.Embed): Args: message (str): The message to log. Will become the description of an embed - Attrs: + Attributes: title (str): The title of the embed color (discord.Color): The color of the embed """ - title = None - color = None + title: str = None + color: discord.Color = None def __init__(self: Self, message: str) -> None: super().__init__( @@ -49,46 +49,46 @@ def modify_embed(self: Self, embed: discord.Embed) -> discord.Embed: class InfoEmbed(LogEmbed): """Embed for info level log events. - Attrs: + Attributes: title (str): The title of the embed color (discord.Color): The color of the embed """ - title = "info" - color = discord.Color.green() + title: str = "info" + color: discord.Color = discord.Color.green() class DebugEmbed(LogEmbed): """Embed for debug level log events. - Attrs: + Attributes: title (str): The title of the embed color (discord.Color): The color of the embed """ - title = "debug" - color = discord.Color.dark_green() + title: str = "debug" + color: discord.Color = discord.Color.dark_green() class WarningEmbed(LogEmbed): """Embed for warning level log events. - Attrs: + Attributes: title (str): The title of the embed color (discord.Color): The color of the embed """ - title = "warning" - color = discord.Color.gold() + title: str = "warning" + color: discord.Color = discord.Color.gold() class ErrorEmbed(LogEmbed): """Embed for error level log events. - Attrs: + Attributes: title (str): The title of the embed color (discord.Color): The color of the embed """ - title = "error" - color = discord.Color.red() + title: str = "error" + color: discord.Color = discord.Color.red() diff --git a/techsupport_bot/commands/__init__.py b/techsupport_bot/commands/__init__.py index ab0153aab..ac6cbd267 100644 --- a/techsupport_bot/commands/__init__.py +++ b/techsupport_bot/commands/__init__.py @@ -16,5 +16,6 @@ from .linter import * from .listen import * from .mock import * +from .relay import * from .roll import * from .wyr import * diff --git a/techsupport_bot/commands/animal.py b/techsupport_bot/commands/animal.py index 9e288b236..9062b583d 100644 --- a/techsupport_bot/commands/animal.py +++ b/techsupport_bot/commands/animal.py @@ -24,17 +24,17 @@ async def setup(bot: bot.TechSupportBot) -> None: class Animals(cogs.BaseCog): """The class for the animals commands - Attrs: + Attributes: CAT_API_URL (str): The URL for the cat API DOG_API_URL (str): The URL for the dog API FOX_API_URL (str): The URL for the fox API FROG_API_URL (str): The URL for the frog API """ - CAT_API_URL = "https://api.thecatapi.com/v1/images/search?limit=1&api_key={}" - DOG_API_URL = "https://dog.ceo/api/breeds/image/random" - FOX_API_URL = "https://randomfox.ca/floof/" - FROG_API_URL = "https://frogs.media/api/random" + CAT_API_URL: str = "https://api.thecatapi.com/v1/images/search?limit=1&api_key={}" + DOG_API_URL: str = "https://dog.ceo/api/breeds/image/random" + FOX_API_URL: str = "https://randomfox.ca/floof/" + FROG_API_URL: str = "https://frogs.media/api/random" @auxiliary.with_typing @commands.command(name="cat", brief="Gets a cat", description="Gets a cat") diff --git a/techsupport_bot/commands/application.py b/techsupport_bot/commands/application.py index 06190bbfd..186f5d5cd 100644 --- a/techsupport_bot/commands/application.py +++ b/techsupport_bot/commands/application.py @@ -20,17 +20,17 @@ class ApplicationStatus(Enum): """Static string mapping of all status This is so the database can always be consistent - Attrs: + Attributes: PENDING (str): The string representation for pending APPROVED (str): The string representation for approved DENIED (str): The string representation for denied REJECTED (str): The string representation for rejected """ - PENDING = "pending" - APPROVED = "approved" - DENIED = "denied" - REJECTED = "rejected" + PENDING: str = "pending" + APPROVED: str = "approved" + DENIED: str = "denied" + REJECTED: str = "rejected" async def setup(bot: bot.TechSupportBot) -> None: @@ -198,11 +198,11 @@ async def wait(self: Self, config: munch.Munch, guild: discord.Guild) -> None: class ApplicationManager(cogs.LoopCog): """This cog is responsible for the majority of functions in the application system - Attrs: + Attributes: application_group (app_commands.Group): The group for the /application commands """ - application_group = app_commands.Group( + application_group: app_commands.Group = app_commands.Group( name="application", description="...", extras={"module": "application"} ) diff --git a/techsupport_bot/commands/burn.py b/techsupport_bot/commands/burn.py index fceed45b5..8d0c3b46c 100644 --- a/techsupport_bot/commands/burn.py +++ b/techsupport_bot/commands/burn.py @@ -29,11 +29,11 @@ async def setup(bot: bot.TechSupportBot) -> None: class Burn(cogs.BaseCog): """Class for Burn command on the discord bot. - Attrs: + Attributes: PHRASES (list[str]): The list of phrases to pick from """ - PHRASES = [ + PHRASES: list[str] = [ "Sick BURN!", "Someone is going to need ointment for that BURN!", "Fire! Call 911! Someone just got BURNED!", diff --git a/techsupport_bot/commands/chatgpt.py b/techsupport_bot/commands/chatgpt.py index 55e35a4ee..8628af51b 100644 --- a/techsupport_bot/commands/chatgpt.py +++ b/techsupport_bot/commands/chatgpt.py @@ -48,12 +48,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class ChatGPT(cogs.BaseCog): """Main extension class - Attrs: + Attributes: API_URL (str): The URL for the openai API SYSTEM_PROMPT (dict[str, str]): The default starting prompt for chatGPT """ - API_URL = "https://api.openai.com/v1/chat/completions" + API_URL: str = "https://api.openai.com/v1/chat/completions" async def preconfig(self: Self) -> None: """Sets up the dict""" @@ -62,7 +62,7 @@ async def preconfig(self: Self) -> None: max_age_seconds=3600, ) - SYSTEM_PROMPT = [ + SYSTEM_PROMPT: dict[str, str] = [ { "role": "system", "content": ( diff --git a/techsupport_bot/commands/conch.py b/techsupport_bot/commands/conch.py index 7256e3f41..a574e53b9 100644 --- a/techsupport_bot/commands/conch.py +++ b/techsupport_bot/commands/conch.py @@ -29,13 +29,13 @@ async def setup(bot: bot.TechSupportBot) -> None: class MagicConch(cogs.BaseCog): """Class to create the conch command for discord bot. - Attrs: + Attributes: RESPONSES (list[str]): The list of random responses for the 8 ball PIC_URL (str): The direct URL for the picture to put in embeds """ - RESPONSES = [ + RESPONSES: list[str] = [ "As I see it, yes.", "Ask again later.", "Better not tell you now.", @@ -57,7 +57,7 @@ class MagicConch(cogs.BaseCog): "Yes - definitely.", "You may rely on it.", ] - PIC_URL = "https://i.imgur.com/vdvGrsR.png" + PIC_URL: str = "https://i.imgur.com/vdvGrsR.png" def format_question(self: Self, question: str) -> str: """This formats a question properly. It will crop it if needed, and add a "?" to the end diff --git a/techsupport_bot/commands/duck.py b/techsupport_bot/commands/duck.py index 3dddd060a..1f7cdfe23 100644 --- a/techsupport_bot/commands/duck.py +++ b/techsupport_bot/commands/duck.py @@ -93,7 +93,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class DuckHunt(cogs.LoopCog): """Class for the actual duck commands - Attrs: + Attributes: DUCK_PIC_URL (str): The picture for the duck BEFRIEND_URL (str): The picture for the befriend target KILL_URL (str): The picture for the kill target @@ -101,14 +101,18 @@ class DuckHunt(cogs.LoopCog): CHANNELS_KEY (str): The config item for the channels that the duck hunt should run """ - DUCK_PIC_URL = "https://cdn.icon-icons.com/icons2/1446/PNG/512/22276duck_98782.png" - BEFRIEND_URL = ( + DUCK_PIC_URL: str = ( + "https://cdn.icon-icons.com/icons2/1446/PNG/512/22276duck_98782.png" + ) + BEFRIEND_URL: str = ( "https://cdn.icon-icons.com/icons2/603/PNG/512/" + "heart_love_valentines_relationship_dating_date_icon-icons.com_55985.png" ) - KILL_URL = "https://cdn.icon-icons.com/icons2/1919/PNG/512/huntingtarget_122049.png" - ON_START = False - CHANNELS_KEY = "hunt_channels" + KILL_URL: str = ( + "https://cdn.icon-icons.com/icons2/1919/PNG/512/huntingtarget_122049.png" + ) + ON_START: bool = False + CHANNELS_KEY: str = "hunt_channels" async def loop_preconfig(self: Self) -> None: """Preconfig for cooldowns""" diff --git a/techsupport_bot/commands/emoji.py b/techsupport_bot/commands/emoji.py index 8e8153834..56d496d79 100644 --- a/techsupport_bot/commands/emoji.py +++ b/techsupport_bot/commands/emoji.py @@ -31,11 +31,11 @@ async def setup(bot: bot.TechSupportBot) -> None: class Emojis(cogs.BaseCog): """Class for all the emoji commands - Attrs: + Attributes: KEY_MAP (dict[str,str]): Some manual mappings from character to emoji """ - KEY_MAP = {"?": "question", "!": "exclamation"} + KEY_MAP: dict[str, str] = {"?": "question", "!": "exclamation"} @classmethod def emoji_from_char(cls: Self, char: str) -> str: diff --git a/techsupport_bot/commands/extension.py b/techsupport_bot/commands/extension.py index 1f6d1f7c7..7891a58de 100644 --- a/techsupport_bot/commands/extension.py +++ b/techsupport_bot/commands/extension.py @@ -37,11 +37,11 @@ class ExtensionControl(cogs.BaseCog): """ The class that holds the extension commands - Attrs: + Attributes: extension_app_command_group (app_commands.Group): The group for the /extension commands """ - extension_app_command_group = app_commands.Group( + extension_app_command_group: app_commands.Group = app_commands.Group( name="extension", description="...", extras={"module": "extension"} ) diff --git a/techsupport_bot/commands/factoids.py b/techsupport_bot/commands/factoids.py index 91a3c9106..d82618639 100644 --- a/techsupport_bot/commands/factoids.py +++ b/techsupport_bot/commands/factoids.py @@ -168,7 +168,7 @@ class CalledFactoid: """A class to allow keeping the original factoid name in tact Without having to call the database lookup function every time - Attrs: + Attributes: original_call_str (str): The original name the user provided for a factoid factoid_db_entry (bot.models.Factoid): The database entry for the original factoid """ @@ -181,35 +181,35 @@ class Properties(Enum): """ This enum is for the new factoid all to be able to handle dynamic properties - Attrs: + Attributes: HIDDEN (str): Representation of hidden DISABLED (str): Representation of disabled RESTRICTED (str): Representation of restricted PROTECTED (str): Representation of protected """ - HIDDEN = "hidden" - DISABLED = "disabled" - RESTRICTED = "restricted" - PROTECTED = "protected" + HIDDEN: str = "hidden" + DISABLED: str = "disabled" + RESTRICTED: str = "restricted" + PROTECTED: str = "protected" class FactoidManager(cogs.MatchCog): """ Manages all factoid features - Attrs: + Attributes: CRON_REGEX (str): The regex to check if a cronjob is correct factoid_app_group (app_commands.Group): Group for /factoid commands """ - CRON_REGEX = ( + CRON_REGEX: str = ( r"^((\*|([0-5]?\d|\*\/\d+)(-([0-5]?\d))?)(,\s*(\*|([0-5]?\d|\*\/\d+)(-([0-5]" + r"?\d))?)){0,59}\s+){4}(\*|([0-7]?\d|\*(\/[1-9]|[1-5]\d)|mon|tue|wed|thu|fri|sat|sun" + r")|\*\/[1-9])$" ) - factoid_app_group = app_commands.Group( + factoid_app_group: app_commands.Group = app_commands.Group( name="factoid", description="Command Group for the Factoids Extension" ) diff --git a/techsupport_bot/commands/giphy.py b/techsupport_bot/commands/giphy.py index 47e8c0505..9f2b276a3 100644 --- a/techsupport_bot/commands/giphy.py +++ b/techsupport_bot/commands/giphy.py @@ -35,13 +35,13 @@ async def setup(bot: bot.TechSupportBot) -> None: class Giphy(cogs.BaseCog): """Class for the giphy extension. - Attrs: + Attributes: GIPHY_URL (str): The URL for the giphy API SEARCH_LIMIT (int): The max amount of gifs to search for """ - GIPHY_URL = "http://api.giphy.com/v1/gifs/search?q={}&api_key={}&limit={}" - SEARCH_LIMIT = 10 + GIPHY_URL: str = "http://api.giphy.com/v1/gifs/search?q={}&api_key={}&limit={}" + SEARCH_LIMIT: int = 10 @staticmethod def parse_url(url: str) -> str: diff --git a/techsupport_bot/commands/github.py b/techsupport_bot/commands/github.py index 689db0b5b..e0e34f55d 100644 --- a/techsupport_bot/commands/github.py +++ b/techsupport_bot/commands/github.py @@ -50,12 +50,12 @@ class IssueCreator(cogs.BaseCog): """ The class that holds the issue commands - Attrs: + Attributes: GITHUB_API_BASE_URL (str): The URL for the github API """ - GITHUB_API_BASE_URL = "https://api.github.com" + GITHUB_API_BASE_URL: str = "https://api.github.com" @commands.check(auxiliary.bot_admin_check_context) @auxiliary.with_typing diff --git a/techsupport_bot/commands/google.py b/techsupport_bot/commands/google.py index 580af1922..75db5faca 100644 --- a/techsupport_bot/commands/google.py +++ b/techsupport_bot/commands/google.py @@ -47,15 +47,17 @@ async def setup(bot: bot.TechSupportBot) -> None: class Googler(cogs.BaseCog): """Class for the google extension for the discord bot. - Attrs: + Attributes: GOOGLE_URL (str): The API URL for google search YOUTUBE_URL (str): The API URL for youtube search ICON_URL (str): The google icon """ - GOOGLE_URL = "https://www.googleapis.com/customsearch/v1" - YOUTUBE_URL = "https://www.googleapis.com/youtube/v3/search?part=id&maxResults=10" - ICON_URL = ( + GOOGLE_URL: str = "https://www.googleapis.com/customsearch/v1" + YOUTUBE_URL: str = ( + "https://www.googleapis.com/youtube/v3/search?part=id&maxResults=10" + ) + ICON_URL: str = ( "https://cdn.icon-icons.com/icons2/673/PNG/512/Google_icon-icons.com_60497.png" ) diff --git a/techsupport_bot/commands/grab.py b/techsupport_bot/commands/grab.py index 690621db5..1d278a858 100644 --- a/techsupport_bot/commands/grab.py +++ b/techsupport_bot/commands/grab.py @@ -71,11 +71,11 @@ async def invalid_channel(ctx: commands.Context) -> bool: class Grabber(cogs.BaseCog): """Class for the actual commands - Attrs: + Attributes: SEARCH_LIMIT (int): The max amount of messages to search when grabbing """ - SEARCH_LIMIT = 20 + SEARCH_LIMIT: int = 20 @auxiliary.with_typing @commands.guild_only() diff --git a/techsupport_bot/commands/hangman.py b/techsupport_bot/commands/hangman.py index b79be7feb..12300e9c1 100644 --- a/techsupport_bot/commands/hangman.py +++ b/techsupport_bot/commands/hangman.py @@ -37,7 +37,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class HangmanGame: """Class for the game hangman. - Attrs: + Attributes: HANG_PICS (list[str]): The list of hangman pictures FINAL_STEP (int): The last step of the hangman game finished (bool): Determines if the game has been finished or not @@ -50,7 +50,7 @@ class HangmanGame: ValueError: A valid alphabetic word wasn't provided """ - HANG_PICS = [ + HANG_PICS: list[str] = [ """ +---+ | | @@ -108,7 +108,7 @@ class HangmanGame: | =========""", ] - FINAL_STEP = len(HANG_PICS) - 1 + FINAL_STEP: int = len(HANG_PICS) - 1 def __init__(self: Self, word: str) -> None: if not word or "_" in word or not word.isalpha(): diff --git a/techsupport_bot/commands/help.py b/techsupport_bot/commands/help.py index edc77f3a0..3752f15fd 100644 --- a/techsupport_bot/commands/help.py +++ b/techsupport_bot/commands/help.py @@ -21,7 +21,7 @@ class PrintableCommand: """A custom class to store formatted information about a command With a priority on being sortable and searchable - Attrs: + Attributes: prefix (str): The prefix to call the command with name (str): The command name usage (str): The usage hints for the command diff --git a/techsupport_bot/commands/hug.py b/techsupport_bot/commands/hug.py index 6cf5286a9..29b157cbf 100644 --- a/techsupport_bot/commands/hug.py +++ b/techsupport_bot/commands/hug.py @@ -25,13 +25,13 @@ async def setup(bot: bot.TechSupportBot) -> None: class Hugger(cogs.BaseCog): """Class to make the hug command. - Attrs: + Attributes: HUGS_SELECTION (list[str]): The list of hug phrases to display ICON_URL (str): The icon to use when hugging """ - HUGS_SELECTION = [ + HUGS_SELECTION: list[str] = [ "{user_giving_hug} hugs {user_to_hug} forever and ever and ever", "{user_giving_hug} wraps arms around {user_to_hug} and clings forever", "{user_giving_hug} hugs {user_to_hug} and gives their hair a sniff", @@ -45,7 +45,7 @@ class Hugger(cogs.BaseCog): "{user_giving_hug} smothers {user_to_hug} with a loving hug", "{user_giving_hug} squeezes {user_to_hug} to death", ] - ICON_URL = ( + ICON_URL: str = ( "https://cdn.icon-icons.com/icons2/1648/PNG/512/10022huggingface_110042.png" ) diff --git a/techsupport_bot/commands/ipinfo.py b/techsupport_bot/commands/ipinfo.py index 4d46cc511..2f147aa82 100644 --- a/techsupport_bot/commands/ipinfo.py +++ b/techsupport_bot/commands/ipinfo.py @@ -24,13 +24,13 @@ async def setup(bot: bot.TechSupportBot) -> None: class IPInfo(cogs.BaseCog): """Class to add ipinfo geodata to the bot. - Attrs: + Attributes: API_URL (str): The API url for IP info IP_ICON_URL (str): The URL for the IP info icon """ - API_URL = "https://ipinfo.io" - IP_ICON_URL = ( + API_URL: str = "https://ipinfo.io" + IP_ICON_URL: str = ( "https://cdn.icon-icons.com/icons2/1858/PNG/512/" "iconfinder-dedicatedipaddress-4263513_117864.png" ) diff --git a/techsupport_bot/commands/iss.py b/techsupport_bot/commands/iss.py index 90d290958..e79f1ef3c 100644 --- a/techsupport_bot/commands/iss.py +++ b/techsupport_bot/commands/iss.py @@ -24,14 +24,14 @@ async def setup(bot: bot.TechSupportBot) -> None: class ISSLocator(cogs.BaseCog): """Class to locate the ISS at its current position. - Attrs: + Attributes: ISS_URL (str): The API URL to get the location of the ISS GEO_URL (str): The API URL to turn lat/lon to location """ - ISS_URL = "http://api.open-notify.org/iss-now.json" - GEO_URL = "https://geocode.xyz/{},{}?geoit=json" + ISS_URL: str = "http://api.open-notify.org/iss-now.json" + GEO_URL: str = "https://geocode.xyz/{},{}?geoit=json" @auxiliary.with_typing @commands.command( diff --git a/techsupport_bot/commands/joke.py b/techsupport_bot/commands/joke.py index 4137bf8e3..4e8f0d5ca 100644 --- a/techsupport_bot/commands/joke.py +++ b/techsupport_bot/commands/joke.py @@ -37,12 +37,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class Joker(cogs.BaseCog): """Class to make up the joke extension. - Attrs: + Attributes: API_URL (str): The joke API URL """ - API_URL = "https://v2.jokeapi.dev/joke/Any" + API_URL: str = "https://v2.jokeapi.dev/joke/Any" async def call_api( self: Self, ctx: commands.Context, config: munch.Munch diff --git a/techsupport_bot/commands/kanye.py b/techsupport_bot/commands/kanye.py index ca8f5fa20..66e21e34d 100644 --- a/techsupport_bot/commands/kanye.py +++ b/techsupport_bot/commands/kanye.py @@ -51,13 +51,13 @@ async def setup(bot: bot.TechSupportBot) -> None: class KanyeQuotes(cogs.LoopCog): """Class to get the Kanye quotes from the api. - Attrs: + Attributes: API_URL (str): The Kanye API URL KANYE_PICS (list[str]): The list of Kanye pics to pick from randomly """ - API_URL = "https://api.kanye.rest" - KANYE_PICS = [ + API_URL: str = "https://api.kanye.rest" + KANYE_PICS: list[str] = [ "https://i.imgur.com/ITmTXGz.jpg", "https://i.imgur.com/o8BkPrL.jpg", "https://i.imgur.com/sA5qP3F.jpg", diff --git a/techsupport_bot/commands/lenny.py b/techsupport_bot/commands/lenny.py index c38efc9fa..672449a4e 100644 --- a/techsupport_bot/commands/lenny.py +++ b/techsupport_bot/commands/lenny.py @@ -25,12 +25,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class Lenny(cogs.BaseCog): """Class for lenny extension. - Attrs: + Attributes: LENNYS_SELECTION (list[str]): The list of lenny faces to pick one randomly """ - LENNYS_SELECTION = [ + LENNYS_SELECTION: list[str] = [ "( ͡° ͜ʖ ͡°)", "( ͠° ͟ʖ ͡°)", "( ͡ʘ ͜ʖ ͡ʘ)", diff --git a/techsupport_bot/commands/news.py b/techsupport_bot/commands/news.py index 9488e7417..a5959526d 100644 --- a/techsupport_bot/commands/news.py +++ b/techsupport_bot/commands/news.py @@ -71,7 +71,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class Category(enum.Enum): """Class to set up categories for the news. - Attrs: + Attributes: BUSINESS (str): The string representation for business ENTERTAINMENT (str): The string representation for entertainment GENERAL (str): The string representation for general @@ -82,24 +82,24 @@ class Category(enum.Enum): """ - BUSINESS = "business" - ENTERTAINMENT = "entertainment" - GENERAL = "general" - HEALTH = "health" - SCIENCE = "science" - SPORTS = "sports" - TECH = "technology" + BUSINESS: str = "business" + ENTERTAINMENT: str = "entertainment" + GENERAL: str = "general" + HEALTH: str = "health" + SCIENCE: str = "science" + SPORTS: str = "sports" + TECH: str = "technology" class News(cogs.LoopCog): """Class to set up the news extension for the discord bot. - Attrs: + Attributes: API_URL (str): The news API URL """ - API_URL = "http://newsapi.org/v2/top-headlines?apiKey={}&country={}" + API_URL: str = "http://newsapi.org/v2/top-headlines?apiKey={}&country={}" async def preconfig(self: Self) -> None: """Sets up the list of valid categories in a class wide variable""" diff --git a/techsupport_bot/commands/poll.py b/techsupport_bot/commands/poll.py index 23b7c78ed..49f06d4d9 100644 --- a/techsupport_bot/commands/poll.py +++ b/techsupport_bot/commands/poll.py @@ -103,16 +103,16 @@ async def validate_data( class ReactionPoller(PollGenerator): """Class to add reactions to the poll generator. - Attrs: + Attributes: OPTION_EMOJIS (list[str]): The list of emojis to react to the message with STOP_EMOJI (str): The stop emoji to reaction to the message with EXAMPLE_DATA (dict[str, str | list[str] | int]): The example poll that the bot can use """ - OPTION_EMOJIS = ["one", "two", "three", "four", "five"] - STOP_EMOJI = "\u26d4" - EXAMPLE_DATA = { + OPTION_EMOJIS: list[str] = ["one", "two", "three", "four", "five"] + STOP_EMOJI: str = "\u26d4" + EXAMPLE_DATA: dict[str, str | list[str] | int] = { "question": "Best ice cream?", "options": ["Chocolate", "Vanilla", "Strawberry", "Cookie Dough", "Other..."], "timeout": 60, @@ -313,17 +313,17 @@ async def wait_for_results( class StrawPoller(PollGenerator): """Class to create a straw poll from discord. - Attrs: + Attributes: EXAMPLE_DATA (dict[str, str | list[str]]): The example poll that the bot can use API_URL (str): The strawpoll API URL """ - EXAMPLE_DATA = { + EXAMPLE_DATA: dict[str, str | list[str]] = { "question": "Best ice cream?", "options": ["Chocolate", "Vanilla", "Strawberry", "Cookie Dough", "Other..."], } - API_URL = "https://strawpoll.com/api/poll" + API_URL: str = "https://strawpoll.com/api/poll" @commands.group( brief="Executes a strawpoll command", diff --git a/techsupport_bot/commands/protect.py b/techsupport_bot/commands/protect.py index 7707919df..0a9515ec9 100644 --- a/techsupport_bot/commands/protect.py +++ b/techsupport_bot/commands/protect.py @@ -147,21 +147,21 @@ async def setup(bot: bot.TechSupportBot) -> None: class Protector(cogs.MatchCog): """Class for the protector command. - Attrs: + Attributes: ALERT_ICON_URL (str): The icon for the alert messages CLIPBOARD_ICON_URL (str): The icon for the paste messages CHARS_PER_NEWLINE (int): The arbitrary length of a line """ - ALERT_ICON_URL = ( + ALERT_ICON_URL: str = ( "https://cdn.icon-icons.com/icons2/2063/PNG/512/" + "alert_danger_warning_notification_icon_124692.png" ) - CLIPBOARD_ICON_URL = ( + CLIPBOARD_ICON_URL: str = ( "https://icon-icons.com/icons2/203/PNG/128/diagram-30_24487.png" ) - CHARS_PER_NEWLINE = 80 + CHARS_PER_NEWLINE: int = 80 async def preconfig(self: Self) -> None: """Method to preconfig the protect.""" diff --git a/techsupport_bot/commands/relay.py b/techsupport_bot/commands/relay.py index 481b0ff9d..dc79bcc52 100644 --- a/techsupport_bot/commands/relay.py +++ b/techsupport_bot/commands/relay.py @@ -42,12 +42,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class DiscordToIRC(cogs.MatchCog): """The discord side of the relay - Attrs: + Attributes: mapping (bidict): The dict that holds the IRC and discord mappings """ - mapping = None # bidict - discord:irc + mapping: bidict = None # bidict - discord:irc async def preconfig(self: Self) -> None: """The preconfig setup for the discord side diff --git a/techsupport_bot/commands/role.py b/techsupport_bot/commands/role.py index a04f280be..3a7c7300a 100644 --- a/techsupport_bot/commands/role.py +++ b/techsupport_bot/commands/role.py @@ -56,7 +56,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class RoleGiver(cogs.BaseCog): """The main class for the role commands - Attrs: + Attributes: role_group (app_commands.Group): The group for the /role commands Args: @@ -72,7 +72,7 @@ def __init__(self: Self, bot: bot.TechSupportBot) -> None: ) self.bot.tree.add_command(self.ctx_menu) - role_group = app_commands.Group(name="role", description="...") + role_group: app_commands.Group = app_commands.Group(name="role", description="...") async def preconfig(self: Self) -> None: """This setups the global lock on the role command, to avoid conflicts""" diff --git a/techsupport_bot/commands/roll.py b/techsupport_bot/commands/roll.py index d53a0be4d..bdab039ed 100644 --- a/techsupport_bot/commands/roll.py +++ b/techsupport_bot/commands/roll.py @@ -25,12 +25,14 @@ async def setup(bot: bot.TechSupportBot) -> None: class Roller(cogs.BaseCog): """Class for the roll command for the extension. - Attrs: + Attributes: ICON_URL (str): The URL for the dice icon """ - ICON_URL = "https://cdn.icon-icons.com/icons2/1465/PNG/512/678gamedice_100992.png" + ICON_URL: str = ( + "https://cdn.icon-icons.com/icons2/1465/PNG/512/678gamedice_100992.png" + ) @auxiliary.with_typing @commands.command( diff --git a/techsupport_bot/commands/rules.py b/techsupport_bot/commands/rules.py index d2af74920..6fff45a28 100644 --- a/techsupport_bot/commands/rules.py +++ b/techsupport_bot/commands/rules.py @@ -28,12 +28,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class Rules(cogs.BaseCog): """Class to define the rules for the extension. - Attrs: + Attributes: RULE_ICON_URL (str): The icon to use for the rules """ - RULE_ICON_URL = ( + RULE_ICON_URL: str = ( "https://cdn.icon-icons.com/icons2/907/PNG" "/512/balance-scale-of-justice_icon-icons.com_70554.png" ) diff --git a/techsupport_bot/commands/spotify.py b/techsupport_bot/commands/spotify.py index e121ac842..2b67314eb 100644 --- a/techsupport_bot/commands/spotify.py +++ b/techsupport_bot/commands/spotify.py @@ -38,7 +38,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class Spotify(cogs.BaseCog): """Class for setting up the Spotify extension. - Attrs: + Attributes: AUTH_URL: The URL for the authentication API for spotify API_URL: The URL for the search spotify API diff --git a/techsupport_bot/commands/translate.py b/techsupport_bot/commands/translate.py index be4e01ee7..36e72eb86 100644 --- a/techsupport_bot/commands/translate.py +++ b/techsupport_bot/commands/translate.py @@ -23,12 +23,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class Translator(cogs.BaseCog): """Class to set up the translate extension. - Attrs: + Attributes: API_URL (str): The translated API URL """ - API_URL = "https://api.mymemory.translated.net/get?q={}&langpair={}|{}" + API_URL: str = "https://api.mymemory.translated.net/get?q={}&langpair={}|{}" @auxiliary.with_typing @commands.command( diff --git a/techsupport_bot/commands/urban.py b/techsupport_bot/commands/urban.py index a5960ecce..6f54edd46 100644 --- a/techsupport_bot/commands/urban.py +++ b/techsupport_bot/commands/urban.py @@ -35,16 +35,16 @@ async def setup(bot: bot.TechSupportBot) -> None: class UrbanDictionary(cogs.BaseCog): """Class for setting up the urban dictionary extension. - Attrs: + Attributes: BASE_URL (str): The base API URL for urban dict SEE_MORE_URL (str): The URL to link to search results from the API ICON_URL (str): The urban dict icon URL """ - BASE_URL = "http://api.urbandictionary.com/v0/define?term=" - SEE_MORE_URL = "https://www.urbandictionary.com/define.php?term=" - ICON_URL = "https://cdn.icon-icons.com/icons2/114/PNG/512/dictionary_19159.png" + BASE_URL: str = "http://api.urbandictionary.com/v0/define?term=" + SEE_MORE_URL: str = "https://www.urbandictionary.com/define.php?term=" + ICON_URL: str = "https://cdn.icon-icons.com/icons2/114/PNG/512/dictionary_19159.png" @auxiliary.with_typing @commands.command( diff --git a/techsupport_bot/commands/who.py b/techsupport_bot/commands/who.py index f26d1bd7c..36a7a14d8 100644 --- a/techsupport_bot/commands/who.py +++ b/techsupport_bot/commands/who.py @@ -64,12 +64,12 @@ async def setup(bot: bot.TechSupportBot) -> None: class Who(cogs.BaseCog): """Class to set up who for the extension. - Attrs: + Attributes: notes (app_commands.Group): The group for the /note commands """ - notes = app_commands.Group( + notes: app_commands.Group = app_commands.Group( name="note", description="Command Group for the Notes Extension" ) diff --git a/techsupport_bot/commands/winerror.py b/techsupport_bot/commands/winerror.py index be34294ce..537c850c3 100644 --- a/techsupport_bot/commands/winerror.py +++ b/techsupport_bot/commands/winerror.py @@ -30,7 +30,7 @@ async def setup(bot: bot.TechSupportBot) -> None: class Error: """The data to pull for the error. - Attrs: + Attributes: name (str): the name of the error source (str): the header file where the error is from description (str): the description of the error @@ -46,7 +46,7 @@ class ErrorCategory: """A category of errors, based on how the error was found This contains the name of the category and a list of errors - Attrs: + Attributes: name (str): The name of the category of errors errors (list[Error]): The list of errors in the category diff --git a/techsupport_bot/commands/wolfram.py b/techsupport_bot/commands/wolfram.py index f7be3510a..08c9dddca 100644 --- a/techsupport_bot/commands/wolfram.py +++ b/techsupport_bot/commands/wolfram.py @@ -35,14 +35,16 @@ async def setup(bot: bot.TechSupportBot) -> None: class Wolfram(cogs.BaseCog): """Class to set up the wolfram extension. - Attrs: + Attributes: API_URL (str): The API URL for wolfram ICON_URL (str): The URL for the wolfram icon """ - 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" + API_URL: str = "http://api.wolframalpha.com/v1/result?appid={}&i={}" + ICON_URL: str = ( + "https://cdn.icon-icons.com/icons2/2107/PNG/512/file_type_wolfram_icon_130071.png" + ) @auxiliary.with_typing @commands.command( diff --git a/techsupport_bot/commands/xkcd.py b/techsupport_bot/commands/xkcd.py index a27d4072a..987d3ffa5 100644 --- a/techsupport_bot/commands/xkcd.py +++ b/techsupport_bot/commands/xkcd.py @@ -26,14 +26,14 @@ async def setup(bot: bot.TechSupportBot) -> None: class XKCD(cogs.BaseCog): """Class to create the xkcd for the extension. - Attrs: + Attributes: MOST_RECENT_API_URL (str): The URL for the most recent comic SPECIFIC_API_URL (str): The URL for a given number comic """ - MOST_RECENT_API_URL = "https://xkcd.com/info.0.json" - SPECIFIC_API_URL = "https://xkcd.com/%s/info.0.json" + MOST_RECENT_API_URL: str = "https://xkcd.com/info.0.json" + SPECIFIC_API_URL: str = "https://xkcd.com/%s/info.0.json" @commands.group( brief="xkcd extension parent", diff --git a/techsupport_bot/core/cogs.py b/techsupport_bot/core/cogs.py index 3f94a6198..004ae8cc2 100644 --- a/techsupport_bot/core/cogs.py +++ b/techsupport_bot/core/cogs.py @@ -18,7 +18,7 @@ class BaseCog(commands.Cog): """The base cog to use when making extensions. - Attrs: + Attributes: COG_TYPE (str): The string representation for the type of cog KEEP_COG_ON_FAILURE (bool): Whether or not to keep the cog loaded if there was an error @@ -29,8 +29,8 @@ class BaseCog(commands.Cog): if it needs to be different than the file name """ - COG_TYPE = "Base" - KEEP_COG_ON_FAILURE = False + COG_TYPE: str = "Base" + KEEP_COG_ON_FAILURE: bool = False def __init__( self: Self, @@ -97,11 +97,11 @@ class MatchCog(BaseCog): This makes the process of handling events simpler for development. - Attrs: + Attributes: COG_TYPE (str): The string representation for the type of cog """ - COG_TYPE = "Match" + COG_TYPE: str = "Match" @commands.Cog.listener() async def on_message(self: Self, message: discord.Message) -> None: @@ -182,7 +182,7 @@ class LoopCog(BaseCog): This currently doesn't utilize the tasks library. - Attrs: + Attributes: COG_TYPE (str): The string representation for the type of cog DEFAULT_WAIT (int): The default time to sleep for TRACKER_WAIT (int): The time to wait before looking for new channels diff --git a/techsupport_bot/core/custom_errors.py b/techsupport_bot/core/custom_errors.py index 372c283ca..f90f7f009 100644 --- a/techsupport_bot/core/custom_errors.py +++ b/techsupport_bot/core/custom_errors.py @@ -70,7 +70,7 @@ def __init__(self: Self, wait: int) -> None: class ErrorResponse: """Object for generating a custom error message from an exception. - Attrs: + Attributes: DEFAULT_MESSAGE (str): The default error message for unclassified errors Args: @@ -79,7 +79,7 @@ class ErrorResponse: dont_print_trace (bool): If true, the stack trace generated will not be logged """ - DEFAULT_MESSAGE = "I ran into an error processing your command" + DEFAULT_MESSAGE: str = "I ran into an error processing your command" def __init__( self: Self, diff --git a/techsupport_bot/core/databases.py b/techsupport_bot/core/databases.py index 6b342fba9..9caf9564f 100644 --- a/techsupport_bot/core/databases.py +++ b/techsupport_bot/core/databases.py @@ -23,8 +23,7 @@ class Applications(bot.db.Model): """The postgres table for applications Currenty used in application.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The automatic primary key guild_id (str): The string of the guild ID the application is in applicant_name (str): The name of the user who submitted the app @@ -32,19 +31,19 @@ class Applications(bot.db.Model): application_status (str): The string representation of the status background (str): The answer to the background question of the application reason (str): The answer to the reason question of the application - application_time (datetime): The time the application was submitted + application_time (datetime.datetime): The time the application was submitted """ __tablename__ = "applications" - pk = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) - guild_id = bot.db.Column(bot.db.String) - applicant_name = bot.db.Column(bot.db.String) - applicant_id = bot.db.Column(bot.db.String) - application_status = bot.db.Column(bot.db.String) - background = bot.db.Column(bot.db.String) - reason = bot.db.Column(bot.db.String) - application_time = bot.db.Column( + pk: int = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) + guild_id: str = bot.db.Column(bot.db.String) + applicant_name: str = bot.db.Column(bot.db.String) + applicant_id: str = bot.db.Column(bot.db.String) + application_status: str = bot.db.Column(bot.db.String) + background: str = bot.db.Column(bot.db.String) + reason: str = bot.db.Column(bot.db.String) + application_time: datetime.datetime = bot.db.Column( bot.db.DateTime, default=datetime.datetime.utcnow ) @@ -52,8 +51,7 @@ class ApplicationBans(bot.db.Model): """The postgres table for users banned from applications Currently used in application.py and who.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The automatic primary key guild_id (str): The string of the guild ID the applicant is banned in applicant_id (str): The string representation of the ID of the user @@ -61,46 +59,46 @@ class ApplicationBans(bot.db.Model): __tablename__ = "appbans" - pk = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) - guild_id = bot.db.Column(bot.db.String) - applicant_id = bot.db.Column(bot.db.String) + pk: int = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) + guild_id: str = bot.db.Column(bot.db.String) + applicant_id: str = bot.db.Column(bot.db.String) class DuckUser(bot.db.Model): """The postgres table for ducks Currently used in duck.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The automatic primary key author_id (str): The string representation of the ID of the user guild_id (str): The string of the guild ID the duckuser has participated in befriend_count (int): The amount of ducks the user has befriended kill_count (int): The amount of ducks the user has killed - updated (datetime): The last time the duck user interacted with a duck + updated (datetime.datetime): The last time the duck user interacted with a duck speed_record (float): The fastest this user has killed or friended a duck """ __tablename__ = "duckusers" - pk = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) - author_id = bot.db.Column(bot.db.String) - guild_id = bot.db.Column(bot.db.String) - befriend_count = bot.db.Column(bot.db.Integer, default=0) - kill_count = bot.db.Column(bot.db.Integer, default=0) - updated = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) - speed_record = bot.db.Column(bot.db.Float, default=80.0) + pk: int = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) + author_id: str = bot.db.Column(bot.db.String) + guild_id: str = bot.db.Column(bot.db.String) + befriend_count: int = bot.db.Column(bot.db.Integer, default=0) + kill_count: int = bot.db.Column(bot.db.Integer, default=0) + updated: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) + speed_record: float = bot.db.Column(bot.db.Float, default=80.0) class Factoid(bot.db.Model): """The postgres table for factoids Currently used in factoid.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: factoid_id (int): The primary key of the factoid name (str): The name of the factoid guild (str): The string guild ID for the guild that the factoid is in message (str): The string message of the factoid - time (datetime): When the factoid was created NOT edited + time (datetime.datetime): When the factoid was created NOT edited embed_config (str): The json of the factoid hidden (bool): If the factoid should be hidden or not protected (bool): If the factoid should be protected @@ -111,24 +109,25 @@ class Factoid(bot.db.Model): __tablename__ = "factoids" - factoid_id = bot.db.Column(bot.db.Integer, primary_key=True) - name = bot.db.Column(bot.db.String) - guild = bot.db.Column(bot.db.String) - message = bot.db.Column(bot.db.String) - time = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) - embed_config = bot.db.Column(bot.db.String, default=None) - hidden = bot.db.Column(bot.db.Boolean, default=False) - protected = bot.db.Column(bot.db.Boolean, default=False) - disabled = bot.db.Column(bot.db.Boolean, default=False) - restricted = bot.db.Column(bot.db.Boolean, default=False) - alias = bot.db.Column(bot.db.String, default=None) + factoid_id: int = bot.db.Column(bot.db.Integer, primary_key=True) + name: str = bot.db.Column(bot.db.String) + guild: str = bot.db.Column(bot.db.String) + message: str = bot.db.Column(bot.db.String) + time: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) + embed_config: str = bot.db.Column(bot.db.String, default=None) + hidden: bool = bot.db.Column(bot.db.Boolean, default=False) + protected: bool = bot.db.Column(bot.db.Boolean, default=False) + disabled: bool = bot.db.Column(bot.db.Boolean, default=False) + restricted: bool = bot.db.Column(bot.db.Boolean, default=False) + alias: str = bot.db.Column(bot.db.String, default=None) class FactoidJob(bot.db.Model): """The postgres table for factoid loops Currently used in factoid.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: job_id (int): The primary key, ID of the job factoid (int): The primary key of the linked factoid channel (str): The channel this loop needs to run in @@ -137,44 +136,44 @@ class FactoidJob(bot.db.Model): __tablename__ = "factoid_jobs" - job_id = bot.db.Column(bot.db.Integer, primary_key=True) - factoid = bot.db.Column( + job_id: int = bot.db.Column(bot.db.Integer, primary_key=True) + factoid: int = bot.db.Column( bot.db.Integer, bot.db.ForeignKey("factoids.factoid_id") ) - channel = bot.db.Column(bot.db.String) - cron = bot.db.Column(bot.db.String) + channel: str = bot.db.Column(bot.db.String) + cron: str = bot.db.Column(bot.db.String) class Grab(bot.db.Model): """The postgres table for grabs Currently used in grab.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for this database author_id (str): The ID of the author of the original grab message channel (str): The channel the message was grabbed from guild (str): The guild the message was grabbed from message (str): The string contents of the message - time (datetime): The time the message was grabbed + time (datetime.datetime): The time the message was grabbed nsfw (bool): Whether the message was grabbed in an NSFW channel """ __tablename__ = "grabs" - pk = bot.db.Column(bot.db.Integer, primary_key=True) - author_id = bot.db.Column(bot.db.String) - channel = bot.db.Column(bot.db.String) - guild = bot.db.Column(bot.db.String) - message = bot.db.Column(bot.db.String) - time = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) - nsfw = bot.db.Column(bot.db.Boolean, default=False) + pk: int = bot.db.Column(bot.db.Integer, primary_key=True) + author_id: str = bot.db.Column(bot.db.String) + channel: str = bot.db.Column(bot.db.String) + guild: str = bot.db.Column(bot.db.String) + message: str = bot.db.Column(bot.db.String) + time: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) + nsfw: bool = bot.db.Column(bot.db.Boolean, default=False) class IRCChannelMapping(bot.db.Model): """The postgres table for IRC->discord maps Currently used in relay.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: map_id (int): The primary key for the database guild_id (str): The guild where the discord channel exists at discord_channel_id (str): The ID of the discord channel @@ -182,122 +181,127 @@ class IRCChannelMapping(bot.db.Model): """ __tablename__ = "ircchannelmap" - map_id = bot.db.Column(bot.db.Integer, primary_key=True) - guild_id = bot.db.Column(bot.db.String, default=None) - discord_channel_id = bot.db.Column(bot.db.String, default=None) - irc_channel_id = bot.db.Column(bot.db.String, default=None) + + map_id: int = bot.db.Column(bot.db.Integer, primary_key=True) + guild_id: str = bot.db.Column(bot.db.String, default=None) + discord_channel_id: str = bot.db.Column(bot.db.String, default=None) + irc_channel_id: str = bot.db.Column(bot.db.String, default=None) class ModmailBan(bot.db.Model): """The postgres table for modmail bans Currently used in modmail.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: user_id (str): The ID of the user banned from modmail """ __tablename__ = "modmail_bans" - user_id = bot.db.Column(bot.db.String, default=None, primary_key=True) + + user_id: str = bot.db.Column(bot.db.String, default=None, primary_key=True) class UserNote(bot.db.Model): """The postgres table for notes Currently used in who.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for this database user_id (str): The user ID that has a note guild_id (str): The guild ID that the note belongs to - updated (datetime): The time the note was created on + updated (datetime.datetime): The time the note was created on author_id (str): The author of the note body (str): The contents of the note """ __tablename__ = "usernote" - pk = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) - user_id = bot.db.Column(bot.db.String) - guild_id = bot.db.Column(bot.db.String) - updated = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) - author_id = bot.db.Column(bot.db.String) - body = bot.db.Column(bot.db.String) + pk: int = bot.db.Column(bot.db.Integer, primary_key=True, autoincrement=True) + user_id: str = bot.db.Column(bot.db.String) + guild_id: str = bot.db.Column(bot.db.String) + updated: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) + author_id: str = bot.db.Column(bot.db.String) + body: str = bot.db.Column(bot.db.String) class Warning(bot.db.Model): """The postgres table for warnings Currently used in protect.py and who.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for the database user_id (str): The user who got warned guild_id (str): The guild this warn occured in reason (str): The reason for the warn - time (datetime): The time the warning was given + time (datetime.datetime): The time the warning was given """ __tablename__ = "warnings" - pk = bot.db.Column(bot.db.Integer, primary_key=True) - user_id = bot.db.Column(bot.db.String) - guild_id = bot.db.Column(bot.db.String) - reason = bot.db.Column(bot.db.String) - time = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) + + pk: int = bot.db.Column(bot.db.Integer, primary_key=True) + user_id: str = bot.db.Column(bot.db.String) + guild_id: str = bot.db.Column(bot.db.String) + reason: str = bot.db.Column(bot.db.String) + time: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) class Config(bot.db.Model): """The postgres table for guild config Currently used nearly everywhere - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for the database guild_id (str): The ID of the guild this config is for config (str): The config text - update_time (datetime): The time the config was last updated + update_time (datetime.datetime): The time the config was last updated """ __tablename__ = "guild_config" - pk = bot.db.Column(bot.db.Integer, primary_key=True) - guild_id = bot.db.Column(bot.db.String) - config = bot.db.Column(bot.db.String) - update_time = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) + + pk: int = bot.db.Column(bot.db.Integer, primary_key=True) + guild_id: str = bot.db.Column(bot.db.String) + config: str = bot.db.Column(bot.db.String) + update_time: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) class Listener(bot.db.Model): """The postgres table for listeners Currently used in listen.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for the database src_id (str): The source channel for the listener dst_id (str): The destination channel for the listener """ __tablename__ = "listeners" - pk = bot.db.Column(bot.db.Integer, primary_key=True) - src_id = bot.db.Column(bot.db.String) - dst_id = bot.db.Column(bot.db.String) + + pk: int = bot.db.Column(bot.db.Integer, primary_key=True) + src_id: str = bot.db.Column(bot.db.String) + dst_id: str = bot.db.Column(bot.db.String) class Rule(bot.db.Model): """The postgres table for rules Currently used in rules.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: pk (int): The primary key for the database guild_id (str): The ID of the guild that these rules are for rules (str): The json representation of the rules """ __tablename__ = "guild_rules" - pk = bot.db.Column(bot.db.Integer, primary_key=True) - guild_id = bot.db.Column(bot.db.String) - rules = bot.db.Column(bot.db.String) + + pk: int = bot.db.Column(bot.db.Integer, primary_key=True) + guild_id: str = bot.db.Column(bot.db.String) + rules: str = bot.db.Column(bot.db.String) class Votes(bot.db.Model): """The postgres table for votes Currently used in voting.py - Attrs: - __tablename__ (str): The name of the table in postgres + Attributes: vote_id (int): The primary key of the vote guild_id (str): The guild the vote belongs to message_id (str): The ID of the message the vote is in @@ -310,29 +314,32 @@ class Votes(bot.db.Model): votes_yes (int): The number of votes for yes votes_no (int): The number of votes for no votes_total (int): The number of votes - start_time (datetime): The start time of the vote + start_time (datetime.datetime): The start time of the vote vote_active (bool): If the vote is current active or not blind (bool): If the vote needs to be blind anonymous (bool): If the vote needs to be anonymous """ __tablename__ = "voting" - vote_id = bot.db.Column(bot.db.Integer, primary_key=True) - guild_id = bot.db.Column(bot.db.String) - message_id = bot.db.Column(bot.db.String) - thread_id = bot.db.Column(bot.db.String) - vote_owner_id = bot.db.Column(bot.db.String) - vote_description = bot.db.Column(bot.db.String) - vote_ids_yes = bot.db.Column(bot.db.String, default="") - vote_ids_no = bot.db.Column(bot.db.String, default="") - vote_ids_all = bot.db.Column(bot.db.String, default="") - votes_yes = bot.db.Column(bot.db.Integer, default=0) - votes_no = bot.db.Column(bot.db.Integer, default=0) - votes_total = bot.db.Column(bot.db.Integer, default=0) - start_time = bot.db.Column(bot.db.DateTime, default=datetime.datetime.utcnow) - vote_active = bot.db.Column(bot.db.Boolean, default=True) - blind = bot.db.Column(bot.db.Boolean, default=False) - anonymous = bot.db.Column(bot.db.Boolean, default=False) + + vote_id: int = bot.db.Column(bot.db.Integer, primary_key=True) + guild_id: str = bot.db.Column(bot.db.String) + message_id: str = bot.db.Column(bot.db.String) + thread_id: str = bot.db.Column(bot.db.String) + vote_owner_id: str = bot.db.Column(bot.db.String) + vote_description: str = bot.db.Column(bot.db.String) + vote_ids_yes: str = bot.db.Column(bot.db.String, default="") + vote_ids_no: str = bot.db.Column(bot.db.String, default="") + vote_ids_all: str = bot.db.Column(bot.db.String, default="") + votes_yes: int = bot.db.Column(bot.db.Integer, default=0) + votes_no: int = bot.db.Column(bot.db.Integer, default=0) + votes_total: int = bot.db.Column(bot.db.Integer, default=0) + start_time: datetime.datetime = bot.db.Column( + bot.db.DateTime, default=datetime.datetime.utcnow + ) + vote_active: bool = bot.db.Column(bot.db.Boolean, default=True) + blind: bool = bot.db.Column(bot.db.Boolean, default=False) + anonymous: bool = bot.db.Column(bot.db.Boolean, default=False) bot.models.Applications = Applications bot.models.AppBans = ApplicationBans diff --git a/techsupport_bot/ircrelay/irc.py b/techsupport_bot/ircrelay/irc.py index 13b6b0f29..725f8d36b 100644 --- a/techsupport_bot/ircrelay/irc.py +++ b/techsupport_bot/ircrelay/irc.py @@ -9,6 +9,7 @@ import threading from typing import Self +import commands import discord import ib3.auth import irc.bot @@ -21,7 +22,7 @@ class IRCBot(ib3.auth.SASL, irc.bot.SingleServerIRCBot): """The IRC bot class. This is the class that runs the entire IRC side of the bot The class to start the entire IRC bot - Attrs: + Attributes: irc_cog (commands.relay.DiscordToIRC): The discord cog for the relay, to allow communication between loop (asyncio.AbstractEventLoop): The discord bots event loop @@ -40,13 +41,13 @@ class IRCBot(ib3.auth.SASL, irc.bot.SingleServerIRCBot): password (str): The password of the IRC bot account """ - irc_cog = None - loop = None - console = logging.getLogger("root") - IRC_BOLD = "" - connection = None - join_thread = None - ready = False + irc_cog: commands.relay.DiscordToIRC = None + loop: asyncio.AbstractEventLoop = None + console: logging.Logger = logging.getLogger("root") + IRC_BOLD: str = "" + connection: irc.client.ServerConnection = None + join_thread: threading.Timer = None + ready: bool = False def __init__( self: Self, diff --git a/techsupport_bot/tests/commands_tests/test_extensions_wyr.py b/techsupport_bot/tests/commands_tests/test_extensions_wyr.py index da4117983..d16490399 100644 --- a/techsupport_bot/tests/commands_tests/test_extensions_wyr.py +++ b/techsupport_bot/tests/commands_tests/test_extensions_wyr.py @@ -96,11 +96,11 @@ async def test_wyr_command_send(self: Self) -> None: class Test_Get_Question: """A set of tests to test the get_question function - Attrs: + Attributes: sample_resource (str): A set of same questions for doing unit tests """ - sample_resource = '"q1o1" || "q1o2"\n"q2o1" || "q2o2"' + sample_resource: str = '"q1o1" || "q1o2"\n"q2o1" || "q2o2"' def test_any_question(self: Self) -> None: """Ensure that get_question gets any question""" diff --git a/techsupport_bot/ui/application.py b/techsupport_bot/ui/application.py index 9ba689855..8474a00ac 100644 --- a/techsupport_bot/ui/application.py +++ b/techsupport_bot/ui/application.py @@ -12,19 +12,19 @@ class Application(discord.ui.Modal, title="Staff interest form"): """The class contianing the modal and all variables for it This must be sent as a response to an interaction, cannot be from a prefix command - Attrs: + Attributes: background (discord.ui.TextInput): The background question for the application reason (discord.ui.TextInput): The reason question for the application """ - background = discord.ui.TextInput( + background: discord.ui.TextInput = discord.ui.TextInput( label="Do you have any IT or programming experience?", style=discord.TextStyle.long, required=True, max_length=300, ) - reason = discord.ui.TextInput( + reason: discord.ui.TextInput = discord.ui.TextInput( label="Why do you want to help here?", style=discord.TextStyle.long, required=True, diff --git a/techsupport_bot/ui/appnotice.py b/techsupport_bot/ui/appnotice.py index 02df029f4..d35bb34bb 100644 --- a/techsupport_bot/ui/appnotice.py +++ b/techsupport_bot/ui/appnotice.py @@ -10,11 +10,13 @@ class AppNotice(discord.ui.View): """The view containing a button and message encouraging users to apply - Attrs: + Attributes: ICON (str): The Icon for the application reminder """ - ICON = "https://icon-icons.com/downloadimage.php?id=14692&root=80/PNG/256/&file=help_15418.png" + ICON: str = ( + "https://icon-icons.com/downloadimage.php?id=14692&root=80/PNG/256/&file=help_15418.png" + ) async def send(self: Self, channel: discord.abc.Messageable, message: str) -> None: """The entry point to this function, will send a message to the given channel diff --git a/techsupport_bot/ui/confirm.py b/techsupport_bot/ui/confirm.py index 6dc317368..2aa5e7217 100644 --- a/techsupport_bot/ui/confirm.py +++ b/techsupport_bot/ui/confirm.py @@ -12,15 +12,15 @@ class ConfirmResponse(Enum): """A class to define the 3 responses - Attrs: + Attributes: CONFIRMED (int): The original author clicked the "confirm" button DENIED (int): The original author clicked the "cancel" button TIMEOUT (int): No buttons were pressed in the timeout range """ - CONFIRMED = auto() - DENIED = auto() - TIMEOUT = auto() + CONFIRMED: int = auto() + DENIED: int = auto() + TIMEOUT: int = auto() class Confirm(discord.ui.View): diff --git a/techsupport_bot/ui/pagination.py b/techsupport_bot/ui/pagination.py index 681cf0fd8..874290f7e 100644 --- a/techsupport_bot/ui/pagination.py +++ b/techsupport_bot/ui/pagination.py @@ -14,7 +14,7 @@ class PaginateView(discord.ui.View): To use this, call the send function. Everything else is automatic - Attrs: + Attributes: current_page (int): The current page number the user is on data (list[str | discord.Embed]): The list of data for the pages timeout (int): The timeout till the buttons dissapear without interaction @@ -22,9 +22,9 @@ class PaginateView(discord.ui.View): """ current_page: int = 1 - data = None - timeout = 120 - message = "" + data: list[str | discord.Embed] = None + timeout: int = 120 + message: discord.Message = "" def add_page_numbers(self: Self) -> None: """A simple function to add page numbers to embed footer""" diff --git a/techsupport_bot/ui/vote_creation.py b/techsupport_bot/ui/vote_creation.py index ef232fc55..823054a7f 100644 --- a/techsupport_bot/ui/vote_creation.py +++ b/techsupport_bot/ui/vote_creation.py @@ -12,18 +12,18 @@ class VoteCreation(discord.ui.Modal, title="Staff voting"): """The class contianing the modal and all variables for it This must be sent as a response to an interaction, cannot be from a prefix command - Attrs: + Attributes: vote_short (discord.TextInput): The title to make the forum thread for the vote vote_reason (discord.TextInput): The main body of the vote """ - vote_short = discord.ui.TextInput( + vote_short: discord.TextInput = discord.ui.TextInput( label="What are you starting a vote for?", style=discord.TextStyle.short, required=True, max_length=94, ) - vote_reason = discord.ui.TextInput( + vote_reason: discord.TextInput = discord.ui.TextInput( label="Describe your vote", style=discord.TextStyle.paragraph, required=True,