mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-12-05 17:02:32 -05:00
Compare commits
33 Commits
8d8918b3c6
...
3.3.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
734ab49f6a | ||
|
|
204d82db8f | ||
|
|
77a5b4c742 | ||
|
|
7707fec199 | ||
|
|
4ef51a165f | ||
|
|
574dabbeac | ||
|
|
e463c307ea | ||
|
|
b8e56f3632 | ||
|
|
dc3fe1f8f8 | ||
|
|
1dda0f95de | ||
|
|
5e5687d0bb | ||
|
|
e0ad67aa3d | ||
|
|
c3eb4abd7a | ||
|
|
d97760997e | ||
|
|
81193d17c7 | ||
|
|
cf78ea06e2 | ||
|
|
26122e56a0 | ||
|
|
d8d3e9fceb | ||
|
|
b3281385e9 | ||
|
|
e6947bdbf6 | ||
|
|
a6d924221d | ||
|
|
cf7db1e891 | ||
|
|
bc544d476b | ||
|
|
10976f218b | ||
|
|
a589838a41 | ||
|
|
e36d1f143d | ||
|
|
9a6f78e62e | ||
|
|
649db87a8a | ||
|
|
c6f9a78d57 | ||
|
|
bd89e4386d | ||
|
|
a962f94a58 | ||
|
|
3471011f85 | ||
|
|
186dbe6118 |
@@ -1,5 +1,86 @@
|
|||||||
.. 3.3.x Changelogs
|
.. 3.3.x Changelogs
|
||||||
|
|
||||||
|
Redbot 3.3.12 (2020-08-18)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
| Thanks to all these amazing people that contributed to this release:
|
||||||
|
| :ghuser:`Dav-Git`, :ghuser:`douglas-cpp`, :ghuser:`flaree`, :ghuser:`jack1142`, :ghuser:`Kowlin`, :ghuser:`MeatyChunks`, :ghuser:`PredaaA`, :ghuser:`Predeactor`, :ghuser:`thisisjvgrace`, :ghuser:`Vexed01`, :ghuser:`zephyrkul`
|
||||||
|
|
||||||
|
End-user changelog
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Core Bot
|
||||||
|
********
|
||||||
|
|
||||||
|
- Red now logs clearer error if it can't find package to load in any cog path during bot startup (:issue:`4079`)
|
||||||
|
|
||||||
|
Mod
|
||||||
|
***
|
||||||
|
|
||||||
|
- ``[p]mute voice`` and ``[p]unmute voice`` now take action instantly if bot has Move Members permission (:issue:`4064`)
|
||||||
|
- Added typing to ``[p](un)mute guild`` to indicate that mute is being processed (:issue:`4066`, :issue:`4172`)
|
||||||
|
|
||||||
|
Streams
|
||||||
|
*******
|
||||||
|
|
||||||
|
- Improve error messages for invalid channel names/IDs (:issue:`4147`, :issue:`4148`)
|
||||||
|
|
||||||
|
Trivia Lists
|
||||||
|
************
|
||||||
|
|
||||||
|
- Added ``whosthatpokemon2`` trivia containing Pokémons from 2nd generation (:issue:`4102`)
|
||||||
|
- Added ``whosthatpokemon3`` trivia containing Pokémons from 3rd generation (:issue:`4141`)
|
||||||
|
|
||||||
|
|
||||||
|
Miscellaneous
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- Updated features list in ``[p]serverinfo`` with the latest changes from Discord (:issue:`4116`)
|
||||||
|
- Simple version of ``[p]serverinfo`` now shows info about more detailed ``[p]serverinfo 1`` (:issue:`4121`)
|
||||||
|
|
||||||
|
|
||||||
|
Redbot 3.3.11 (2020-08-10)
|
||||||
|
==========================
|
||||||
|
|
||||||
|
| Thanks to all these amazing people that contributed to this release:
|
||||||
|
| :ghuser:`douglas-cpp`, :ghuser:`Drapersniper`, :ghuser:`jack1142`, :ghuser:`MeatyChunks`, :ghuser:`Vexed01`, :ghuser:`yamikaitou`
|
||||||
|
|
||||||
|
End-user changelog
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Audio
|
||||||
|
*****
|
||||||
|
|
||||||
|
- Audio should now work again on all voice regions (:issue:`4162`, :issue:`4168`)
|
||||||
|
- Removed an edge case where an unfriendly error message was sent in Audio cog (:issue:`3879`)
|
||||||
|
|
||||||
|
Cleanup
|
||||||
|
*******
|
||||||
|
|
||||||
|
- Fixed a bug causing ``[p]cleanup`` commands to clear all messages within last 2 weeks when ``0`` is passed as the amount of messages to delete (:issue:`4114`, :issue:`4115`)
|
||||||
|
|
||||||
|
CustomCommands
|
||||||
|
**************
|
||||||
|
|
||||||
|
- ``[p]cc show`` now sends an error message when command with the provided name couldn't be found (:issue:`4108`)
|
||||||
|
|
||||||
|
Downloader
|
||||||
|
**********
|
||||||
|
|
||||||
|
- ``[p]findcog`` no longer fails for 3rd-party cogs without any author (:issue:`4032`, :issue:`4042`)
|
||||||
|
- Update commands no longer crash when a different repo is added under a repo name that was once used (:issue:`4086`)
|
||||||
|
|
||||||
|
Permissions
|
||||||
|
***********
|
||||||
|
|
||||||
|
- ``[p]permissions removeserverrule`` and ``[p]permissions removeglobalrule`` no longer error when trying to remove a rule that doesn't exist (:issue:`4028`, :issue:`4036`)
|
||||||
|
|
||||||
|
Warnings
|
||||||
|
********
|
||||||
|
|
||||||
|
- ``[p]warn`` now sends an error message (instead of no feedback) when an unregistered reason is used by someone who doesn't have Administrator permission (:issue:`3839`, :issue:`3840`)
|
||||||
|
|
||||||
|
|
||||||
Redbot 3.3.10 (2020-07-09)
|
Redbot 3.3.10 (2020-07-09)
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ Then run the following command:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
CONFIGURE_OPTS=--enable-optimizations pyenv install 3.8.3 -v
|
CONFIGURE_OPTS=--enable-optimizations pyenv install 3.8.5 -v
|
||||||
|
|
||||||
This may take a long time to complete, depending on your hardware. For some machines (such as
|
This may take a long time to complete, depending on your hardware. For some machines (such as
|
||||||
Raspberry Pis and micro-tier VPSes), it may take over an hour; in this case, you may wish to remove
|
Raspberry Pis and micro-tier VPSes), it may take over an hour; in this case, you may wish to remove
|
||||||
@@ -409,7 +409,7 @@ After that is finished, run:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
pyenv global 3.8.3
|
pyenv global 3.8.5
|
||||||
|
|
||||||
Pyenv is now installed and your system should be configured to run Python 3.8.
|
Pyenv is now installed and your system should be configured to run Python 3.8.
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ Using PowerShell and Chocolatey (recommended)
|
|||||||
*********************************************
|
*********************************************
|
||||||
|
|
||||||
To install via PowerShell, search "powershell" in the Windows start menu,
|
To install via PowerShell, search "powershell" in the Windows start menu,
|
||||||
right-click on it and then click "Run as administrator"
|
right-click on it and then click "Run as administrator".
|
||||||
|
|
||||||
Then run each of the following commands:
|
Then run each of the following commands:
|
||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||||
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||||
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||||
choco upgrade git --params "/GitOnlyOnPath /WindowsTerminal" -y
|
choco upgrade git --params "/GitOnlyOnPath /WindowsTerminal" -y
|
||||||
choco upgrade visualstudio2019-workload-vctools -y
|
choco upgrade visualstudio2019-workload-vctools -y
|
||||||
@@ -63,7 +64,7 @@ Manually installing dependencies
|
|||||||
|
|
||||||
* `MSVC Build tools <https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019>`_
|
* `MSVC Build tools <https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019>`_
|
||||||
|
|
||||||
* `Python 3.8.1 <https://www.python.org/downloads/>`_ - Red needs Python 3.8.1 or greater
|
* `Python 3.8.1 or greater <https://www.python.org/downloads/>`_
|
||||||
|
|
||||||
.. attention:: Please make sure that the box to add Python to PATH is CHECKED, otherwise
|
.. attention:: Please make sure that the box to add Python to PATH is CHECKED, otherwise
|
||||||
you may run into issues when trying to run Red.
|
you may run into issues when trying to run Red.
|
||||||
@@ -86,7 +87,7 @@ Creating a Virtual Environment
|
|||||||
|
|
||||||
.. tip::
|
.. tip::
|
||||||
|
|
||||||
If you want to learn more about virtual environments, see page: `about-venvs`
|
If you want to learn more about virtual environments, see page: `about-venvs`.
|
||||||
|
|
||||||
We require installing Red into a virtual environment. Don't be scared, it's very
|
We require installing Red into a virtual environment. Don't be scared, it's very
|
||||||
straightforward.
|
straightforward.
|
||||||
@@ -95,7 +96,12 @@ First, choose a directory where you would like to create your virtual environmen
|
|||||||
to keep it in a location which is easy to type out the path to. From now, we'll call it
|
to keep it in a location which is easy to type out the path to. From now, we'll call it
|
||||||
``redenv`` and it will be located in your home directory.
|
``redenv`` and it will be located in your home directory.
|
||||||
|
|
||||||
Start with opening a command prompt (open Start, search for "command prompt", then click it)
|
Start with opening a command prompt (open Start, search for "command prompt", then click it).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You shouldn't run command prompt as administrator when creating your virtual environment, or
|
||||||
|
running Red.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
@@ -144,11 +150,6 @@ Run **one** of the following set of commands, depending on what extras you want
|
|||||||
python -m pip install -U pip setuptools wheel
|
python -m pip install -U pip setuptools wheel
|
||||||
python -m pip install -U Red-DiscordBot[postgres]
|
python -m pip install -U Red-DiscordBot[postgres]
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
These commands are also used for updating Red
|
|
||||||
|
|
||||||
--------------------------
|
--------------------------
|
||||||
Setting Up and Running Red
|
Setting Up and Running Red
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ def _update_event_loop_policy():
|
|||||||
_asyncio.set_event_loop_policy(_uvloop.EventLoopPolicy())
|
_asyncio.set_event_loop_policy(_uvloop.EventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
__version__ = "3.3.11.dev1"
|
__version__ = "3.3.12"
|
||||||
version_info = VersionInfo.from_str(__version__)
|
version_info = VersionInfo.from_str(__version__)
|
||||||
|
|
||||||
# Filter fuzzywuzzy slow sequence matcher warning
|
# Filter fuzzywuzzy slow sequence matcher warning
|
||||||
|
|||||||
@@ -576,6 +576,16 @@ class PlayerCommands(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
notify_channel = self.bot.get_channel(notify_channel)
|
notify_channel = self.bot.get_channel(notify_channel)
|
||||||
await self.send_embed_msg(notify_channel, title=_("Couldn't get a valid track."))
|
await self.send_embed_msg(notify_channel, title=_("Couldn't get a valid track."))
|
||||||
return
|
return
|
||||||
|
except TrackEnqueueError:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable to Get Track"),
|
||||||
|
description=_(
|
||||||
|
"I'm unable get a track from Lavalink at the moment, try again in a few "
|
||||||
|
"minutes."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if not guild_data["auto_play"]:
|
if not guild_data["auto_play"]:
|
||||||
await ctx.invoke(self.command_audioset_autoplay_toggle)
|
await ctx.invoke(self.command_audioset_autoplay_toggle)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ from ...apis.playlist_interface import create_playlist, delete_playlist, get_all
|
|||||||
from ...audio_dataclasses import LocalPath, Query
|
from ...audio_dataclasses import LocalPath, Query
|
||||||
from ...audio_logging import IS_DEBUG, debug_exc_log
|
from ...audio_logging import IS_DEBUG, debug_exc_log
|
||||||
from ...converters import ComplexScopeParser, ScopeParser
|
from ...converters import ComplexScopeParser, ScopeParser
|
||||||
from ...errors import MissingGuild, TooManyMatches
|
from ...errors import MissingGuild, TooManyMatches, TrackEnqueueError
|
||||||
from ...utils import PlaylistScope
|
from ...utils import PlaylistScope
|
||||||
from ..abc import MixinMeta
|
from ..abc import MixinMeta
|
||||||
from ..cog_utils import CompositeMetaClass, LazyGreedyConverter, PlaylistConverter, _
|
from ..cog_utils import CompositeMetaClass, LazyGreedyConverter, PlaylistConverter, _
|
||||||
@@ -1817,6 +1817,7 @@ class PlaylistCommands(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
uploaded_playlist_name = uploaded_playlist.get(
|
uploaded_playlist_name = uploaded_playlist.get(
|
||||||
"name", (file_url.split("/")[6]).split(".")[0]
|
"name", (file_url.split("/")[6]).split(".")[0]
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
if self.api_interface is not None and (
|
if self.api_interface is not None and (
|
||||||
not uploaded_playlist_url
|
not uploaded_playlist_url
|
||||||
or not self.match_yt_playlist(uploaded_playlist_url)
|
or not self.match_yt_playlist(uploaded_playlist_url)
|
||||||
@@ -1854,6 +1855,16 @@ class PlaylistCommands(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
playlist_url=uploaded_playlist_url,
|
playlist_url=uploaded_playlist_url,
|
||||||
scope_data=(scope, author, guild, specified_user),
|
scope_data=(scope, author, guild, specified_user),
|
||||||
)
|
)
|
||||||
|
except TrackEnqueueError:
|
||||||
|
self.update_player_lock(ctx, False)
|
||||||
|
return await self.send_embed_msg(
|
||||||
|
ctx,
|
||||||
|
title=_("Unable to Get Track"),
|
||||||
|
description=_(
|
||||||
|
"I'm unable get a track from Lavalink at the moment, try again in a few "
|
||||||
|
"minutes."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
@commands.cooldown(1, 60, commands.BucketType.member)
|
@commands.cooldown(1, 60, commands.BucketType.member)
|
||||||
@command_playlist.command(
|
@command_playlist.command(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import logging
|
|||||||
import discord
|
import discord
|
||||||
import lavalink
|
import lavalink
|
||||||
|
|
||||||
from ...errors import DatabaseError
|
from ...errors import DatabaseError, TrackEnqueueError
|
||||||
from ..abc import MixinMeta
|
from ..abc import MixinMeta
|
||||||
from ..cog_utils import CompositeMetaClass, _
|
from ..cog_utils import CompositeMetaClass, _
|
||||||
|
|
||||||
@@ -62,12 +62,25 @@ class LavalinkEvents(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
await self.api_interface.autoplay(player, self.playlist_api)
|
await self.api_interface.autoplay(player, self.playlist_api)
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
notify_channel = player.fetch("channel")
|
notify_channel = player.fetch("channel")
|
||||||
if notify_channel:
|
|
||||||
notify_channel = self.bot.get_channel(notify_channel)
|
notify_channel = self.bot.get_channel(notify_channel)
|
||||||
|
if notify_channel:
|
||||||
await self.send_embed_msg(
|
await self.send_embed_msg(
|
||||||
notify_channel, title=_("Couldn't get a valid track.")
|
notify_channel, title=_("Couldn't get a valid track.")
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
except TrackEnqueueError:
|
||||||
|
notify_channel = player.fetch("channel")
|
||||||
|
notify_channel = self.bot.get_channel(notify_channel)
|
||||||
|
if notify_channel:
|
||||||
|
await self.send_embed_msg(
|
||||||
|
notify_channel,
|
||||||
|
title=_("Unable to Get Track"),
|
||||||
|
description=_(
|
||||||
|
"I'm unable get a track from Lavalink at the moment, try again in a few "
|
||||||
|
"minutes."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return
|
||||||
if event_type == lavalink.LavalinkEvents.TRACK_START and notify:
|
if event_type == lavalink.LavalinkEvents.TRACK_START and notify:
|
||||||
notify_channel = player.fetch("channel")
|
notify_channel = player.fetch("channel")
|
||||||
if notify_channel:
|
if notify_channel:
|
||||||
@@ -180,7 +193,9 @@ class LavalinkEvents(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
colour=await self.bot.get_embed_color(message_channel),
|
colour=await self.bot.get_embed_color(message_channel),
|
||||||
title=_("Track Stuck"),
|
title=_("Track Stuck"),
|
||||||
description="{}".format(description),
|
description=_(
|
||||||
|
"Playback of the song has stopped due to an unexcepted error.\n{error}"
|
||||||
|
).format(error=description),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from .errors import LavalinkDownloadFailed
|
|||||||
|
|
||||||
log = logging.getLogger("red.audio.manager")
|
log = logging.getLogger("red.audio.manager")
|
||||||
JAR_VERSION: Final[str] = "3.3.1"
|
JAR_VERSION: Final[str] = "3.3.1"
|
||||||
JAR_BUILD: Final[int] = 1068
|
JAR_BUILD: Final[int] = 1069
|
||||||
LAVALINK_DOWNLOAD_URL: Final[str] = (
|
LAVALINK_DOWNLOAD_URL: Final[str] = (
|
||||||
"https://github.com/Cog-Creators/Lavalink-Jars/releases/download/"
|
"https://github.com/Cog-Creators/Lavalink-Jars/releases/download/"
|
||||||
f"{JAR_VERSION}_{JAR_BUILD}/"
|
f"{JAR_VERSION}_{JAR_BUILD}/"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Union, List, Callable, Set
|
from typing import Callable, List, Optional, Set, Union
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ from redbot.core.i18n import Translator, cog_i18n
|
|||||||
from redbot.core.utils.chat_formatting import humanize_number
|
from redbot.core.utils.chat_formatting import humanize_number
|
||||||
from redbot.core.utils.mod import slow_deletion, mass_purge
|
from redbot.core.utils.mod import slow_deletion, mass_purge
|
||||||
from redbot.core.utils.predicates import MessagePredicate
|
from redbot.core.utils.predicates import MessagePredicate
|
||||||
from .converters import RawMessageIds
|
from .converters import PositiveInt, RawMessageIds, positive_int
|
||||||
|
|
||||||
_ = Translator("Cleanup", __file__)
|
_ = Translator("Cleanup", __file__)
|
||||||
|
|
||||||
@@ -60,9 +60,9 @@ class Cleanup(commands.Cog):
|
|||||||
async def get_messages_for_deletion(
|
async def get_messages_for_deletion(
|
||||||
*,
|
*,
|
||||||
channel: discord.TextChannel,
|
channel: discord.TextChannel,
|
||||||
number: int = None,
|
number: Optional[PositiveInt] = None,
|
||||||
check: Callable[[discord.Message], bool] = lambda x: True,
|
check: Callable[[discord.Message], bool] = lambda x: True,
|
||||||
limit: int = None,
|
limit: Optional[PositiveInt] = None,
|
||||||
before: Union[discord.Message, datetime] = None,
|
before: Union[discord.Message, datetime] = None,
|
||||||
after: Union[discord.Message, datetime] = None,
|
after: Union[discord.Message, datetime] = None,
|
||||||
delete_pinned: bool = False,
|
delete_pinned: bool = False,
|
||||||
@@ -105,7 +105,7 @@ class Cleanup(commands.Cog):
|
|||||||
break
|
break
|
||||||
if message_filter(message):
|
if message_filter(message):
|
||||||
collected.append(message)
|
collected.append(message)
|
||||||
if number and number <= len(collected):
|
if number is not None and number <= len(collected):
|
||||||
break
|
break
|
||||||
|
|
||||||
return collected
|
return collected
|
||||||
@@ -120,7 +120,7 @@ class Cleanup(commands.Cog):
|
|||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(manage_messages=True)
|
@commands.bot_has_permissions(manage_messages=True)
|
||||||
async def text(
|
async def text(
|
||||||
self, ctx: commands.Context, text: str, number: int, delete_pinned: bool = False
|
self, ctx: commands.Context, text: str, number: positive_int, delete_pinned: bool = False
|
||||||
):
|
):
|
||||||
"""Delete the last X messages matching the specified text.
|
"""Delete the last X messages matching the specified text.
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ class Cleanup(commands.Cog):
|
|||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(manage_messages=True)
|
@commands.bot_has_permissions(manage_messages=True)
|
||||||
async def user(
|
async def user(
|
||||||
self, ctx: commands.Context, user: str, number: int, delete_pinned: bool = False
|
self, ctx: commands.Context, user: str, number: positive_int, delete_pinned: bool = False
|
||||||
):
|
):
|
||||||
"""Delete the last X messages from a specified user.
|
"""Delete the last X messages from a specified user.
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ class Cleanup(commands.Cog):
|
|||||||
self,
|
self,
|
||||||
ctx: commands.Context,
|
ctx: commands.Context,
|
||||||
message_id: RawMessageIds,
|
message_id: RawMessageIds,
|
||||||
number: int,
|
number: positive_int,
|
||||||
delete_pinned: bool = False,
|
delete_pinned: bool = False,
|
||||||
):
|
):
|
||||||
"""Deletes X messages before specified message.
|
"""Deletes X messages before specified message.
|
||||||
@@ -351,7 +351,9 @@ class Cleanup(commands.Cog):
|
|||||||
@cleanup.command()
|
@cleanup.command()
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(manage_messages=True)
|
@commands.bot_has_permissions(manage_messages=True)
|
||||||
async def messages(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
|
async def messages(
|
||||||
|
self, ctx: commands.Context, number: positive_int, delete_pinned: bool = False
|
||||||
|
):
|
||||||
"""Delete the last X messages.
|
"""Delete the last X messages.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@@ -372,7 +374,7 @@ class Cleanup(commands.Cog):
|
|||||||
to_delete.append(ctx.message)
|
to_delete.append(ctx.message)
|
||||||
|
|
||||||
reason = "{}({}) deleted {} messages in channel {}.".format(
|
reason = "{}({}) deleted {} messages in channel {}.".format(
|
||||||
author.name, author.id, number, channel.name
|
author.name, author.id, len(to_delete), channel.name
|
||||||
)
|
)
|
||||||
log.info(reason)
|
log.info(reason)
|
||||||
|
|
||||||
@@ -381,7 +383,9 @@ class Cleanup(commands.Cog):
|
|||||||
@cleanup.command(name="bot")
|
@cleanup.command(name="bot")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(manage_messages=True)
|
@commands.bot_has_permissions(manage_messages=True)
|
||||||
async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
|
async def cleanup_bot(
|
||||||
|
self, ctx: commands.Context, number: positive_int, delete_pinned: bool = False
|
||||||
|
):
|
||||||
"""Clean up command messages and messages from the bot."""
|
"""Clean up command messages and messages from the bot."""
|
||||||
|
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
@@ -458,7 +462,7 @@ class Cleanup(commands.Cog):
|
|||||||
async def cleanup_self(
|
async def cleanup_self(
|
||||||
self,
|
self,
|
||||||
ctx: commands.Context,
|
ctx: commands.Context,
|
||||||
number: int,
|
number: positive_int,
|
||||||
match_pattern: str = None,
|
match_pattern: str = None,
|
||||||
delete_pinned: bool = False,
|
delete_pinned: bool = False,
|
||||||
):
|
):
|
||||||
@@ -531,7 +535,7 @@ class Cleanup(commands.Cog):
|
|||||||
@cleanup.command(name="spam")
|
@cleanup.command(name="spam")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
@commands.bot_has_permissions(manage_messages=True)
|
@commands.bot_has_permissions(manage_messages=True)
|
||||||
async def cleanup_spam(self, ctx: commands.Context, number: int = 50):
|
async def cleanup_spam(self, ctx: commands.Context, number: positive_int = PositiveInt(50)):
|
||||||
"""Deletes duplicate messages in the channel from the last X messages and keeps only one copy.
|
"""Deletes duplicate messages in the channel from the last X messages and keeps only one copy.
|
||||||
|
|
||||||
Defaults to 50.
|
Defaults to 50.
|
||||||
|
|||||||
@@ -1,12 +1,30 @@
|
|||||||
from redbot.core.commands import Converter, BadArgument
|
from typing import NewType, TYPE_CHECKING
|
||||||
|
|
||||||
|
from redbot.core.commands import BadArgument, Context, Converter
|
||||||
from redbot.core.i18n import Translator
|
from redbot.core.i18n import Translator
|
||||||
|
from redbot.core.utils.chat_formatting import inline
|
||||||
|
|
||||||
_ = Translator("Cleanup", __file__)
|
_ = Translator("Cleanup", __file__)
|
||||||
|
|
||||||
|
|
||||||
class RawMessageIds(Converter):
|
class RawMessageIds(Converter):
|
||||||
async def convert(self, ctx, argument):
|
async def convert(self, ctx: Context, argument: str) -> int:
|
||||||
if argument.isnumeric() and len(argument) >= 17:
|
if argument.isnumeric() and len(argument) >= 17:
|
||||||
return int(argument)
|
return int(argument)
|
||||||
|
|
||||||
raise BadArgument(_("{} doesn't look like a valid message ID.").format(argument))
|
raise BadArgument(_("{} doesn't look like a valid message ID.").format(argument))
|
||||||
|
|
||||||
|
|
||||||
|
PositiveInt = NewType("PositiveInt", int)
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
positive_int = PositiveInt
|
||||||
|
else:
|
||||||
|
|
||||||
|
def positive_int(arg: str) -> int:
|
||||||
|
try:
|
||||||
|
ret = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
raise BadArgument(_("{arg} is not an integer.").format(arg=inline(arg)))
|
||||||
|
if ret <= 0:
|
||||||
|
raise BadArgument(_("{arg} is not a positive integer.").format(arg=inline(arg)))
|
||||||
|
return ret
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ class CustomCommands(commands.Cog):
|
|||||||
try:
|
try:
|
||||||
cmd = await self.commandobj.get_full(ctx.message, command_name)
|
cmd = await self.commandobj.get_full(ctx.message, command_name)
|
||||||
except NotFound:
|
except NotFound:
|
||||||
ctx.send(_("I could not not find that custom command."))
|
await ctx.send(_("I could not not find that custom command."))
|
||||||
return
|
return
|
||||||
|
|
||||||
responses = cmd["response"]
|
responses = cmd["response"]
|
||||||
|
|||||||
@@ -303,9 +303,21 @@ class Downloader(commands.Cog):
|
|||||||
hashes: Dict[Tuple[Repo, str], Set[InstalledModule]] = defaultdict(set)
|
hashes: Dict[Tuple[Repo, str], Set[InstalledModule]] = defaultdict(set)
|
||||||
for module in modules:
|
for module in modules:
|
||||||
module.repo = cast(Repo, module.repo)
|
module.repo = cast(Repo, module.repo)
|
||||||
if module.repo.commit != module.commit and await module.repo.is_ancestor(
|
if module.repo.commit != module.commit:
|
||||||
module.commit, module.repo.commit
|
try:
|
||||||
):
|
should_add = await module.repo.is_ancestor(module.commit, module.repo.commit)
|
||||||
|
except errors.UnknownRevision:
|
||||||
|
# marking module for update if the saved commit data is invalid
|
||||||
|
last_module_occurrence = await module.repo.get_last_module_occurrence(
|
||||||
|
module.name
|
||||||
|
)
|
||||||
|
if last_module_occurrence is not None and not last_module_occurrence.disabled:
|
||||||
|
if last_module_occurrence.type == InstallableType.COG:
|
||||||
|
cogs_to_update.add(last_module_occurrence)
|
||||||
|
elif last_module_occurrence.type == InstallableType.SHARED_LIBRARY:
|
||||||
|
libraries_to_update.add(last_module_occurrence)
|
||||||
|
else:
|
||||||
|
if should_add:
|
||||||
hashes[(module.repo, module.commit)].add(module)
|
hashes[(module.repo, module.commit)].add(module)
|
||||||
|
|
||||||
update_commits = []
|
update_commits = []
|
||||||
@@ -1387,7 +1399,11 @@ class Downloader(commands.Cog):
|
|||||||
cog_name = self.cog_name_from_instance(cog)
|
cog_name = self.cog_name_from_instance(cog)
|
||||||
installed, cog_installable = await self.is_installed(cog_name)
|
installed, cog_installable = await self.is_installed(cog_name)
|
||||||
if installed:
|
if installed:
|
||||||
made_by = humanize_list(cog_installable.author) or _("Missing from info.json")
|
made_by = (
|
||||||
|
humanize_list(cog_installable.author)
|
||||||
|
if cog_installable.author
|
||||||
|
else _("Missing from info.json")
|
||||||
|
)
|
||||||
repo_url = (
|
repo_url = (
|
||||||
_("Missing from installed repos")
|
_("Missing from installed repos")
|
||||||
if cog_installable.repo is None
|
if cog_installable.repo is None
|
||||||
|
|||||||
@@ -198,6 +198,11 @@ class Repo(RepoJSONMixin):
|
|||||||
descendant_rev : `str`
|
descendant_rev : `str`
|
||||||
Descendant revision
|
Descendant revision
|
||||||
|
|
||||||
|
Raises
|
||||||
|
------
|
||||||
|
.UnknownRevision
|
||||||
|
When git cannot find one of the provided revisions.
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
bool
|
bool
|
||||||
@@ -212,10 +217,17 @@ class Repo(RepoJSONMixin):
|
|||||||
maybe_ancestor_rev=maybe_ancestor_rev,
|
maybe_ancestor_rev=maybe_ancestor_rev,
|
||||||
descendant_rev=descendant_rev,
|
descendant_rev=descendant_rev,
|
||||||
)
|
)
|
||||||
p = await self._run(git_command, valid_exit_codes=valid_exit_codes)
|
p = await self._run(git_command, valid_exit_codes=valid_exit_codes, debug_only=True)
|
||||||
|
|
||||||
if p.returncode in valid_exit_codes:
|
if p.returncode in valid_exit_codes:
|
||||||
return not bool(p.returncode)
|
return not bool(p.returncode)
|
||||||
|
|
||||||
|
# this is a plumbing command so we're safe here
|
||||||
|
stderr = p.stderr.decode(**DECODE_PARAMS).strip()
|
||||||
|
if stderr.startswith(("fatal: Not a valid object name", "fatal: Not a valid commit name")):
|
||||||
|
rev, *__ = stderr[31:].split(maxsplit=1)
|
||||||
|
raise errors.UnknownRevision(f"Revision {rev} cannot be found.", git_command)
|
||||||
|
|
||||||
raise errors.GitException(
|
raise errors.GitException(
|
||||||
f"Git failed to determine if commit {maybe_ancestor_rev}"
|
f"Git failed to determine if commit {maybe_ancestor_rev}"
|
||||||
f" is ancestor of {descendant_rev} for repo at path: {self.folder_path}",
|
f" is ancestor of {descendant_rev} for repo at path: {self.folder_path}",
|
||||||
|
|||||||
@@ -532,7 +532,10 @@ class Economy(commands.Cog):
|
|||||||
@guild_only_check()
|
@guild_only_check()
|
||||||
async def payouts(self, ctx: commands.Context):
|
async def payouts(self, ctx: commands.Context):
|
||||||
"""Show the payouts for the slot machine."""
|
"""Show the payouts for the slot machine."""
|
||||||
|
try:
|
||||||
await ctx.author.send(SLOT_PAYOUTS_MSG)
|
await ctx.author.send(SLOT_PAYOUTS_MSG)
|
||||||
|
except discord.Forbidden:
|
||||||
|
await ctx.send(_("I can't send direct messages to you."))
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@guild_only_check()
|
@guild_only_check()
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ class Filter(commands.Cog):
|
|||||||
elif isinstance(server_or_channel, discord.TextChannel):
|
elif isinstance(server_or_channel, discord.TextChannel):
|
||||||
async with self.config.channel(server_or_channel).filter() as cur_list:
|
async with self.config.channel(server_or_channel).filter() as cur_list:
|
||||||
for w in words:
|
for w in words:
|
||||||
if w.lower not in cur_list and w:
|
if w.lower() not in cur_list and w:
|
||||||
cur_list.append(w.lower())
|
cur_list.append(w.lower())
|
||||||
added = True
|
added = True
|
||||||
|
|
||||||
|
|||||||
@@ -267,7 +267,13 @@ class General(commands.Cog):
|
|||||||
data.add_field(name=_("Voice Channels"), value=voice_channels)
|
data.add_field(name=_("Voice Channels"), value=voice_channels)
|
||||||
data.add_field(name=_("Roles"), value=humanize_number(len(guild.roles)))
|
data.add_field(name=_("Roles"), value=humanize_number(len(guild.roles)))
|
||||||
data.add_field(name=_("Owner"), value=str(guild.owner))
|
data.add_field(name=_("Owner"), value=str(guild.owner))
|
||||||
data.set_footer(text=_("Server ID: ") + str(guild.id))
|
data.set_footer(
|
||||||
|
text=_("Server ID: ")
|
||||||
|
+ str(guild.id)
|
||||||
|
+ _(" • Use {command} for more info on the server.").format(
|
||||||
|
command=f"{ctx.clean_prefix}serverinfo 1"
|
||||||
|
)
|
||||||
|
)
|
||||||
if guild.icon_url:
|
if guild.icon_url:
|
||||||
data.set_author(name=guild.name, url=guild.icon_url)
|
data.set_author(name=guild.name, url=guild.icon_url)
|
||||||
data.set_thumbnail(url=guild.icon_url)
|
data.set_thumbnail(url=guild.icon_url)
|
||||||
@@ -364,7 +370,7 @@ class General(commands.Cog):
|
|||||||
"VERIFIED": _("Verified"),
|
"VERIFIED": _("Verified"),
|
||||||
"DISCOVERABLE": _("Server Discovery"),
|
"DISCOVERABLE": _("Server Discovery"),
|
||||||
"FEATURABLE": _("Featurable"),
|
"FEATURABLE": _("Featurable"),
|
||||||
"PUBLIC": _("Public"),
|
"COMMUNITY": _("Community"),
|
||||||
"PUBLIC_DISABLED": _("Public disabled"),
|
"PUBLIC_DISABLED": _("Public disabled"),
|
||||||
"INVITE_SPLASH": _("Splash Invite"),
|
"INVITE_SPLASH": _("Splash Invite"),
|
||||||
"VIP_REGIONS": _("VIP Voice Servers"),
|
"VIP_REGIONS": _("VIP Voice Servers"),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from typing import cast, Optional
|
|||||||
|
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import commands, checks, i18n, modlog
|
from redbot.core import commands, checks, i18n, modlog
|
||||||
|
from redbot.core.utils import AsyncIter
|
||||||
from redbot.core.utils.chat_formatting import format_perms_list
|
from redbot.core.utils.chat_formatting import format_perms_list
|
||||||
from redbot.core.utils.mod import get_audit_reason, is_allowed_by_hierarchy
|
from redbot.core.utils.mod import get_audit_reason, is_allowed_by_hierarchy
|
||||||
from .abc import MixinMeta
|
from .abc import MixinMeta
|
||||||
@@ -207,6 +208,17 @@ class MuteMixin(MixinMeta):
|
|||||||
await ctx.send(
|
await ctx.send(
|
||||||
_("Muted {user} in channel {channel.name}").format(user=user, channel=channel)
|
_("Muted {user} in channel {channel.name}").format(user=user, channel=channel)
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
if channel.permissions_for(ctx.me).move_members:
|
||||||
|
await user.move_to(channel)
|
||||||
|
else:
|
||||||
|
raise RuntimeError
|
||||||
|
except (discord.Forbidden, RuntimeError):
|
||||||
|
await ctx.send(
|
||||||
|
_(
|
||||||
|
"Because I don't have the Move Members permission, this will take into effect when the user rejoins."
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(issue)
|
await ctx.send(issue)
|
||||||
|
|
||||||
@@ -255,11 +267,10 @@ class MuteMixin(MixinMeta):
|
|||||||
audit_reason = get_audit_reason(author, reason)
|
audit_reason = get_audit_reason(author, reason)
|
||||||
|
|
||||||
mute_success = []
|
mute_success = []
|
||||||
|
async with ctx.typing():
|
||||||
for channel in guild.channels:
|
for channel in guild.channels:
|
||||||
success, issue = await self.mute_user(guild, channel, author, user, audit_reason)
|
success, issue = await self.mute_user(guild, channel, author, user, audit_reason)
|
||||||
mute_success.append((success, issue))
|
mute_success.append((success, issue))
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
try:
|
|
||||||
await modlog.create_case(
|
await modlog.create_case(
|
||||||
self.bot,
|
self.bot,
|
||||||
guild,
|
guild,
|
||||||
@@ -271,8 +282,6 @@ class MuteMixin(MixinMeta):
|
|||||||
until=None,
|
until=None,
|
||||||
channel=None,
|
channel=None,
|
||||||
)
|
)
|
||||||
except RuntimeError as e:
|
|
||||||
await ctx.send(e)
|
|
||||||
await ctx.send(_("User has been muted in this server."))
|
await ctx.send(_("User has been muted in this server."))
|
||||||
|
|
||||||
@commands.group()
|
@commands.group()
|
||||||
@@ -322,6 +331,17 @@ class MuteMixin(MixinMeta):
|
|||||||
await ctx.send(
|
await ctx.send(
|
||||||
_("Unmuted {user} in channel {channel.name}").format(user=user, channel=channel)
|
_("Unmuted {user} in channel {channel.name}").format(user=user, channel=channel)
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
if channel.permissions_for(ctx.me).move_members:
|
||||||
|
await user.move_to(channel)
|
||||||
|
else:
|
||||||
|
raise RuntimeError
|
||||||
|
except (discord.Forbidden, RuntimeError):
|
||||||
|
await ctx.send(
|
||||||
|
_(
|
||||||
|
"Because I don't have the Move Members permission, this will take into effect when the user rejoins."
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await ctx.send(_("Unmute failed. Reason: {}").format(message))
|
await ctx.send(_("Unmute failed. Reason: {}").format(message))
|
||||||
|
|
||||||
@@ -372,11 +392,12 @@ class MuteMixin(MixinMeta):
|
|||||||
audit_reason = get_audit_reason(author, reason)
|
audit_reason = get_audit_reason(author, reason)
|
||||||
|
|
||||||
unmute_success = []
|
unmute_success = []
|
||||||
|
async with ctx.typing():
|
||||||
for channel in guild.channels:
|
for channel in guild.channels:
|
||||||
success, message = await self.unmute_user(guild, channel, author, user, audit_reason)
|
success, message = await self.unmute_user(
|
||||||
|
guild, channel, author, user, audit_reason
|
||||||
|
)
|
||||||
unmute_success.append((success, message))
|
unmute_success.append((success, message))
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
try:
|
|
||||||
await modlog.create_case(
|
await modlog.create_case(
|
||||||
self.bot,
|
self.bot,
|
||||||
guild,
|
guild,
|
||||||
@@ -387,8 +408,6 @@ class MuteMixin(MixinMeta):
|
|||||||
reason,
|
reason,
|
||||||
until=None,
|
until=None,
|
||||||
)
|
)
|
||||||
except RuntimeError as e:
|
|
||||||
await ctx.send(e)
|
|
||||||
await ctx.send(_("User has been unmuted in this server."))
|
await ctx.send(_("User has been unmuted in this server."))
|
||||||
|
|
||||||
async def mute_user(
|
async def mute_user(
|
||||||
|
|||||||
@@ -282,6 +282,7 @@ class Permissions(commands.Cog):
|
|||||||
except discord.Forbidden:
|
except discord.Forbidden:
|
||||||
await ctx.send(_("I'm not allowed to DM you."))
|
await ctx.send(_("I'm not allowed to DM you."))
|
||||||
else:
|
else:
|
||||||
|
if not isinstance(ctx.channel, discord.DMChannel):
|
||||||
await ctx.send(_("I've just sent the file to you via DM."))
|
await ctx.send(_("I've just sent the file to you via DM."))
|
||||||
finally:
|
finally:
|
||||||
file.close()
|
file.close()
|
||||||
@@ -599,8 +600,8 @@ class Permissions(commands.Cog):
|
|||||||
cog_or_cmd.obj.clear_rule_for(model_id, guild_id=guild_id)
|
cog_or_cmd.obj.clear_rule_for(model_id, guild_id=guild_id)
|
||||||
guild_id, model_id = str(guild_id), str(model_id)
|
guild_id, model_id = str(guild_id), str(model_id)
|
||||||
async with self.config.custom(cog_or_cmd.type, cog_or_cmd.name).all() as rules:
|
async with self.config.custom(cog_or_cmd.type, cog_or_cmd.name).all() as rules:
|
||||||
if guild_id in rules and rules[guild_id]:
|
if (guild_rules := rules.get(guild_id)) is not None:
|
||||||
del rules[guild_id][model_id]
|
guild_rules.pop(model_id, None)
|
||||||
|
|
||||||
async def _set_default_rule(
|
async def _set_default_rule(
|
||||||
self, rule: Optional[bool], cog_or_cmd: CogOrCommand, guild_id: int
|
self, rule: Optional[bool], cog_or_cmd: CogOrCommand, guild_id: int
|
||||||
|
|||||||
@@ -271,6 +271,13 @@ class Reports(commands.Cog):
|
|||||||
|
|
||||||
with contextlib.suppress(discord.Forbidden, discord.HTTPException):
|
with contextlib.suppress(discord.Forbidden, discord.HTTPException):
|
||||||
if val is None:
|
if val is None:
|
||||||
|
if await self.config.guild(ctx.guild).output_channel() is None:
|
||||||
|
await author.send(
|
||||||
|
_(
|
||||||
|
"This server has no reports channel set up. Please contact a server admin."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
await author.send(
|
await author.send(
|
||||||
_("There was an error sending your report, please contact a server admin.")
|
_("There was an error sending your report, please contact a server admin.")
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -505,14 +505,13 @@ class Streams(commands.Cog):
|
|||||||
|
|
||||||
@message.command(name="mention")
|
@message.command(name="mention")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
async def with_mention(self, ctx: commands.Context, message: str = None):
|
async def with_mention(self, ctx: commands.Context, *, message: str = None):
|
||||||
"""Set stream alert message when mentions are enabled.
|
"""Set stream alert message when mentions are enabled.
|
||||||
|
|
||||||
Use `{mention}` in the message to insert the selected mentions.
|
Use `{mention}` in the message to insert the selected mentions.
|
||||||
|
Use `{stream}` in the message to insert the channel or user name.
|
||||||
|
|
||||||
Use `{stream.name}` in the message to insert the channel or user name.
|
For example: `[p]streamset message mention {mention}, {stream} is live!`
|
||||||
|
|
||||||
For example: `[p]streamset message mention "{mention}, {stream.name} is live!"`
|
|
||||||
"""
|
"""
|
||||||
if message is not None:
|
if message is not None:
|
||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
@@ -523,12 +522,12 @@ class Streams(commands.Cog):
|
|||||||
|
|
||||||
@message.command(name="nomention")
|
@message.command(name="nomention")
|
||||||
@commands.guild_only()
|
@commands.guild_only()
|
||||||
async def without_mention(self, ctx: commands.Context, message: str = None):
|
async def without_mention(self, ctx: commands.Context, *, message: str = None):
|
||||||
"""Set stream alert message when mentions are disabled.
|
"""Set stream alert message when mentions are disabled.
|
||||||
|
|
||||||
Use `{stream.name}` in the message to insert the channel or user name.
|
Use `{stream}` in the message to insert the channel or user name.
|
||||||
|
|
||||||
For example: `[p]streamset message nomention "{stream.name} is live!"`
|
For example: `[p]streamset message nomention {stream} is live!`
|
||||||
"""
|
"""
|
||||||
if message is not None:
|
if message is not None:
|
||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
@@ -724,7 +723,12 @@ class Streams(commands.Cog):
|
|||||||
channel.guild
|
channel.guild
|
||||||
).live_message_mention()
|
).live_message_mention()
|
||||||
if alert_msg:
|
if alert_msg:
|
||||||
content = alert_msg.format(mention=mention_str, stream=stream)
|
content = alert_msg # Stop bad things from happening here...
|
||||||
|
content = content.replace(
|
||||||
|
"{stream.name}", str(stream.name)
|
||||||
|
) # Backwards compatability
|
||||||
|
content = content.replace("{stream}", str(stream.name))
|
||||||
|
content = content.replace("{mention}", mention_str)
|
||||||
else:
|
else:
|
||||||
content = _("{mention}, {stream} is live!").format(
|
content = _("{mention}, {stream} is live!").format(
|
||||||
mention=mention_str,
|
mention=mention_str,
|
||||||
@@ -737,7 +741,11 @@ class Streams(commands.Cog):
|
|||||||
channel.guild
|
channel.guild
|
||||||
).live_message_nomention()
|
).live_message_nomention()
|
||||||
if alert_msg:
|
if alert_msg:
|
||||||
content = alert_msg.format(stream=stream)
|
content = alert_msg # Stop bad things from happening here...
|
||||||
|
content = content.replace(
|
||||||
|
"{stream.name}", str(stream.name)
|
||||||
|
) # Backwards compatability
|
||||||
|
content = content.replace("{stream}", str(stream.name))
|
||||||
else:
|
else:
|
||||||
content = _("{stream} is live!").format(
|
content = _("{stream} is live!").format(
|
||||||
stream=escape(
|
stream=escape(
|
||||||
|
|||||||
@@ -190,6 +190,12 @@ class YoutubeStream(Stream):
|
|||||||
raise StreamNotFound()
|
raise StreamNotFound()
|
||||||
elif "items" in data:
|
elif "items" in data:
|
||||||
return data["items"][0][resource]
|
return data["items"][0][resource]
|
||||||
|
elif (
|
||||||
|
"pageInfo" in data
|
||||||
|
and "totalResults" in data["pageInfo"]
|
||||||
|
and data["pageInfo"]["totalResults"] < 1
|
||||||
|
):
|
||||||
|
raise StreamNotFound()
|
||||||
raise APIError()
|
raise APIError()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
@@ -1,303 +1,303 @@
|
|||||||
AUTHOR: aikaterna
|
AUTHOR: aikaterna
|
||||||
Who's that pokemon? https://cdn.discord.red/i/JhaHtAM.png:
|
Who's that Pokémon? https://cdn.discord.red/i/JhaHtAM.png:
|
||||||
- Bulbasaur
|
- Bulbasaur
|
||||||
Who's that pokemon? https://cdn.discord.red/i/J42krSc.png:
|
Who's that Pokémon? https://cdn.discord.red/i/J42krSc.png:
|
||||||
- Ivysaur
|
- Ivysaur
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Y6aQTvu.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Y6aQTvu.png:
|
||||||
- Venusaur
|
- Venusaur
|
||||||
Who's that pokemon? https://cdn.discord.red/i/GzGY0m5.png:
|
Who's that Pokémon? https://cdn.discord.red/i/GzGY0m5.png:
|
||||||
- Charmander
|
- Charmander
|
||||||
Who's that pokemon? https://cdn.discord.red/i/GPqbMp9.png:
|
Who's that Pokémon? https://cdn.discord.red/i/GPqbMp9.png:
|
||||||
- Charmeleon
|
- Charmeleon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Dpx11Hv.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Dpx11Hv.png:
|
||||||
- Charizard
|
- Charizard
|
||||||
Who's that pokemon? https://cdn.discord.red/i/hWxoVFP.png:
|
Who's that Pokémon? https://cdn.discord.red/i/hWxoVFP.png:
|
||||||
- Squirtle
|
- Squirtle
|
||||||
Who's that pokemon? https://cdn.discord.red/i/FAXNExP.png:
|
Who's that Pokémon? https://cdn.discord.red/i/FAXNExP.png:
|
||||||
- Wartortle
|
- Wartortle
|
||||||
Who's that pokemon? https://cdn.discord.red/i/b8dIcMs.png:
|
Who's that Pokémon? https://cdn.discord.red/i/b8dIcMs.png:
|
||||||
- Blastoise
|
- Blastoise
|
||||||
Who's that pokemon? https://cdn.discord.red/i/5THSh9F.png:
|
Who's that Pokémon? https://cdn.discord.red/i/5THSh9F.png:
|
||||||
- Caterpie
|
- Caterpie
|
||||||
Who's that pokemon? https://cdn.discord.red/i/g7J4azT.png:
|
Who's that Pokémon? https://cdn.discord.red/i/g7J4azT.png:
|
||||||
- Metapod
|
- Metapod
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Gln47Ns.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Gln47Ns.png:
|
||||||
- Butterfree
|
- Butterfree
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Nurfd3B.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Nurfd3B.png:
|
||||||
- Weedle
|
- Weedle
|
||||||
Who's that pokemon? https://cdn.discord.red/i/RbTimG9.png:
|
Who's that Pokémon? https://cdn.discord.red/i/RbTimG9.png:
|
||||||
- Kakuna
|
- Kakuna
|
||||||
Who's that pokemon? https://cdn.discord.red/i/4hqx40k.png:
|
Who's that Pokémon? https://cdn.discord.red/i/4hqx40k.png:
|
||||||
- Beedrill
|
- Beedrill
|
||||||
Who's that pokemon? https://cdn.discord.red/i/SH9ogxU.png:
|
Who's that Pokémon? https://cdn.discord.red/i/SH9ogxU.png:
|
||||||
- Pidgey
|
- Pidgey
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ciZdrwt.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ciZdrwt.png:
|
||||||
- Pidgeotto
|
- Pidgeotto
|
||||||
Who's that pokemon? https://cdn.discord.red/i/8pTnBh7.png:
|
Who's that Pokémon? https://cdn.discord.red/i/8pTnBh7.png:
|
||||||
- Pidgeot
|
- Pidgeot
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Q9dISQq.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Q9dISQq.png:
|
||||||
- Rattata
|
- Rattata
|
||||||
Who's that pokemon? https://cdn.discord.red/i/qu5PdyR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/qu5PdyR.png:
|
||||||
- Raticate
|
- Raticate
|
||||||
Who's that pokemon? https://cdn.discord.red/i/FcU64Fe.png:
|
Who's that Pokémon? https://cdn.discord.red/i/FcU64Fe.png:
|
||||||
- Spearow
|
- Spearow
|
||||||
Who's that pokemon? https://cdn.discord.red/i/3RPuh1B.png:
|
Who's that Pokémon? https://cdn.discord.red/i/3RPuh1B.png:
|
||||||
- Fearow
|
- Fearow
|
||||||
Who's that pokemon? https://cdn.discord.red/i/waJYATU.png:
|
Who's that Pokémon? https://cdn.discord.red/i/waJYATU.png:
|
||||||
- Ekans
|
- Ekans
|
||||||
Who's that pokemon? https://cdn.discord.red/i/xpfF1DV.png:
|
Who's that Pokémon? https://cdn.discord.red/i/xpfF1DV.png:
|
||||||
- Arbok
|
- Arbok
|
||||||
Who's that pokemon? https://cdn.discord.red/i/A6KEQ75.png:
|
Who's that Pokémon? https://cdn.discord.red/i/A6KEQ75.png:
|
||||||
- Pikachu
|
- Pikachu
|
||||||
Who's that pokemon? https://cdn.discord.red/i/TqzNM9a.png:
|
Who's that Pokémon? https://cdn.discord.red/i/TqzNM9a.png:
|
||||||
- Raichu
|
- Raichu
|
||||||
Who's that pokemon? https://cdn.discord.red/i/8XJouBF.png:
|
Who's that Pokémon? https://cdn.discord.red/i/8XJouBF.png:
|
||||||
- Sandshrew
|
- Sandshrew
|
||||||
Who's that pokemon? https://cdn.discord.red/i/x0bbRtg.png:
|
Who's that Pokémon? https://cdn.discord.red/i/x0bbRtg.png:
|
||||||
- Sandslash
|
- Sandslash
|
||||||
Who's that pokemon? https://cdn.discord.red/i/jkcrKwF.png:
|
Who's that Pokémon? https://cdn.discord.red/i/jkcrKwF.png:
|
||||||
- Nidoran
|
- Nidoran
|
||||||
Who's that pokemon? https://cdn.discord.red/i/3EmECpN.png:
|
Who's that Pokémon? https://cdn.discord.red/i/3EmECpN.png:
|
||||||
- Nidorina
|
- Nidorina
|
||||||
Who's that pokemon? https://cdn.discord.red/i/r8X77i2.png:
|
Who's that Pokémon? https://cdn.discord.red/i/r8X77i2.png:
|
||||||
- Nidoqueen
|
- Nidoqueen
|
||||||
Who's that pokemon? https://cdn.discord.red/i/5Ny72io.png:
|
Who's that Pokémon? https://cdn.discord.red/i/5Ny72io.png:
|
||||||
- Nidoran
|
- Nidoran
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ZhsSCE4.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ZhsSCE4.png:
|
||||||
- Nidorino
|
- Nidorino
|
||||||
Who's that pokemon? https://cdn.discord.red/i/YVjcgD9.png:
|
Who's that Pokémon? https://cdn.discord.red/i/YVjcgD9.png:
|
||||||
- Nidoking
|
- Nidoking
|
||||||
Who's that pokemon? https://cdn.discord.red/i/C0jvtgd.png:
|
Who's that Pokémon? https://cdn.discord.red/i/C0jvtgd.png:
|
||||||
- Clefairy
|
- Clefairy
|
||||||
Who's that pokemon? https://cdn.discord.red/i/JAvpC50.png:
|
Who's that Pokémon? https://cdn.discord.red/i/JAvpC50.png:
|
||||||
- Clefable
|
- Clefable
|
||||||
Who's that pokemon? https://cdn.discord.red/i/QcxFvi7.png:
|
Who's that Pokémon? https://cdn.discord.red/i/QcxFvi7.png:
|
||||||
- Vulpix
|
- Vulpix
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Q3SRhH3.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Q3SRhH3.png:
|
||||||
- Ninetales
|
- Ninetales
|
||||||
Who's that pokemon? https://cdn.discord.red/i/hKwx2UP.png:
|
Who's that Pokémon? https://cdn.discord.red/i/hKwx2UP.png:
|
||||||
- Jigglypuff
|
- Jigglypuff
|
||||||
Who's that pokemon? https://cdn.discord.red/i/HI6GLIM.png:
|
Who's that Pokémon? https://cdn.discord.red/i/HI6GLIM.png:
|
||||||
- Wigglytuff
|
- Wigglytuff
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ygyr0wR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ygyr0wR.png:
|
||||||
- Zubat
|
- Zubat
|
||||||
Who's that pokemon? https://cdn.discord.red/i/7amMKJd.png:
|
Who's that Pokémon? https://cdn.discord.red/i/7amMKJd.png:
|
||||||
- Golbat
|
- Golbat
|
||||||
Who's that pokemon? https://cdn.discord.red/i/NMd1UkL.png:
|
Who's that Pokémon? https://cdn.discord.red/i/NMd1UkL.png:
|
||||||
- Oddish
|
- Oddish
|
||||||
Who's that pokemon? https://cdn.discord.red/i/0Pm1MZ6.png:
|
Who's that Pokémon? https://cdn.discord.red/i/0Pm1MZ6.png:
|
||||||
- Gloom
|
- Gloom
|
||||||
Who's that pokemon? https://cdn.discord.red/i/WGjuCBJ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/WGjuCBJ.png:
|
||||||
- Vileplume
|
- Vileplume
|
||||||
Who's that pokemon? https://cdn.discord.red/i/fHkDxEI.png:
|
Who's that Pokémon? https://cdn.discord.red/i/fHkDxEI.png:
|
||||||
- Paras
|
- Paras
|
||||||
Who's that pokemon? https://cdn.discord.red/i/JgC6p0O.png:
|
Who's that Pokémon? https://cdn.discord.red/i/JgC6p0O.png:
|
||||||
- Parasect
|
- Parasect
|
||||||
Who's that pokemon? https://cdn.discord.red/i/xgElemy.png:
|
Who's that Pokémon? https://cdn.discord.red/i/xgElemy.png:
|
||||||
- Venonat
|
- Venonat
|
||||||
Who's that pokemon? https://cdn.discord.red/i/n69EDYY.png:
|
Who's that Pokémon? https://cdn.discord.red/i/n69EDYY.png:
|
||||||
- Venomoth
|
- Venomoth
|
||||||
Who's that pokemon? https://cdn.discord.red/i/gncAD9E.png:
|
Who's that Pokémon? https://cdn.discord.red/i/gncAD9E.png:
|
||||||
- Diglett
|
- Diglett
|
||||||
Who's that pokemon? https://cdn.discord.red/i/XgzUqSP.png:
|
Who's that Pokémon? https://cdn.discord.red/i/XgzUqSP.png:
|
||||||
- Dugtrio
|
- Dugtrio
|
||||||
Who's that pokemon? https://cdn.discord.red/i/abjRwp0.png:
|
Who's that Pokémon? https://cdn.discord.red/i/abjRwp0.png:
|
||||||
- Meowth
|
- Meowth
|
||||||
Who's that pokemon? https://cdn.discord.red/i/nnDIR3w.png:
|
Who's that Pokémon? https://cdn.discord.red/i/nnDIR3w.png:
|
||||||
- Persian
|
- Persian
|
||||||
Who's that pokemon? https://cdn.discord.red/i/fAXPqen.png:
|
Who's that Pokémon? https://cdn.discord.red/i/fAXPqen.png:
|
||||||
- Psyduck
|
- Psyduck
|
||||||
Who's that pokemon? https://cdn.discord.red/i/rq8Q3HN.png:
|
Who's that Pokémon? https://cdn.discord.red/i/rq8Q3HN.png:
|
||||||
- Golduck
|
- Golduck
|
||||||
Who's that pokemon? https://cdn.discord.red/i/vMjgxYs.png:
|
Who's that Pokémon? https://cdn.discord.red/i/vMjgxYs.png:
|
||||||
- Mankey
|
- Mankey
|
||||||
Who's that pokemon? https://cdn.discord.red/i/rLnDp0u.png:
|
Who's that Pokémon? https://cdn.discord.red/i/rLnDp0u.png:
|
||||||
- Primeape
|
- Primeape
|
||||||
Who's that pokemon? https://cdn.discord.red/i/IeyfkCU.png:
|
Who's that Pokémon? https://cdn.discord.red/i/IeyfkCU.png:
|
||||||
- Growlithe
|
- Growlithe
|
||||||
Who's that pokemon? https://cdn.discord.red/i/35xsszF.png:
|
Who's that Pokémon? https://cdn.discord.red/i/35xsszF.png:
|
||||||
- Arcanine
|
- Arcanine
|
||||||
Who's that pokemon? https://cdn.discord.red/i/M5KDU86.png:
|
Who's that Pokémon? https://cdn.discord.red/i/M5KDU86.png:
|
||||||
- Poliwag
|
- Poliwag
|
||||||
Who's that pokemon? https://cdn.discord.red/i/K033cK1.png:
|
Who's that Pokémon? https://cdn.discord.red/i/K033cK1.png:
|
||||||
- Poliwhirl
|
- Poliwhirl
|
||||||
Who's that pokemon? https://cdn.discord.red/i/o5Hv7AK.png:
|
Who's that Pokémon? https://cdn.discord.red/i/o5Hv7AK.png:
|
||||||
- Poliwrath
|
- Poliwrath
|
||||||
Who's that pokemon? https://cdn.discord.red/i/AhNIqr8.png:
|
Who's that Pokémon? https://cdn.discord.red/i/AhNIqr8.png:
|
||||||
- Abra
|
- Abra
|
||||||
Who's that pokemon? https://cdn.discord.red/i/2L2aPtx.png:
|
Who's that Pokémon? https://cdn.discord.red/i/2L2aPtx.png:
|
||||||
- Kadabra
|
- Kadabra
|
||||||
Who's that pokemon? https://cdn.discord.red/i/kGuFJDY.png:
|
Who's that Pokémon? https://cdn.discord.red/i/kGuFJDY.png:
|
||||||
- Alakazam
|
- Alakazam
|
||||||
Who's that pokemon? https://cdn.discord.red/i/YQUTREX.png:
|
Who's that Pokémon? https://cdn.discord.red/i/YQUTREX.png:
|
||||||
- Machop
|
- Machop
|
||||||
Who's that pokemon? https://cdn.discord.red/i/YL7C8i8.png:
|
Who's that Pokémon? https://cdn.discord.red/i/YL7C8i8.png:
|
||||||
- Machoke
|
- Machoke
|
||||||
Who's that pokemon? https://cdn.discord.red/i/1355Vod.png:
|
Who's that Pokémon? https://cdn.discord.red/i/1355Vod.png:
|
||||||
- Machamp
|
- Machamp
|
||||||
Who's that pokemon? https://cdn.discord.red/i/VxA12Ot.png:
|
Who's that Pokémon? https://cdn.discord.red/i/VxA12Ot.png:
|
||||||
- Bellsprout
|
- Bellsprout
|
||||||
Who's that pokemon? https://cdn.discord.red/i/D6mgIJJ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/D6mgIJJ.png:
|
||||||
- Weepinbell
|
- Weepinbell
|
||||||
Who's that pokemon? https://cdn.discord.red/i/NMSvlCz.png:
|
Who's that Pokémon? https://cdn.discord.red/i/NMSvlCz.png:
|
||||||
- Victreebel
|
- Victreebel
|
||||||
Who's that pokemon? https://cdn.discord.red/i/IoJmVzO.png:
|
Who's that Pokémon? https://cdn.discord.red/i/IoJmVzO.png:
|
||||||
- Tentacool
|
- Tentacool
|
||||||
Who's that pokemon? https://cdn.discord.red/i/0O9TNYv.png:
|
Who's that Pokémon? https://cdn.discord.red/i/0O9TNYv.png:
|
||||||
- Tentacruel
|
- Tentacruel
|
||||||
Who's that pokemon? https://cdn.discord.red/i/tFK8d3z.png:
|
Who's that Pokémon? https://cdn.discord.red/i/tFK8d3z.png:
|
||||||
- Geodude
|
- Geodude
|
||||||
Who's that pokemon? https://cdn.discord.red/i/lgew3Ca.png:
|
Who's that Pokémon? https://cdn.discord.red/i/lgew3Ca.png:
|
||||||
- Graveler
|
- Graveler
|
||||||
Who's that pokemon? https://cdn.discord.red/i/mG8wAHs.png:
|
Who's that Pokémon? https://cdn.discord.red/i/mG8wAHs.png:
|
||||||
- Golem
|
- Golem
|
||||||
Who's that pokemon? https://cdn.discord.red/i/N6un8iO.png:
|
Who's that Pokémon? https://cdn.discord.red/i/N6un8iO.png:
|
||||||
- Ponyta
|
- Ponyta
|
||||||
Who's that pokemon? https://cdn.discord.red/i/T7ADHJo.png:
|
Who's that Pokémon? https://cdn.discord.red/i/T7ADHJo.png:
|
||||||
- Rapidash
|
- Rapidash
|
||||||
Who's that pokemon? https://cdn.discord.red/i/6RBzLij.png:
|
Who's that Pokémon? https://cdn.discord.red/i/6RBzLij.png:
|
||||||
- Slowpoke
|
- Slowpoke
|
||||||
Who's that pokemon? https://cdn.discord.red/i/7ju6OBY.png:
|
Who's that Pokémon? https://cdn.discord.red/i/7ju6OBY.png:
|
||||||
- Slowbro
|
- Slowbro
|
||||||
Who's that pokemon? https://cdn.discord.red/i/KnhQMxQ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/KnhQMxQ.png:
|
||||||
- Magnemite
|
- Magnemite
|
||||||
Who's that pokemon? https://cdn.discord.red/i/bJDh47R.png:
|
Who's that Pokémon? https://cdn.discord.red/i/bJDh47R.png:
|
||||||
- Magneton
|
- Magneton
|
||||||
Who's that pokemon? https://cdn.discord.red/i/WMJFI92.png:
|
Who's that Pokémon? https://cdn.discord.red/i/WMJFI92.png:
|
||||||
- Farfetch'd
|
- Farfetch'd
|
||||||
Who's that pokemon? https://cdn.discord.red/i/pw6UYNR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/pw6UYNR.png:
|
||||||
- Doduo
|
- Doduo
|
||||||
Who's that pokemon? https://cdn.discord.red/i/WE8YHaR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/WE8YHaR.png:
|
||||||
- Dodrio
|
- Dodrio
|
||||||
Who's that pokemon? https://cdn.discord.red/i/vZlSSqS.png:
|
Who's that Pokémon? https://cdn.discord.red/i/vZlSSqS.png:
|
||||||
- Seel
|
- Seel
|
||||||
Who's that pokemon? https://cdn.discord.red/i/3erUdvZ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/3erUdvZ.png:
|
||||||
- Dewgong
|
- Dewgong
|
||||||
Who's that pokemon? https://cdn.discord.red/i/FkecTd4.png:
|
Who's that Pokémon? https://cdn.discord.red/i/FkecTd4.png:
|
||||||
- Grimer
|
- Grimer
|
||||||
Who's that pokemon? https://cdn.discord.red/i/nHl2BrL.png:
|
Who's that Pokémon? https://cdn.discord.red/i/nHl2BrL.png:
|
||||||
- Muk
|
- Muk
|
||||||
Who's that pokemon? https://cdn.discord.red/i/o9xX4uR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/o9xX4uR.png:
|
||||||
- Shellder
|
- Shellder
|
||||||
Who's that pokemon? https://cdn.discord.red/i/oC0mdzt.png:
|
Who's that Pokémon? https://cdn.discord.red/i/oC0mdzt.png:
|
||||||
- Cloyster
|
- Cloyster
|
||||||
Who's that pokemon? https://cdn.discord.red/i/xhPTiG2.png:
|
Who's that Pokémon? https://cdn.discord.red/i/xhPTiG2.png:
|
||||||
- Gastly
|
- Gastly
|
||||||
Who's that pokemon? https://cdn.discord.red/i/eLwmupW.png:
|
Who's that Pokémon? https://cdn.discord.red/i/eLwmupW.png:
|
||||||
- Haunter
|
- Haunter
|
||||||
Who's that pokemon? https://cdn.discord.red/i/SpBQNMG.png:
|
Who's that Pokémon? https://cdn.discord.red/i/SpBQNMG.png:
|
||||||
- Gengar
|
- Gengar
|
||||||
Who's that pokemon? https://cdn.discord.red/i/oP8J2tJ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/oP8J2tJ.png:
|
||||||
- Onix
|
- Onix
|
||||||
Who's that pokemon? https://cdn.discord.red/i/oJ3ZHfP.png:
|
Who's that Pokémon? https://cdn.discord.red/i/oJ3ZHfP.png:
|
||||||
- Drowzee
|
- Drowzee
|
||||||
Who's that pokemon? https://cdn.discord.red/i/eutXYlt.png:
|
Who's that Pokémon? https://cdn.discord.red/i/eutXYlt.png:
|
||||||
- Hypno
|
- Hypno
|
||||||
Who's that pokemon? https://cdn.discord.red/i/nd7n8su.png:
|
Who's that Pokémon? https://cdn.discord.red/i/nd7n8su.png:
|
||||||
- Krabby
|
- Krabby
|
||||||
Who's that pokemon? https://cdn.discord.red/i/GE9Ddfg.png:
|
Who's that Pokémon? https://cdn.discord.red/i/GE9Ddfg.png:
|
||||||
- Kingler
|
- Kingler
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ZTgtF9V.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ZTgtF9V.png:
|
||||||
- Voltorb
|
- Voltorb
|
||||||
Who's that pokemon? https://cdn.discord.red/i/pQASpgA.png:
|
Who's that Pokémon? https://cdn.discord.red/i/pQASpgA.png:
|
||||||
- Electrode
|
- Electrode
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Fk9QAG4.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Fk9QAG4.png:
|
||||||
- Exeggcute
|
- Exeggcute
|
||||||
Who's that pokemon? https://cdn.discord.red/i/d9VcfpV.png:
|
Who's that Pokémon? https://cdn.discord.red/i/d9VcfpV.png:
|
||||||
- Exeggutor
|
- Exeggutor
|
||||||
Who's that pokemon? https://cdn.discord.red/i/GZMPoPQ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/GZMPoPQ.png:
|
||||||
- Cubone
|
- Cubone
|
||||||
Who's that pokemon? https://cdn.discord.red/i/v2pv554.png:
|
Who's that Pokémon? https://cdn.discord.red/i/v2pv554.png:
|
||||||
- Marowak
|
- Marowak
|
||||||
Who's that pokemon? https://cdn.discord.red/i/cg8BnLd.png:
|
Who's that Pokémon? https://cdn.discord.red/i/cg8BnLd.png:
|
||||||
- Hitmonlee
|
- Hitmonlee
|
||||||
Who's that pokemon? https://cdn.discord.red/i/26iLMlQ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/26iLMlQ.png:
|
||||||
- Hitmonchan
|
- Hitmonchan
|
||||||
Who's that pokemon? https://cdn.discord.red/i/GRxldku.png:
|
Who's that Pokémon? https://cdn.discord.red/i/GRxldku.png:
|
||||||
- Lickitung
|
- Lickitung
|
||||||
Who's that pokemon? https://cdn.discord.red/i/y5dbZrK.png:
|
Who's that Pokémon? https://cdn.discord.red/i/y5dbZrK.png:
|
||||||
- Koffing
|
- Koffing
|
||||||
Who's that pokemon? https://cdn.discord.red/i/LFWBBMh.png:
|
Who's that Pokémon? https://cdn.discord.red/i/LFWBBMh.png:
|
||||||
- Weezing
|
- Weezing
|
||||||
Who's that pokemon? https://cdn.discord.red/i/JlDE7HF.png:
|
Who's that Pokémon? https://cdn.discord.red/i/JlDE7HF.png:
|
||||||
- Rhyhorn
|
- Rhyhorn
|
||||||
Who's that pokemon? https://cdn.discord.red/i/CtdI8PO.png:
|
Who's that Pokémon? https://cdn.discord.red/i/CtdI8PO.png:
|
||||||
- Rhydon
|
- Rhydon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/caw6rxF.png:
|
Who's that Pokémon? https://cdn.discord.red/i/caw6rxF.png:
|
||||||
- Chansey
|
- Chansey
|
||||||
Who's that pokemon? https://cdn.discord.red/i/L2MkNsi.png:
|
Who's that Pokémon? https://cdn.discord.red/i/L2MkNsi.png:
|
||||||
- Tangela
|
- Tangela
|
||||||
Who's that pokemon? https://cdn.discord.red/i/QrbUc6x.png:
|
Who's that Pokémon? https://cdn.discord.red/i/QrbUc6x.png:
|
||||||
- Kangaskhan
|
- Kangaskhan
|
||||||
Who's that pokemon? https://cdn.discord.red/i/rHITC4u.png:
|
Who's that Pokémon? https://cdn.discord.red/i/rHITC4u.png:
|
||||||
- Horsea
|
- Horsea
|
||||||
Who's that pokemon? https://cdn.discord.red/i/gmw99bY.png:
|
Who's that Pokémon? https://cdn.discord.red/i/gmw99bY.png:
|
||||||
- Seadra
|
- Seadra
|
||||||
Who's that pokemon? https://cdn.discord.red/i/nlXApwH.png:
|
Who's that Pokémon? https://cdn.discord.red/i/nlXApwH.png:
|
||||||
- Goldeen
|
- Goldeen
|
||||||
Who's that pokemon? https://cdn.discord.red/i/IOxPciL.png:
|
Who's that Pokémon? https://cdn.discord.red/i/IOxPciL.png:
|
||||||
- Seaking
|
- Seaking
|
||||||
Who's that pokemon? https://cdn.discord.red/i/rEJK5dk.png:
|
Who's that Pokémon? https://cdn.discord.red/i/rEJK5dk.png:
|
||||||
- Staryu
|
- Staryu
|
||||||
Who's that pokemon? https://cdn.discord.red/i/nKMh7m4.png:
|
Who's that Pokémon? https://cdn.discord.red/i/nKMh7m4.png:
|
||||||
- Starmie
|
- Starmie
|
||||||
Who's that pokemon? https://cdn.discord.red/i/zZYsvYZ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/zZYsvYZ.png:
|
||||||
- Mr. Mime
|
- Mr. Mime
|
||||||
Who's that pokemon? https://cdn.discord.red/i/987JigM.png:
|
Who's that Pokémon? https://cdn.discord.red/i/987JigM.png:
|
||||||
- Scyther
|
- Scyther
|
||||||
Who's that pokemon? https://cdn.discord.red/i/71vLjQC.png:
|
Who's that Pokémon? https://cdn.discord.red/i/71vLjQC.png:
|
||||||
- Jynx
|
- Jynx
|
||||||
Who's that pokemon? https://cdn.discord.red/i/gyVHrsJ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/gyVHrsJ.png:
|
||||||
- Electabuzz
|
- Electabuzz
|
||||||
Who's that pokemon? https://cdn.discord.red/i/1WTGued.png:
|
Who's that Pokémon? https://cdn.discord.red/i/1WTGued.png:
|
||||||
- Magmar
|
- Magmar
|
||||||
Who's that pokemon? https://cdn.discord.red/i/V8y1cHT.png:
|
Who's that Pokémon? https://cdn.discord.red/i/V8y1cHT.png:
|
||||||
- Pinsir
|
- Pinsir
|
||||||
Who's that pokemon? https://cdn.discord.red/i/OG6geA9.png:
|
Who's that Pokémon? https://cdn.discord.red/i/OG6geA9.png:
|
||||||
- Tauros
|
- Tauros
|
||||||
Who's that pokemon? https://cdn.discord.red/i/LsfwWH7.png:
|
Who's that Pokémon? https://cdn.discord.red/i/LsfwWH7.png:
|
||||||
- Magikarp
|
- Magikarp
|
||||||
Who's that pokemon? https://cdn.discord.red/i/3FzgA70.png:
|
Who's that Pokémon? https://cdn.discord.red/i/3FzgA70.png:
|
||||||
- Gyarados
|
- Gyarados
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Dz7EXjw.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Dz7EXjw.png:
|
||||||
- Lapras
|
- Lapras
|
||||||
Who's that pokemon? https://cdn.discord.red/i/LYL4rX1.png:
|
Who's that Pokémon? https://cdn.discord.red/i/LYL4rX1.png:
|
||||||
- Ditto
|
- Ditto
|
||||||
Who's that pokemon? https://cdn.discord.red/i/c9KOJH1.png:
|
Who's that Pokémon? https://cdn.discord.red/i/c9KOJH1.png:
|
||||||
- Eevee
|
- Eevee
|
||||||
Who's that pokemon? https://cdn.discord.red/i/F8uPBoY.png:
|
Who's that Pokémon? https://cdn.discord.red/i/F8uPBoY.png:
|
||||||
- Vaporeon
|
- Vaporeon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ChlK8yg.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ChlK8yg.png:
|
||||||
- Jolteon
|
- Jolteon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/EjAuEZM.png:
|
Who's that Pokémon? https://cdn.discord.red/i/EjAuEZM.png:
|
||||||
- Flareon
|
- Flareon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/lCWdbLS.png:
|
Who's that Pokémon? https://cdn.discord.red/i/lCWdbLS.png:
|
||||||
- Porygon
|
- Porygon
|
||||||
Who's that pokemon? https://cdn.discord.red/i/ajEgvvx.png:
|
Who's that Pokémon? https://cdn.discord.red/i/ajEgvvx.png:
|
||||||
- Omanyte
|
- Omanyte
|
||||||
Who's that pokemon? https://cdn.discord.red/i/B7wu0zJ.png:
|
Who's that Pokémon? https://cdn.discord.red/i/B7wu0zJ.png:
|
||||||
- Omastar
|
- Omastar
|
||||||
Who's that pokemon? https://cdn.discord.red/i/7fO1Js6.png:
|
Who's that Pokémon? https://cdn.discord.red/i/7fO1Js6.png:
|
||||||
- Kabuto
|
- Kabuto
|
||||||
Who's that pokemon? https://cdn.discord.red/i/g0h7oas.png:
|
Who's that Pokémon? https://cdn.discord.red/i/g0h7oas.png:
|
||||||
- Kabutops
|
- Kabutops
|
||||||
Who's that pokemon? https://cdn.discord.red/i/XgGhtIu.png:
|
Who's that Pokémon? https://cdn.discord.red/i/XgGhtIu.png:
|
||||||
- Aerodactyl
|
- Aerodactyl
|
||||||
Who's that pokemon? https://cdn.discord.red/i/q1vGvnR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/q1vGvnR.png:
|
||||||
- Snorlax
|
- Snorlax
|
||||||
Who's that pokemon? https://cdn.discord.red/i/7Lb8533.png:
|
Who's that Pokémon? https://cdn.discord.red/i/7Lb8533.png:
|
||||||
- Articuno
|
- Articuno
|
||||||
Who's that pokemon? https://cdn.discord.red/i/Dk1StF5.png:
|
Who's that Pokémon? https://cdn.discord.red/i/Dk1StF5.png:
|
||||||
- Zapdos
|
- Zapdos
|
||||||
Who's that pokemon? https://cdn.discord.red/i/rrcCaAR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/rrcCaAR.png:
|
||||||
- Moltres
|
- Moltres
|
||||||
Who's that pokemon? https://cdn.discord.red/i/JU0mWkj.png:
|
Who's that Pokémon? https://cdn.discord.red/i/JU0mWkj.png:
|
||||||
- Dratini
|
- Dratini
|
||||||
Who's that pokemon? https://cdn.discord.red/i/SsGWg1B.png:
|
Who's that Pokémon? https://cdn.discord.red/i/SsGWg1B.png:
|
||||||
- Dragonair
|
- Dragonair
|
||||||
Who's that pokemon? https://cdn.discord.red/i/snr8HO7.png:
|
Who's that Pokémon? https://cdn.discord.red/i/snr8HO7.png:
|
||||||
- Dragonite
|
- Dragonite
|
||||||
Who's that pokemon? https://cdn.discord.red/i/RW89rJR.png:
|
Who's that Pokémon? https://cdn.discord.red/i/RW89rJR.png:
|
||||||
- Mewtwo
|
- Mewtwo
|
||||||
Who's that pokemon? https://cdn.discord.red/i/dezUCAt.png:
|
Who's that Pokémon? https://cdn.discord.red/i/dezUCAt.png:
|
||||||
- Mew
|
- Mew
|
||||||
|
|||||||
201
redbot/cogs/trivia/data/lists/whosthatpokemon2.yaml
Normal file
201
redbot/cogs/trivia/data/lists/whosthatpokemon2.yaml
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
AUTHOR: aikaterna, owo
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/161fDs6.png:
|
||||||
|
- Chikorita
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/9mBd4k5.png:
|
||||||
|
- Bayleef
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/JK6EdFS.png:
|
||||||
|
- Meganium
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/VANqEey.png:
|
||||||
|
- Cyndaquil
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/wo3W5f8.png:
|
||||||
|
- Quilava
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/la2mCq5.png:
|
||||||
|
- Typhlosion
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/NOE3zVe.png:
|
||||||
|
- Totodile
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/7mIaKvA.png:
|
||||||
|
- Croconaw
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/pkRCy4p.png:
|
||||||
|
- Feraligatr
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/R2RQJJD.png:
|
||||||
|
- Sentret
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/zVeD6jY.png:
|
||||||
|
- Furret
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/tu0igAj.png:
|
||||||
|
- Hoothoot
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/qokx2sz.png:
|
||||||
|
- Noctowl
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/LqBvwkd.png:
|
||||||
|
- Ledyba
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/Ri77MSO.png:
|
||||||
|
- Ledian
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/GvFKVrG.png:
|
||||||
|
- Spinarak
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/MN7OIfR.png:
|
||||||
|
- Ariados
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/e5hYFQF.png:
|
||||||
|
- Crobat
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/YOyKw1M.png:
|
||||||
|
- Chinchou
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/WZEHcW2.png:
|
||||||
|
- Lanturn
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/1YqVBUU.png:
|
||||||
|
- Pichu
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/BzyRRM6.png:
|
||||||
|
- Cleffa
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/HLzHnoR.png:
|
||||||
|
- Igglybuff
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/7eIACOx.png:
|
||||||
|
- Togepi
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/Wihw9ed.png:
|
||||||
|
- Togetic
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/sEcT1wG.png:
|
||||||
|
- Natu
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/WP50IsH.png:
|
||||||
|
- Xatu
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/aeU3eLQ.png:
|
||||||
|
- Mareep
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/CMjVBM2.png:
|
||||||
|
- Flaaffy
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/0rL21y3.png:
|
||||||
|
- Ampharos
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/r83gWqG.png:
|
||||||
|
- Bellossom
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/nDX9cFZ.png:
|
||||||
|
- Marill
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/i8MzcBG.png:
|
||||||
|
- Azumarill
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/9lvsmrK.png:
|
||||||
|
- Sudowoodo
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/1MOC4py.png:
|
||||||
|
- Politoed
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/MtHPKHY.png:
|
||||||
|
- Hoppip
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/G3B7gou.png:
|
||||||
|
- Skiploom
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/3PqW6d4.png:
|
||||||
|
- Jumpluff
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/7E4uSrM.png:
|
||||||
|
- Aipom
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/TQp3Nm6.png:
|
||||||
|
- Sunkern
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/uz2MQ0c.png:
|
||||||
|
- Sunflora
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/NiC8tpF.png:
|
||||||
|
- Yanma
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/yvgjiCQ.png:
|
||||||
|
- Wooper
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/7NSgVte.png:
|
||||||
|
- Quagsire
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/d6xPUYS.png:
|
||||||
|
- Espeon
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/1D2T81X.png:
|
||||||
|
- Umbreon
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/mdOMOgS.png:
|
||||||
|
- Murkrow
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/6ReUa0W.png:
|
||||||
|
- Slowking
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/JA1k4GF.png:
|
||||||
|
- Misdreavus
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/sLKauTP.png:
|
||||||
|
- Unown
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/gtzSsQh.png:
|
||||||
|
- Wobbuffet
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/Zz1hdae.png:
|
||||||
|
- Girafarig
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/7v0ktVt.png:
|
||||||
|
- Pineco
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/dGt2LtM.png:
|
||||||
|
- Forretress
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/3d7i0nA.png:
|
||||||
|
- Dunsparce
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/EZFfXGQ.png:
|
||||||
|
- Gligar
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/FicMmX2.png:
|
||||||
|
- Steelix
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/EWlbb3g.png:
|
||||||
|
- Snubbull
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/Es7SFIu.png:
|
||||||
|
- Granbull
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/qWvJSNs.png:
|
||||||
|
- Qwilfish
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/zl9gJ8s.png:
|
||||||
|
- Scizor
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/ZSkIWg1.png:
|
||||||
|
- Shuckle
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/ivmNVBQ.png:
|
||||||
|
- Heracross
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/cVNGBvn.png:
|
||||||
|
- Sneasel
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/gwKceRk.png:
|
||||||
|
- Teddiursa
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/mShUvcr.png:
|
||||||
|
- Ursaring
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/QnOMvBY.png:
|
||||||
|
- Slugma
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/rHUlbZ7.png:
|
||||||
|
- Magcargo
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/SLVkdUf.png:
|
||||||
|
- Swinub
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/rMgYSAy.png:
|
||||||
|
- Piloswine
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/fYLQexl.png:
|
||||||
|
- Corsola
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/LFKLE7w.png:
|
||||||
|
- Remoraid
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/YxMYn4W.png:
|
||||||
|
- Octillery
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/QFaIdNN.png:
|
||||||
|
- Delibird
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/tRT4c6d.png:
|
||||||
|
- Mantine
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/zaFbLo8.png:
|
||||||
|
- Skarmory
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/sqAekho.png:
|
||||||
|
- Houndour
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/mijoGZI.png:
|
||||||
|
- Houndoom
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/XNCoyFy.png:
|
||||||
|
- Kingdra
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/2yXKuEh.png:
|
||||||
|
- Phanpy
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/eAodrXb.png:
|
||||||
|
- Donphan
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/JJkzySs.png:
|
||||||
|
- Porygon2
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/FOK8Yla.png:
|
||||||
|
- Stantler
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/o2Hb9ck.png:
|
||||||
|
- Smeargle
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/NjCcsZh.png:
|
||||||
|
- Tyrogue
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/mpUCBUn.png:
|
||||||
|
- Hitmontop
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/GPpT5pn.png:
|
||||||
|
- Smoochum
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/ELqP5eZ.png:
|
||||||
|
- Elekid
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/V7iMoJ4.png:
|
||||||
|
- Magby
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/xXU0CvW.png:
|
||||||
|
- Miltank
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/QUO0wOi.png:
|
||||||
|
- Blissey
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/lC2VuSh.png:
|
||||||
|
- Raikou
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/5eIF2yf.png:
|
||||||
|
- Entei
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/wRv6jf7.png:
|
||||||
|
- Suicune
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/tJJvIYK.png:
|
||||||
|
- Larvitar
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/9GZXyuU.png:
|
||||||
|
- Pupitar
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/A2ZWKBK.png:
|
||||||
|
- Tyranitar
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/QQGb5yJ.png:
|
||||||
|
- Lugia
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/d3x47sk.png:
|
||||||
|
- Ho-Oh
|
||||||
|
Who's that Pokémon? https://cdn.discord.red/i/B6oIkT4.png:
|
||||||
|
- Celebi
|
||||||
@@ -4,7 +4,7 @@ import time
|
|||||||
import random
|
import random
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import bank
|
from redbot.core import bank, errors
|
||||||
from redbot.core.i18n import Translator
|
from redbot.core.i18n import Translator
|
||||||
from redbot.core.utils.chat_formatting import box, bold, humanize_list, humanize_number
|
from redbot.core.utils.chat_formatting import box, bold, humanize_list, humanize_number
|
||||||
from redbot.core.utils.common_filters import normalize_smartquotes
|
from redbot.core.utils.common_filters import normalize_smartquotes
|
||||||
@@ -305,7 +305,7 @@ class TriviaSession:
|
|||||||
LOG.debug("Paying trivia winner: %d credits --> %s", amount, str(winner))
|
LOG.debug("Paying trivia winner: %d credits --> %s", amount, str(winner))
|
||||||
try:
|
try:
|
||||||
await bank.deposit_credits(winner, int(multiplier * score))
|
await bank.deposit_credits(winner, int(multiplier * score))
|
||||||
except bank.BalanceTooHigh as e:
|
except errors.BalanceTooHigh as e:
|
||||||
await bank.set_balance(winner, e.max_balance)
|
await bank.set_balance(winner, e.max_balance)
|
||||||
await self.ctx.send(
|
await self.ctx.send(
|
||||||
_(
|
_(
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ class Trivia(commands.Cog):
|
|||||||
)
|
)
|
||||||
padding = [" " * (len(h) - len(f)) for h, f in zip(headers, fields)]
|
padding = [" " * (len(h) - len(f)) for h, f in zip(headers, fields)]
|
||||||
fields = tuple(f + padding[i] for i, f in enumerate(fields))
|
fields = tuple(f + padding[i] for i, f in enumerate(fields))
|
||||||
lines.append(" | ".join(fields).format(member=member, **m_data))
|
lines.append(" | ".join(fields))
|
||||||
if rank == top:
|
if rank == top:
|
||||||
break
|
break
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import contextlib
|
import contextlib
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from copy import copy
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
@@ -350,22 +351,27 @@ class Warnings(commands.Cog):
|
|||||||
|
|
||||||
reason_type = None
|
reason_type = None
|
||||||
async with self.config.guild(ctx.guild).reasons() as registered_reasons:
|
async with self.config.guild(ctx.guild).reasons() as registered_reasons:
|
||||||
if reason.lower() not in registered_reasons:
|
if (reason_type := registered_reasons.get(reason.lower())) is None:
|
||||||
msg = _("That is not a registered reason!")
|
msg = _("That is not a registered reason!")
|
||||||
if custom_allowed:
|
if custom_allowed:
|
||||||
reason_type = {"description": reason, "points": points}
|
reason_type = {"description": reason, "points": points}
|
||||||
elif (
|
else:
|
||||||
ctx.guild.owner == ctx.author
|
# logic taken from `[p]permissions canrun`
|
||||||
or ctx.channel.permissions_for(ctx.author).administrator
|
fake_message = copy(ctx.message)
|
||||||
or await ctx.bot.is_owner(ctx.author)
|
fake_message.content = f"{ctx.prefix}warningset allowcustomreasons"
|
||||||
):
|
fake_context = await ctx.bot.get_context(fake_message)
|
||||||
|
try:
|
||||||
|
can = await self.allowcustomreasons.can_run(
|
||||||
|
fake_context, check_all_parents=True, change_permission_state=False
|
||||||
|
)
|
||||||
|
except commands.CommandError:
|
||||||
|
can = False
|
||||||
|
if can:
|
||||||
msg += " " + _(
|
msg += " " + _(
|
||||||
"Do `{prefix}warningset allowcustomreasons true` to enable custom "
|
"Do `{prefix}warningset allowcustomreasons true` to enable custom "
|
||||||
"reasons."
|
"reasons."
|
||||||
).format(prefix=ctx.clean_prefix)
|
).format(prefix=ctx.clean_prefix)
|
||||||
return await ctx.send(msg)
|
return await ctx.send(msg)
|
||||||
else:
|
|
||||||
reason_type = registered_reasons[reason.lower()]
|
|
||||||
if reason_type is None:
|
if reason_type is None:
|
||||||
return
|
return
|
||||||
member_settings = self.config.member(user)
|
member_settings = self.config.member(user)
|
||||||
|
|||||||
@@ -657,12 +657,20 @@ class RedBase(
|
|||||||
for package in packages:
|
for package in packages:
|
||||||
try:
|
try:
|
||||||
spec = await self._cog_mgr.find_cog(package)
|
spec = await self._cog_mgr.find_cog(package)
|
||||||
|
if spec is None:
|
||||||
|
log.error(
|
||||||
|
"Failed to load package %s (package was not found in any cog path)",
|
||||||
|
package,
|
||||||
|
)
|
||||||
|
await self.remove_loaded_package(package)
|
||||||
|
to_remove.append(package)
|
||||||
|
continue
|
||||||
await asyncio.wait_for(self.load_extension(spec), 30)
|
await asyncio.wait_for(self.load_extension(spec), 30)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
log.exception("Failed to load package %s (timeout)", package)
|
log.exception("Failed to load package %s (timeout)", package)
|
||||||
to_remove.append(package)
|
to_remove.append(package)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception("Failed to load package {}".format(package), exc_info=e)
|
log.exception("Failed to load package %s", package, exc_info=e)
|
||||||
await self.remove_loaded_package(package)
|
await self.remove_loaded_package(package)
|
||||||
to_remove.append(package)
|
to_remove.append(package)
|
||||||
for package in to_remove:
|
for package in to_remove:
|
||||||
|
|||||||
@@ -2629,7 +2629,7 @@ class Core(commands.Cog, CoreLogic):
|
|||||||
ctx: commands.Context,
|
ctx: commands.Context,
|
||||||
channel: Optional[Union[discord.TextChannel, discord.CategoryChannel]] = None,
|
channel: Optional[Union[discord.TextChannel, discord.CategoryChannel]] = None,
|
||||||
):
|
):
|
||||||
"""Remove a channel or category from ignore the list.
|
"""Remove a channel or category from the ignore list.
|
||||||
|
|
||||||
Defaults to the current channel.
|
Defaults to the current channel.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -81,14 +81,15 @@ async def test_is_ancestor(mocker, repo, maybe_ancestor_rev, descendant_rev, ret
|
|||||||
descendant_rev=descendant_rev,
|
descendant_rev=descendant_rev,
|
||||||
),
|
),
|
||||||
valid_exit_codes=(0, 1),
|
valid_exit_codes=(0, 1),
|
||||||
|
debug_only=True,
|
||||||
)
|
)
|
||||||
assert ret is expected
|
assert ret is expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_is_ancestor_raise(mocker, repo):
|
async def test_is_ancestor_object_raise(mocker, repo):
|
||||||
m = _mock_run(mocker, repo, 128)
|
m = _mock_run(mocker, repo, 128, b"", b"fatal: Not a valid object name invalid1")
|
||||||
with pytest.raises(GitException):
|
with pytest.raises(UnknownRevision):
|
||||||
await repo.is_ancestor("invalid1", "invalid2")
|
await repo.is_ancestor("invalid1", "invalid2")
|
||||||
|
|
||||||
m.assert_called_once_with(
|
m.assert_called_once_with(
|
||||||
@@ -99,6 +100,33 @@ async def test_is_ancestor_raise(mocker, repo):
|
|||||||
descendant_rev="invalid2",
|
descendant_rev="invalid2",
|
||||||
),
|
),
|
||||||
valid_exit_codes=(0, 1),
|
valid_exit_codes=(0, 1),
|
||||||
|
debug_only=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_is_ancestor_commit_raise(mocker, repo):
|
||||||
|
m = _mock_run(
|
||||||
|
mocker,
|
||||||
|
repo,
|
||||||
|
128,
|
||||||
|
b"",
|
||||||
|
b"fatal: Not a valid commit name 0123456789abcde0123456789abcde0123456789",
|
||||||
|
)
|
||||||
|
with pytest.raises(UnknownRevision):
|
||||||
|
await repo.is_ancestor(
|
||||||
|
"0123456789abcde0123456789abcde0123456789", "c950fc05a540dd76b944719c2a3302da2e2f3090"
|
||||||
|
)
|
||||||
|
|
||||||
|
m.assert_called_once_with(
|
||||||
|
ProcessFormatter().format(
|
||||||
|
repo.GIT_IS_ANCESTOR,
|
||||||
|
path=repo.folder_path,
|
||||||
|
maybe_ancestor_rev="0123456789abcde0123456789abcde0123456789",
|
||||||
|
descendant_rev="c950fc05a540dd76b944719c2a3302da2e2f3090",
|
||||||
|
),
|
||||||
|
valid_exit_codes=(0, 1),
|
||||||
|
debug_only=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ async def test_git_is_ancestor_false(git_repo):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_git_is_ancestor_invalid_ref(git_repo):
|
async def test_git_is_ancestor_invalid_object(git_repo):
|
||||||
p = await git_repo._run(
|
p = await git_repo._run(
|
||||||
ProcessFormatter().format(
|
ProcessFormatter().format(
|
||||||
git_repo.GIT_IS_ANCESTOR,
|
git_repo.GIT_IS_ANCESTOR,
|
||||||
@@ -394,6 +394,22 @@ async def test_git_is_ancestor_invalid_ref(git_repo):
|
|||||||
assert p.stderr.decode().strip() == "fatal: Not a valid object name invalid1"
|
assert p.stderr.decode().strip() == "fatal: Not a valid object name invalid1"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_git_is_ancestor_invalid_commit(git_repo):
|
||||||
|
p = await git_repo._run(
|
||||||
|
ProcessFormatter().format(
|
||||||
|
git_repo.GIT_IS_ANCESTOR,
|
||||||
|
path=git_repo.folder_path,
|
||||||
|
maybe_ancestor_rev="0123456789abcde0123456789abcde0123456789",
|
||||||
|
descendant_rev="c950fc05a540dd76b944719c2a3302da2e2f3090",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert p.returncode == 128
|
||||||
|
assert p.stderr.decode().strip() == (
|
||||||
|
"fatal: Not a valid commit name 0123456789abcde0123456789abcde0123456789"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_git_check_if_module_exists_true(git_repo):
|
async def test_git_check_if_module_exists_true(git_repo):
|
||||||
p = await git_repo._run(
|
p = await git_repo._run(
|
||||||
|
|||||||
Reference in New Issue
Block a user