Merge branch 'master' into fifo_develop
This commit is contained in:
		
						commit
						bed6cf8bb7
					
				| @ -14,11 +14,13 @@ Cog Function | |||||||
| | exclusiverole | **Alpha** | <details><summary>Prevent certain roles from getting any other roles</summary>Fully functional, but pretty simple</details> | | | exclusiverole | **Alpha** | <details><summary>Prevent certain roles from getting any other roles</summary>Fully functional, but pretty simple</details> | | ||||||
| | fifo | **Alpha** | <details><summary>Schedule commands to be run at certain times or intervals</summary>Just released, please report bugs as you find them. Only works for bot owner for now</details> | | | fifo | **Alpha** | <details><summary>Schedule commands to be run at certain times or intervals</summary>Just released, please report bugs as you find them. Only works for bot owner for now</details> | | ||||||
| | fight | **Incomplete** | <details><summary>Organize bracket tournaments within discord</summary>Still in-progress, a massive project</details> | | | fight | **Incomplete** | <details><summary>Organize bracket tournaments within discord</summary>Still in-progress, a massive project</details> | | ||||||
|  | | firstmessage | **Release** | <details><summary>Simple cog to provide a jump link to the first message in a channel/summary>Just released, please report bugs as you find them.</details> | | ||||||
| | flag | **Alpha** | <details><summary>Create temporary marks on users that expire after specified time</summary>Ported, will not import old data. Please report bugs</details> | | | flag | **Alpha** | <details><summary>Create temporary marks on users that expire after specified time</summary>Ported, will not import old data. Please report bugs</details> | | ||||||
| | forcemention | **Alpha** | <details><summary>Mentions unmentionable roles</summary>Very simple cog, mention doesn't persist</details> | | | forcemention | **Alpha** | <details><summary>Mentions unmentionable roles</summary>Very simple cog, mention doesn't persist</details> | | ||||||
| | hangman | **Beta** | <details><summary>Play a game of hangman</summary>Some visual glitches and needs more customization</details> | | | hangman | **Beta** | <details><summary>Play a game of hangman</summary>Some visual glitches and needs more customization</details> | | ||||||
| | howdoi | **Incomplete** | <details><summary>Ask coding questions and get results from StackExchange</summary>Not yet functional</details> | | | howdoi | **Incomplete** | <details><summary>Ask coding questions and get results from StackExchange</summary>Not yet functional</details> | | ||||||
| | infochannel | **Beta** | <details><summary>Create a channel to display server info</summary>Just released, please report bugs</details> | | | infochannel | **Beta** | <details><summary>Create a channel to display server info</summary>Due to rate limits, this does not update as often as it once did</details> | | ||||||
|  | | isitdown | **Beta** | <details><summary>Check if a website/url is down</summary>Just released, please report bugs</details> | | ||||||
| | launchlib | **Beta** | <details><summary>Access rocket launch data</summary>Just released, please report bugs</details> | | | launchlib | **Beta** | <details><summary>Access rocket launch data</summary>Just released, please report bugs</details> | | ||||||
| | leaver | **Beta** | <details><summary>Send a message in a channel when a user leaves the server</summary>Seems to be functional, please report any bugs or suggestions</details> | | | leaver | **Beta** | <details><summary>Send a message in a channel when a user leaves the server</summary>Seems to be functional, please report any bugs or suggestions</details> | | ||||||
| | lovecalculator | **Alpha** | <details><summary>Calculate the love between two users</summary>[Snap-Ons] Just updated to V3</details> | | | lovecalculator | **Alpha** | <details><summary>Calculate the love between two users</summary>[Snap-Ons] Just updated to V3</details> | | ||||||
| @ -38,7 +40,7 @@ Cog Function | |||||||
| | unicode | **Alpha** | <details><summary>Encode and Decode unicode characters</summary>[Snap-Ons] Just updated to V3</details> | | | unicode | **Alpha** | <details><summary>Encode and Decode unicode characters</summary>[Snap-Ons] Just updated to V3</details> | | ||||||
| | werewolf | **Pre-Alpha** | <details><summary>Play the classic party game Werewolf within discord</summary>Another massive project currently being developed, will be fully customizable</details> | | | werewolf | **Pre-Alpha** | <details><summary>Play the classic party game Werewolf within discord</summary>Another massive project currently being developed, will be fully customizable</details> | | ||||||
| 
 | 
 | ||||||
| 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 | # Installation | ||||||
| ### Recommended - Built-in Downloader | ### Recommended - Built-in Downloader | ||||||
|  | |||||||
| @ -1,8 +1,13 @@ | |||||||
| """Module to manage audio trivia sessions.""" | """Module to manage audio trivia sessions.""" | ||||||
| import asyncio | import asyncio | ||||||
|  | import logging | ||||||
| 
 | 
 | ||||||
| import lavalink | import lavalink | ||||||
|  | from lavalink.enums import LoadType | ||||||
| from redbot.cogs.trivia import TriviaSession | 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): | class AudioSession(TriviaSession): | ||||||
| @ -23,9 +28,9 @@ class AudioSession(TriviaSession): | |||||||
|     async def run(self): |     async def run(self): | ||||||
|         """Run the audio trivia session. |         """Run the audio trivia session. | ||||||
| 
 | 
 | ||||||
|                 In order for the trivia session to be stopped correctly, this should |         In order for the trivia session to be stopped correctly, this should | ||||||
|                 only be called internally by `TriviaSession.start`. |         only be called internally by `TriviaSession.start`. | ||||||
|                 """ |         """ | ||||||
|         await self._send_startup_msg() |         await self._send_startup_msg() | ||||||
|         max_score = self.settings["max_score"] |         max_score = self.settings["max_score"] | ||||||
|         delay = self.settings["delay"] |         delay = self.settings["delay"] | ||||||
| @ -36,8 +41,9 @@ class AudioSession(TriviaSession): | |||||||
|             self.count += 1 |             self.count += 1 | ||||||
|             await self.player.stop() |             await self.player.stop() | ||||||
| 
 | 
 | ||||||
|             msg = "**Question number {}!**\n\nName this audio!".format(self.count) |             msg = bold(f"Question number {self.count}!") + "\n\nName this audio!" | ||||||
|             await self.ctx.send(msg) |             await self.ctx.maybe_send_embed(msg) | ||||||
|  |             log.debug(f"Audio question: {question}") | ||||||
|             # print("Audio question: {}".format(question)) |             # print("Audio question: {}".format(question)) | ||||||
| 
 | 
 | ||||||
|             # await self.ctx.invoke(self.audio.play(ctx=self.ctx, query=question)) |             # await self.ctx.invoke(self.audio.play(ctx=self.ctx, query=question)) | ||||||
| @ -45,18 +51,28 @@ class AudioSession(TriviaSession): | |||||||
| 
 | 
 | ||||||
|             # await self.ctx.invoke(self.player.play, query=question) |             # await self.ctx.invoke(self.player.play, query=question) | ||||||
|             query = question.strip("<>") |             query = question.strip("<>") | ||||||
|             tracks = await self.player.get_tracks(query) |             load_result = await self.player.load_tracks(query) | ||||||
|             seconds = tracks[0].length / 1000 |             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 | ||||||
|  |             tracks = load_result.tracks | ||||||
|  | 
 | ||||||
|  |             track = tracks[0] | ||||||
|  |             seconds = track.length / 1000 | ||||||
| 
 | 
 | ||||||
|             if self.settings["repeat"] and seconds < delay: |             if self.settings["repeat"] and seconds < delay: | ||||||
|  |                 # Append it until it's longer than the delay | ||||||
|                 tot_length = seconds + 0 |                 tot_length = seconds + 0 | ||||||
|                 while tot_length < delay: |                 while tot_length < delay: | ||||||
|                     self.player.add(self.ctx.author, tracks[0]) |                     self.player.add(self.ctx.author, track) | ||||||
|                     tot_length += seconds |                     tot_length += seconds | ||||||
|             else: |             else: | ||||||
|                 self.player.add(self.ctx.author, tracks[0]) |                 self.player.add(self.ctx.author, track) | ||||||
| 
 | 
 | ||||||
|             if not self.player.current: |             if not self.player.current: | ||||||
|  |                 log.debug("Pressing play") | ||||||
|                 await self.player.play() |                 await self.player.play() | ||||||
| 
 | 
 | ||||||
|             continue_ = await self.wait_for_answer(answers, delay, timeout) |             continue_ = await self.wait_for_answer(answers, delay, timeout) | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| import datetime | import datetime | ||||||
|  | import logging | ||||||
| import pathlib | import pathlib | ||||||
| from typing import List | from typing import List | ||||||
| 
 | 
 | ||||||
| @ -15,7 +16,7 @@ from redbot.core.utils.chat_formatting import box | |||||||
| from .audiosession import AudioSession | from .audiosession import AudioSession | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # from redbot.cogs.audio.utils import userlimit | log = logging.getLogger("red.fox_v3.audiotrivia") | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AudioTrivia(Trivia): | class AudioTrivia(Trivia): | ||||||
| @ -83,24 +84,24 @@ class AudioTrivia(Trivia): | |||||||
|             self.audio: Audio = self.bot.get_cog("Audio") |             self.audio: Audio = self.bot.get_cog("Audio") | ||||||
| 
 | 
 | ||||||
|         if self.audio is None: |         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 |             return | ||||||
| 
 | 
 | ||||||
|         categories = [c.lower() for c in categories] |         categories = [c.lower() for c in categories] | ||||||
|         session = self._get_trivia_session(ctx.channel) |         session = self._get_trivia_session(ctx.channel) | ||||||
|         if session is not None: |         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 |             return | ||||||
|         status = await self.audio.config.status() |         status = await self.audio.config.status() | ||||||
|         notify = await self.audio.config.guild(ctx.guild).notify() |         notify = await self.audio.config.guild(ctx.guild).notify() | ||||||
| 
 | 
 | ||||||
|         if status: |         if status: | ||||||
|             await ctx.send( |             await ctx.maybe_send_embed( | ||||||
|                 f"It is recommended to disable audio status with `{ctx.prefix}audioset status`" |                 f"It is recommended to disable audio status with `{ctx.prefix}audioset status`" | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|         if notify: |         if notify: | ||||||
|             await ctx.send( |             await ctx.maybe_send_embed( | ||||||
|                 f"It is recommended to disable audio notify with `{ctx.prefix}audioset notify`" |                 f"It is recommended to disable audio notify with `{ctx.prefix}audioset notify`" | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
| @ -109,12 +110,12 @@ class AudioTrivia(Trivia): | |||||||
|                 if not ctx.author.voice.channel.permissions_for( |                 if not ctx.author.voice.channel.permissions_for( | ||||||
|                     ctx.me |                     ctx.me | ||||||
|                 ).connect or self.audio.is_vc_full(ctx.author.voice.channel): |                 ).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) |                 await lavalink.connect(ctx.author.voice.channel) | ||||||
|                 lavaplayer = lavalink.get_player(ctx.guild.id) |                 lavaplayer = lavalink.get_player(ctx.guild.id) | ||||||
|                 lavaplayer.store("connect", datetime.datetime.utcnow()) |                 lavaplayer.store("connect", datetime.datetime.utcnow()) | ||||||
|             except AttributeError: |             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 = lavalink.get_player(ctx.guild.id) | ||||||
|         lavaplayer.store("channel", ctx.channel.id)  # What's this for? I dunno |         lavaplayer.store("channel", ctx.channel.id)  # What's this for? I dunno | ||||||
| @ -122,7 +123,7 @@ class AudioTrivia(Trivia): | |||||||
|         await self.audio.set_player_settings(ctx) |         await self.audio.set_player_settings(ctx) | ||||||
| 
 | 
 | ||||||
|         if not ctx.author.voice or ctx.author.voice.channel != lavaplayer.channel: |         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." |                 "You must be in the voice channel to use the audiotrivia command." | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
| @ -134,13 +135,13 @@ class AudioTrivia(Trivia): | |||||||
|             try: |             try: | ||||||
|                 dict_ = self.get_audio_list(category) |                 dict_ = self.get_audio_list(category) | ||||||
|             except FileNotFoundError: |             except FileNotFoundError: | ||||||
|                 await ctx.send( |                 await ctx.maybe_send_embed( | ||||||
|                     "Invalid category `{0}`. See `{1}audiotrivia list`" |                     "Invalid category `{0}`. See `{1}audiotrivia list`" | ||||||
|                     " for a list of trivia categories." |                     " for a list of trivia categories." | ||||||
|                     "".format(category, ctx.prefix) |                     "".format(category, ctx.prefix) | ||||||
|                 ) |                 ) | ||||||
|             except InvalidListError: |             except InvalidListError: | ||||||
|                 await ctx.send( |                 await ctx.maybe_send_embed( | ||||||
|                     "There was an error parsing the trivia list for" |                     "There was an error parsing the trivia list for" | ||||||
|                     " the `{}` category. It may be formatted" |                     " the `{}` category. It may be formatted" | ||||||
|                     " incorrectly.".format(category) |                     " incorrectly.".format(category) | ||||||
| @ -151,7 +152,7 @@ class AudioTrivia(Trivia): | |||||||
|                 continue |                 continue | ||||||
|             return |             return | ||||||
|         if not trivia_dict: |         if not trivia_dict: | ||||||
|             await ctx.send( |             await ctx.maybe_send_embed( | ||||||
|                 "The trivia list was parsed successfully, however it appears to be empty!" |                 "The trivia list was parsed successfully, however it appears to be empty!" | ||||||
|             ) |             ) | ||||||
|             return |             return | ||||||
| @ -166,7 +167,10 @@ class AudioTrivia(Trivia): | |||||||
|         # Delay in audiosettings overwrites delay in settings |         # Delay in audiosettings overwrites delay in settings | ||||||
|         combined_settings = {**settings, **audiosettings} |         combined_settings = {**settings, **audiosettings} | ||||||
|         session = AudioSession.start( |         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) |         self.trivia_sessions.append(session) | ||||||
|         LOG.debug("New audio trivia session; #%s in %d", ctx.channel, ctx.guild.id) |         LOG.debug("New audio trivia session; #%s in %d", ctx.channel, ctx.guild.id) | ||||||
|  | |||||||
| @ -1,13 +1,13 @@ | |||||||
| AUTHOR: Plab | AUTHOR: Plab | ||||||
| https://www.youtube.com/watch?v=--bWm9hhoZo: | https://www.youtube.com/watch?v=f9O2Rjn1azc: | ||||||
| - Transistor | - Transistor | ||||||
| https://www.youtube.com/watch?v=-4nCbgayZNE: | https://www.youtube.com/watch?v=PgUhYFkVdSY: | ||||||
| - Dark Cloud 2 | - Dark Cloud 2 | ||||||
| - Dark Cloud II | - Dark Cloud II | ||||||
| https://www.youtube.com/watch?v=-64NlME4lJU: | https://www.youtube.com/watch?v=1T1RZttyMwU: | ||||||
| - Mega Man 7 | - Mega Man 7 | ||||||
| - Mega Man VII | - Mega Man VII | ||||||
| https://www.youtube.com/watch?v=-AesqnudNuw: | https://www.youtube.com/watch?v=AdDbbzuq1vY: | ||||||
| - Mega Man 9 | - Mega Man 9 | ||||||
| - Mega Man IX | - Mega Man IX | ||||||
| https://www.youtube.com/watch?v=-BmGDtP2t7M: | https://www.youtube.com/watch?v=-BmGDtP2t7M: | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ from discord.ext.commands.view import StringView | |||||||
| from redbot.core import Config, checks, commands | from redbot.core import Config, checks, commands | ||||||
| from redbot.core.bot import Red | from redbot.core.bot import Red | ||||||
| from redbot.core.utils.chat_formatting import box, pagify | 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") | log = logging.getLogger("red.fox_v3.ccrole") | ||||||
| 
 | 
 | ||||||
| @ -358,23 +359,24 @@ class CCRole(commands.Cog): | |||||||
|         else: |         else: | ||||||
|             target = message.author |             target = message.author | ||||||
| 
 | 
 | ||||||
|  |         reason = get_audit_reason(message.author) | ||||||
|  | 
 | ||||||
|         if cmd["aroles"]: |         if cmd["aroles"]: | ||||||
|             arole_list = [ |             arole_list = [ | ||||||
|                 discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["aroles"] |                 discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["aroles"] | ||||||
|             ] |             ] | ||||||
|             try: |             try: | ||||||
|                 await target.add_roles(*arole_list) |                 await target.add_roles(*arole_list, reason=reason) | ||||||
|             except discord.Forbidden: |             except discord.Forbidden: | ||||||
|                 log.exception(f"Permission error: Unable to add roles") |                 log.exception(f"Permission error: Unable to add roles") | ||||||
|                 await ctx.send("Permission error: Unable to add roles") |                 await ctx.send("Permission error: Unable to add roles") | ||||||
|         await asyncio.sleep(1) |  | ||||||
| 
 | 
 | ||||||
|         if cmd["rroles"]: |         if cmd["rroles"]: | ||||||
|             rrole_list = [ |             rrole_list = [ | ||||||
|                 discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["rroles"] |                 discord.utils.get(message.guild.roles, id=roleid) for roleid in cmd["rroles"] | ||||||
|             ] |             ] | ||||||
|             try: |             try: | ||||||
|                 await target.remove_roles(*rrole_list) |                 await target.remove_roles(*rrole_list, reason=reason) | ||||||
|             except discord.Forbidden: |             except discord.Forbidden: | ||||||
|                 log.exception(f"Permission error: Unable to remove roles") |                 log.exception(f"Permission error: Unable to remove roles") | ||||||
|                 await ctx.send("Permission error: Unable to remove roles") |                 await ctx.send("Permission error: Unable to remove roles") | ||||||
|  | |||||||
| @ -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 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.  | depending on how much training Chatter has done.  | ||||||
| 
 | 
 | ||||||
| The sqlite database can be safely deleted at any time. Deletion will only erase training data. | The sqlite database can be safely deleted at any time. Deletion will only erase training data. | ||||||
| @ -50,7 +50,9 @@ Linux is a bit easier, but only tested on Debian and Ubuntu. | |||||||
| 
 | 
 | ||||||
| ## Windows Prerequisites | ## 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/) | [Visual Studio C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) | ||||||
| 
 | 
 | ||||||
| @ -83,6 +85,7 @@ pip install --no-deps "chatterbot>=1.1" | |||||||
| #### Step 3: Load Chatter | #### Step 3: Load Chatter | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|  | [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]cog install Fox chatter | ||||||
| [p]load chatter | [p]load chatter | ||||||
| ``` | ``` | ||||||
| @ -92,7 +95,7 @@ pip install --no-deps "chatterbot>=1.1" | |||||||
| #### Step 1: Built-in Downloader | #### Step 1: Built-in Downloader | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| [p]cog install Chatter | [p]cog install <Fox> Chatter | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| #### Step 2: Install Requirements | #### Step 2: Install Requirements | ||||||
|  | |||||||
| @ -463,7 +463,7 @@ class Chatter(Cog): | |||||||
|         # Thank you Cog-Creators |         # Thank you Cog-Creators | ||||||
|         channel: discord.TextChannel = message.channel |         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 |             pass  # good to go | ||||||
|         else: |         else: | ||||||
|             when_mentionables = commands.when_mentioned(self.bot, message) |             when_mentionables = commands.when_mentioned(self.bot, message) | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ from apscheduler.schedulers.base import STATE_PAUSED, STATE_RUNNING | |||||||
| from redbot.core import Config, checks, commands | from redbot.core import Config, checks, commands | ||||||
| from redbot.core.bot import Red | from redbot.core.bot import Red | ||||||
| from redbot.core.commands import TimedeltaConverter | from redbot.core.commands import TimedeltaConverter | ||||||
|  | from redbot.core.utils.chat_formatting import pagify | ||||||
| 
 | 
 | ||||||
| from .datetime_cron_converters import CronConverter, DatetimeConverter, TimezoneConverter | from .datetime_cron_converters import CronConverter, DatetimeConverter, TimezoneConverter | ||||||
| from .task import Task | from .task import Task | ||||||
| @ -306,7 +307,11 @@ class FIFO(commands.Cog): | |||||||
|                 out += f"{task_name}: {task_data}\n" |                 out += f"{task_name}: {task_data}\n" | ||||||
| 
 | 
 | ||||||
|             if out: |             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: |             else: | ||||||
|                 await ctx.maybe_send_embed("No tasks to list") |                 await ctx.maybe_send_embed("No tasks to list") | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,6 +16,7 @@ | |||||||
|     "bobloy", |     "bobloy", | ||||||
|     "utilities", |     "utilities", | ||||||
|     "tool", |     "tool", | ||||||
|  |     "tools", | ||||||
|     "roles", |     "roles", | ||||||
|     "schedule", |     "schedule", | ||||||
|     "cron", |     "cron", | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								firstmessage/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								firstmessage/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | from .firstmessage import FirstMessage | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | async def setup(bot): | ||||||
|  |     bot.add_cog(FirstMessage(bot)) | ||||||
							
								
								
									
										49
									
								
								firstmessage/firstmessage.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								firstmessage/firstmessage.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | 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 | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     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): | ||||||
|  |         """ | ||||||
|  |         Provide a link to the first message in current or provided channel. | ||||||
|  |         """ | ||||||
|  |         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) | ||||||
							
								
								
									
										17
									
								
								firstmessage/info.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								firstmessage/info.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | { | ||||||
|  |   "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", | ||||||
|  |     "tools" | ||||||
|  |   ] | ||||||
|  | } | ||||||
| @ -6,4 +6,3 @@ def setup(bot): | |||||||
|     n = Hangman(bot) |     n = Hangman(bot) | ||||||
|     data_manager.bundled_data_path(n) |     data_manager.bundled_data_path(n) | ||||||
|     bot.add_cog(n) |     bot.add_cog(n) | ||||||
|     bot.add_listener(n.on_react, "on_reaction_add") |  | ||||||
|  | |||||||
| @ -50,27 +50,27 @@ class Hangman(Cog): | |||||||
|             theface = await self.config.guild(guild).theface() |             theface = await self.config.guild(guild).theface() | ||||||
|             self.hanglist[guild] = ( |             self.hanglist[guild] = ( | ||||||
|                 """> |                 """> | ||||||
|                    \_________ |                    \\_________ | ||||||
|                     |/         |                     |/         | ||||||
|                     |               |                     |               | ||||||
|                     |                 |                     |                 | ||||||
|                     |                  |                     |                  | ||||||
|                     |                |                     |                | ||||||
|                     |                    |                     |                    | ||||||
|                     |\___                  |                     |\\___                  | ||||||
|                     """, |                     """, | ||||||
|                 """> |                 """> | ||||||
|                    \_________ |                    \\_________ | ||||||
|                     |/   |       |                     |/   |       | ||||||
|                     |               |                     |               | ||||||
|                     |                 |                     |                 | ||||||
|                     |                  |                     |                  | ||||||
|                     |                |                     |                | ||||||
|                     |                    |                     |                    | ||||||
|                     |\___                  |                     |\\___                  | ||||||
|                     H""", |                     H""", | ||||||
|                 """> |                 """> | ||||||
|                    \_________        |                    \\_________        | ||||||
|                     |/   |               |                     |/   |               | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
| @ -79,10 +79,10 @@ class Hangman(Cog): | |||||||
|                     |                        |                     |                        | ||||||
|                     |                          |                     |                          | ||||||
|                     |                           |                     |                           | ||||||
|                     |\___                        |                     |\\___                        | ||||||
|                     HA""", |                     HA""", | ||||||
|                 """> |                 """> | ||||||
|                    \________                |                    \\________                | ||||||
|                     |/   |                    |                     |/   |                    | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
| @ -91,10 +91,10 @@ class Hangman(Cog): | |||||||
|                     |    |                     |                     |    |                     | ||||||
|                     |                            |                     |                            | ||||||
|                     |                             |                     |                             | ||||||
|                     |\___                     |                     |\\___                     | ||||||
|                     HAN""", |                     HAN""", | ||||||
|                 """> |                 """> | ||||||
|                    \_________              |                    \\_________              | ||||||
|                     |/   |                |                     |/   |                | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
| @ -103,43 +103,43 @@ class Hangman(Cog): | |||||||
|                     |     |                     |                     |     |                     | ||||||
|                     |                         |                     |                         | ||||||
|                     |                           |                     |                           | ||||||
|                     |\___                           |                     |\\___                           | ||||||
|                     HANG""", |                     HANG""", | ||||||
|                 """> |                 """> | ||||||
|                    \_________               |                    \\_________               | ||||||
|                     |/   |                      |                     |/   |                      | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
|                 + """                       |                 + """                       | ||||||
|                     |   /|\                     |                     |   /|\\                     | ||||||
|                     |     |                        |                     |     |                        | ||||||
|                     |                              |                     |                              | ||||||
|                     |                             |                     |                             | ||||||
|                     |\___                           |                     |\\___                           | ||||||
|                     HANGM""", |                     HANGM""", | ||||||
|                 """> |                 """> | ||||||
|                    \________                    |                    \\________                    | ||||||
|                     |/   |                          |                     |/   |                          | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
|                 + """                        |                 + """                        | ||||||
|                     |   /|\                              |                     |   /|\\                              | ||||||
|                     |     |                           |                     |     |                           | ||||||
|                     |   /                             |                     |   /                             | ||||||
|                     |                                   |                     |                                   | ||||||
|                     |\___                               |                     |\\___                               | ||||||
|                     HANGMA""", |                     HANGMA""", | ||||||
|                 """> |                 """> | ||||||
|                    \________ |                    \\________ | ||||||
|                     |/   |      |                     |/   |      | ||||||
|                     |   """ |                     |   """ | ||||||
|                 + theface |                 + theface | ||||||
|                 + """      |                 + """      | ||||||
|                     |   /|\            |                     |   /|\\            | ||||||
|                     |     |         |                     |     |         | ||||||
|                     |   / \         |                     |   / \\         | ||||||
|                     |                |                     |                | ||||||
|                     |\___            |                     |\\___            | ||||||
|                     HANGMAN""", |                     HANGMAN""", | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
| @ -255,7 +255,7 @@ class Hangman(Cog): | |||||||
|             elif i in self.the_data[guild]["guesses"] or i not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": |             elif i in self.the_data[guild]["guesses"] or i not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": | ||||||
|                 out_str += "__" + i + "__ " |                 out_str += "__" + i + "__ " | ||||||
|             else: |             else: | ||||||
|                 out_str += "**\_** " |                 out_str += "**\\_** " | ||||||
|                 self.winbool[guild] = False |                 self.winbool[guild] = False | ||||||
| 
 | 
 | ||||||
|         return out_str |         return out_str | ||||||
| @ -286,10 +286,10 @@ class Hangman(Cog): | |||||||
| 
 | 
 | ||||||
|         await self._reprintgame(message) |         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]): |     async def on_react(self, reaction, user: Union[discord.User, discord.Member]): | ||||||
|         """ Thanks to flapjack reactpoll for guidelines |         """Thanks to flapjack reactpoll for guidelines | ||||||
|             https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py""" |         https://github.com/flapjax/FlapJack-Cogs/blob/master/reactpoll/reactpoll.py""" | ||||||
|         guild: discord.Guild = getattr(user, "guild", None) |         guild: discord.Guild = getattr(user, "guild", None) | ||||||
|         if guild is None: |         if guild is None: | ||||||
|             return |             return | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								isitdown/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								isitdown/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | from .isitdown import IsItDown | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | async def setup(bot): | ||||||
|  |     bot.add_cog(IsItDown(bot)) | ||||||
							
								
								
									
										17
									
								
								isitdown/info.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								isitdown/info.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | { | ||||||
|  |   "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", | ||||||
|  |     "tools" | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								isitdown/isitdown.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								isitdown/isitdown.py
									
									
									
									
									
										Normal file
									
								
							| @ -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 | ||||||
| @ -22,7 +22,9 @@ class LaunchLib(commands.Cog): | |||||||
|     def __init__(self, bot: Red): |     def __init__(self, bot: Red): | ||||||
|         super().__init__() |         super().__init__() | ||||||
|         self.bot = bot |         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 = {} |         default_guild = {} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -75,9 +75,7 @@ class LastSeen(Cog): | |||||||
|         else: |         else: | ||||||
|             last_seen = await self.config.member(member).seen() |             last_seen = await self.config.member(member).seen() | ||||||
|             if last_seen is None: |             if last_seen is None: | ||||||
|                 await ctx.maybe_send_embed( |                 await ctx.maybe_send_embed("I've never seen this user") | ||||||
|                     embed=discord.Embed(description="I've never seen this user") |  | ||||||
|                 ) |  | ||||||
|                 return |                 return | ||||||
|             last_seen = self.get_date_time(last_seen) |             last_seen = self.get_date_time(last_seen) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -360,7 +360,9 @@ class PlantTycoon(commands.Cog): | |||||||
|             ``{0}prune``: Prune your plant.\n""" |             ``{0}prune``: Prune your plant.\n""" | ||||||
| 
 | 
 | ||||||
|             em = discord.Embed( |             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_thumbnail(url="https://image.prntscr.com/image/AW7GuFIBSeyEgkR2W3SeiQ.png") | ||||||
|             em.set_footer( |             em.set_footer( | ||||||
| @ -525,7 +527,8 @@ class PlantTycoon(commands.Cog): | |||||||
| 
 | 
 | ||||||
|         if t: |         if t: | ||||||
|             em = discord.Embed( |             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.set_thumbnail(url=plant["image"]) | ||||||
|             em.add_field(name="**Name**", value=plant["name"]) |             em.add_field(name="**Name**", value=plant["name"]) | ||||||
| @ -583,7 +586,8 @@ class PlantTycoon(commands.Cog): | |||||||
|         author = ctx.author |         author = ctx.author | ||||||
|         if product is None: |         if product is None: | ||||||
|             em = discord.Embed( |             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: |             for pd in self.products: | ||||||
|                 em.add_field( |                 em.add_field( | ||||||
| @ -616,8 +620,11 @@ class PlantTycoon(commands.Cog): | |||||||
|                         await gardener.save_gardener() |                         await gardener.save_gardener() | ||||||
|                         message = "You bought {}.".format(product.lower()) |                         message = "You bought {}.".format(product.lower()) | ||||||
|                     else: |                     else: | ||||||
|                         message = "You don't have enough Thneeds. You have {}, but need {}.".format( |                         message = ( | ||||||
|                             gardener.points, self.products[product.lower()]["cost"] * amount, |                             "You don't have enough Thneeds. You have {}, but need {}.".format( | ||||||
|  |                                 gardener.points, | ||||||
|  |                                 self.products[product.lower()]["cost"] * amount, | ||||||
|  |                             ) | ||||||
|                         ) |                         ) | ||||||
|                 else: |                 else: | ||||||
|                     message = "I don't have this product." |                     message = "I don't have this product." | ||||||
|  | |||||||
| @ -1,3 +1,4 @@ | |||||||
|  | import logging | ||||||
| from typing import List, Union | from typing import List, Union | ||||||
| 
 | 
 | ||||||
| import discord | import discord | ||||||
| @ -5,6 +6,8 @@ from redbot.core import Config, commands | |||||||
| from redbot.core.bot import Red | from redbot.core.bot import Red | ||||||
| from redbot.core.commands import Cog | from redbot.core.commands import Cog | ||||||
| 
 | 
 | ||||||
|  | log = logging.getLogger("red.fox_v3.reactrestrict") | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class ReactRestrictCombo: | class ReactRestrictCombo: | ||||||
|     def __init__(self, message_id, role_id): |     def __init__(self, message_id, role_id): | ||||||
| @ -131,10 +134,12 @@ class ReactRestrict(Cog): | |||||||
|             If no such channel or member can be found. |             If no such channel or member can be found. | ||||||
|         """ |         """ | ||||||
|         channel = self.bot.get_channel(channel_id) |         channel = self.bot.get_channel(channel_id) | ||||||
|  |         if channel is None: | ||||||
|  |             raise LookupError("no channel found.") | ||||||
|         try: |         try: | ||||||
|             member = channel.guild.get_member(user_id) |             member = channel.guild.get_member(user_id) | ||||||
|         except AttributeError as e: |         except AttributeError as e: | ||||||
|             raise LookupError("No channel found.") from e |             raise LookupError("No member found.") from e | ||||||
| 
 | 
 | ||||||
|         if member is None: |         if member is None: | ||||||
|             raise LookupError("No member found.") |             raise LookupError("No member found.") | ||||||
| @ -168,7 +173,7 @@ class ReactRestrict(Cog): | |||||||
|         """ |         """ | ||||||
|         channel = self.bot.get_channel(channel_id) |         channel = self.bot.get_channel(channel_id) | ||||||
|         try: |         try: | ||||||
|             return await channel.get_message(message_id) |             return await channel.fetch_message(message_id) | ||||||
|         except discord.NotFound: |         except discord.NotFound: | ||||||
|             pass |             pass | ||||||
|         except AttributeError:  # VoiceChannel object has no attribute 'get_message' |         except AttributeError:  # VoiceChannel object has no attribute 'get_message' | ||||||
| @ -186,9 +191,11 @@ class ReactRestrict(Cog): | |||||||
|         :param message_id: |         :param message_id: | ||||||
|         :return: |         :return: | ||||||
|         """ |         """ | ||||||
|         for channel in ctx.guild.channels: | 
 | ||||||
|  |         guild: discord.Guild = ctx.guild | ||||||
|  |         for channel in guild.text_channels: | ||||||
|             try: |             try: | ||||||
|                 return await channel.get_message(message_id) |                 return await channel.fetch_message(message_id) | ||||||
|             except discord.NotFound: |             except discord.NotFound: | ||||||
|                 pass |                 pass | ||||||
|             except AttributeError:  # VoiceChannel object has no attribute 'get_message' |             except AttributeError:  # VoiceChannel object has no attribute 'get_message' | ||||||
| @ -232,7 +239,7 @@ class ReactRestrict(Cog): | |||||||
|         # noinspection PyTypeChecker |         # noinspection PyTypeChecker | ||||||
|         await self.add_reactrestrict(message_id, role) |         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() |     @reactrestrict.command() | ||||||
|     async def remove(self, ctx: commands.Context, message_id: int, role: discord.Role): |     async def remove(self, ctx: commands.Context, message_id: int, role: discord.Role): | ||||||
| @ -248,37 +255,38 @@ class ReactRestrict(Cog): | |||||||
|         # noinspection PyTypeChecker |         # noinspection PyTypeChecker | ||||||
|         await self.remove_react(message_id, role) |         await self.remove_react(message_id, role) | ||||||
| 
 | 
 | ||||||
|         await ctx.send("Reaction removed.") |         await ctx.send("React restriction removed.") | ||||||
| 
 | 
 | ||||||
|     @commands.Cog.listener() |     @commands.Cog.listener() | ||||||
|     async def on_raw_reaction_add( |     async def on_raw_reaction_add(self, payload: discord.RawReactionActionEvent): | ||||||
|         self, emoji: discord.PartialEmoji, message_id: int, channel_id: int, user_id: int |  | ||||||
|     ): |  | ||||||
|         """ |         """ | ||||||
|         Event handler for long term reaction watching. |         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 |         emoji = payload.emoji | ||||||
|         else: |         message_id = payload.message_id | ||||||
|             emoji_id = emoji.name |         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) |         has_reactrestrict, combos = await self.has_reactrestrict_combo(message_id) | ||||||
| 
 | 
 | ||||||
|         if not has_reactrestrict: |         if not has_reactrestrict: | ||||||
|  |             log.debug("Message not react restricted") | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             member = self._get_member(channel_id, user_id) |             member = self._get_member(channel_id, user_id) | ||||||
|         except LookupError: |         except LookupError: | ||||||
|  |             log.exception("Unable to get member from guild") | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         if member.bot: |         if member.bot: | ||||||
|  |             log.debug("Won't remove reactions added by bots") | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         if await self.bot.cog_disabled_in_guild(self, member.guild): |         if await self.bot.cog_disabled_in_guild(self, member.guild): | ||||||
| @ -287,14 +295,19 @@ class ReactRestrict(Cog): | |||||||
|         try: |         try: | ||||||
|             roles = [self._get_role(member.guild, c.role_id) for c in combos] |             roles = [self._get_role(member.guild, c.role_id) for c in combos] | ||||||
|         except LookupError: |         except LookupError: | ||||||
|  |             log.exception("Couldn't get approved roles from combos") | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         for apprrole in roles: |         for apprrole in roles: | ||||||
|             if apprrole in member.roles: |             if apprrole in member.roles: | ||||||
|  |                 log.debug("Has approved role") | ||||||
|                 return |                 return | ||||||
| 
 | 
 | ||||||
|         message = await self._get_message_from_channel(channel_id, message_id) |         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: |     #     try: | ||||||
|     #         await member.add_roles(*roles) |     #         await member.add_roles(*roles) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 bobloy
						bobloy