mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-12-05 17:02:32 -05:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cb5394e96 | ||
|
|
2b2dbd25f7 | ||
|
|
dd4cd0eeb1 | ||
|
|
ee7b0cf730 | ||
|
|
95ef5d6348 | ||
|
|
23192b9ef6 | ||
|
|
7cd98c8a63 | ||
|
|
fca7686701 | ||
|
|
be767478f4 | ||
|
|
b3ad5d90ed | ||
|
|
fb093b7411 | ||
|
|
e4ea3110e3 | ||
|
|
79676c4f72 | ||
|
|
d61827b92c | ||
|
|
1f1f46c70f | ||
|
|
9188e4a7ec | ||
|
|
e5a780eb0c | ||
|
|
d8c85a2b15 | ||
|
|
83080bc5a2 | ||
|
|
233bfc59ac | ||
|
|
c606caf3a3 | ||
|
|
efdf69552f | ||
|
|
38531bf95c | ||
|
|
6d714db928 | ||
|
|
f8e7497695 | ||
|
|
d6ef812704 | ||
|
|
4f81bc9621 | ||
|
|
59276ce2a5 | ||
|
|
96791bd72b | ||
|
|
8756b22f5a | ||
|
|
487d256f46 | ||
|
|
fe0b6aaba4 | ||
|
|
017c8a6900 | ||
|
|
afe4af0dc2 | ||
|
|
fb8e4430ac | ||
|
|
7499f5dbfa | ||
|
|
c7b58aa65b | ||
|
|
705d9b8238 | ||
|
|
1bc650b0f9 | ||
|
|
580aeea4e2 | ||
|
|
8495824843 | ||
|
|
18bb3611fa | ||
|
|
9f7bf8d1a2 | ||
|
|
82146eda3d | ||
|
|
d75881e1a3 | ||
|
|
5be967e8c5 | ||
|
|
d9fa875d84 | ||
|
|
04f93c98d2 | ||
|
|
402f6c19e7 | ||
|
|
84b0df0437 |
7
.github/CODEOWNERS
vendored
7
.github/CODEOWNERS
vendored
@@ -22,6 +22,8 @@ redbot/core/sentry_setup.py @Kowlin @tekulvw
|
||||
redbot/core/utils/chat_formatting.py @tekulvw
|
||||
redbot/core/utils/mod.py @palmtree5
|
||||
redbot/core/utils/data_converter.py @mikeshardmind
|
||||
redbot/core/utils/antispam.py @mikeshardmind
|
||||
redbot/core/utils/tunnel.py @mikeshardmind
|
||||
|
||||
# Cogs
|
||||
redbot/cogs/admin/* @tekulvw
|
||||
@@ -40,6 +42,7 @@ redbot/cogs/modlog/* @palmtree5
|
||||
redbot/cogs/streams/* @Twentysix26 @palmtree5
|
||||
redbot/cogs/trivia/* @Tobotimus
|
||||
redbot/cogs/dataconverter/* @mikeshardmind
|
||||
redbot/cogs/reports/* @mikeshardmind
|
||||
|
||||
# Docs
|
||||
docs/* @tekulvw @palmtree5
|
||||
@@ -49,3 +52,7 @@ setup.py @tekulvw
|
||||
redbot/__init__.py @tekulvw
|
||||
redbot/__main__.py @tekulvw
|
||||
redbot/setup.py @tekulvw
|
||||
|
||||
# Others
|
||||
.travis.yml @Kowlin
|
||||
crowdin.yml @Kowlin
|
||||
|
||||
25
.github/ISSUE_TEMPLATE/command_bug.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/command_bug.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Command bugs
|
||||
|
||||
<!--
|
||||
Did you find a bug with a command? Fill out the following:
|
||||
-->
|
||||
|
||||
#### Command name
|
||||
|
||||
<!-- Replace this line with the name of the command -->
|
||||
|
||||
#### What cog is this command from?
|
||||
|
||||
<!-- Replace this line with the name of the cog -->
|
||||
|
||||
#### What were you expecting to happen?
|
||||
|
||||
<!-- Replace this line with a description of what you were expecting to happen -->
|
||||
|
||||
#### What actually happened?
|
||||
|
||||
<!-- Replace this line with a description of what actually happened. Include any error messages -->
|
||||
|
||||
#### How can we reproduce this issue?
|
||||
|
||||
<!-- Replace with numbered steps to reproduce the issue -->
|
||||
35
.github/ISSUE_TEMPLATE/feature_req.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/feature_req.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Feature request
|
||||
|
||||
<!-- This template is for feature requests. Please fill out the following: -->
|
||||
|
||||
|
||||
#### Select the type of feature you are requesting:
|
||||
|
||||
<!-- To check a box, replace the space between the [] with a x -->
|
||||
|
||||
- [ ] Cog
|
||||
- [ ] Command
|
||||
- [ ] API functionality
|
||||
|
||||
#### Describe your requested feature
|
||||
|
||||
<!--
|
||||
Feel free to describe in as much detail as you wish.
|
||||
|
||||
If you are requesting a cog to be included in core:
|
||||
- Describe the functionality in as much detail as possible
|
||||
- Include the command structure, if possible
|
||||
- Please note that unless it's something that should be core functionality,
|
||||
we reserve the right to reject your suggestion and point you to our cog
|
||||
board to request it for a third-party cog
|
||||
|
||||
If you are requesting a command:
|
||||
- Include what cog it should be in and a name for the command
|
||||
- Describe the intended functionality for the command
|
||||
- Note any restrictions on who can use the command or where it can be used
|
||||
|
||||
If you are requesting API functionality:
|
||||
- Describe what it should do
|
||||
- Note whether it is to extend existing functionality or introduce new functionality
|
||||
|
||||
-->
|
||||
21
.github/ISSUE_TEMPLATE/other_bug.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/other_bug.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Other bugs
|
||||
|
||||
<!--
|
||||
Did you find a bug with something other than a command? Fill out the following:
|
||||
-->
|
||||
|
||||
#### What were you trying to do?
|
||||
|
||||
<!-- Replace this line with a description of what you were trying to do -->
|
||||
|
||||
#### What were you expecting to happen?
|
||||
|
||||
<!-- Replace this line with a description of what you were expecting to happen -->
|
||||
|
||||
#### What actually happened?
|
||||
|
||||
<!-- Replace this line with a description of what actually happened. Include any error messages -->
|
||||
|
||||
#### How can we reproduce this issue?
|
||||
|
||||
<!-- Replace with numbered steps to reproduce the issue -->
|
||||
14
.github/PULL_REQUEST_TEMPLATE/bugfix.md
vendored
Normal file
14
.github/PULL_REQUEST_TEMPLATE/bugfix.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Bugfix request
|
||||
|
||||
<!--
|
||||
To be used for pull requests that fix a bug
|
||||
-->
|
||||
|
||||
#### Describe the bug being fixed
|
||||
|
||||
<!--
|
||||
If an issue exists for the bug, mention
|
||||
that this PR fixes that issue
|
||||
-->
|
||||
|
||||
#### Anything we need to know about this fix?
|
||||
20
.github/PULL_REQUEST_TEMPLATE/enhancement.md
vendored
Normal file
20
.github/PULL_REQUEST_TEMPLATE/enhancement.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Enhancement request
|
||||
|
||||
<!--
|
||||
To be used for PRs which enhance existing features
|
||||
-->
|
||||
|
||||
#### Describe the enhancement
|
||||
|
||||
<!--
|
||||
Describe what your changes do.
|
||||
If adding commands, describe any restrictions on their usage.
|
||||
- For example, who can use the command? Where can it be used?
|
||||
-->
|
||||
|
||||
#### Does this enhancement break existing functionality?
|
||||
|
||||
<!-- To check a box, replace the space between the [] with a x -->
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
21
.github/PULL_REQUEST_TEMPLATE/new_feature.md
vendored
Normal file
21
.github/PULL_REQUEST_TEMPLATE/new_feature.md
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# New feature addition
|
||||
|
||||
<!--
|
||||
To be used for PRs which add a new feature
|
||||
Examples of this include new APIs, new core cogs, etc.
|
||||
-->
|
||||
|
||||
#### What type of feature is this?
|
||||
|
||||
<!-- To check a box, replace the space between the [] with a x -->
|
||||
|
||||
- [ ] New core cog
|
||||
- [ ] New API
|
||||
- [ ] Other
|
||||
|
||||
#### Describe the feature
|
||||
|
||||
<!--
|
||||
If you are adding a cog, describe its commands in detail (functionality, usage restrictions, etc).
|
||||
If the new feature introduces new requirements, please try to explain why they are necessary.
|
||||
-->
|
||||
16
.github/PULL_REQUEST_TEMPLATE/release.md
vendored
Normal file
16
.github/PULL_REQUEST_TEMPLATE/release.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# New release
|
||||
|
||||
<!--
|
||||
To be used by collaborators for doing releases.
|
||||
Most contributors will not need to use this.
|
||||
-->
|
||||
|
||||
#### Version
|
||||
|
||||
|
||||
|
||||
#### Has a draft release been created for this?
|
||||
|
||||
- [ ] Yes
|
||||
- [ ] No
|
||||
|
||||
5
.github/PULL_REQUEST_TEMPLATE/translations.md
vendored
Normal file
5
.github/PULL_REQUEST_TEMPLATE/translations.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Translations update
|
||||
|
||||
<!--
|
||||
Used for PRs updating translations from Crowdin
|
||||
-->
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -156,3 +156,5 @@ ENV/
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
# pytest
|
||||
.pytest_cache/
|
||||
|
||||
34
.travis.yml
34
.travis.yml
@@ -17,16 +17,11 @@ script:
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: Deployment
|
||||
- stage: PyPi Deployment
|
||||
if: tag IS present
|
||||
python: 3.5.3
|
||||
env:
|
||||
- DEPLOYING=true
|
||||
before_deployment:
|
||||
- curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
|
||||
- echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y crowdin
|
||||
deploy:
|
||||
- provider: pypi
|
||||
user: Red-DiscordBot
|
||||
@@ -38,11 +33,22 @@ jobs:
|
||||
branch: V3/develop
|
||||
python: 3.5.3
|
||||
tags: true
|
||||
- provider: script
|
||||
script: python3 ./generate_strings.py
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: Cog-Creators/Red-DiscordBot
|
||||
branch: V3/develop
|
||||
python: 3.5.3
|
||||
tags: true
|
||||
- stage: Crowdin Deployment
|
||||
if: tag IS present
|
||||
python: 3.5.3
|
||||
env:
|
||||
- DEPLOYING=true
|
||||
before_deployment:
|
||||
- curl https://artifacts.crowdin.com/repo/GPG-KEY-crowdin | sudo apt-key add -
|
||||
- echo "deb https://artifacts.crowdin.com/repo/deb/ /" | sudo tee -a /etc/apt/sources.list
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y crowdin
|
||||
deploy:
|
||||
- provider: script
|
||||
script: python3 ./generate_strings.py
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: Cog-Creators/Red-DiscordBot
|
||||
branch: V3/develop
|
||||
python: 3.5.3
|
||||
tags: true
|
||||
|
||||
48
docs/autostart_systemd.rst
Normal file
48
docs/autostart_systemd.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
.. systemd service guide
|
||||
|
||||
==========================
|
||||
Setting up auto-restart using systemd on Linux
|
||||
==========================
|
||||
|
||||
---------------------------
|
||||
Creating the service file
|
||||
---------------------------
|
||||
|
||||
Create the new service file:
|
||||
|
||||
:code:`sudo nano /etc/systemd/system/red@.service`
|
||||
|
||||
Paste the following and replace all instances of :code:`username` with the username your bot is running under (hopefully not root):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[Unit]
|
||||
Description=%I redbot
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/home/username/.local/bin/redbot %I --no-prompt
|
||||
User=username
|
||||
Group=username
|
||||
Type=idle
|
||||
Restart=always
|
||||
RestartSec=15
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Save and exit :code:`ctrl + O; enter; ctrl + x`
|
||||
|
||||
---------------------------
|
||||
Starting and enabling the service
|
||||
---------------------------
|
||||
|
||||
To start the bot, run the service and add the instance name after the **@**:
|
||||
|
||||
:code:`sudo systemctl start red@instancename`
|
||||
|
||||
To set the bot to start on boot, you must enable the service, again adding the instance name after the **@**:
|
||||
|
||||
:code:`sudo systemctl enable red@instancename`
|
||||
|
||||
.. note:: This same file can be used to start as many instances of the bot as you wish, without creating more service files, just start and enable more services and add any bot instance name after the **@**
|
||||
@@ -62,10 +62,11 @@ author = 'Cog Creators'
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
from redbot.core import __version__
|
||||
# The short X.Y version.
|
||||
version = '3.0.0b11'
|
||||
version = __version__
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.0.0b11'
|
||||
release = __version__
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -16,6 +16,12 @@ Embed Helpers
|
||||
.. automodule:: redbot.core.utils.embed
|
||||
:members:
|
||||
|
||||
Menu Helpers
|
||||
============
|
||||
|
||||
.. automodule:: redbot.core.utils.menus
|
||||
:members:
|
||||
|
||||
Mod Helpers
|
||||
===========
|
||||
|
||||
@@ -26,4 +32,10 @@ V2 Data Conversion
|
||||
==================
|
||||
|
||||
.. automodule:: redbot.core.utils.data_converter
|
||||
:members: DataConverter
|
||||
:members: DataConverter
|
||||
|
||||
Tunnel
|
||||
======
|
||||
|
||||
.. automodule:: redbot.core.utils.tunnel
|
||||
:members: Tunnel
|
||||
@@ -90,6 +90,6 @@ have successfully created a cog!
|
||||
Additional resources
|
||||
--------------------
|
||||
|
||||
Be sure to check out the `migration guide </guide_migration>`_ for some resources
|
||||
Be sure to check out the :doc:`/guide_migration` for some resources
|
||||
on developing cogs for V3. This will also cover differences between V2 and V3 for
|
||||
those who developed cogs for V2.
|
||||
|
||||
@@ -82,7 +82,7 @@ Here's an example of that in use:
|
||||
need to be awaited
|
||||
"""
|
||||
|
||||
# First we give the converter out cog's Config instance.
|
||||
# First we give the converter our cog's Config instance.
|
||||
converter = dc(self.config)
|
||||
|
||||
# next we design a way to get all of the data into Config's internal
|
||||
|
||||
@@ -15,8 +15,10 @@ Welcome to Red - Discord Bot's documentation!
|
||||
install_ubuntu
|
||||
install_debian
|
||||
install_centos
|
||||
install_arch
|
||||
install_raspbian
|
||||
cog_dataconverter
|
||||
autostart_systemd
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
55
docs/install_arch.rst
Normal file
55
docs/install_arch.rst
Normal file
@@ -0,0 +1,55 @@
|
||||
.. arch install guide
|
||||
|
||||
==============================
|
||||
Installing Red on Arch Linux
|
||||
==============================
|
||||
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, make a new one.
|
||||
|
||||
:code:`https://wiki.archlinux.org/index.php/Users_and_groups`
|
||||
|
||||
-------------------------------
|
||||
Installing the pre-requirements
|
||||
-------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo pacman -Syu python-pip git base-devel jre8-openjdk
|
||||
|
||||
------------------
|
||||
Installing the bot
|
||||
------------------
|
||||
|
||||
To install without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
To install with audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
|
||||
|
||||
To install the development version (without audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
|
||||
|
||||
To install the development version (with audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
|
||||
|
||||
------------------------
|
||||
Setting up your instance
|
||||
------------------------
|
||||
|
||||
Run :code:`redbot-setup` and follow the prompts. It will ask first for where you want to
|
||||
store the data (the default is :code:`~/.local/share/Red-DiscordBot`) and will then ask
|
||||
for confirmation of that selection. Next, it will ask you to choose your storage backend
|
||||
(the default here is JSON). It will then ask for a name for your instance. This can be
|
||||
anything as long as it does not contain spaces; however, keep in mind that this is the
|
||||
name you will use to run your bot, and so it should be something you can remember.
|
||||
|
||||
-----------
|
||||
Running Red
|
||||
-----------
|
||||
|
||||
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
|
||||
your token and a prefix.
|
||||
@@ -4,6 +4,8 @@
|
||||
Installing Red on CentOS 7
|
||||
==========================
|
||||
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Step_by_Step_Guide/s1-starting-create-account.html>`_.
|
||||
|
||||
---------------------------
|
||||
Installing pre-requirements
|
||||
---------------------------
|
||||
@@ -12,7 +14,7 @@ Installing pre-requirements
|
||||
|
||||
yum -y groupinstall development
|
||||
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
|
||||
yum -y install yum-utils wget which python35u python35u-pip python35u-devel openssl-devel libffi-devel git opus-devel java-1.8.0-openjdk
|
||||
yum -y install yum-utils wget which python35u python35u-pip python35u-devel openssl-devel libffi-devel git java-1.8.0-openjdk
|
||||
sh -c "$(wget https://gist.githubusercontent.com/mustafaturan/7053900/raw/27f4c8bad3ee2bb0027a1a52dc8501bf1e53b270/latest-ffmpeg-centos6.sh -O -)"
|
||||
|
||||
--------------
|
||||
@@ -21,19 +23,19 @@ Installing Red
|
||||
|
||||
Without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
With audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
|
||||
|
||||
To install the development version (without audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
|
||||
|
||||
To install the development version (with audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
|
||||
|
||||
----------------------
|
||||
Setting up an instance
|
||||
@@ -51,4 +53,4 @@ Running Red
|
||||
-----------
|
||||
|
||||
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
|
||||
your token and a prefix.
|
||||
your token and a prefix.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Installing Red on Debian Stretch
|
||||
================================
|
||||
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, make a new one.
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://manpages.debian.org/stretch/adduser/adduser.8.en.html>`_.
|
||||
|
||||
---------------------------
|
||||
Installing pre-requirements
|
||||
@@ -14,7 +14,7 @@ Installing pre-requirements
|
||||
|
||||
echo "deb http://httpredir.debian.org/debian stretch-backports main contrib non-free" >> /etc/apt/sources.list
|
||||
apt-get update
|
||||
apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git ffmpeg libopus-dev unzip default-jre -y
|
||||
apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
|
||||
|
||||
------------------
|
||||
Installing the bot
|
||||
@@ -52,4 +52,4 @@ Running Red
|
||||
-----------
|
||||
|
||||
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
|
||||
your token and a prefix.
|
||||
your token and a prefix.
|
||||
|
||||
@@ -15,8 +15,6 @@ Installing pre-requirements
|
||||
* After the installation, install the required packages by pasting the commands and pressing enter, one-by-one:
|
||||
* :code:`brew install python3 --with-brewed-openssl`
|
||||
* :code:`brew install git`
|
||||
* :code:`brew install ffmpeg --with-ffplay`
|
||||
* :code:`brew install opus`
|
||||
* :code:`brew tap caskroom/versions`
|
||||
* :code:`brew cask install java8`
|
||||
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
Installing Red on Raspbian Stretch
|
||||
==================================
|
||||
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <https://www.raspberrypi.org/documentation/linux/usage/users.md>`_.
|
||||
|
||||
---------------------------
|
||||
Installing pre-requirements
|
||||
---------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git libav-tools libopus-dev unzip default-jre -y
|
||||
sudo apt-get install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
|
||||
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
@@ -18,19 +21,19 @@ Installing Red
|
||||
|
||||
Without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
With audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
|
||||
|
||||
To install the development version (without audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
|
||||
|
||||
To install the development version (with audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
|
||||
|
||||
----------------------
|
||||
Setting up an instance
|
||||
@@ -50,4 +53,4 @@ Running Red
|
||||
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
|
||||
your token and a prefix.
|
||||
|
||||
.. warning:: Audio will not work on Raspberry Pi's **below** 2B. This is a CPU problem and *cannot* be fixed.
|
||||
.. warning:: Audio will not work on Raspberry Pi's **below** 2B. This is a CPU problem and *cannot* be fixed.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Installing Red on Ubuntu 16.04
|
||||
==============================
|
||||
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, make a new one.
|
||||
.. warning:: For safety reasons, DO NOT install Red with a root user. Instead, `make a new one <http://manpages.ubuntu.com/manpages/artful/man8/adduser.8.html>`_.
|
||||
|
||||
-------------------------------
|
||||
Installing the pre-requirements
|
||||
@@ -12,7 +12,8 @@ Installing the pre-requirements
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git ffmpeg libopus-dev unzip default-jre -y
|
||||
sudo apt install python3.5-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
|
||||
|
||||
|
||||
------------------
|
||||
Installing the bot
|
||||
@@ -20,19 +21,19 @@ Installing the bot
|
||||
|
||||
To install without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
To install with audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice] --user`
|
||||
|
||||
To install the development version (without audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot --user`
|
||||
|
||||
To install the development version (with audio):
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
|
||||
:code:`pip3 install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice] --user`
|
||||
|
||||
------------------------
|
||||
Setting up your instance
|
||||
@@ -50,4 +51,4 @@ Running Red
|
||||
-----------
|
||||
|
||||
Run :code:`redbot <your instance name>` and run through the initial setup. This will ask for
|
||||
your token and a prefix.
|
||||
your token and a prefix.
|
||||
|
||||
@@ -375,7 +375,7 @@ class Admin:
|
||||
@checks.is_owner()
|
||||
async def serverlock(self, ctx: commands.Context):
|
||||
"""
|
||||
Locks a bot to it's current servers only.
|
||||
Locks a bot to its current servers only.
|
||||
"""
|
||||
serverlocked = await self.conf.serverlocked()
|
||||
await self.conf.serverlocked.set(not serverlocked)
|
||||
|
||||
@@ -65,7 +65,7 @@ class Announcer:
|
||||
try:
|
||||
await channel.send(self.message)
|
||||
except discord.Forbidden:
|
||||
await bot_owner.send("I could not announce to guild: {}".format(
|
||||
await bot_owner.send("I could not announce to server: {}".format(
|
||||
g.id
|
||||
))
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Arabic\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Bulgarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Danish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-27 01:49-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: German\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Greek\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Pirate English\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Finnish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Hungarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Indonesian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:26-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Korean\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: LOLCAT\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Dutch\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Polish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Swedish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Arabic\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Bulgarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Danish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-27 01:49-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: German\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Greek\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Pirate English\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Finnish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Hungarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Indonesian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:26-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Korean\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: LOLCAT\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Dutch\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Polish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Swedish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -2,7 +2,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
from pathlib import Path
|
||||
from aiohttp import ClientSession
|
||||
import shutil
|
||||
import asyncio
|
||||
|
||||
from .audio import Audio
|
||||
from .manager import start_lavalink_server
|
||||
from discord.ext import commands
|
||||
from redbot.core.data_manager import cog_data_path
|
||||
import redbot.core
|
||||
|
||||
LAVALINK_BUILD = 3112
|
||||
LAVALINK_BUILD_URL = (
|
||||
"https://ci.fredboat.com/repository/download/"
|
||||
"Lavalink_Build/{}:id/Lavalink.jar?guest=1"
|
||||
).format(LAVALINK_BUILD)
|
||||
LAVALINK_DOWNLOAD_URL = (
|
||||
"https://github.com/Cog-Creators/Red-DiscordBot/"
|
||||
"releases/download/{}/Lavalink.jar"
|
||||
).format(redbot.core.__version__)
|
||||
|
||||
LAVALINK_DOWNLOAD_DIR = cog_data_path(raw_name="Audio")
|
||||
LAVALINK_JAR_FILE = LAVALINK_DOWNLOAD_DIR / "Lavalink.jar"
|
||||
@@ -23,7 +22,7 @@ BUNDLED_APP_YML_FILE = Path(__file__).parent / "application.yml"
|
||||
|
||||
async def download_lavalink(session):
|
||||
with LAVALINK_JAR_FILE.open(mode='wb') as f:
|
||||
async with session.get(LAVALINK_BUILD_URL) as resp:
|
||||
async with session.get(LAVALINK_DOWNLOAD_URL) as resp:
|
||||
while True:
|
||||
chunk = await resp.content.read(512)
|
||||
if not chunk:
|
||||
@@ -33,24 +32,25 @@ async def download_lavalink(session):
|
||||
|
||||
async def maybe_download_lavalink(loop, cog):
|
||||
jar_exists = LAVALINK_JAR_FILE.exists()
|
||||
current_build = await cog.config.current_build()
|
||||
current_build = redbot.core.VersionInfo(*await cog.config.current_build())
|
||||
|
||||
if not jar_exists or current_build < LAVALINK_BUILD:
|
||||
session = ClientSession(loop=loop)
|
||||
|
||||
if not jar_exists or current_build < redbot.core.version_info:
|
||||
LAVALINK_DOWNLOAD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
with ClientSession(loop=loop) as session:
|
||||
await download_lavalink(session)
|
||||
await cog.config.current_build.set(LAVALINK_BUILD)
|
||||
await download_lavalink(session)
|
||||
await cog.config.current_build.set(redbot.core.version_info.to_json())
|
||||
|
||||
session.close()
|
||||
|
||||
shutil.copyfile(str(BUNDLED_APP_YML_FILE), str(APP_YML_FILE))
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot):
|
||||
cog = Audio(bot)
|
||||
await maybe_download_lavalink(bot.loop, cog)
|
||||
await start_lavalink_server(bot.loop)
|
||||
if not await cog.config.use_external_lavalink():
|
||||
await maybe_download_lavalink(bot.loop, cog)
|
||||
await start_lavalink_server(bot.loop)
|
||||
|
||||
async def _finish():
|
||||
await cog.init_config()
|
||||
bot.add_cog(cog)
|
||||
|
||||
bot.loop.create_task(_finish())
|
||||
bot.add_cog(cog)
|
||||
bot.loop.create_task(cog.init_config())
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import datetime
|
||||
import discord
|
||||
import heapq
|
||||
import lavalink
|
||||
import math
|
||||
import re
|
||||
import redbot.core
|
||||
from discord.ext import commands
|
||||
from redbot.core import Config, checks, bank
|
||||
|
||||
from .manager import shutdown_lavalink_server
|
||||
|
||||
__version__ = "0.0.4"
|
||||
__version__ = "0.0.5a"
|
||||
__author__ = ["aikaterna", "billy/bollo/ati"]
|
||||
|
||||
|
||||
class Audio:
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
self.config = Config.get_conf(self, 2711759128, force_registration=True)
|
||||
self.config = Config.get_conf(self, 2711759130, force_registration=True)
|
||||
|
||||
default_global = {
|
||||
"host": 'localhost',
|
||||
@@ -24,7 +27,8 @@ class Audio:
|
||||
"ws_port": '2332',
|
||||
"password": 'youshallnotpass',
|
||||
"status": False,
|
||||
"current_build": 0
|
||||
"current_build": [3, 0, 0, 'alpha', 0],
|
||||
"use_external_lavalink": False
|
||||
}
|
||||
|
||||
default_guild = {
|
||||
@@ -32,6 +36,7 @@ class Audio:
|
||||
"dj_role": None,
|
||||
"jukebox": False,
|
||||
"jukebox_price": 0,
|
||||
"playlists": {},
|
||||
"notify": False,
|
||||
"repeat": False,
|
||||
"shuffle": False,
|
||||
@@ -43,6 +48,7 @@ class Audio:
|
||||
self.config.register_guild(**default_guild)
|
||||
self.config.register_global(**default_global)
|
||||
self.skip_votes = {}
|
||||
self.session = aiohttp.ClientSession()
|
||||
|
||||
async def init_config(self):
|
||||
host = await self.config.host()
|
||||
@@ -93,10 +99,11 @@ class Audio:
|
||||
await self.bot.change_presence(activity=None)
|
||||
if playing_servers == 1:
|
||||
await self.bot.change_presence(activity=discord.Activity(name=get_single_title,
|
||||
type=discord.ActivityType.listening))
|
||||
type=discord.ActivityType.listening))
|
||||
if playing_servers > 1:
|
||||
await self.bot.change_presence(activity=discord.Activity(name='music in {} servers'.format(playing_servers),
|
||||
type=discord.ActivityType.playing))
|
||||
await self.bot.change_presence(
|
||||
activity=discord.Activity(name='music in {} servers'.format(playing_servers),
|
||||
type=discord.ActivityType.playing))
|
||||
|
||||
if event_type == lavalink.LavalinkEvents.QUEUE_END and notify:
|
||||
notify_channel = player.fetch('channel')
|
||||
@@ -110,10 +117,22 @@ class Audio:
|
||||
await self.bot.change_presence(activity=None)
|
||||
if playing_servers == 1:
|
||||
await self.bot.change_presence(activity=discord.Activity(name=get_single_title,
|
||||
type=discord.ActivityType.listening))
|
||||
type=discord.ActivityType.listening))
|
||||
if playing_servers > 1:
|
||||
await self.bot.change_presence(activity=discord.Activity(name='music in {} servers'.format(playing_servers),
|
||||
type=discord.ActivityType.playing))
|
||||
await self.bot.change_presence(
|
||||
activity=discord.Activity(name='music in {} servers'.format(playing_servers),
|
||||
type=discord.ActivityType.playing))
|
||||
|
||||
if event_type == lavalink.LavalinkEvents.TRACK_EXCEPTION:
|
||||
message_channel = player.fetch('channel')
|
||||
if message_channel:
|
||||
message_channel = self.bot.get_channel(message_channel)
|
||||
embed = discord.Embed(colour=message_channel.guild.me.top_role.colour, title='Track Error',
|
||||
description='{}\n**[{}]({})**'.format(extra, player.current.title,
|
||||
player.current.uri))
|
||||
embed.set_footer(text='Skipping...')
|
||||
await message_channel.send(embed=embed)
|
||||
await player.skip()
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@@ -129,7 +148,6 @@ class Audio:
|
||||
dj_role_id = await self.config.guild(ctx.guild).dj_role()
|
||||
if dj_role_id is None:
|
||||
await self._embed_msg(ctx, 'Please set a role to use with DJ mode. Enter the role name now.')
|
||||
|
||||
def check(m):
|
||||
return m.author == ctx.author
|
||||
try:
|
||||
@@ -158,8 +176,6 @@ class Audio:
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
async def jukebox(self, ctx, price: int):
|
||||
"""Set a price for queueing songs for non-mods. 0 to disable."""
|
||||
jukebox = await self.config.guild(ctx.guild).jukebox()
|
||||
jukebox_price = await self.config.guild(ctx.guild).jukebox_price()
|
||||
if price < 0:
|
||||
return await self._embed_msg(ctx, 'Can\'t be less than zero.')
|
||||
if price == 0:
|
||||
@@ -168,7 +184,7 @@ class Audio:
|
||||
else:
|
||||
jukebox = True
|
||||
await self._embed_msg(ctx, 'Track queueing command price set to {} {}.'.format(
|
||||
price, await bank.get_currency_name(ctx.guild)))
|
||||
price, await bank.get_currency_name(ctx.guild)))
|
||||
|
||||
await self.config.guild(ctx.guild).jukebox_price.set(price)
|
||||
await self.config.guild(ctx.guild).jukebox.set(jukebox)
|
||||
@@ -185,14 +201,16 @@ class Audio:
|
||||
async def settings(self, ctx):
|
||||
"""Show the current settings."""
|
||||
data = await self.config.guild(ctx.guild).all()
|
||||
global_data = await self.config.all()
|
||||
dj_role_obj = discord.utils.get(ctx.guild.roles, id=data['dj_role'])
|
||||
dj_enabled = data['dj_enabled']
|
||||
jukebox = data['jukebox']
|
||||
jukebox_price = data['jukebox_price']
|
||||
status = await self.config.status()
|
||||
jarbuild = redbot.core.__version__
|
||||
|
||||
vote_percent = data['vote_percent']
|
||||
msg = ('```ini\n'
|
||||
'----Guild Settings----\n')
|
||||
'----Server Settings----\n')
|
||||
if dj_enabled:
|
||||
msg += 'DJ Role: [{}]\n'.format(dj_role_obj.name)
|
||||
if jukebox:
|
||||
@@ -201,12 +219,14 @@ class Audio:
|
||||
msg += ('Repeat: [{repeat}]\n'
|
||||
'Shuffle: [{shuffle}]\n'
|
||||
'Song notify msgs: [{notify}]\n'
|
||||
'Songs as status: [{0}]\n'.format(status, **data))
|
||||
'Songs as status: [{status}]\n'.format(**global_data, **data))
|
||||
if vote_percent > 0:
|
||||
msg += ('Vote skip: [{vote_enabled}]\n'
|
||||
'Skip percentage: [{vote_percent}%]\n').format(**data)
|
||||
msg += ('---Lavalink Settings---\n'
|
||||
'Cog version: {}\n```'.format(__version__))
|
||||
'Cog version: [{}]\n'
|
||||
'Jar build: [{}]\n'
|
||||
'External server: [{use_external_lavalink}]```').format(__version__, jarbuild, **global_data)
|
||||
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, description=msg)
|
||||
return await ctx.send(embed=embed)
|
||||
@@ -248,10 +268,10 @@ class Audio:
|
||||
connect_dur = self._dynamic_time(int((datetime.datetime.utcnow() - connect_start).total_seconds()))
|
||||
try:
|
||||
server_list.append('{} [`{}`]: **[{}]({})**'.format(p.channel.guild.name, connect_dur,
|
||||
p.current.title, p.current.uri))
|
||||
p.current.title, p.current.uri))
|
||||
except AttributeError:
|
||||
server_list.append('{} [`{}`]: **{}**'.format(p.channel.guild.name, connect_dur,
|
||||
'Nothing playing.'))
|
||||
'Nothing playing.'))
|
||||
if server_num == 0:
|
||||
servers = 'Not connected anywhere.'
|
||||
else:
|
||||
@@ -268,7 +288,7 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to bump a song.')
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
@@ -290,7 +310,7 @@ class Audio:
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to disconnect.')
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'There are other people listening to music.')
|
||||
else:
|
||||
await lavalink.get_player(ctx.guild.id).stop()
|
||||
@@ -336,7 +356,7 @@ class Audio:
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
vote_enabled = await self.config.guild(ctx.guild).vote_enabled()
|
||||
if dj_enabled or vote_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return
|
||||
|
||||
if player.current:
|
||||
@@ -345,6 +365,7 @@ class Audio:
|
||||
|
||||
def check(r, u):
|
||||
return r.message.id == message.id and u == ctx.message.author
|
||||
|
||||
try:
|
||||
(r, u) = await self.bot.wait_for('reaction_add', check=check, timeout=10.0)
|
||||
except asyncio.TimeoutError:
|
||||
@@ -372,14 +393,14 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to pause the music.')
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to pause songs.')
|
||||
|
||||
command = ctx.invoked_with
|
||||
if player.current and not player.paused and command == 'pause':
|
||||
if player.current and not player.paused and command != 'resume':
|
||||
await player.pause()
|
||||
embed = discord.Embed(
|
||||
colour=ctx.guild.me.top_role.colour, title='Track Paused',
|
||||
@@ -390,7 +411,7 @@ class Audio:
|
||||
)
|
||||
return await ctx.send(embed=embed)
|
||||
|
||||
if player.paused and command == 'resume':
|
||||
if player.paused and command != 'pause':
|
||||
await player.pause(False)
|
||||
embed = discord.Embed(
|
||||
colour=ctx.guild.me.top_role.colour,
|
||||
@@ -448,7 +469,7 @@ class Audio:
|
||||
description=queue_user_list)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.command(aliases=['p'])
|
||||
@commands.command()
|
||||
async def play(self, ctx, *, query):
|
||||
"""Play a URL or search for a song."""
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
@@ -464,16 +485,18 @@ class Audio:
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to queue songs.')
|
||||
if not await self._currency_check(ctx, jukebox_price):
|
||||
return
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
player.store('channel', ctx.channel.id)
|
||||
player.store('guild', ctx.guild.id)
|
||||
await self._data_check(ctx)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to use the play command.')
|
||||
if not await self._currency_check(ctx, jukebox_price):
|
||||
return
|
||||
|
||||
if not query:
|
||||
return await self._embed_msg(ctx, 'No songs to play.')
|
||||
query = query.strip('<>')
|
||||
if not query.startswith('http'):
|
||||
query = 'ytsearch:{}'.format(query)
|
||||
@@ -484,6 +507,7 @@ class Audio:
|
||||
|
||||
queue_duration = await self._queue_duration(ctx)
|
||||
queue_total_duration = lavalink.utils.format_time(queue_duration)
|
||||
before_queue_length = len(player.queue) + 1
|
||||
|
||||
if 'list' in query and 'ytsearch:' not in query:
|
||||
for track in tracks:
|
||||
@@ -491,7 +515,8 @@ class Audio:
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Playlist Enqueued',
|
||||
description='Added {} tracks to the queue.'.format(len(tracks)))
|
||||
if not shuffle and queue_duration > 0:
|
||||
embed.set_footer(text='{} until start of playlist playback'.format(queue_total_duration))
|
||||
embed.set_footer(text='{} until start of playlist playback: starts at #{} in queue'.format(
|
||||
queue_total_duration, before_queue_length))
|
||||
if not player.current:
|
||||
await player.play()
|
||||
else:
|
||||
@@ -500,11 +525,329 @@ class Audio:
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Track Enqueued',
|
||||
description='**[{}]({})**'.format(single_track.title, single_track.uri))
|
||||
if not shuffle and queue_duration > 0:
|
||||
embed.set_footer(text='{} until track playback'.format(queue_total_duration))
|
||||
embed.set_footer(text='{} until track playback: #{} in queue'.format(
|
||||
queue_total_duration, before_queue_length))
|
||||
if not player.current:
|
||||
await player.play()
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
async def playlist(self, ctx):
|
||||
"""Playlist configuration options."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help()
|
||||
|
||||
@playlist.command(name='append')
|
||||
async def _playlist_append(self, ctx, playlist_name, *url):
|
||||
"""Add a song URL, playlist link, or quick search to the end of a saved playlist."""
|
||||
if not await self._playlist_check(ctx):
|
||||
return
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
try:
|
||||
if (playlists[playlist_name]['author'] != ctx.author.id and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You are not the author of that playlist.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
to_append = await self._playlist_tracks(ctx, player, url)
|
||||
if not to_append:
|
||||
return
|
||||
track_list = playlists[playlist_name]['tracks']
|
||||
if track_list:
|
||||
playlists[playlist_name]['tracks'] = track_list + to_append
|
||||
else:
|
||||
playlists[playlist_name]['tracks'] = to_append
|
||||
except KeyError:
|
||||
return await self._embed_msg(ctx, 'No playlist with that name.')
|
||||
if playlists[playlist_name]['playlist_url'] is not None:
|
||||
playlists[playlist_name]['playlist_url'] = None
|
||||
if len(to_append) == 1:
|
||||
track_title = to_append[0]['info']['title']
|
||||
return await self._embed_msg(ctx, '{} appended to {}.'.format(track_title, playlist_name))
|
||||
await self._embed_msg(ctx, '{} tracks appended to {}.'.format(len(to_append), playlist_name))
|
||||
|
||||
@playlist.command(name='create')
|
||||
async def _playlist_create(self, ctx, playlist_name):
|
||||
"""Create an empty playlist."""
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to save playlists.')
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
if playlist_name in playlists:
|
||||
return await self._embed_msg(ctx, 'Playlist name already exists, try again with a different name.')
|
||||
playlist_list = self._to_json(ctx, None, None)
|
||||
playlists[playlist_name] = playlist_list
|
||||
await self._embed_msg(ctx, 'Empty playlist {} created.'.format(playlist_name))
|
||||
|
||||
@playlist.command(name='delete')
|
||||
async def _playlist_delete(self, ctx, playlist_name):
|
||||
"""Delete a saved playlist."""
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
try:
|
||||
if (playlists[playlist_name]['author'] != ctx.author.id and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You are not the author of that playlist.')
|
||||
del playlists[playlist_name]
|
||||
except KeyError:
|
||||
return await self._embed_msg(ctx, 'No playlist with that name.')
|
||||
await self._embed_msg(ctx, '{} playlist deleted.'.format(playlist_name))
|
||||
|
||||
@playlist.command(name='info')
|
||||
async def _playlist_info(self, ctx, playlist_name):
|
||||
"""Retrieve information from a saved playlist."""
|
||||
playlists = await self.config.guild(ctx.guild).playlists.get_raw()
|
||||
try:
|
||||
author_id = playlists[playlist_name]['author']
|
||||
except KeyError:
|
||||
return await self._embed_msg(ctx, 'No playlist with that name.')
|
||||
author_obj = self.bot.get_user(author_id)
|
||||
playlist_url = playlists[playlist_name]['playlist_url']
|
||||
try:
|
||||
track_len = len(playlists[playlist_name]['tracks'])
|
||||
except TypeError:
|
||||
track_len = 0
|
||||
if playlist_url is None:
|
||||
playlist_url = '**Custom playlist.**'
|
||||
else:
|
||||
playlist_url = 'URL: <{}>'.format(playlist_url)
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Playlist info for {}:'.format(playlist_name),
|
||||
description='Author: **{}**\n{}'.format(author_obj,
|
||||
playlist_url))
|
||||
embed.set_footer(text='{} track(s)'.format(track_len))
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@playlist.command(name='list')
|
||||
async def _playlist_list(self, ctx):
|
||||
"""List saved playlists."""
|
||||
playlists = await self.config.guild(ctx.guild).playlists.get_raw()
|
||||
playlist_list = []
|
||||
for playlist_name in playlists:
|
||||
playlist_list.append(playlist_name)
|
||||
abc_names = sorted(playlist_list, key=str.lower)
|
||||
all_playlists = ', '.join(abc_names)
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Playlists for {}:'.format(ctx.guild.name),
|
||||
description=all_playlists)
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@playlist.command(name='queue')
|
||||
async def _playlist_queue(self, ctx, playlist_name=None):
|
||||
"""Save the queue to a playlist."""
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to save playlists.')
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
if playlist_name in playlists:
|
||||
return await self._embed_msg(ctx, 'Playlist name already exists, try again with a different name.')
|
||||
if not self._player_check(ctx):
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
tracklist = []
|
||||
np_song = self._track_creator(player, 'np')
|
||||
tracklist.append(np_song)
|
||||
for track in player.queue:
|
||||
queue_idx = player.queue.index(track)
|
||||
track_obj = self._track_creator(player, queue_idx)
|
||||
tracklist.append(track_obj)
|
||||
if not playlist_name:
|
||||
await self._embed_msg(ctx, 'Please enter a name for this playlist.')
|
||||
def check(m):
|
||||
return m.author == ctx.author
|
||||
try:
|
||||
playlist_name_msg = await ctx.bot.wait_for('message', timeout=15.0, check=check)
|
||||
playlist_name = str(playlist_name_msg.content)
|
||||
if len(playlist_name) > 20:
|
||||
return await self._embed_msg(ctx, 'Try the command again with a shorter name.')
|
||||
if playlist_name in playlists:
|
||||
return await self._embed_msg(ctx, 'Playlist name already exists, try again with a different name.')
|
||||
except asyncio.TimeoutError:
|
||||
return await self._embed_msg(ctx, 'No playlist name entered, try again later.')
|
||||
playlist_list = self._to_json(ctx, None, tracklist)
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
playlists[playlist_name] = playlist_list
|
||||
await self._embed_msg(ctx, 'Playlist {} saved from current queue: {} tracks added.'.format(
|
||||
playlist_name, len(tracklist)))
|
||||
|
||||
@playlist.command(name='remove')
|
||||
async def _playlist_remove(self, ctx, playlist_name, url):
|
||||
"""Remove a song from a playlist by url."""
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
try:
|
||||
if (playlists[playlist_name]['author'] != ctx.author.id and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You are not the author of that playlist.')
|
||||
except KeyError:
|
||||
return await self._embed_msg(ctx, 'No playlist with that name.')
|
||||
track_list = playlists[playlist_name]['tracks']
|
||||
clean_list = [track for track in track_list if not url == track['info']['uri']]
|
||||
if len(playlists[playlist_name]['tracks']) == len(clean_list):
|
||||
return await self._embed_msg(ctx, 'URL not in playlist.')
|
||||
del_count = len(playlists[playlist_name]['tracks']) - len(clean_list)
|
||||
if not clean_list:
|
||||
del playlists[playlist_name]
|
||||
return await self._embed_msg(ctx, 'No songs left, removing playlist.')
|
||||
playlists[playlist_name]['tracks'] = clean_list
|
||||
if playlists[playlist_name]['playlist_url'] is not None:
|
||||
playlists[playlist_name]['playlist_url'] = None
|
||||
if del_count > 1:
|
||||
await self._embed_msg(ctx, '{} entries have been removed from the {} playlist.'.format(
|
||||
del_count, playlist_name))
|
||||
else:
|
||||
await self._embed_msg(ctx, 'The track has been removed from the {} playlist.'.format(playlist_name))
|
||||
|
||||
@playlist.command(name='save')
|
||||
async def _playlist_save(self, ctx, playlist_name, playlist_url):
|
||||
"""Save a playlist from a url."""
|
||||
if not await self._playlist_check(ctx):
|
||||
return
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
tracklist = await self._playlist_tracks(ctx, player, playlist_url)
|
||||
playlist_list = self._to_json(ctx, playlist_url, tracklist)
|
||||
if tracklist is not None:
|
||||
async with self.config.guild(ctx.guild).playlists() as playlists:
|
||||
playlists[playlist_name] = playlist_list
|
||||
return await self._embed_msg(ctx, 'Playlist {} saved: {} tracks added.'.format(
|
||||
playlist_name, len(tracklist)))
|
||||
|
||||
@playlist.command(name='start')
|
||||
async def _playlist_start(self, ctx, playlist_name=None):
|
||||
"""Load a playlist into the queue."""
|
||||
if not await self._playlist_check(ctx):
|
||||
return
|
||||
playlists = await self.config.guild(ctx.guild).playlists.get_raw()
|
||||
author_obj = self.bot.get_user(ctx.author.id)
|
||||
track_count = 0
|
||||
try:
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
for track in playlists[playlist_name]["tracks"]:
|
||||
player.add(author_obj, lavalink.rest_api.Track(data=track))
|
||||
track_count = track_count + 1
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Playlist Enqueued',
|
||||
description='Added {} tracks to the queue.'.format(track_count))
|
||||
await ctx.send(embed=embed)
|
||||
if not player.current:
|
||||
await player.play()
|
||||
except TypeError:
|
||||
await ctx.invoke(self.play, query=playlists[playlist_name]["playlist_url"])
|
||||
except KeyError:
|
||||
await self._embed_msg(ctx, 'That playlist doesn\'t exist.')
|
||||
|
||||
@checks.is_owner()
|
||||
@playlist.command(name='upload')
|
||||
async def _playlist_upload(self, ctx):
|
||||
"""Convert a Red v2 playlist file to a playlist."""
|
||||
if not await self._playlist_check(ctx):
|
||||
return
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
await self._embed_msg(ctx, 'Please upload the playlist file. Any other message will cancel this operation.')
|
||||
def check(m):
|
||||
return m.author == ctx.author
|
||||
try:
|
||||
file_message = await ctx.bot.wait_for('message', timeout=30.0, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
return await self._embed_msg(ctx, 'No file detected, try again later.')
|
||||
try:
|
||||
file_url = file_message.attachments[0].url
|
||||
except IndexError:
|
||||
return await self._embed_msg(ctx, 'Upload canceled.')
|
||||
v2_playlist_name = (file_url.split('/')[6]).split('.')[0]
|
||||
file_suffix = file_url.rsplit('.', 1)[1]
|
||||
if file_suffix != "txt":
|
||||
return await self._embed_msg(ctx, 'Only playlist files can be uploaded.')
|
||||
async with self.session.request('GET', file_url) as r:
|
||||
v2_playlist = await r.json(content_type='text/plain')
|
||||
try:
|
||||
v2_playlist_url = v2_playlist["link"]
|
||||
except KeyError:
|
||||
v2_playlist_url = None
|
||||
if (not v2_playlist_url or not self._match_yt_playlist(v2_playlist_url) or not
|
||||
await player.get_tracks(v2_playlist_url)):
|
||||
track_list = []
|
||||
track_count = 0
|
||||
async with self.config.guild(ctx.guild).playlists() as v3_playlists:
|
||||
try:
|
||||
if v3_playlists[v2_playlist_name]:
|
||||
return await self._embed_msg(ctx, 'A playlist already exists with this name.')
|
||||
except KeyError:
|
||||
pass
|
||||
embed1 = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Please wait, adding tracks...')
|
||||
playlist_msg = await ctx.send(embed=embed1)
|
||||
for song_url in v2_playlist["playlist"]:
|
||||
track = await player.get_tracks(song_url)
|
||||
try:
|
||||
track_obj = self._track_creator(player, other_track=track[0])
|
||||
track_list.append(track_obj)
|
||||
track_count = track_count + 1
|
||||
except IndexError:
|
||||
pass
|
||||
if track_count % 5 == 0:
|
||||
embed2 = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Loading track {}/{}...'.format(
|
||||
track_count, len(v2_playlist["playlist"])))
|
||||
await playlist_msg.edit(embed=embed2)
|
||||
if not track_list:
|
||||
return await self._embed_msg(ctx, 'No tracks found.')
|
||||
playlist_list = self._to_json(ctx, v2_playlist_url, track_list)
|
||||
v3_playlists[v2_playlist_name] = playlist_list
|
||||
if len(v2_playlist["playlist"]) != track_count:
|
||||
bad_tracks = len(v2_playlist["playlist"]) - track_count
|
||||
msg = ('Added {} tracks from the {} playlist. {} track(s) could not '
|
||||
'be loaded.'.format(track_count, v2_playlist_name, bad_tracks))
|
||||
else:
|
||||
msg = 'Added {} tracks from the {} playlist.'.format(track_count, v2_playlist_name)
|
||||
embed3 = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Playlist Saved', description=msg)
|
||||
await playlist_msg.edit(embed=embed3)
|
||||
else:
|
||||
await ctx.invoke(self._playlist_save, v2_playlist_name, v2_playlist_url)
|
||||
|
||||
async def _playlist_check(self, ctx):
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
jukebox_price = await self.config.guild(ctx.guild).jukebox_price()
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
await self._embed_msg(ctx, 'You need the DJ role to use playlists.')
|
||||
return False
|
||||
if not self._player_check(ctx):
|
||||
try:
|
||||
await lavalink.connect(ctx.author.voice.channel)
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
player.store('connect', datetime.datetime.utcnow())
|
||||
except AttributeError:
|
||||
await self._embed_msg(ctx, 'Connect to a voice channel first.')
|
||||
return False
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
player.store('channel', ctx.channel.id)
|
||||
player.store('guild', ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._embed_msg(ctx, 'You must be in the voice channel to use the playlist command.')
|
||||
return False
|
||||
if not await self._currency_check(ctx, jukebox_price):
|
||||
return False
|
||||
await self._data_check(ctx)
|
||||
return True
|
||||
|
||||
async def _playlist_tracks(self, ctx, player, query):
|
||||
search = False
|
||||
if type(query) is tuple:
|
||||
query = " ".join(query)
|
||||
if not query.startswith('http'):
|
||||
query = " ".join(query)
|
||||
query = 'ytsearch:{}'.format(query)
|
||||
search = True
|
||||
tracks = await player.get_tracks(query)
|
||||
if not tracks:
|
||||
return await self._embed_msg(ctx, 'Nothing found.')
|
||||
tracklist = []
|
||||
if not search:
|
||||
for track in tracks:
|
||||
track_obj = self._track_creator(player, other_track=track)
|
||||
tracklist.append(track_obj)
|
||||
else:
|
||||
track_obj = self._track_creator(player, other_track=tracks[0])
|
||||
tracklist.append(track_obj)
|
||||
return tracklist
|
||||
|
||||
@commands.command()
|
||||
async def prev(self, ctx):
|
||||
"""Skips to the start of the previously played track."""
|
||||
@@ -514,10 +857,10 @@ class Audio:
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
shuffle = await self.config.guild(ctx.guild).shuffle()
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to skip songs.')
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to skip the music.')
|
||||
if shuffle:
|
||||
return await self._embed_msg(ctx, 'Turn shuffle off to use this command.')
|
||||
@@ -525,7 +868,7 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'No previous track.')
|
||||
else:
|
||||
last_track = await player.get_tracks(player.fetch('prev_song'))
|
||||
player.add(player.fetch('prev_requester').id, last_track[0])
|
||||
player.add(player.fetch('prev_requester'), last_track[0])
|
||||
queue_len = len(player.queue)
|
||||
bump_song = player.queue[-1]
|
||||
player.queue.insert(0, bump_song)
|
||||
@@ -556,7 +899,10 @@ class Audio:
|
||||
end = start + items_per_page
|
||||
|
||||
queue_list = ''
|
||||
arrow = await self._draw_time(ctx)
|
||||
try:
|
||||
arrow = await self._draw_time(ctx)
|
||||
except AttributeError:
|
||||
return await self._embed_msg(ctx, 'There\'s nothing in the queue.')
|
||||
pos = lavalink.utils.format_time(player.position)
|
||||
|
||||
if player.current.is_stream:
|
||||
@@ -581,8 +927,8 @@ class Audio:
|
||||
|
||||
for i, track in enumerate(player.queue[start:end], start=start):
|
||||
req_user = track.requester
|
||||
next = i + 1
|
||||
queue_list += '`{}.` **[{}]({})**, requested by **{}**\n'.format(next, track.title, track.uri, req_user)
|
||||
_next = i + 1
|
||||
queue_list += '`{}.` **[{}]({})**, requested by **{}**\n'.format(_next, track.title, track.uri, req_user)
|
||||
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Queue for ' + ctx.guild.name,
|
||||
description=queue_list)
|
||||
@@ -610,7 +956,7 @@ class Audio:
|
||||
await self._data_check(ctx)
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to toggle repeat.')
|
||||
await self._embed_msg(ctx, 'Repeat songs: {}.'.format(repeat))
|
||||
|
||||
@@ -627,7 +973,7 @@ class Audio:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to remove songs.')
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to manage the queue.')
|
||||
if index > len(player.queue) or index < 1:
|
||||
return await self._embed_msg(ctx, 'Song number must be greater than 1 and within the queue limit.')
|
||||
@@ -660,7 +1006,7 @@ class Audio:
|
||||
player.store('channel', ctx.channel.id)
|
||||
player.store('guild', ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to enqueue songs.')
|
||||
|
||||
query = query.strip('<>')
|
||||
@@ -680,8 +1026,8 @@ class Audio:
|
||||
end = start + items_per_page
|
||||
search_list = ''
|
||||
for i, track in enumerate(tracks[start:end], start=start):
|
||||
next = i + 1
|
||||
search_list += '`{0}.` [**{1}**]({2})\n'.format(next, track.title,
|
||||
_next = i + 1
|
||||
search_list += '`{0}.` [**{1}**]({2})\n'.format(_next, track.title,
|
||||
track.uri)
|
||||
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Tracks Found:', description=search_list)
|
||||
@@ -714,7 +1060,8 @@ class Audio:
|
||||
queue_duration = await self._queue_duration(ctx)
|
||||
queue_total_duration = lavalink.utils.format_time(queue_duration)
|
||||
if not shuffle and queue_duration > 0:
|
||||
songembed.set_footer(text='{} until start of search playback'.format(queue_total_duration))
|
||||
songembed.set_footer(text='{} until start of search playback: starts at #{} in queue'.format(
|
||||
queue_total_duration, (len(player.queue) + 1)))
|
||||
for track in tracks:
|
||||
player.add(ctx.author, track)
|
||||
if not player.current:
|
||||
@@ -734,7 +1081,8 @@ class Audio:
|
||||
queue_duration = await self._queue_duration(ctx)
|
||||
queue_total_duration = lavalink.utils.format_time(queue_duration)
|
||||
if not shuffle and queue_duration > 0:
|
||||
embed.set_footer(text='{} until track playback'.format(queue_total_duration))
|
||||
embed.set_footer(text='{} until track playback: #{} in queue'.format(queue_total_duration, (
|
||||
len(player.queue) + 1)))
|
||||
player.add(ctx.author, search_choice)
|
||||
if not player.current:
|
||||
await player.play()
|
||||
@@ -748,10 +1096,10 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to use seek.')
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to use seek.')
|
||||
if player.current:
|
||||
if player.current.is_stream:
|
||||
@@ -781,7 +1129,7 @@ class Audio:
|
||||
await self._data_check(ctx)
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to toggle shuffle.')
|
||||
await self._embed_msg(ctx, 'Shuffle songs: {}.'.format(shuffle))
|
||||
|
||||
@@ -792,12 +1140,12 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to skip the music.')
|
||||
dj_enabled = await self.config.guild(ctx.guild).dj_enabled()
|
||||
vote_enabled = await self.config.guild(ctx.guild).vote_enabled()
|
||||
if dj_enabled and not vote_enabled and not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'You need the DJ role to skip songs.')
|
||||
if vote_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
@@ -845,18 +1193,26 @@ class Audio:
|
||||
is_admin = discord.utils.get(ctx.guild.get_member(member.id).roles, id=admin_role) is not None
|
||||
is_mod = discord.utils.get(ctx.guild.get_member(member.id).roles, id=mod_role) is not None
|
||||
is_bot = member.bot is True
|
||||
|
||||
return is_active_dj or is_owner or is_server_owner or is_coowner or is_admin or is_mod or is_bot
|
||||
|
||||
async def _is_alone(self, ctx, member):
|
||||
try:
|
||||
nonbots = sum(not m.bot for m in ctx.guild.get_member(member.id).voice.channel.members)
|
||||
user_voice = ctx.guild.get_member(member.id).voice
|
||||
bot_voice = ctx.guild.get_member(self.bot.user.id).voice
|
||||
nonbots = sum(not m.bot for m in user_voice.channel.members)
|
||||
if user_voice.channel != bot_voice.channel:
|
||||
nonbots = nonbots + 1
|
||||
except AttributeError:
|
||||
if ctx.guild.get_member(self.bot.user.id).voice is not None:
|
||||
nonbots = sum(not m.bot for m in ctx.guild.get_member(self.bot.user.id).voice.channel.members)
|
||||
if nonbots == 1:
|
||||
nonbots = 2
|
||||
elif ctx.guild.get_member(member.id).voice.channel.members == 1:
|
||||
nonbots = 1
|
||||
else:
|
||||
nonbots = 2
|
||||
alone = nonbots <= 1
|
||||
|
||||
return is_active_dj or is_owner or is_server_owner or is_coowner or is_admin or is_mod or is_bot or alone
|
||||
nonbots = 0
|
||||
return nonbots <= 1
|
||||
|
||||
async def _has_dj_role(self, ctx, member):
|
||||
dj_role_id = await self.config.guild(ctx.guild).dj_role()
|
||||
@@ -898,10 +1254,10 @@ class Audio:
|
||||
return await self._embed_msg(ctx, 'Nothing playing.')
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to stop the music.')
|
||||
if vote_enabled or vote_enabled and dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._is_alone(ctx, ctx.author):
|
||||
return await self._embed_msg(ctx, 'There are other people listening - vote to skip instead.')
|
||||
if dj_enabled and not vote_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author):
|
||||
@@ -928,7 +1284,7 @@ class Audio:
|
||||
if self._player_check(ctx):
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
if ((not ctx.author.voice or ctx.author.voice.channel != player.channel) and not
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
await self._can_instaskip(ctx, ctx.author)):
|
||||
return await self._embed_msg(ctx, 'You must be in the voice channel to change the volume.')
|
||||
if dj_enabled:
|
||||
if not await self._can_instaskip(ctx, ctx.author) and not await self._has_dj_role(ctx, ctx.author):
|
||||
@@ -955,29 +1311,76 @@ class Audio:
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help()
|
||||
|
||||
@llsetup.command()
|
||||
async def external(self, ctx):
|
||||
"""Toggles using external lavalink servers."""
|
||||
external = await self.config.use_external_lavalink()
|
||||
await self.config.use_external_lavalink.set(not external)
|
||||
if external:
|
||||
await self.config.host.set('localhost')
|
||||
await self.config.password.set('youshallnotpass')
|
||||
await self.config.rest_port.set(2333)
|
||||
await self.config.ws_port.set(2332)
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='External lavalink server: {}.'.format(
|
||||
not external))
|
||||
embed.set_footer(text='Defaults reset.')
|
||||
return await ctx.send(embed=embed)
|
||||
else:
|
||||
await self._embed_msg(ctx, 'External lavalink server: {}.'.format(not external))
|
||||
|
||||
@llsetup.command()
|
||||
async def host(self, ctx, host):
|
||||
"""Set the lavalink server host."""
|
||||
await self.config.host.set(host)
|
||||
await self._embed_msg(ctx, 'Host set to {}.'.format(host))
|
||||
if await self._check_external():
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='Host set to {}.'.format(host))
|
||||
embed.set_footer(text='External lavalink server set to True.')
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
await self._embed_msg(ctx, 'Host set to {}.'.format(host))
|
||||
|
||||
@llsetup.command()
|
||||
async def password(self, ctx, passw):
|
||||
async def password(self, ctx, password):
|
||||
"""Set the lavalink server password."""
|
||||
await self.config.passw.set(str(passw))
|
||||
await self._embed_msg(ctx, 'Server password set to {}.'.format(passw))
|
||||
await self.config.password.set(str(password))
|
||||
if await self._check_external():
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour,
|
||||
title='Server password set to {}.'.format(password))
|
||||
embed.set_footer(text='External lavalink server set to True.')
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
await self._embed_msg(ctx, 'Server password set to {}.'.format(password))
|
||||
|
||||
@llsetup.command()
|
||||
async def restport(self, ctx, rest_port):
|
||||
"""Set the lavalink REST server port."""
|
||||
await self.config.rest_port.set(str(rest_port))
|
||||
await self._embed_msg(ctx, 'REST port set to {}.'.format(rest_port))
|
||||
await self.config.rest_port.set(rest_port)
|
||||
if await self._check_external():
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour, title='REST port set to {}.'.format(rest_port))
|
||||
embed.set_footer(text='External lavalink server set to True.')
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
await self._embed_msg(ctx, 'REST port set to {}.'.format(rest_port))
|
||||
|
||||
@llsetup.command()
|
||||
async def wsport(self, ctx, rest_port):
|
||||
async def wsport(self, ctx, ws_port):
|
||||
"""Set the lavalink websocket server port."""
|
||||
await self.config.ws_port.set(str(ws_port))
|
||||
await self._embed_msg(ctx, 'Websocket port set to {}.'.format(ws_port))
|
||||
await self.config.rest_port.set(ws_port)
|
||||
if await self._check_external():
|
||||
embed = discord.Embed(colour=ctx.guild.me.top_role.colour,
|
||||
title='Websocket port set to {}.'.format(ws_port))
|
||||
embed.set_footer(text='External lavalink server set to True.')
|
||||
await ctx.send(embed=embed)
|
||||
else:
|
||||
await self._embed_msg(ctx, 'Websocket port set to {}.'.format(ws_port))
|
||||
|
||||
async def _check_external(self):
|
||||
external = await self.config.use_external_lavalink()
|
||||
if not external:
|
||||
await self.config.use_external_lavalink.set(True)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
async def _clear_react(message):
|
||||
@@ -1011,7 +1414,8 @@ class Audio:
|
||||
if player.volume != volume:
|
||||
await player.set_volume(volume)
|
||||
|
||||
async def _draw_time(self, ctx):
|
||||
@staticmethod
|
||||
async def _draw_time(ctx):
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
paused = player.paused
|
||||
pos = player.position
|
||||
@@ -1061,6 +1465,15 @@ class Audio:
|
||||
else:
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def _match_yt_playlist(url):
|
||||
yt_list_playlist = re.compile(
|
||||
r'^(https?\:\/\/)?(www\.)?(youtube\.com|youtu\.?be)'
|
||||
r'(\/playlist\?).*(list=)(.*)(&|$)')
|
||||
if yt_list_playlist.match(url):
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
async def _queue_duration(ctx):
|
||||
player = lavalink.get_player(ctx.guild.id)
|
||||
@@ -1068,7 +1481,7 @@ class Audio:
|
||||
for i in range(len(player.queue)):
|
||||
if not player.queue[i].is_stream:
|
||||
duration.append(player.queue[i].length)
|
||||
queue_duration = sum(duration)
|
||||
queue_duration = sum(duration)
|
||||
if not player.queue:
|
||||
queue_duration = 0
|
||||
try:
|
||||
@@ -1089,6 +1502,32 @@ class Audio:
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _to_json(ctx, playlist_url, tracklist):
|
||||
playlist = {"author": ctx.author.id, "playlist_url": playlist_url, "tracks": tracklist}
|
||||
return playlist
|
||||
|
||||
@staticmethod
|
||||
def _track_creator(player, position=None, other_track=None):
|
||||
if position == 'np':
|
||||
queued_track = player.current
|
||||
elif position is None:
|
||||
queued_track = other_track
|
||||
else:
|
||||
queued_track = player.queue[position]
|
||||
track_keys = queued_track._info.keys()
|
||||
track_values = queued_track._info.values()
|
||||
track_id = queued_track.track_identifier
|
||||
track_info = {}
|
||||
for k, v in zip(track_keys, track_values):
|
||||
track_info[k] = v
|
||||
keys = ['track', 'info']
|
||||
values = [track_id, track_info]
|
||||
track_obj = {}
|
||||
for key, value in zip(keys, values):
|
||||
track_obj[key] = value
|
||||
return track_obj
|
||||
|
||||
async def on_voice_state_update(self, member, before, after):
|
||||
if after.channel != before.channel:
|
||||
try:
|
||||
@@ -1097,6 +1536,7 @@ class Audio:
|
||||
pass
|
||||
|
||||
def __unload(self):
|
||||
self.session.close()
|
||||
lavalink.unregister_event_listener(self.event_handler)
|
||||
self.bot.loop.create_task(lavalink.close())
|
||||
shutdown_lavalink_server()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Arabic\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: ar_SA\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Bulgarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: bg_BG\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Danish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: da_DK\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-27 01:49-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: German\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: de_DE\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "Tritt zuerst einem Sprachkanal bei!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr "Lass uns eine Datei abspielen, die vorhanden ist"
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{} spielt ein Lied..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "YouTube Links bitte"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "Ich bin noch nicht einmal mit einem Sprachkanal verbunden!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "Lautstärke einstellen."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Greek\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: el_GR\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Pirate English\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: en_PT\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "Aye! Ye need to sail y'ur ship first!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{} be dancing to Shanty..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "Aye! A rope to youtube is required!"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "Aye! I never boarded ye ship!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "Aye, shouting voice changed."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Spanish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: es_ES\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Finnish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: fi_FI\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:32-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:41-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: fr_FR\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "Rejoignez un salon vocal d'abord!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr "Veuillez faire jouer un fichier qui existe"
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{} joue une chanson..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "Veuillez entrer des liens YouTube"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "Je ne suis pas connecté à un salon vocal!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "Volume changé."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Hungarian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: hu_HU\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Indonesian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: id_ID\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "Bergabung dengan channel suara dulu!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr "Tolong memutar file yang ada"
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{} sedang memainkan sebuah lagu..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "Link YouTube"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "Saya belum memasuki channel suara!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "Suara telah di atur."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Italian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: it_IT\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Japanese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: ja_JP\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:26-0400\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Korean\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: ko_KR\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "커맨드를 사용하기 전에 음성 채널에 접속해야 해요!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr "파일을 재생해볼게요!"
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{}이(가) 음악을 재생하는 중..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "유튜브 링크를 부탁해요!"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "제가 음성 채널에 접속할 수 없어요!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "음량이 변경됐어요."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: LOLCAT\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: lol_US\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Dutch\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: nl_NL\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:42-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: no_NO\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Polish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: pl_PL\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: pt_BR\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:33-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: pt_PT\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-04-02 19:27-0400\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: ru_RU\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Swedish\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: sv_SE\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr "Hoppa in i en röstkanal först!"
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr "Spela en fil som finns tack"
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr "{} spelar en låt..."
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr "Youtube länkar tack"
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr "Jag är inte ens ansluten till en röstkanal!"
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr "Volymnivån inställd."
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: red-discordbot\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: 2018-02-25 21:34-0500\n"
|
||||
"POT-Creation-Date: 2018-04-02 17:36+AKDT\n"
|
||||
"PO-Revision-Date: 2018-04-15 16:43-0400\n"
|
||||
"Last-Translator: Kowlin <boxedpp@gmail.com>\n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -16,27 +16,3 @@ msgstr ""
|
||||
"X-Crowdin-File: /cogs/audio/locales/messages.pot\n"
|
||||
"Language: zh_CN\n"
|
||||
|
||||
#: ../audio.py:25 ../audio.py:45
|
||||
msgid "Join a voice channel first!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:33
|
||||
msgid "Let's play a file that exists pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:38 ../audio.py:58
|
||||
msgid "{} is playing a song..."
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:48
|
||||
msgid "Youtube links pls"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:67 ../audio.py:77 ../audio.py:87 ../audio.py:97
|
||||
msgid "I'm not even connected to a voice channel!"
|
||||
msgstr ""
|
||||
|
||||
#: ../audio.py:95
|
||||
msgid "Volume set."
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
import shlex
|
||||
import shutil
|
||||
import asyncio
|
||||
from subprocess import Popen, DEVNULL
|
||||
from subprocess import Popen, DEVNULL, PIPE
|
||||
import os
|
||||
import logging
|
||||
|
||||
log = logging.getLogger('red.audio.manager')
|
||||
|
||||
proc = None
|
||||
SHUTDOWN = asyncio.Event()
|
||||
|
||||
|
||||
def has_java_error(pid):
|
||||
from . import LAVALINK_DOWNLOAD_DIR
|
||||
poss_error_file = LAVALINK_DOWNLOAD_DIR / 'hs_err_pid{}.log'.format(pid)
|
||||
return poss_error_file.exists()
|
||||
|
||||
|
||||
async def monitor_lavalink_server(loop):
|
||||
while not SHUTDOWN.is_set():
|
||||
if proc.poll() is not None:
|
||||
@@ -14,13 +24,55 @@ async def monitor_lavalink_server(loop):
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
if not SHUTDOWN.is_set():
|
||||
print("Lavalink jar shutdown, restarting.")
|
||||
await start_lavalink_server(loop)
|
||||
log.info("Lavalink jar shutdown.")
|
||||
if not has_java_error(proc.pid):
|
||||
log.info("Restarting Lavalink jar.")
|
||||
await start_lavalink_server(loop)
|
||||
else:
|
||||
log.error("Your Java is borked. Please find the hs_err_pid{}.log file"
|
||||
" in the Audio data folder and report this issue.".format(
|
||||
proc.pid
|
||||
))
|
||||
|
||||
|
||||
async def has_java(loop):
|
||||
java_available = shutil.which('java') is not None
|
||||
if not java_available:
|
||||
return False
|
||||
|
||||
version = await get_java_version(loop)
|
||||
return version >= (1, 8), version
|
||||
|
||||
|
||||
async def get_java_version(loop):
|
||||
"""
|
||||
This assumes we've already checked that java exists.
|
||||
"""
|
||||
proc = Popen(
|
||||
shlex.split("java -version", posix=os.name == 'posix'),
|
||||
stdout=PIPE, stderr=PIPE
|
||||
)
|
||||
_, err = proc.communicate()
|
||||
|
||||
version_info = str(err, encoding='utf-8')
|
||||
|
||||
version_line = version_info.split('\n')[0]
|
||||
version_start = version_line.find('"')
|
||||
version_string = version_line[version_start + 1:-1]
|
||||
major, minor = version_string.split('.')[:2]
|
||||
return int(major), int(minor)
|
||||
|
||||
async def start_lavalink_server(loop):
|
||||
java_available, java_version = await has_java(loop)
|
||||
if not java_available:
|
||||
raise RuntimeError("You must install Java 1.8+ for Lavalink to run.")
|
||||
|
||||
extra_flags = ""
|
||||
if java_version == (1, 8):
|
||||
extra_flags = "-Dsun.zip.disableMemoryMapping=true"
|
||||
|
||||
from . import LAVALINK_DOWNLOAD_DIR, LAVALINK_JAR_FILE
|
||||
start_cmd = "java -jar {}".format(LAVALINK_JAR_FILE.resolve())
|
||||
start_cmd = "java {} -jar {}".format(extra_flags, LAVALINK_JAR_FILE.resolve())
|
||||
|
||||
global proc
|
||||
proc = Popen(
|
||||
@@ -29,13 +81,16 @@ async def start_lavalink_server(loop):
|
||||
stdout=DEVNULL, stderr=DEVNULL
|
||||
)
|
||||
|
||||
print("Lavalink jar started. PID: {}".format(proc.pid))
|
||||
log.info("Lavalink jar started. PID: {}".format(proc.pid))
|
||||
|
||||
loop.create_task(monitor_lavalink_server(loop))
|
||||
|
||||
|
||||
def shutdown_lavalink_server():
|
||||
print("Shutting down lavalink server.")
|
||||
log.info("Shutting down lavalink server.")
|
||||
SHUTDOWN.set()
|
||||
global proc
|
||||
if proc is not None:
|
||||
proc.terminate()
|
||||
proc.wait()
|
||||
proc = None
|
||||
|
||||
@@ -87,11 +87,11 @@ class Bank:
|
||||
@checks.is_owner()
|
||||
async def bankset_toggleglobal(self, ctx: commands.Context, confirm: bool=False):
|
||||
"""Toggles whether the bank is global or not
|
||||
If the bank is global, it will become per-guild
|
||||
If the bank is per-guild, it will become global"""
|
||||
If the bank is global, it will become per-server
|
||||
If the bank is per-server, it will become global"""
|
||||
cur_setting = await bank.is_global()
|
||||
|
||||
word = _("per-guild") if cur_setting else _("global")
|
||||
word = _("per-server") if cur_setting else _("global")
|
||||
if confirm is False:
|
||||
await ctx.send(
|
||||
_("This will toggle the bank to be {}, deleting all accounts "
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user