Compare commits

...

15 Commits
3.4.1 ... 3.4.2

Author SHA1 Message Date
jack1142
ac9149870e Version bump to 3.4.2 (#4561) 2020-10-28 19:31:13 +01:00
jack1142
f850ded822 Red 3.4.2 - Changelog (#4560)
* Changelog

* Add 4559

* Fix release date

* This contributor is important too :)

* We need to hire automatic grammar checker

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>

* update

* ...

Co-authored-by: Flame442 <34169552+Flame442@users.noreply.github.com>
2020-10-28 19:24:50 +01:00
Draper
06b87368f6 [Audio] Allow LLSET in DMs (#4562) 2020-10-28 10:55:00 -07:00
aikaterna
af65b73fb2 [Audio] Update Lavalink.jar version (#4559) 2020-10-28 17:20:23 +00:00
Draper
0feacee7f2 [Audio] Fix local search (#4553) 2020-10-28 09:07:50 -07:00
jack1142
4aa84a5d22 Add better error logging for unexpected errors, add error messages for exceeded YouTube quota (#4552) 2020-10-28 11:37:56 +00:00
Draper
c95d526bc6 Merge pull request #4558 from jack1142/V3/never_trust_slime
Never trust Slime
2020-10-28 11:25:26 +00:00
jack1142
b77afeed34 Never trust Slime 2020-10-28 12:17:37 +01:00
Stonedestroyer
7db2ba556d Fixes concurrency spelling with time(s) (#4450)
* Change spelling

* Change for translation
2020-10-28 11:56:27 +01:00
PredaaA
bd0955ac44 [Streams] Remove the __del__ (#4512)
* [Streams] Remove the `__del__`

* Add a teardown function to call Streams.cog_unload()

* Apparently I forgot cog_unload is called automatically (Thanks @rapptz
lol)

Co-authored-by: palmtree5 <3577255+palmtree5@users.noreply.github.com>
2020-10-28 11:55:05 +01:00
jack1142
0d650f6765 Remove multi-line commands from Unix install docs (#4550) 2020-10-28 11:54:43 +01:00
jack1142
8b2c6226f6 Add metadata file to redbot --debuginfo (#4557) 2020-10-28 11:54:16 +01:00
bobloy
252951c706 [Docs] Cleanup Cog Guide (#4488)
* Autogenerated doc and index spot

* Update command descriptions

* Use qualified name in titles and new command descriptions

* Add arguments to descriptions and cleanup self examples.

* Examples are bulleted and indented.

* Handle aliases (none), examples are bulleted and indented

* Switch to alphabetical

* Fix X typo
2020-10-28 00:51:19 -04:00
jack1142
532ac6cfa9 I mean... Technically we fixed the security issue, right? (#4556) 2020-10-28 02:34:11 +01:00
Kowlin
868059f062 3.4.2.dev bump (#4549)
Co-authored-by: jack1142 <6032823+jack1142@users.noreply.github.com>
2020-10-27 21:24:19 +01:00
15 changed files with 482 additions and 58 deletions

View File

@@ -1,5 +1,36 @@
.. 3.4.x Changelogs
Redbot 3.4.2 (2020-10-28)
=========================
| Thanks to all these amazing people that contributed to this release:
| :ghuser:`aikaterna`, :ghuser:`Drapersniper`, :ghuser:`jack1142`, :ghuser:`Kowlin`, :ghuser:`PredaaA`, :ghuser:`Stonedestroyer`
Read before updating
--------------------
1. Information for Audio users that are using an external Lavalink instance (if you don't know what that is, you should skip this point):
Red 3.4.2 uses a new Lavalink jar that you will need to manually update from `our GitHub <https://github.com/Cog-Creators/Lavalink-Jars/releases/tag/3.3.1.4_1128>`_.
End-user changelog
------------------
- **Core Bot** - Added info about the metadata file to ``redbot --debuginfo`` (:issue:`4557`)
- **Audio** - Fixed the ``[p]local search`` command (:issue:`4553`)
- **Audio** - Fixed random "Something broke when playing the track." errors for YouTube tracks (:issue:`4559`)
- **Audio** - Commands in ``[p]llset`` group can now be used in DMs (:issue:`4562`)
- **Mod** - Fixed ``[p]massban`` not working for banning members that are in the server (:issue:`4556`, :issue:`4555`)
- **Streams** - Added error messages when exceeding the YouTube quota in the Streams cog (:issue:`4552`)
- **Streams** - Improved logging for unexpected errors in the Streams cog (:issue:`4552`)
Documentation changes
---------------------
- Added `cog guide for Cleanup cog <cleanup>` (:issue:`4488`)
- Removed multi-line commands from `install_linux_mac` to avoid confusing readers (:issue:`4550`)
Redbot 3.4.1 (2020-10-27)
=========================

296
docs/cog_guides/cleanup.rst Normal file
View File

@@ -0,0 +1,296 @@
.. _cleanup:
=======
Cleanup
=======
This is the cog guide for the cleanup cog. You will
find detailed docs about usage and commands.
``[p]`` is considered as your prefix.
.. note:: To use this cog, load it by typing this::
[p]load cleanup
.. _cleanup-usage:
-----
Usage
-----
This cog contains commands used for "cleaning up" (deleting) messages.
This is designed as a moderator tool and offers many convenient use cases.
All cleanup commands only apply to the channel the command is executed in.
Messages older than two weeks cannot be mass deleted.
This is a limitation of the API.
.. _cleanup-commands:
--------
Commands
--------
.. _cleanup-command-cleanup:
^^^^^^^
cleanup
^^^^^^^
**Syntax**
.. code-block:: none
[p]cleanup
**Description**
Base command for deleting messages.
.. _cleanup-command-cleanup-after:
"""""""""""""
cleanup after
"""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup after <message_id> [delete_pinned=False]
**Description**
Delete all messages after a specified message.
To get a message id, enable developer mode in Discord's
settings, 'appearance' tab. Then right click a message
and copy its id.
**Arguments:**
- ``<message_id>`` The id of the message to cleanup after. This message won't be deleted.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-before:
""""""""""""""
cleanup before
""""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup before <message_id> <number> [delete_pinned=False]
**Description**
Deletes X messages before the specified message.
To get a message id, enable developer mode in Discord's
settings, 'appearance' tab. Then right click a message
and copy its id.
**Arguments:**
- ``<message_id>`` The id of the message to cleanup before. This message won't be deleted.
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-between:
"""""""""""""""
cleanup between
"""""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup between <one> <two> [delete_pinned=False]
**Description**
Delete the messages between Message One and Message Two, providing the messages IDs.
The first message ID should be the older message and the second one the newer.
Example:
- ``[p]cleanup between 123456789123456789 987654321987654321``
**Arguments:**
- ``<one>`` The id of the message to cleanup after. This message won't be deleted.
- ``<two>`` The id of the message to cleanup before. This message won't be deleted.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-bot:
"""""""""""
cleanup bot
"""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup bot <number> [delete_pinned=False]
**Description**
Clean up command messages and messages from the bot.
Can only cleanup custom commands and alias commands if those cogs are loaded.
**Arguments:**
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-messages:
""""""""""""""""
cleanup messages
""""""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup messages <number> [delete_pinned=False]
**Description**
Delete the last X messages.
Example:
- ``[p]cleanup messages 26``
**Arguments:**
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-self:
""""""""""""
cleanup self
""""""""""""
**Syntax**
.. code-block:: none
[p]cleanup self <number> [match_pattern] [delete_pinned=False]
**Description**
Clean up messages owned by the bot.
By default, all messages are cleaned. If a second argument is specified,
it is used for pattern matching - only messages containing the given text will be deleted.
Examples:
- ``[p]cleanup self 6``
- ``[p]cleanup self 10 Pong``
- ``[p]cleanup self 7 "" True``
**Arguments:**
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<match_pattern>`` The text that messages must contain to be deleted. Use "" to skip this.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-spam:
""""""""""""
cleanup spam
""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup spam [number=50]
**Description**
Deletes duplicate messages in the channel from the last X messages and keeps only one copy.
Defaults to 50.
**Arguments:**
- ``<number>`` The number of messages to check for duplicates. Must be a positive integer.
.. _cleanup-command-cleanup-text:
""""""""""""
cleanup text
""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup text <text> <number> [delete_pinned=False]
**Description**
Delete the last X messages matching the specified text.
Example:
- ``[p]cleanup text "test" 5``
Remember to use double quotes.
**Arguments:**
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False
.. _cleanup-command-cleanup-user:
""""""""""""
cleanup user
""""""""""""
.. note:: |mod-lock|
**Syntax**
.. code-block:: none
[p]cleanup user <user> <number> [delete_pinned=False]
**Description**
Delete the last X messages from a specified user.
Examples:
- ``[p]cleanup user @Twentysix 2``
- ``[p]cleanup user Red 6``
**Arguments:**
- ``<user>`` The user whose messages are to be cleaned up.
- ``<number>`` The max number of messages to cleanup. Must be a positive integer.
- ``<delete_pinned>`` Whether to delete pinned messages or not. Defaults to False

View File

@@ -35,6 +35,7 @@ Welcome to Red - Discord Bot's documentation!
cog_guides/admin
cog_guides/alias
cog_guides/bank
cog_guides/cleanup
red_core_data_statement
.. toctree::

View File

@@ -59,8 +59,7 @@ CentOS and RHEL 7
.. code-block:: none
sudo yum -y groupinstall development
sudo yum -y install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel \
openssl-devel xz xz-devel tk-devel libffi-devel findutils java-11-openjdk-headless
sudo yum -y install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel tk-devel libffi-devel findutils java-11-openjdk-headless
sudo yum -y install centos-release-scl
sudo yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++
echo "source scl_source enable devtoolset-8" >> ~/.bashrc
@@ -89,8 +88,7 @@ CentOS and RHEL 8
sudo yum -y install epel-release
sudo yum -y update
sudo yum -y groupinstall development
sudo yum -y install git zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel \
openssl-devel xz xz-devel tk-devel libffi-devel findutils java-11-openjdk-headless
sudo yum -y install git zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel tk-devel libffi-devel findutils java-11-openjdk-headless
Complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.
@@ -109,9 +107,7 @@ Debian/Raspbian Buster. This guide will tell you how. First, run the following c
.. code-block:: none
sudo apt update
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev libgdbm-dev uuid-dev python3-openssl git openjdk-11-jre-headless
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev libgdbm-dev uuid-dev python3-openssl git openjdk-11-jre-headless
CXX=/usr/bin/g++
Complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.
@@ -180,9 +176,7 @@ First, add the Opt-Python community repository:
.. code-block:: none
source /etc/os-release
sudo zypper -n ar -f \
https://download.opensuse.org/repositories/home:/Rotkraut:/Opt-Python/openSUSE_Leap_${VERSION_ID}/ \
Opt-Python
sudo zypper -n ar -f https://download.opensuse.org/repositories/home:/Rotkraut:/Opt-Python/openSUSE_Leap_${VERSION_ID}/ Opt-Python
sudo zypper -n --gpg-auto-import-keys ref
Now install the pre-requirements with zypper:
@@ -253,8 +247,7 @@ Now install the pre-requirements with apt:
.. code-block:: none
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
build-essential
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
Continue by `creating-venv-linux`.
@@ -284,8 +277,7 @@ Now install the pre-requirements with apt:
.. code-block:: none
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
build-essential
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
Continue by `creating-venv-linux`.
@@ -309,8 +301,7 @@ Now install the pre-requirements with apt:
.. code-block:: none
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
build-essential
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
Continue by `creating-venv-linux`.
@@ -335,9 +326,7 @@ installing pyenv. To do this, first run the following commands:
.. code-block:: none
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev \
libxmlsec1-dev libffi-dev liblzma-dev libgdbm-dev uuid-dev python3-openssl git openjdk-11-jre-headless
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev libgdbm-dev uuid-dev python3-openssl git openjdk-11-jre-headless
CXX=/usr/bin/g++
And then complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.

View File

@@ -191,7 +191,7 @@ def _update_event_loop_policy():
_asyncio.set_event_loop_policy(_uvloop.EventLoopPolicy())
__version__ = "3.4.1"
__version__ = "3.4.2"
version_info = VersionInfo.from_str(__version__)
# Filter fuzzywuzzy slow sequence matcher warning

View File

@@ -97,6 +97,7 @@ def debug_info():
+ "OS version: {}\n".format(osver)
+ "System arch: {}\n".format(platform.machine())
+ "User: {}\n".format(user_who_ran)
+ "Metadata file: {}\n".format(data_manager.config_file)
)
print(info)
sys.exit(0)

View File

@@ -17,7 +17,6 @@ _ = Translator("Audio", Path(__file__))
class LavalinkSetupCommands(MixinMeta, metaclass=CompositeMetaClass):
@commands.group(name="llsetup", aliases=["llset"])
@commands.is_owner()
@commands.guild_only()
@commands.bot_has_permissions(embed_links=True)
async def command_llsetup(self, ctx: commands.Context):
"""Lavalink server configuration options."""

View File

@@ -643,9 +643,9 @@ class PlayerCommands(MixinMeta, metaclass=CompositeMetaClass):
<search term>` to search on SoundCloud instead of YouTube.
"""
if not isinstance(query, (str, Query)):
if not isinstance(query, (str, list, Query)):
raise RuntimeError(
f"Expected 'query' to be a string or Query object but received: {type(query)} - this is an unexpected argument type, please report it."
f"Expected 'query' to be a string, list or Query object but received: {type(query)} - this is an unexpected argument type, please report it."
)
async def _search_menu(

View File

@@ -24,7 +24,7 @@ from .utils import task_callback
_ = Translator("Audio", pathlib.Path(__file__))
log = logging.getLogger("red.audio.manager")
JAR_VERSION: Final[str] = "3.3.1.4"
JAR_BUILD: Final[int] = 1115
JAR_BUILD: Final[int] = 1128
LAVALINK_DOWNLOAD_URL: Final[str] = (
"https://github.com/Cog-Creators/Lavalink-Jars/releases/download/"
f"{JAR_VERSION}_{JAR_BUILD}/"

View File

@@ -20,7 +20,14 @@ log = logging.getLogger("red.cleanup")
@cog_i18n(_)
class Cleanup(commands.Cog):
"""Commands for cleaning up messages."""
"""This cog contains commands used for "cleaning up" (deleting) messages.
This is designed as a moderator tool and offers many convenient use cases.
All cleanup commands only apply to the channel the command is executed in.
Messages older than two weeks cannot be mass deleted.
This is a limitation of the API.
"""
def __init__(self, bot: Red):
super().__init__()
@@ -117,7 +124,7 @@ class Cleanup(commands.Cog):
@commands.group()
async def cleanup(self, ctx: commands.Context):
"""Delete messages."""
"""Base command for deleting messages."""
pass
@cleanup.command()
@@ -130,9 +137,14 @@ class Cleanup(commands.Cog):
"""Delete the last X messages matching the specified text.
Example:
`[p]cleanup text "test" 5`
- `[p]cleanup text "test" 5`
Remember to use double quotes.
**Arguments:**
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
@@ -180,8 +192,14 @@ class Cleanup(commands.Cog):
"""Delete the last X messages from a specified user.
Examples:
`[p]cleanup user @\u200bTwentysix 2`
`[p]cleanup user Red 6`
- `[p]cleanup user @Twentysix 2`
- `[p]cleanup user Red 6`
**Arguments:**
- `<user>` The user whose messages are to be cleaned up.
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
@@ -246,6 +264,11 @@ class Cleanup(commands.Cog):
To get a message id, enable developer mode in Discord's
settings, 'appearance' tab. Then right click a message
and copy its id.
**Arguments:**
- `<message_id>` The id of the message to cleanup after. This message won't be deleted.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
@@ -281,11 +304,17 @@ class Cleanup(commands.Cog):
number: positive_int,
delete_pinned: bool = False,
):
"""Deletes X messages before specified message.
"""Deletes X messages before the specified message.
To get a message id, enable developer mode in Discord's
settings, 'appearance' tab. Then right click a message
and copy its id.
**Arguments:**
- `<message_id>` The id of the message to cleanup before. This message won't be deleted.
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
@@ -327,7 +356,13 @@ class Cleanup(commands.Cog):
The first message ID should be the older message and the second one the newer.
Example:
`[p]cleanup between 123456789123456789 987654321987654321`
- `[p]cleanup between 123456789123456789 987654321987654321`
**Arguments:**
- `<one>` The id of the message to cleanup after. This message won't be deleted.
- `<two>` The id of the message to cleanup before. This message won't be deleted.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
author = ctx.author
@@ -367,7 +402,12 @@ class Cleanup(commands.Cog):
"""Delete the last X messages.
Example:
`[p]cleanup messages 26`
- `[p]cleanup messages 26`
**Arguments:**
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
@@ -397,7 +437,15 @@ class Cleanup(commands.Cog):
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.
Can only cleanup custom commands and alias commands if those cogs are loaded.
**Arguments:**
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
author = ctx.message.author
@@ -479,8 +527,19 @@ class Cleanup(commands.Cog):
):
"""Clean up messages owned by the bot.
By default, all messages are cleaned. If a third argument is specified,
By default, all messages are cleaned. If a second argument is specified,
it is used for pattern matching - only messages containing the given text will be deleted.
Examples:
- `[p]cleanup self 6`
- `[p]cleanup self 10 Pong`
- `[p]cleanup self 7 "" True`
**Arguments:**
- `<number>` The max number of messages to cleanup. Must be a positive integer.
- `<match_pattern>` The text that messages must contain to be deleted. Use "" to skip this.
- `<delete_pinned>` Whether to delete pinned messages or not. Defaults to False
"""
channel = ctx.channel
author = ctx.message.author
@@ -551,6 +610,10 @@ class Cleanup(commands.Cog):
"""Deletes duplicate messages in the channel from the last X messages and keeps only one copy.
Defaults to 50.
**Arguments:**
- `<number>` The number of messages to check for duplicates. Must be a positive integer.
"""
msgs = []
spam = []

View File

@@ -460,7 +460,7 @@ class KickBanMixin(MixinMeta):
to_query = to_query[100:]
# Call `ban_user()` method for all users that turned out to be guild members.
for member in members:
for user_id, member in members.items():
try:
success, reason = await self.ban_user(
user=member, ctx=ctx, days=days, reason=reason, create_modlog_case=True

View File

@@ -18,5 +18,9 @@ class InvalidYoutubeCredentials(StreamsError):
pass
class YoutubeQuotaExceeded(StreamsError):
pass
class OfflineStream(StreamsError):
pass

View File

@@ -19,6 +19,7 @@ from .errors import (
OfflineStream,
StreamNotFound,
StreamsError,
YoutubeQuotaExceeded,
)
from . import streamtypes as _streamtypes
@@ -262,7 +263,19 @@ class Streams(commands.Cog):
"The YouTube API key is either invalid or has not been set. See {command}."
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`")
)
except APIError:
except YoutubeQuotaExceeded:
await ctx.send(
_(
"YouTube quota has been exceeded."
" Try again later or contact the owner if this continues."
)
)
except APIError as e:
log.error(
"Something went wrong whilst trying to contact the stream service's API.\n"
"Raw response data:\n%r",
e,
)
await ctx.send(
_("Something went wrong whilst trying to contact the stream service's API.")
)
@@ -412,7 +425,19 @@ class Streams(commands.Cog):
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`")
)
return
except APIError:
except YoutubeQuotaExceeded:
await ctx.send(
_(
"YouTube quota has been exceeded."
" Try again later or contact the owner if this continues."
)
)
except APIError as e:
log.error(
"Something went wrong whilst trying to contact the stream service's API.\n"
"Raw response data:\n%r",
e,
)
await ctx.send(
_("Something went wrong whilst trying to contact the stream service's API.")
)
@@ -845,5 +870,3 @@ class Streams(commands.Cog):
def cog_unload(self):
if self.task:
self.task.cancel()
__del__ = cog_unload

View File

@@ -14,6 +14,7 @@ from .errors import (
InvalidTwitchCredentials,
InvalidYoutubeCredentials,
StreamNotFound,
YoutubeQuotaExceeded,
)
from redbot.core.i18n import Translator
from redbot.core.utils.chat_formatting import humanize_number
@@ -180,12 +181,16 @@ class YoutubeStream(Stream):
async with session.get(YOUTUBE_CHANNELS_ENDPOINT, params=params) as r:
data = await r.json()
if (
"error" in data
and data["error"]["code"] == 400
and data["error"]["errors"][0]["reason"] == "keyInvalid"
):
raise InvalidYoutubeCredentials()
if "error" in data:
error_code = data["error"]["code"]
if error_code == 400 and data["error"]["errors"][0]["reason"] == "keyInvalid":
raise InvalidYoutubeCredentials()
elif error_code == 403 and data["error"]["errors"][0]["reason"] in (
"dailyLimitExceeded",
"quotaExceeded",
"rateLimitExceeded",
):
raise YoutubeQuotaExceeded()
elif "items" in data and len(data["items"]) == 0:
raise StreamNotFound()
elif "items" in data:
@@ -196,7 +201,7 @@ class YoutubeStream(Stream):
and data["pageInfo"]["totalResults"] < 1
):
raise StreamNotFound()
raise APIError()
raise APIError(data)
def __repr__(self):
return "<{0.__class__.__name__}: {0.name} (ID: {0.id})>".format(self)
@@ -276,7 +281,7 @@ class TwitchStream(Stream):
elif r.status == 404:
raise StreamNotFound()
else:
raise APIError()
raise APIError(data)
async def fetch_id(self):
header = {"Client-ID": str(self._client_id)}
@@ -298,7 +303,7 @@ class TwitchStream(Stream):
elif r.status == 401:
raise InvalidTwitchCredentials()
else:
raise APIError()
raise APIError(data)
def make_embed(self, data):
is_rerun = data["type"] == "rerun"
@@ -347,7 +352,7 @@ class HitboxStream(Stream):
# self.already_online = True
return self.make_embed(data)
raise APIError()
raise APIError(data)
def make_embed(self, data):
base_url = "https://edge.sf.hitbox.tv"
@@ -386,7 +391,7 @@ class PicartoStream(Stream):
elif r.status == 404:
raise StreamNotFound()
else:
raise APIError()
raise APIError(data)
def make_embed(self, data):
avatar = rnd(

View File

@@ -303,15 +303,27 @@ def init_events(bot, cli_flags):
await ctx.send(msg, delete_after=error.retry_after)
elif isinstance(error, commands.MaxConcurrencyReached):
if error.per is commands.BucketType.default:
msg = _(
"Too many people using this command."
" It can only be used {number} time(s) concurrently."
).format(number=error.number)
if error.number > 1:
msg = _(
"Too many people using this command."
" It can only be used {number} times concurrently."
).format(number=error.number)
else:
msg = _(
"Too many people using this command."
" It can only be used {number} time concurrently."
).format(number=error.number)
else:
msg = _(
"Too many people using this command."
" It can only be used {number} time(s) per {type} concurrently."
).format(number=error.number, type=error.per.name)
if error.number > 1:
msg = _(
"Too many people using this command."
" It can only be used {number} times per {type} concurrently."
).format(number=error.number, type=error.per.name)
else:
msg = _(
"Too many people using this command."
" It can only be used {number} time per {type} concurrently."
).format(number=error.number, type=error.per.name)
await ctx.send(msg)
else:
log.exception(type(error).__name__, exc_info=error)