From 9f6a05ae88b651dcc0571c03260ea6e0afced0ad Mon Sep 17 00:00:00 2001 From: bobloy Date: Sat, 5 Sep 2020 15:26:38 -0400 Subject: [PATCH 01/25] Update README.md More verbose downloader instructions --- chatter/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chatter/README.md b/chatter/README.md index e8c03d6..ecaf625 100644 --- a/chatter/README.md +++ b/chatter/README.md @@ -83,6 +83,7 @@ pip install --no-deps "chatterbot>=1.1" #### Step 3: Load Chatter ``` +[p]repo add Fox https://github.com/bobloy/Fox-V3 [p]cog install Fox chatter [p]load chatter ``` @@ -92,7 +93,7 @@ pip install --no-deps "chatterbot>=1.1" #### Step 1: Built-in Downloader ``` -[p]cog install Chatter +[p]cog install Chatter ``` #### Step 2: Install Requirements From 5eb31a277dcfb73207b45bbcb3e0cceb18d07c64 Mon Sep 17 00:00:00 2001 From: bobloy Date: Tue, 8 Sep 2020 12:27:19 -0400 Subject: [PATCH 02/25] Update README.md --- chatter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chatter/README.md b/chatter/README.md index ecaf625..9b0eb6b 100644 --- a/chatter/README.md +++ b/chatter/README.md @@ -83,7 +83,7 @@ pip install --no-deps "chatterbot>=1.1" #### Step 3: Load Chatter ``` -[p]repo add Fox https://github.com/bobloy/Fox-V3 +[p]repo add Fox https://github.com/bobloy/Fox-V3 # If you didn't already do this in step 1 [p]cog install Fox chatter [p]load chatter ``` From 2e65c137f3c082083d901876543ec2f1f5eb3a80 Mon Sep 17 00:00:00 2001 From: bobloy Date: Tue, 8 Sep 2020 15:40:40 -0400 Subject: [PATCH 03/25] Update README.md Added 64 bit python requirement for Windows --- chatter/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chatter/README.md b/chatter/README.md index 9b0eb6b..f82fd0b 100644 --- a/chatter/README.md +++ b/chatter/README.md @@ -50,7 +50,9 @@ Linux is a bit easier, but only tested on Debian and Ubuntu. ## Windows Prerequisites -Install these on your windows machine before attempting the installation +**Requires 64 Bit Python to continue on Windows.** + +Install these on your windows machine before attempting the installation: [Visual Studio C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) From b8aceb003ea494edc52eeef76f4b0c2580eb5bc8 Mon Sep 17 00:00:00 2001 From: bobloy Date: Tue, 8 Sep 2020 15:41:24 -0400 Subject: [PATCH 04/25] Update README.md Fix tyop --- chatter/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chatter/README.md b/chatter/README.md index f82fd0b..8ef6734 100644 --- a/chatter/README.md +++ b/chatter/README.md @@ -29,7 +29,7 @@ Chatter by default uses spaCy's `en_core_web_md` training model, which is ~50 MB Chatter can potential use spaCy's `en_core_web_lg` training model, which is ~800 MB -Chatter uses as sqlite database that can potentially take up a large amount os disk space, +Chatter uses as sqlite database that can potentially take up a large amount of disk space, depending on how much training Chatter has done. The sqlite database can be safely deleted at any time. Deletion will only erase training data. From 6af1d06b2c0105393638d82ec475876e31718ab4 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 10 Sep 2020 09:15:55 -0400 Subject: [PATCH 05/25] Add identifier to launchlib config in case I use it later --- launchlib/launchlib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/launchlib/launchlib.py b/launchlib/launchlib.py index e34a23d..ae870fd 100644 --- a/launchlib/launchlib.py +++ b/launchlib/launchlib.py @@ -22,7 +22,9 @@ class LaunchLib(commands.Cog): def __init__(self, bot: Red): super().__init__() self.bot = bot - self.config = Config.get_conf(self, identifier=0, force_registration=True) + self.config = Config.get_conf( + self, identifier=7697117110991047610598, force_registration=True + ) default_guild = {} From 92caf16fe977ba168ec343f7484a6ce099c42732 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 10 Sep 2020 09:17:02 -0400 Subject: [PATCH 06/25] FirstMessage initial commit --- firstmessage/__init__.py | 5 ++++ firstmessage/firstmessage.py | 48 ++++++++++++++++++++++++++++++++++++ firstmessage/info.json | 16 ++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 firstmessage/__init__.py create mode 100644 firstmessage/firstmessage.py create mode 100644 firstmessage/info.json diff --git a/firstmessage/__init__.py b/firstmessage/__init__.py new file mode 100644 index 0000000..4dab2ed --- /dev/null +++ b/firstmessage/__init__.py @@ -0,0 +1,5 @@ +from .firstmessage import FirstMessage + + +async def setup(bot): + bot.add_cog(FirstMessage(bot)) diff --git a/firstmessage/firstmessage.py b/firstmessage/firstmessage.py new file mode 100644 index 0000000..b74ea40 --- /dev/null +++ b/firstmessage/firstmessage.py @@ -0,0 +1,48 @@ +import logging + +import discord +from redbot.core import Config, commands +from redbot.core.bot import Red + +log = logging.getLogger("red.fox_v3.firstmessage") + + +class FirstMessage(commands.Cog): + """ + Provides a link to the first message in the provided channel + + Less important information about the cog + """ + + def __init__(self, bot: Red): + super().__init__() + self.bot = bot + self.config = Config.get_conf( + self, identifier=701051141151167710111511597103101, force_registration=True + ) + + default_guild = {} + + self.config.register_guild(**default_guild) + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete""" + return + + @commands.command() + async def firstmessage(self, ctx: commands.Context, channel: discord.TextChannel = None): + if channel is None: + channel = ctx.channel + try: + message: discord.Message = ( + await channel.history(limit=1, oldest_first=True).flatten() + )[0] + except (discord.Forbidden, discord.HTTPException): + log.exception(f"Unable to read message history for {channel.id=}") + await ctx.maybe_send_embed("Unable to read message history for that channel") + return + + em = discord.Embed(description=f"[First Message in {channel.mention}]({message.jump_url})") + em.set_author(name=message.author.display_name, icon_url=message.author.avatar_url) + + await ctx.send(embed=em) diff --git a/firstmessage/info.json b/firstmessage/info.json new file mode 100644 index 0000000..c01766f --- /dev/null +++ b/firstmessage/info.json @@ -0,0 +1,16 @@ +{ + "author": [ + "Bobloy" + ], + "min_bot_version": "3.4.0", + "description": "Simple cog to jump to the first message of a channel easily", + "hidden": false, + "install_msg": "Thank you for installing FirstMessage.\nGet started with `[p]load firstmessage`, then `[p]help FirstMessage`", + "short": "Simple cog to jump to first message of a channel", + "end_user_data_statement": "This cog does not store any End User Data", + "tags": [ + "bobloy", + "utilities", + "tool" + ] +} \ No newline at end of file From f9388454a5cae33f47ba79c32c3989cf943fdd68 Mon Sep 17 00:00:00 2001 From: bobloy Date: Thu, 10 Sep 2020 21:22:50 -0400 Subject: [PATCH 07/25] Another guild bug --- chatter/chat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chatter/chat.py b/chatter/chat.py index a81e669..ad8e37b 100644 --- a/chatter/chat.py +++ b/chatter/chat.py @@ -463,7 +463,7 @@ class Chatter(Cog): # Thank you Cog-Creators channel: discord.TextChannel = message.channel - if channel.id == await self.config.guild(guild).chatchannel(): + if guild is not None and channel.id == await self.config.guild(guild).chatchannel(): pass # good to go else: when_mentionables = commands.when_mentioned(self.bot, message) From cb6693f3829abe36f6c467d04501bd7920a33a04 Mon Sep 17 00:00:00 2001 From: bobloy Date: Fri, 11 Sep 2020 09:35:08 -0400 Subject: [PATCH 08/25] Add description of first message --- firstmessage/firstmessage.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/firstmessage/firstmessage.py b/firstmessage/firstmessage.py index b74ea40..f13bd60 100644 --- a/firstmessage/firstmessage.py +++ b/firstmessage/firstmessage.py @@ -10,8 +10,6 @@ log = logging.getLogger("red.fox_v3.firstmessage") class FirstMessage(commands.Cog): """ Provides a link to the first message in the provided channel - - Less important information about the cog """ def __init__(self, bot: Red): @@ -31,6 +29,9 @@ class FirstMessage(commands.Cog): @commands.command() async def firstmessage(self, ctx: commands.Context, channel: discord.TextChannel = None): + """ + Provide a link to the first message in current or provided channel. + """ if channel is None: channel = ctx.channel try: From 7092bd590b070afaba89182069f2a55068a5462f Mon Sep 17 00:00:00 2001 From: bobloy Date: Fri, 11 Sep 2020 09:43:16 -0400 Subject: [PATCH 09/25] FirstMessage added to cog list --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a9ab8f..26e39d1 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Cog Function | exclusiverole | **Alpha** |
Prevent certain roles from getting any other rolesFully functional, but pretty simple
| | fifo | **Alpha** |
Schedule commands to be run at certain times or intervalsJust released, please report bugs as you find them. Only works for bot owner for now
| | fight | **Incomplete** |
Organize bracket tournaments within discordStill in-progress, a massive project
| +| firstmessage | **Release** |
Simple cog to provide a jump link to the first message in a channel/summary>Just released, please report bugs as you find them.
| | flag | **Alpha** |
Create temporary marks on users that expire after specified timePorted, will not import old data. Please report bugs
| | forcemention | **Alpha** |
Mentions unmentionable rolesVery simple cog, mention doesn't persist
| | hangman | **Beta** |
Play a game of hangmanSome visual glitches and needs more customization
| @@ -38,7 +39,7 @@ Cog Function | unicode | **Alpha** |
Encode and Decode unicode characters[Snap-Ons] Just updated to V3
| | werewolf | **Pre-Alpha** |
Play the classic party game Werewolf within discordAnother massive project currently being developed, will be fully customizable
| -Check out my V2 cogs at [Fox-Cogs v2](https://github.com/bobloy/Fox-Cogs) +Check out *Deprecated* my V2 cogs at [Fox-Cogs v2](https://github.com/bobloy/Fox-Cogs) # Installation ### Recommended - Built-in Downloader From 260a3bc62df8bbc58ac91e4f5870c3935d29c251 Mon Sep 17 00:00:00 2001 From: bobloy Date: Fri, 11 Sep 2020 14:58:34 -0400 Subject: [PATCH 10/25] IsItDown initial commit --- isitdown/__init__.py | 5 ++++ isitdown/isitdown.py | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 isitdown/__init__.py create mode 100644 isitdown/isitdown.py diff --git a/isitdown/__init__.py b/isitdown/__init__.py new file mode 100644 index 0000000..fdebc2a --- /dev/null +++ b/isitdown/__init__.py @@ -0,0 +1,5 @@ +from .isitdown import IsItDown + + +async def setup(bot): + bot.add_cog(IsItDown(bot)) diff --git a/isitdown/isitdown.py b/isitdown/isitdown.py new file mode 100644 index 0000000..f786928 --- /dev/null +++ b/isitdown/isitdown.py @@ -0,0 +1,58 @@ +import logging +import re + +import aiohttp +from redbot.core import Config, commands +from redbot.core.bot import Red + +log = logging.getLogger("red.fox_v3.isitdown") + + +class IsItDown(commands.Cog): + """ + Cog Description + + Less important information about the cog + """ + + def __init__(self, bot: Red): + super().__init__() + self.bot = bot + self.config = Config.get_conf(self, identifier=0, force_registration=True) + + default_guild = {"iids": []} # List of tuple pairs (channel_id, website) + + self.config.register_guild(**default_guild) + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete""" + return + + @commands.command(alias=["iid"]) + async def isitdown(self, ctx: commands.Context, url_to_check): + """ + Check if the provided url is down + + Alias: iid + """ + try: + resp = await self._check_if_down(url_to_check) + except AssertionError: + await ctx.maybe_send_embed("Invalid URL provided. Make sure not to include `http://`") + return + + if resp["isitdown"]: + await ctx.maybe_send_embed(f"{url_to_check} is DOWN!") + else: + await ctx.maybe_send_embed(f"{url_to_check} is UP!") + + async def _check_if_down(self, url_to_check): + url = re.compile(r"https?://(www\.)?") + url.sub("", url_to_check).strip().strip("/") + + url = f"https://isitdown.site/api/v3/{url}" + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + assert response.status == 200 + resp = await response.json() + return resp From 360f294ca0b7c0798e5063146244f2442362fd38 Mon Sep 17 00:00:00 2001 From: bobloy Date: Fri, 11 Sep 2020 15:06:30 -0400 Subject: [PATCH 11/25] IsItDown initial commit --- README.md | 3 ++- isitdown/info.json | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 isitdown/info.json diff --git a/README.md b/README.md index 26e39d1..ec76ead 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Cog Function | forcemention | **Alpha** |
Mentions unmentionable rolesVery simple cog, mention doesn't persist
| | hangman | **Beta** |
Play a game of hangmanSome visual glitches and needs more customization
| | howdoi | **Incomplete** |
Ask coding questions and get results from StackExchangeNot yet functional
| -| infochannel | **Beta** |
Create a channel to display server infoJust released, please report bugs
| +| infochannel | **Beta** |
Create a channel to display server infoDue to rate limits, this does not update as often as it once did
| +| isitdown | **Beta** |
Check if a website/url is downJust released, please report bugs
| | launchlib | **Beta** |
Access rocket launch dataJust released, please report bugs
| | leaver | **Beta** |
Send a message in a channel when a user leaves the serverSeems to be functional, please report any bugs or suggestions
| | lovecalculator | **Alpha** |
Calculate the love between two users[Snap-Ons] Just updated to V3
| diff --git a/isitdown/info.json b/isitdown/info.json new file mode 100644 index 0000000..0a2fb07 --- /dev/null +++ b/isitdown/info.json @@ -0,0 +1,16 @@ +{ + "author": [ + "Bobloy" + ], + "min_bot_version": "3.4.0", + "description": "Check if a website/url is down using the https://isitdown.site/ api", + "hidden": false, + "install_msg": "Thank you for installing IsItDown.\nGet started with `[p]load isitdown`, then `[p]help IsItDown`", + "short": "Check if a website/url is down", + "end_user_data_statement": "This cog does not store any End User Data", + "tags": [ + "bobloy", + "utilities", + "tool" + ] +} \ No newline at end of file From 2e000b11904f2759bcfa175c73bcbb2214c8d9b9 Mon Sep 17 00:00:00 2001 From: bobloy Date: Mon, 14 Sep 2020 10:00:38 -0400 Subject: [PATCH 12/25] "tools" is more common --- fifo/info.json | 1 + firstmessage/info.json | 3 ++- isitdown/info.json | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fifo/info.json b/fifo/info.json index c9a80dd..dda63ce 100644 --- a/fifo/info.json +++ b/fifo/info.json @@ -16,6 +16,7 @@ "bobloy", "utilities", "tool", + "tools", "roles", "schedule", "cron", diff --git a/firstmessage/info.json b/firstmessage/info.json index c01766f..f656d32 100644 --- a/firstmessage/info.json +++ b/firstmessage/info.json @@ -11,6 +11,7 @@ "tags": [ "bobloy", "utilities", - "tool" + "tool", + "tools" ] } \ No newline at end of file diff --git a/isitdown/info.json b/isitdown/info.json index 0a2fb07..d321732 100644 --- a/isitdown/info.json +++ b/isitdown/info.json @@ -11,6 +11,7 @@ "tags": [ "bobloy", "utilities", - "tool" + "tool", + "tools" ] } \ No newline at end of file From 58054c7a92ddca8176ae739dd9bdafd3ef397e12 Mon Sep 17 00:00:00 2001 From: bobloy Date: Tue, 15 Sep 2020 15:39:41 -0400 Subject: [PATCH 13/25] Rate limits are for NERDS --- ccrole/ccrole.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ccrole/ccrole.py b/ccrole/ccrole.py index 190050d..77a7fd3 100644 --- a/ccrole/ccrole.py +++ b/ccrole/ccrole.py @@ -367,7 +367,6 @@ class CCRole(commands.Cog): except discord.Forbidden: log.exception(f"Permission error: Unable to add roles") await ctx.send("Permission error: Unable to add roles") - await asyncio.sleep(1) if cmd["rroles"]: rrole_list = [ From eddac5b8b2ad8df9df6f33a5315fed272ce2d800 Mon Sep 17 00:00:00 2001 From: jack1142 <6032823+jack1142@users.noreply.github.com> Date: Tue, 15 Sep 2020 23:56:07 +0200 Subject: [PATCH 14/25] [ccrole] Specify an audit log reason --- ccrole/ccrole.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ccrole/ccrole.py b/ccrole/ccrole.py index 77a7fd3..eb654b1 100644 --- a/ccrole/ccrole.py +++ b/ccrole/ccrole.py @@ -7,6 +7,7 @@ from discord.ext.commands.view import StringView from redbot.core import Config, checks, commands from redbot.core.bot import Red from redbot.core.utils.chat_formatting import box, pagify +from redbot.core.utils.mod import get_audit_reason log = logging.getLogger("red.fox_v3.ccrole") @@ -358,12 +359,14 @@ class CCRole(commands.Cog): else: target = message.author + reason = get_audit_reason(message.author) + if cmd["aroles"]: arole_list = [ discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["aroles"] ] try: - await target.add_roles(*arole_list) + await target.add_roles(*arole_list, reason=reason) except discord.Forbidden: log.exception(f"Permission error: Unable to add roles") await ctx.send("Permission error: Unable to add roles") @@ -373,7 +376,7 @@ class CCRole(commands.Cog): discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["rroles"] ] try: - await target.remove_roles(*rrole_list) + await target.remove_roles(*rrole_list, reason=reason) except discord.Forbidden: log.exception(f"Permission error: Unable to remove roles") await ctx.send("Permission error: Unable to remove roles") From 88ef4753398778b1881060dddb1c835197c4c99b Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 16 Sep 2020 13:42:35 -0400 Subject: [PATCH 15/25] Bring reactrestrict into the modern discord era --- reactrestrict/reactrestrict.py | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/reactrestrict/reactrestrict.py b/reactrestrict/reactrestrict.py index 4030538..226cf24 100644 --- a/reactrestrict/reactrestrict.py +++ b/reactrestrict/reactrestrict.py @@ -1,3 +1,4 @@ +import logging from typing import List, Union import discord @@ -5,6 +6,7 @@ from redbot.core import Config, commands from redbot.core.bot import Red from redbot.core.commands import Cog +log = logging.getLogger("red.fox_v3.reactrestrict") class ReactRestrictCombo: def __init__(self, message_id, role_id): @@ -131,10 +133,12 @@ class ReactRestrict(Cog): If no such channel or member can be found. """ channel = self.bot.get_channel(channel_id) + if channel is None: + raise LookupError("no channel found.") try: member = channel.guild.get_member(user_id) except AttributeError as e: - raise LookupError("No channel found.") from e + raise LookupError("No member found.") from e if member is None: raise LookupError("No member found.") @@ -168,7 +172,7 @@ class ReactRestrict(Cog): """ channel = self.bot.get_channel(channel_id) try: - return await channel.get_message(message_id) + return await channel.fetch_message(message_id) except discord.NotFound: pass except AttributeError: # VoiceChannel object has no attribute 'get_message' @@ -186,9 +190,11 @@ class ReactRestrict(Cog): :param message_id: :return: """ - for channel in ctx.guild.channels: + + guild: discord.Guild = ctx.guild + for channel in guild.text_channels: try: - return await channel.get_message(message_id) + return await channel.fetch_message(message_id) except discord.NotFound: pass except AttributeError: # VoiceChannel object has no attribute 'get_message' @@ -251,34 +257,35 @@ class ReactRestrict(Cog): await ctx.send("Reaction removed.") @commands.Cog.listener() - async def on_raw_reaction_add( - self, emoji: discord.PartialEmoji, message_id: int, channel_id: int, user_id: int - ): + async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): """ Event handler for long term reaction watching. - - :param discord.PartialReactionEmoji emoji: - :param int message_id: - :param int channel_id: - :param int user_id: - :return: """ - if emoji.is_custom_emoji(): - emoji_id = emoji.id - else: - emoji_id = emoji.name + + emoji = payload.emoji + message_id = payload.message_id + channel_id = payload.channel_id + user_id = payload.user_id + + # if emoji.is_custom_emoji(): + # emoji_id = emoji.id + # else: + # emoji_id = emoji.name has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id) if not has_reactrestrict: + log.debug("Message not react restricted") return try: member = self._get_member(channel_id, user_id) except LookupError: + log.exception("Unable to get member from guild") return if member.bot: + log.debug("Won't remove reactions added by bots") return if await self.bot.cog_disabled_in_guild(self, member.guild): @@ -287,10 +294,12 @@ class ReactRestrict(Cog): try: roles = [self._get_role(member.guild, c.role_id) for c in combos] except LookupError: + log.exception("Couldn't get approved roles from combos") return for apprrole in roles: if apprrole in member.roles: + log.debug("Has approved role") return message = await self._get_message_from_channel(channel_id, message_id) From 8ecdf45fa796ca2d90f5a0d50d3fa1cc562d0766 Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 16 Sep 2020 13:43:56 -0400 Subject: [PATCH 16/25] One more error handler --- reactrestrict/reactrestrict.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reactrestrict/reactrestrict.py b/reactrestrict/reactrestrict.py index 226cf24..25a32c1 100644 --- a/reactrestrict/reactrestrict.py +++ b/reactrestrict/reactrestrict.py @@ -303,7 +303,10 @@ class ReactRestrict(Cog): return message = await self._get_message_from_channel(channel_id, message_id) - await message.remove_reaction(emoji, member) + try: + await message.remove_reaction(emoji, member) + except (discord.Forbidden, discord.NotFound, discord.HTTPException): + log.exception("Unable to remove reaction") # try: # await member.add_roles(*roles) From 18e5cc12ff570b966bee92cc7a394fc055a7e1f7 Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 16 Sep 2020 13:46:22 -0400 Subject: [PATCH 17/25] Black formatting --- reactrestrict/reactrestrict.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reactrestrict/reactrestrict.py b/reactrestrict/reactrestrict.py index 25a32c1..79c3c1c 100644 --- a/reactrestrict/reactrestrict.py +++ b/reactrestrict/reactrestrict.py @@ -8,6 +8,7 @@ from redbot.core.commands import Cog log = logging.getLogger("red.fox_v3.reactrestrict") + class ReactRestrictCombo: def __init__(self, message_id, role_id): self.message_id = message_id @@ -238,7 +239,7 @@ class ReactRestrict(Cog): # noinspection PyTypeChecker await self.add_reactrestrict(message_id, role) - await ctx.maybe_send_embed("Message|Role combo added.") + await ctx.maybe_send_embed("Message|Role restriction added.") @reactrestrict.command() async def remove(self, ctx: commands.Context, message_id: int, role: discord.Role): @@ -254,7 +255,7 @@ class ReactRestrict(Cog): # noinspection PyTypeChecker await self.remove_react(message_id, role) - await ctx.send("Reaction removed.") + await ctx.send("React restriction removed.") @commands.Cog.listener() async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): From a046102549da655aff84aee909c73c135daea713 Mon Sep 17 00:00:00 2001 From: bobloy Date: Sat, 19 Sep 2020 20:24:41 -0400 Subject: [PATCH 18/25] Hotfix maybe_send_embed in lseen --- lseen/lseen.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lseen/lseen.py b/lseen/lseen.py index a451f57..3348b65 100644 --- a/lseen/lseen.py +++ b/lseen/lseen.py @@ -75,9 +75,7 @@ class LastSeen(Cog): else: last_seen = await self.config.member(member).seen() if last_seen is None: - await ctx.maybe_send_embed( - embed=discord.Embed(description="I've never seen this user") - ) + await ctx.maybe_send_embed("I've never seen this user") return last_seen = self.get_date_time(last_seen) From f69e8fdb1a039c1b5f8f3e376d669188d4d22d73 Mon Sep 17 00:00:00 2001 From: bobloy Date: Mon, 21 Sep 2020 11:35:35 -0400 Subject: [PATCH 19/25] Handle track errors gracefully --- audiotrivia/audiosession.py | 21 +++++++++++++++------ audiotrivia/audiotrivia.py | 8 ++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/audiotrivia/audiosession.py b/audiotrivia/audiosession.py index 780d4b9..4207fab 100644 --- a/audiotrivia/audiosession.py +++ b/audiotrivia/audiosession.py @@ -1,8 +1,12 @@ """Module to manage audio trivia sessions.""" import asyncio +import logging import lavalink from redbot.cogs.trivia import TriviaSession +from redbot.core.utils.chat_formatting import bold + +log = logging.getLogger("red.fox_v3.audiotrivia.audiosession") class AudioSession(TriviaSession): @@ -23,9 +27,9 @@ class AudioSession(TriviaSession): async def run(self): """Run the audio trivia session. - In order for the trivia session to be stopped correctly, this should - only be called internally by `TriviaSession.start`. - """ + In order for the trivia session to be stopped correctly, this should + only be called internally by `TriviaSession.start`. + """ await self._send_startup_msg() max_score = self.settings["max_score"] delay = self.settings["delay"] @@ -36,8 +40,8 @@ class AudioSession(TriviaSession): self.count += 1 await self.player.stop() - msg = "**Question number {}!**\n\nName this audio!".format(self.count) - await self.ctx.send(msg) + msg = bold(f"Question number {self.count}!") + "\n\nName this audio!" + await self.ctx.maybe_send_embed(msg) # print("Audio question: {}".format(question)) # await self.ctx.invoke(self.audio.play(ctx=self.ctx, query=question)) @@ -45,7 +49,12 @@ class AudioSession(TriviaSession): # await self.ctx.invoke(self.player.play, query=question) query = question.strip("<>") - tracks = await self.player.get_tracks(query) + load_result = await self.player.load_tracks(query) + if load_result.has_error: + await self.ctx.maybe_send_embed(f"Track has error, skipping. See logs for details") + log.info(f"Track has error: {load_result.exception_message}") + continue # Skip tracks with error + tracks = load_result.tracks seconds = tracks[0].length / 1000 if self.settings["repeat"] and seconds < delay: diff --git a/audiotrivia/audiotrivia.py b/audiotrivia/audiotrivia.py index c0c88fd..ec7b5ea 100644 --- a/audiotrivia/audiotrivia.py +++ b/audiotrivia/audiotrivia.py @@ -1,4 +1,5 @@ import datetime +import logging import pathlib from typing import List @@ -15,7 +16,7 @@ from redbot.core.utils.chat_formatting import box from .audiosession import AudioSession -# from redbot.cogs.audio.utils import userlimit +log = logging.getLogger("red.fox_v3.audiotrivia") class AudioTrivia(Trivia): @@ -166,7 +167,10 @@ class AudioTrivia(Trivia): # Delay in audiosettings overwrites delay in settings combined_settings = {**settings, **audiosettings} session = AudioSession.start( - ctx=ctx, question_list=trivia_dict, settings=combined_settings, player=lavaplayer, + ctx=ctx, + question_list=trivia_dict, + settings=combined_settings, + player=lavaplayer, ) self.trivia_sessions.append(session) LOG.debug("New audio trivia session; #%s in %d", ctx.channel, ctx.guild.id) From ec5d713fa01285d2f315ce9ebbcb128e4dfe78d4 Mon Sep 17 00:00:00 2001 From: bobloy Date: Mon, 21 Sep 2020 13:49:33 -0400 Subject: [PATCH 20/25] Correct listeners --- hangman/__init__.py | 1 - hangman/hangman.py | 48 ++++++++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/hangman/__init__.py b/hangman/__init__.py index dbc62e7..35012c4 100644 --- a/hangman/__init__.py +++ b/hangman/__init__.py @@ -6,4 +6,3 @@ def setup(bot): n = Hangman(bot) data_manager.bundled_data_path(n) bot.add_cog(n) - bot.add_listener(n.on_react, "on_reaction_add") diff --git a/hangman/hangman.py b/hangman/hangman.py index c7d005d..2b6ab07 100644 --- a/hangman/hangman.py +++ b/hangman/hangman.py @@ -50,27 +50,27 @@ class Hangman(Cog): theface = await self.config.guild(guild).theface() self.hanglist[guild] = ( """> - \_________ + \\_________ |/ | | | | | - |\___ + |\\___ """, """> - \_________ + \\_________ |/ | | | | | | - |\___ + |\\___ H""", """> - \_________ + \\_________ |/ | | """ + theface @@ -79,10 +79,10 @@ class Hangman(Cog): | | | - |\___ + |\\___ HA""", """> - \________ + \\________ |/ | | """ + theface @@ -91,10 +91,10 @@ class Hangman(Cog): | | | | - |\___ + |\\___ HAN""", """> - \_________ + \\_________ |/ | | """ + theface @@ -103,43 +103,43 @@ class Hangman(Cog): | | | | - |\___ + |\\___ HANG""", """> - \_________ + \\_________ |/ | | """ + theface + """ - | /|\ + | /|\\ | | | | - |\___ + |\\___ HANGM""", """> - \________ + \\________ |/ | | """ + theface + """ - | /|\ + | /|\\ | | | / | - |\___ + |\\___ HANGMA""", """> - \________ + \\________ |/ | | """ + theface + """ - | /|\ + | /|\\ | | - | / \ + | / \\ | - |\___ + |\\___ HANGMAN""", ) @@ -255,7 +255,7 @@ class Hangman(Cog): elif i in self.the_data[guild]["guesses"] or i not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": out_str += "__" + i + "__ " else: - out_str += "**\_** " + out_str += "**\\_** " self.winbool[guild] = False return out_str @@ -286,10 +286,10 @@ class Hangman(Cog): await self._reprintgame(message) - @commands.Cog.listener() + @commands.Cog.listener("on_reaction_add") async def on_react(self, reaction, user: Union[discord.User, discord.Member]): - """ Thanks to flapjack reactpoll for guidelines - https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py""" + """Thanks to flapjack reactpoll for guidelines + https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py""" guild: discord.Guild = getattr(user, "guild", None) if guild is None: return From e0042780a1f9db38e29e42862da2972bd42a46fe Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 23 Sep 2020 11:39:34 -0400 Subject: [PATCH 21/25] Better detection of bad questions in trivia --- audiotrivia/audiosession.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/audiotrivia/audiosession.py b/audiotrivia/audiosession.py index 4207fab..04d53c2 100644 --- a/audiotrivia/audiosession.py +++ b/audiotrivia/audiosession.py @@ -3,6 +3,7 @@ import asyncio import logging import lavalink +from lavalink.enums import LoadType from redbot.cogs.trivia import TriviaSession from redbot.core.utils.chat_formatting import bold @@ -42,6 +43,7 @@ class AudioSession(TriviaSession): msg = bold(f"Question number {self.count}!") + "\n\nName this audio!" await self.ctx.maybe_send_embed(msg) + log.debug(f"Audio question: {question}") # print("Audio question: {}".format(question)) # await self.ctx.invoke(self.audio.play(ctx=self.ctx, query=question)) @@ -50,7 +52,8 @@ class AudioSession(TriviaSession): # await self.ctx.invoke(self.player.play, query=question) query = question.strip("<>") load_result = await self.player.load_tracks(query) - if load_result.has_error: + log.debug(f"{load_result.load_type=}") + if load_result.has_error or load_result.load_type != LoadType.TRACK_LOADED: await self.ctx.maybe_send_embed(f"Track has error, skipping. See logs for details") log.info(f"Track has error: {load_result.exception_message}") continue # Skip tracks with error @@ -66,6 +69,7 @@ class AudioSession(TriviaSession): self.player.add(self.ctx.author, tracks[0]) if not self.player.current: + log.debug("Pressing play") await self.player.play() continue_ = await self.wait_for_answer(answers, delay, timeout) From bf81d7c1573a86026d26fc3c15befde72486b34e Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 23 Sep 2020 11:57:17 -0400 Subject: [PATCH 22/25] Embeds and track variable --- audiotrivia/audiosession.py | 9 ++++++--- audiotrivia/audiotrivia.py | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/audiotrivia/audiosession.py b/audiotrivia/audiosession.py index 04d53c2..1bdff02 100644 --- a/audiotrivia/audiosession.py +++ b/audiotrivia/audiosession.py @@ -58,15 +58,18 @@ class AudioSession(TriviaSession): log.info(f"Track has error: {load_result.exception_message}") continue # Skip tracks with error tracks = load_result.tracks - seconds = tracks[0].length / 1000 + + track = tracks[0] + seconds = track.length / 1000 if self.settings["repeat"] and seconds < delay: + # Append it until it's longer than the delay tot_length = seconds + 0 while tot_length < delay: - self.player.add(self.ctx.author, tracks[0]) + self.player.add(self.ctx.author, track) tot_length += seconds else: - self.player.add(self.ctx.author, tracks[0]) + self.player.add(self.ctx.author, track) if not self.player.current: log.debug("Pressing play") diff --git a/audiotrivia/audiotrivia.py b/audiotrivia/audiotrivia.py index ec7b5ea..0bab980 100644 --- a/audiotrivia/audiotrivia.py +++ b/audiotrivia/audiotrivia.py @@ -84,24 +84,24 @@ class AudioTrivia(Trivia): self.audio: Audio = self.bot.get_cog("Audio") if self.audio is None: - await ctx.send("Audio is not loaded. Load it and try again") + await ctx.maybe_send_embed("Audio is not loaded. Load it and try again") return categories = [c.lower() for c in categories] session = self._get_trivia_session(ctx.channel) if session is not None: - await ctx.send("There is already an ongoing trivia session in this channel.") + await ctx.maybe_send_embed("There is already an ongoing trivia session in this channel.") return status = await self.audio.config.status() notify = await self.audio.config.guild(ctx.guild).notify() if status: - await ctx.send( + await ctx.maybe_send_embed( f"It is recommended to disable audio status with `{ctx.prefix}audioset status`" ) if notify: - await ctx.send( + await ctx.maybe_send_embed( f"It is recommended to disable audio notify with `{ctx.prefix}audioset notify`" ) @@ -110,12 +110,12 @@ class AudioTrivia(Trivia): if not ctx.author.voice.channel.permissions_for( ctx.me ).connect or self.audio.is_vc_full(ctx.author.voice.channel): - return await ctx.send("I don't have permission to connect to your channel.") + return await ctx.maybe_send_embed("I don't have permission to connect to your channel.") await lavalink.connect(ctx.author.voice.channel) lavaplayer = lavalink.get_player(ctx.guild.id) lavaplayer.store("connect", datetime.datetime.utcnow()) except AttributeError: - return await ctx.send("Connect to a voice channel first.") + return await ctx.maybe_send_embed("Connect to a voice channel first.") lavaplayer = lavalink.get_player(ctx.guild.id) lavaplayer.store("channel", ctx.channel.id) # What's this for? I dunno @@ -123,7 +123,7 @@ class AudioTrivia(Trivia): await self.audio.set_player_settings(ctx) if not ctx.author.voice or ctx.author.voice.channel != lavaplayer.channel: - return await ctx.send( + return await ctx.maybe_send_embed( "You must be in the voice channel to use the audiotrivia command." ) @@ -135,13 +135,13 @@ class AudioTrivia(Trivia): try: dict_ = self.get_audio_list(category) except FileNotFoundError: - await ctx.send( + await ctx.maybe_send_embed( "Invalid category `{0}`. See `{1}audiotrivia list`" " for a list of trivia categories." "".format(category, ctx.prefix) ) except InvalidListError: - await ctx.send( + await ctx.maybe_send_embed( "There was an error parsing the trivia list for" " the `{}` category. It may be formatted" " incorrectly.".format(category) @@ -152,7 +152,7 @@ class AudioTrivia(Trivia): continue return if not trivia_dict: - await ctx.send( + await ctx.maybe_send_embed( "The trivia list was parsed successfully, however it appears to be empty!" ) return From f05a8bf4f60f0f2fcb7f9188c3514d080a3f385b Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 23 Sep 2020 12:07:20 -0400 Subject: [PATCH 23/25] *some* games fixed --- audiotrivia/data/lists/games.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/audiotrivia/data/lists/games.yaml b/audiotrivia/data/lists/games.yaml index c3a9078..4de795a 100644 --- a/audiotrivia/data/lists/games.yaml +++ b/audiotrivia/data/lists/games.yaml @@ -1,13 +1,13 @@ AUTHOR: Plab -https://www.youtube.com/watch?v=--bWm9hhoZo: +https://www.youtube.com/watch?v=f9O2Rjn1azc: - Transistor -https://www.youtube.com/watch?v=-4nCbgayZNE: +https://www.youtube.com/watch?v=PgUhYFkVdSY: - Dark Cloud 2 - Dark Cloud II -https://www.youtube.com/watch?v=-64NlME4lJU: +https://www.youtube.com/watch?v=1T1RZttyMwU: - Mega Man 7 - Mega Man VII -https://www.youtube.com/watch?v=-AesqnudNuw: +https://www.youtube.com/watch?v=AdDbbzuq1vY: - Mega Man 9 - Mega Man IX https://www.youtube.com/watch?v=-BmGDtP2t7M: From 608f4259658aaa1d46d0bbb8df939c280bbcd460 Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 23 Sep 2020 12:15:53 -0400 Subject: [PATCH 24/25] Fix very long lists --- fifo/fifo.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fifo/fifo.py b/fifo/fifo.py index e84e342..91c9190 100644 --- a/fifo/fifo.py +++ b/fifo/fifo.py @@ -10,6 +10,7 @@ from apscheduler.schedulers.base import STATE_PAUSED, STATE_RUNNING from redbot.core import Config, checks, commands from redbot.core.bot import Red from redbot.core.commands import TimedeltaConverter +from redbot.core.utils.chat_formatting import pagify from .datetime_cron_converters import CronConverter, DatetimeConverter from .task import Task @@ -306,7 +307,11 @@ class FIFO(commands.Cog): out += f"{task_name}: {task_data}\n" if out: - await ctx.maybe_send_embed(out) + if len(out) > 2000: + for page in pagify(out): + await ctx.maybe_send_embed(page) + else: + await ctx.maybe_send_embed(out) else: await ctx.maybe_send_embed("No tasks to list") From d13331d52d3f18c3098e500057b9d35519a94fcc Mon Sep 17 00:00:00 2001 From: bobloy Date: Wed, 23 Sep 2020 20:26:20 -0400 Subject: [PATCH 25/25] black --- planttycoon/planttycoon.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/planttycoon/planttycoon.py b/planttycoon/planttycoon.py index 61e5e06..665fc9a 100644 --- a/planttycoon/planttycoon.py +++ b/planttycoon/planttycoon.py @@ -360,7 +360,9 @@ class PlantTycoon(commands.Cog): ``{0}prune``: Prune your plant.\n""" em = discord.Embed( - title=title, description=description.format(prefix), color=discord.Color.green(), + title=title, + description=description.format(prefix), + color=discord.Color.green(), ) em.set_thumbnail(url="https://image.prntscr.com/image/AW7GuFIBSeyEgkR2W3SeiQ.png") em.set_footer( @@ -525,7 +527,8 @@ class PlantTycoon(commands.Cog): if t: em = discord.Embed( - title="Plant statistics of {}".format(plant["name"]), color=discord.Color.green(), + title="Plant statistics of {}".format(plant["name"]), + color=discord.Color.green(), ) em.set_thumbnail(url=plant["image"]) em.add_field(name="**Name**", value=plant["name"]) @@ -583,7 +586,8 @@ class PlantTycoon(commands.Cog): author = ctx.author if product is None: em = discord.Embed( - title="All gardening supplies that you can buy:", color=discord.Color.green(), + title="All gardening supplies that you can buy:", + color=discord.Color.green(), ) for pd in self.products: em.add_field( @@ -616,8 +620,11 @@ class PlantTycoon(commands.Cog): await gardener.save_gardener() message = "You bought {}.".format(product.lower()) else: - message = "You don't have enough Thneeds. You have {}, but need {}.".format( - gardener.points, self.products[product.lower()]["cost"] * amount, + message = ( + "You don't have enough Thneeds. You have {}, but need {}.".format( + gardener.points, + self.products[product.lower()]["cost"] * amount, + ) ) else: message = "I don't have this product."