mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-12-06 09:22:31 -05:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac9149870e | ||
|
|
f850ded822 | ||
|
|
06b87368f6 | ||
|
|
af65b73fb2 | ||
|
|
0feacee7f2 | ||
|
|
4aa84a5d22 | ||
|
|
c95d526bc6 | ||
|
|
b77afeed34 | ||
|
|
7db2ba556d | ||
|
|
bd0955ac44 | ||
|
|
0d650f6765 | ||
|
|
8b2c6226f6 | ||
|
|
252951c706 | ||
|
|
532ac6cfa9 | ||
|
|
868059f062 |
@@ -1,5 +1,36 @@
|
|||||||
.. 3.4.x Changelogs
|
.. 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)
|
Redbot 3.4.1 (2020-10-27)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|||||||
296
docs/cog_guides/cleanup.rst
Normal file
296
docs/cog_guides/cleanup.rst
Normal 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
|
||||||
@@ -35,6 +35,7 @@ Welcome to Red - Discord Bot's documentation!
|
|||||||
cog_guides/admin
|
cog_guides/admin
|
||||||
cog_guides/alias
|
cog_guides/alias
|
||||||
cog_guides/bank
|
cog_guides/bank
|
||||||
|
cog_guides/cleanup
|
||||||
red_core_data_statement
|
red_core_data_statement
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ CentOS and RHEL 7
|
|||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
sudo yum -y groupinstall development
|
sudo yum -y groupinstall development
|
||||||
sudo yum -y install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel \
|
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
|
||||||
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 centos-release-scl
|
||||||
sudo yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++
|
sudo yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++
|
||||||
echo "source scl_source enable devtoolset-8" >> ~/.bashrc
|
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 install epel-release
|
||||||
sudo yum -y update
|
sudo yum -y update
|
||||||
sudo yum -y groupinstall development
|
sudo yum -y groupinstall development
|
||||||
sudo yum -y install git zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel \
|
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
|
||||||
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>`.
|
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
|
.. code-block:: none
|
||||||
|
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
|
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
|
||||||
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++
|
CXX=/usr/bin/g++
|
||||||
|
|
||||||
Complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.
|
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
|
.. code-block:: none
|
||||||
|
|
||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
sudo zypper -n ar -f \
|
sudo zypper -n ar -f https://download.opensuse.org/repositories/home:/Rotkraut:/Opt-Python/openSUSE_Leap_${VERSION_ID}/ Opt-Python
|
||||||
https://download.opensuse.org/repositories/home:/Rotkraut:/Opt-Python/openSUSE_Leap_${VERSION_ID}/ \
|
|
||||||
Opt-Python
|
|
||||||
sudo zypper -n --gpg-auto-import-keys ref
|
sudo zypper -n --gpg-auto-import-keys ref
|
||||||
|
|
||||||
Now install the pre-requirements with zypper:
|
Now install the pre-requirements with zypper:
|
||||||
@@ -253,8 +247,7 @@ Now install the pre-requirements with apt:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
|
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
|
||||||
build-essential
|
|
||||||
|
|
||||||
Continue by `creating-venv-linux`.
|
Continue by `creating-venv-linux`.
|
||||||
|
|
||||||
@@ -284,8 +277,7 @@ Now install the pre-requirements with apt:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
|
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
|
||||||
build-essential
|
|
||||||
|
|
||||||
Continue by `creating-venv-linux`.
|
Continue by `creating-venv-linux`.
|
||||||
|
|
||||||
@@ -309,8 +301,7 @@ Now install the pre-requirements with apt:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless \
|
sudo apt -y install python3.8 python3.8-dev python3.8-venv python3-pip git openjdk-11-jre-headless build-essential
|
||||||
build-essential
|
|
||||||
|
|
||||||
Continue by `creating-venv-linux`.
|
Continue by `creating-venv-linux`.
|
||||||
|
|
||||||
@@ -335,9 +326,7 @@ installing pyenv. To do this, first run the following commands:
|
|||||||
|
|
||||||
.. code-block:: none
|
.. code-block:: none
|
||||||
|
|
||||||
sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
|
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
|
||||||
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++
|
CXX=/usr/bin/g++
|
||||||
|
|
||||||
And then complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.
|
And then complete the rest of the installation by `installing Python 3.8 with pyenv <install-python-pyenv>`.
|
||||||
|
|||||||
@@ -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.4.1"
|
__version__ = "3.4.2"
|
||||||
version_info = VersionInfo.from_str(__version__)
|
version_info = VersionInfo.from_str(__version__)
|
||||||
|
|
||||||
# Filter fuzzywuzzy slow sequence matcher warning
|
# Filter fuzzywuzzy slow sequence matcher warning
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ def debug_info():
|
|||||||
+ "OS version: {}\n".format(osver)
|
+ "OS version: {}\n".format(osver)
|
||||||
+ "System arch: {}\n".format(platform.machine())
|
+ "System arch: {}\n".format(platform.machine())
|
||||||
+ "User: {}\n".format(user_who_ran)
|
+ "User: {}\n".format(user_who_ran)
|
||||||
|
+ "Metadata file: {}\n".format(data_manager.config_file)
|
||||||
)
|
)
|
||||||
print(info)
|
print(info)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ _ = Translator("Audio", Path(__file__))
|
|||||||
class LavalinkSetupCommands(MixinMeta, metaclass=CompositeMetaClass):
|
class LavalinkSetupCommands(MixinMeta, metaclass=CompositeMetaClass):
|
||||||
@commands.group(name="llsetup", aliases=["llset"])
|
@commands.group(name="llsetup", aliases=["llset"])
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
@commands.guild_only()
|
|
||||||
@commands.bot_has_permissions(embed_links=True)
|
@commands.bot_has_permissions(embed_links=True)
|
||||||
async def command_llsetup(self, ctx: commands.Context):
|
async def command_llsetup(self, ctx: commands.Context):
|
||||||
"""Lavalink server configuration options."""
|
"""Lavalink server configuration options."""
|
||||||
|
|||||||
@@ -643,9 +643,9 @@ class PlayerCommands(MixinMeta, metaclass=CompositeMetaClass):
|
|||||||
<search term>` to search on SoundCloud instead of YouTube.
|
<search term>` to search on SoundCloud instead of YouTube.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(query, (str, Query)):
|
if not isinstance(query, (str, list, Query)):
|
||||||
raise RuntimeError(
|
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(
|
async def _search_menu(
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from .utils import task_callback
|
|||||||
_ = Translator("Audio", pathlib.Path(__file__))
|
_ = Translator("Audio", pathlib.Path(__file__))
|
||||||
log = logging.getLogger("red.audio.manager")
|
log = logging.getLogger("red.audio.manager")
|
||||||
JAR_VERSION: Final[str] = "3.3.1.4"
|
JAR_VERSION: Final[str] = "3.3.1.4"
|
||||||
JAR_BUILD: Final[int] = 1115
|
JAR_BUILD: Final[int] = 1128
|
||||||
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}/"
|
||||||
|
|||||||
@@ -20,7 +20,14 @@ log = logging.getLogger("red.cleanup")
|
|||||||
|
|
||||||
@cog_i18n(_)
|
@cog_i18n(_)
|
||||||
class Cleanup(commands.Cog):
|
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):
|
def __init__(self, bot: Red):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -117,7 +124,7 @@ class Cleanup(commands.Cog):
|
|||||||
|
|
||||||
@commands.group()
|
@commands.group()
|
||||||
async def cleanup(self, ctx: commands.Context):
|
async def cleanup(self, ctx: commands.Context):
|
||||||
"""Delete messages."""
|
"""Base command for deleting messages."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@cleanup.command()
|
@cleanup.command()
|
||||||
@@ -130,9 +137,14 @@ class Cleanup(commands.Cog):
|
|||||||
"""Delete the last X messages matching the specified text.
|
"""Delete the last X messages matching the specified text.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
`[p]cleanup text "test" 5`
|
- `[p]cleanup text "test" 5`
|
||||||
|
|
||||||
Remember to use double quotes.
|
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
|
channel = ctx.channel
|
||||||
@@ -180,8 +192,14 @@ class Cleanup(commands.Cog):
|
|||||||
"""Delete the last X messages from a specified user.
|
"""Delete the last X messages from a specified user.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
`[p]cleanup user @\u200bTwentysix 2`
|
- `[p]cleanup user @Twentysix 2`
|
||||||
`[p]cleanup user Red 6`
|
- `[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
|
channel = ctx.channel
|
||||||
|
|
||||||
@@ -246,6 +264,11 @@ class Cleanup(commands.Cog):
|
|||||||
To get a message id, enable developer mode in Discord's
|
To get a message id, enable developer mode in Discord's
|
||||||
settings, 'appearance' tab. Then right click a message
|
settings, 'appearance' tab. Then right click a message
|
||||||
and copy its id.
|
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
|
channel = ctx.channel
|
||||||
@@ -281,11 +304,17 @@ class Cleanup(commands.Cog):
|
|||||||
number: positive_int,
|
number: positive_int,
|
||||||
delete_pinned: bool = False,
|
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
|
To get a message id, enable developer mode in Discord's
|
||||||
settings, 'appearance' tab. Then right click a message
|
settings, 'appearance' tab. Then right click a message
|
||||||
and copy its id.
|
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
|
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.
|
The first message ID should be the older message and the second one the newer.
|
||||||
|
|
||||||
Example:
|
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
|
channel = ctx.channel
|
||||||
author = ctx.author
|
author = ctx.author
|
||||||
@@ -367,7 +402,12 @@ class Cleanup(commands.Cog):
|
|||||||
"""Delete the last X messages.
|
"""Delete the last X messages.
|
||||||
|
|
||||||
Example:
|
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
|
channel = ctx.channel
|
||||||
@@ -397,7 +437,15 @@ class Cleanup(commands.Cog):
|
|||||||
async def cleanup_bot(
|
async def cleanup_bot(
|
||||||
self, ctx: commands.Context, number: positive_int, delete_pinned: bool = False
|
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
|
channel = ctx.channel
|
||||||
author = ctx.message.author
|
author = ctx.message.author
|
||||||
@@ -479,8 +527,19 @@ class Cleanup(commands.Cog):
|
|||||||
):
|
):
|
||||||
"""Clean up messages owned by the bot.
|
"""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.
|
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
|
channel = ctx.channel
|
||||||
author = ctx.message.author
|
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.
|
"""Deletes duplicate messages in the channel from the last X messages and keeps only one copy.
|
||||||
|
|
||||||
Defaults to 50.
|
Defaults to 50.
|
||||||
|
|
||||||
|
**Arguments:**
|
||||||
|
|
||||||
|
- `<number>` The number of messages to check for duplicates. Must be a positive integer.
|
||||||
"""
|
"""
|
||||||
msgs = []
|
msgs = []
|
||||||
spam = []
|
spam = []
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ class KickBanMixin(MixinMeta):
|
|||||||
to_query = to_query[100:]
|
to_query = to_query[100:]
|
||||||
|
|
||||||
# Call `ban_user()` method for all users that turned out to be guild members.
|
# 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:
|
try:
|
||||||
success, reason = await self.ban_user(
|
success, reason = await self.ban_user(
|
||||||
user=member, ctx=ctx, days=days, reason=reason, create_modlog_case=True
|
user=member, ctx=ctx, days=days, reason=reason, create_modlog_case=True
|
||||||
|
|||||||
@@ -18,5 +18,9 @@ class InvalidYoutubeCredentials(StreamsError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class YoutubeQuotaExceeded(StreamsError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OfflineStream(StreamsError):
|
class OfflineStream(StreamsError):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from .errors import (
|
|||||||
OfflineStream,
|
OfflineStream,
|
||||||
StreamNotFound,
|
StreamNotFound,
|
||||||
StreamsError,
|
StreamsError,
|
||||||
|
YoutubeQuotaExceeded,
|
||||||
)
|
)
|
||||||
from . import streamtypes as _streamtypes
|
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}."
|
"The YouTube API key is either invalid or has not been set. See {command}."
|
||||||
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`")
|
).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(
|
await ctx.send(
|
||||||
_("Something went wrong whilst trying to contact the stream service's API.")
|
_("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`")
|
).format(command=f"`{ctx.clean_prefix}streamset youtubekey`")
|
||||||
)
|
)
|
||||||
return
|
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(
|
await ctx.send(
|
||||||
_("Something went wrong whilst trying to contact the stream service's API.")
|
_("Something went wrong whilst trying to contact the stream service's API.")
|
||||||
)
|
)
|
||||||
@@ -845,5 +870,3 @@ class Streams(commands.Cog):
|
|||||||
def cog_unload(self):
|
def cog_unload(self):
|
||||||
if self.task:
|
if self.task:
|
||||||
self.task.cancel()
|
self.task.cancel()
|
||||||
|
|
||||||
__del__ = cog_unload
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from .errors import (
|
|||||||
InvalidTwitchCredentials,
|
InvalidTwitchCredentials,
|
||||||
InvalidYoutubeCredentials,
|
InvalidYoutubeCredentials,
|
||||||
StreamNotFound,
|
StreamNotFound,
|
||||||
|
YoutubeQuotaExceeded,
|
||||||
)
|
)
|
||||||
from redbot.core.i18n import Translator
|
from redbot.core.i18n import Translator
|
||||||
from redbot.core.utils.chat_formatting import humanize_number
|
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:
|
async with session.get(YOUTUBE_CHANNELS_ENDPOINT, params=params) as r:
|
||||||
data = await r.json()
|
data = await r.json()
|
||||||
|
|
||||||
if (
|
if "error" in data:
|
||||||
"error" in data
|
error_code = data["error"]["code"]
|
||||||
and data["error"]["code"] == 400
|
if error_code == 400 and data["error"]["errors"][0]["reason"] == "keyInvalid":
|
||||||
and data["error"]["errors"][0]["reason"] == "keyInvalid"
|
raise InvalidYoutubeCredentials()
|
||||||
):
|
elif error_code == 403 and data["error"]["errors"][0]["reason"] in (
|
||||||
raise InvalidYoutubeCredentials()
|
"dailyLimitExceeded",
|
||||||
|
"quotaExceeded",
|
||||||
|
"rateLimitExceeded",
|
||||||
|
):
|
||||||
|
raise YoutubeQuotaExceeded()
|
||||||
elif "items" in data and len(data["items"]) == 0:
|
elif "items" in data and len(data["items"]) == 0:
|
||||||
raise StreamNotFound()
|
raise StreamNotFound()
|
||||||
elif "items" in data:
|
elif "items" in data:
|
||||||
@@ -196,7 +201,7 @@ class YoutubeStream(Stream):
|
|||||||
and data["pageInfo"]["totalResults"] < 1
|
and data["pageInfo"]["totalResults"] < 1
|
||||||
):
|
):
|
||||||
raise StreamNotFound()
|
raise StreamNotFound()
|
||||||
raise APIError()
|
raise APIError(data)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<{0.__class__.__name__}: {0.name} (ID: {0.id})>".format(self)
|
return "<{0.__class__.__name__}: {0.name} (ID: {0.id})>".format(self)
|
||||||
@@ -276,7 +281,7 @@ class TwitchStream(Stream):
|
|||||||
elif r.status == 404:
|
elif r.status == 404:
|
||||||
raise StreamNotFound()
|
raise StreamNotFound()
|
||||||
else:
|
else:
|
||||||
raise APIError()
|
raise APIError(data)
|
||||||
|
|
||||||
async def fetch_id(self):
|
async def fetch_id(self):
|
||||||
header = {"Client-ID": str(self._client_id)}
|
header = {"Client-ID": str(self._client_id)}
|
||||||
@@ -298,7 +303,7 @@ class TwitchStream(Stream):
|
|||||||
elif r.status == 401:
|
elif r.status == 401:
|
||||||
raise InvalidTwitchCredentials()
|
raise InvalidTwitchCredentials()
|
||||||
else:
|
else:
|
||||||
raise APIError()
|
raise APIError(data)
|
||||||
|
|
||||||
def make_embed(self, data):
|
def make_embed(self, data):
|
||||||
is_rerun = data["type"] == "rerun"
|
is_rerun = data["type"] == "rerun"
|
||||||
@@ -347,7 +352,7 @@ class HitboxStream(Stream):
|
|||||||
# self.already_online = True
|
# self.already_online = True
|
||||||
return self.make_embed(data)
|
return self.make_embed(data)
|
||||||
|
|
||||||
raise APIError()
|
raise APIError(data)
|
||||||
|
|
||||||
def make_embed(self, data):
|
def make_embed(self, data):
|
||||||
base_url = "https://edge.sf.hitbox.tv"
|
base_url = "https://edge.sf.hitbox.tv"
|
||||||
@@ -386,7 +391,7 @@ class PicartoStream(Stream):
|
|||||||
elif r.status == 404:
|
elif r.status == 404:
|
||||||
raise StreamNotFound()
|
raise StreamNotFound()
|
||||||
else:
|
else:
|
||||||
raise APIError()
|
raise APIError(data)
|
||||||
|
|
||||||
def make_embed(self, data):
|
def make_embed(self, data):
|
||||||
avatar = rnd(
|
avatar = rnd(
|
||||||
|
|||||||
@@ -303,15 +303,27 @@ def init_events(bot, cli_flags):
|
|||||||
await ctx.send(msg, delete_after=error.retry_after)
|
await ctx.send(msg, delete_after=error.retry_after)
|
||||||
elif isinstance(error, commands.MaxConcurrencyReached):
|
elif isinstance(error, commands.MaxConcurrencyReached):
|
||||||
if error.per is commands.BucketType.default:
|
if error.per is commands.BucketType.default:
|
||||||
msg = _(
|
if error.number > 1:
|
||||||
"Too many people using this command."
|
msg = _(
|
||||||
" It can only be used {number} time(s) concurrently."
|
"Too many people using this command."
|
||||||
).format(number=error.number)
|
" 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:
|
else:
|
||||||
msg = _(
|
if error.number > 1:
|
||||||
"Too many people using this command."
|
msg = _(
|
||||||
" It can only be used {number} time(s) per {type} concurrently."
|
"Too many people using this command."
|
||||||
).format(number=error.number, type=error.per.name)
|
" 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)
|
await ctx.send(msg)
|
||||||
else:
|
else:
|
||||||
log.exception(type(error).__name__, exc_info=error)
|
log.exception(type(error).__name__, exc_info=error)
|
||||||
|
|||||||
Reference in New Issue
Block a user