mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-12-06 09:22:31 -05:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8096cd803e | ||
|
|
27b0d606c8 | ||
|
|
af220e497f | ||
|
|
892b2487f5 | ||
|
|
7971c02dc5 | ||
|
|
c1d8272b49 | ||
|
|
bce5dd26f3 | ||
|
|
04e97f3516 | ||
|
|
7eed033c9e | ||
|
|
a2fe1a8757 | ||
|
|
9ee860c3f0 | ||
|
|
1dbe9537e9 | ||
|
|
775f4ce69a | ||
|
|
e83beeef34 | ||
|
|
e77cfff892 | ||
|
|
9495432b8f | ||
|
|
d71c334a34 | ||
|
|
aa8cc90ad0 | ||
|
|
589041556e | ||
|
|
85354f2722 | ||
|
|
c0c5535005 | ||
|
|
e126cf9f4e | ||
|
|
c2d23b37a7 | ||
|
|
3a968d707f | ||
|
|
b07c44c8b4 | ||
|
|
43b0a58649 | ||
|
|
f258e93cf7 | ||
|
|
93138b04cb | ||
|
|
0cf54ec9c2 | ||
|
|
ce031cf7bd | ||
|
|
e6495bc7c0 | ||
|
|
1b196bf0fb | ||
|
|
dbed24aaca | ||
|
|
48a7a21aca | ||
|
|
f595afab18 | ||
|
|
0aca00b245 | ||
|
|
9af58d3abf | ||
|
|
dd5ef3696f | ||
|
|
03d49bac53 | ||
|
|
6c082a10b1 | ||
|
|
77944e195a | ||
|
|
6ebfdef025 | ||
|
|
bc39a6741c | ||
|
|
bda7e08208 | ||
|
|
aa69dd381f | ||
|
|
1fd8a8e0a6 | ||
|
|
1329fa1b09 | ||
|
|
b550f38eed | ||
|
|
ae7b912ac8 | ||
|
|
af9478922e | ||
|
|
7acea29cdb | ||
|
|
6082eb21e3 | ||
|
|
a91cda4995 | ||
|
|
7959654dc8 | ||
|
|
dc9a85ca98 | ||
|
|
591ed50ac3 | ||
|
|
47350328e6 | ||
|
|
75ed749cb3 | ||
|
|
f44ea8b749 | ||
|
|
76c0071f57 | ||
|
|
2a396b4438 | ||
|
|
51a54863c5 | ||
|
|
06f986b92e | ||
|
|
652ceba845 | ||
|
|
16d0f54d8f | ||
|
|
872cce784a | ||
|
|
aec3ad382a | ||
|
|
9d4f9ef73c | ||
|
|
cf7cafc261 | ||
|
|
e3bff7e87c | ||
|
|
4b19421075 | ||
|
|
cf371e8093 | ||
|
|
5eeadc6399 | ||
|
|
f6823ea3d1 | ||
|
|
f24290c423 | ||
|
|
f8a36885fe | ||
|
|
a555eff2cc | ||
|
|
05c389623c | ||
|
|
bf00f5e9a2 | ||
|
|
7685c4d5d5 | ||
|
|
e701ec9617 | ||
|
|
6c1ee096a1 | ||
|
|
2df282222f | ||
|
|
43c7bd48c7 | ||
|
|
86579068d9 | ||
|
|
8e6ab9aa35 | ||
|
|
77566a887a | ||
|
|
9d0eca1914 | ||
|
|
79a3164d9d | ||
|
|
eb73e48192 | ||
|
|
cd6af7f185 | ||
|
|
3d6020b9cf | ||
|
|
461f03aac0 | ||
|
|
35149f8837 | ||
|
|
c0d01f32a6 | ||
|
|
83a0459b6a | ||
|
|
50f6dcef2f | ||
|
|
5c514fd663 | ||
|
|
1c2196f78f | ||
|
|
43cc3c40f3 | ||
|
|
7a6a4cf59d | ||
|
|
3bcf375204 | ||
|
|
a175bdc1c7 | ||
|
|
b557b437a3 | ||
|
|
d1f0b59b5d | ||
|
|
3ece3a1f2b | ||
|
|
1f1a85de18 | ||
|
|
e08c9dafa6 | ||
|
|
ad27607ccc | ||
|
|
c1bcca4432 | ||
|
|
9f2ed694ce | ||
|
|
edadd8f2fd | ||
|
|
afa08713e0 | ||
|
|
d23620727e | ||
|
|
b456c6ad3b | ||
|
|
0298b53803 | ||
|
|
bfd6e4af3f | ||
|
|
31612aae4a |
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -24,6 +24,8 @@ 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
|
||||
redbot/core/utils/caching.py @mikeshardmind
|
||||
redbot/core/utils/common_filters.py @mikeshardmind
|
||||
|
||||
# Cogs
|
||||
redbot/cogs/admin/* @tekulvw
|
||||
@@ -44,6 +46,7 @@ redbot/cogs/trivia/* @Tobotimus
|
||||
redbot/cogs/dataconverter/* @mikeshardmind
|
||||
redbot/cogs/reports/* @mikeshardmind
|
||||
redbot/cogs/permissions/* @mikeshardmind
|
||||
redbot/cogs/warnings/* @palmtree5
|
||||
|
||||
# Docs
|
||||
docs/* @tekulvw @palmtree5
|
||||
|
||||
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -31,7 +31,7 @@ We love receiving contributions from our community. Any assistance you can provi
|
||||
# 2. Ground Rules
|
||||
We've made a point to use [ZenHub](https://www.zenhub.com/) (a plugin for GitHub) as our main source of collaboration and coordination. Your experience contributing to Red will be greatly improved if you go get that plugin.
|
||||
1. Ensure cross compatibility for Windows, Mac OS and Linux.
|
||||
2. Ensure all Python features used in contributions exist and work in Python 3.5 and above.
|
||||
2. Ensure all Python features used in contributions exist and work in Python 3.6 and above.
|
||||
3. Create new tests for code you add or bugs you fix. It helps us help you by making sure we don't accidentally break anything :grinning:
|
||||
4. Create any issues for new features you'd like to implement and explain why this feature is useful to everyone and not just you personally.
|
||||
5. Don't add new cogs unless specifically given approval in an issue discussing said cog idea.
|
||||
@@ -53,7 +53,7 @@ Red's repository is configured to follow a particular development workflow, usin
|
||||
|
||||
### 4.1 Setting up your development environment
|
||||
The following requirements must be installed prior to setting up:
|
||||
- Python 3.6
|
||||
- Python 3.6.2 or greater
|
||||
- git
|
||||
- pip
|
||||
- pipenv
|
||||
@@ -79,7 +79,7 @@ Note: If you haven't used `pipenv` before but are comfortable with virtualenvs,
|
||||
We've recently started using [tox](https://github.com/tox-dev/tox) to run all of our tests. It's extremely simple to use, and if you followed the previous section correctly, it is already installed to your virtual environment.
|
||||
|
||||
Currently, tox does the following, creating its own virtual environments for each stage:
|
||||
- Runs all of our unit tests with [pytest](https://github.com/pytest-dev/pytest) on both python 3.5 and 3.6 (test environments `py35` and `py36` respectively)
|
||||
- Runs all of our unit tests with [pytest](https://github.com/pytest-dev/pytest) on python 3.6 and 3.7 (test environments `py36` and `py37`)
|
||||
- Ensures documentation builds without warnings, and all hyperlinks have a valid destination (test environment `docs`)
|
||||
- Ensures that the code meets our style guide with [black](https://github.com/ambv/black) (test environment `style`)
|
||||
|
||||
@@ -94,8 +94,6 @@ Our style checker of choice, [black](https://github.com/ambv/black), actually ha
|
||||
|
||||
Use the command `black --help` to see how to use this tool. The full style guide is explained in detail on [black's GitHub repository](https://github.com/ambv/black). **There is one exception to this**, however, which is that we set the line length to 99, instead of black's default 88. When using `black` on the command line, simply use it like so: `black -l 99 <src>`.
|
||||
|
||||
Note: Python 3.6+ is required to install and run black. If you installed your development environment with Python 3.5, black will not be installed.
|
||||
|
||||
### 4.4 Make
|
||||
You may have noticed we have a `Makefile` and a `make.bat` in the top-level directory. For now, you can do two things with them:
|
||||
1. `make reformat`: Reformat all python files in the project with Black
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
*.json
|
||||
*.exe
|
||||
*.dll
|
||||
*.pot
|
||||
.data
|
||||
!/tests/cogs/dataconverter/data/**/*.json
|
||||
|
||||
|
||||
@@ -4,10 +4,11 @@ formats:
|
||||
build:
|
||||
image: latest
|
||||
|
||||
requirements_file: docs/requirements.txt
|
||||
requirements_file: dependency_links.txt
|
||||
|
||||
python:
|
||||
version: 3.6
|
||||
pip_install: true
|
||||
extra_requirements:
|
||||
- docs
|
||||
- mongo
|
||||
|
||||
31
.travis.yml
31
.travis.yml
@@ -1,33 +1,37 @@
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
language: python
|
||||
cache: pip
|
||||
notifications:
|
||||
email: false
|
||||
sudo: true
|
||||
|
||||
python:
|
||||
- 3.6.5
|
||||
- 3.6.6
|
||||
- 3.7
|
||||
env:
|
||||
global:
|
||||
PIPENV_IGNORE_VIRTUALENVS=1
|
||||
matrix:
|
||||
- TOXENV=py
|
||||
- TOXENV=docs
|
||||
- TOXENV=style
|
||||
TOXENV=py
|
||||
|
||||
install:
|
||||
- pip install --upgrade pip pipenv
|
||||
- pipenv install --dev
|
||||
- pip install --upgrade pip tox
|
||||
|
||||
script:
|
||||
- pipenv run tox
|
||||
- tox
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- python: 3.6.6
|
||||
env: TOXENV=docs
|
||||
- python: 3.6.6
|
||||
env: TOXENV=style
|
||||
|
||||
# These jobs only occur on tag creation for V3/develop if the prior ones succeed
|
||||
- stage: PyPi Deployment
|
||||
if: tag IS present
|
||||
python: 3.6.5
|
||||
python: 3.6.6
|
||||
env:
|
||||
- DEPLOYING=true
|
||||
deploy:
|
||||
@@ -39,11 +43,11 @@ jobs:
|
||||
on:
|
||||
repo: Cog-Creators/Red-DiscordBot
|
||||
branch: V3/develop
|
||||
python: 3.6.5
|
||||
python: 3.6.6
|
||||
tags: true
|
||||
- stage: Crowdin Deployment
|
||||
if: tag IS present
|
||||
python: 3.6.5
|
||||
python: 3.6.6
|
||||
env:
|
||||
- DEPLOYING=true
|
||||
before_deploy:
|
||||
@@ -51,12 +55,13 @@ jobs:
|
||||
- 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
|
||||
- pip install redgettext==2.1
|
||||
deploy:
|
||||
- provider: script
|
||||
script: python3 ./generate_strings.py
|
||||
script: make gettext
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: Cog-Creators/Red-DiscordBot
|
||||
branch: V3/develop
|
||||
python: 3.6.5
|
||||
python: 3.6.6
|
||||
tags: true
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
include README.rst
|
||||
include README.md
|
||||
include LICENSE
|
||||
include requirements.txt
|
||||
include discord/bin/*.dll
|
||||
include redbot/cogs/audio/application.yml
|
||||
include dependency_links.txt
|
||||
|
||||
3
Makefile
3
Makefile
@@ -2,3 +2,6 @@ reformat:
|
||||
black -l 99 `git ls-files "*.py"`
|
||||
stylecheck:
|
||||
black --check -l 99 `git ls-files "*.py"`
|
||||
gettext:
|
||||
redgettext --command-docstrings --verbose --recursive redbot --exclude-files "redbot/pytest/**/*"
|
||||
crowdin upload
|
||||
|
||||
14
Pipfile
14
Pipfile
@@ -4,17 +4,9 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
"discord.py" = { git = 'git://github.com/Rapptz/discord.py', ref = '7eb918b19e3e60b56eb9039eb267f8f3477c5e17', editable = true}
|
||||
"e1839a8" = {path = ".", editable = true}
|
||||
"discord.py" = { git = 'git://github.com/Rapptz/discord.py', ref = 'rewrite', editable = true }
|
||||
"e1839a8" = { path = ".", editable = true, extras = ['mongo', 'voice'] }
|
||||
|
||||
[dev-packages]
|
||||
tox = "*"
|
||||
pytest = "*"
|
||||
pytest-asyncio = "*"
|
||||
sphinx = ">1.7"
|
||||
sphinxcontrib-asyncio = "*"
|
||||
sphinx-rtd-theme = "*"
|
||||
black = "*"
|
||||
|
||||
[pipenv]
|
||||
allow_prereleases = true
|
||||
"e1839a9" = { path = ".", editable = true, extras = ['docs', 'test', 'style'] }
|
||||
|
||||
590
Pipfile.lock
generated
590
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "dcd688e81a2d0e793236e0335eb7cb9558d8b4acb66934afffcc0612cce2ec53"
|
||||
"sha256": "edd35f353e1fadc20094e40de6627db77fd61303da01794214c44d748e99838b"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -16,28 +16,30 @@
|
||||
"default": {
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:129d83dd067760cec3cfd4456b5c6d7ac29f2c639d856884568fd539bed5a51f",
|
||||
"sha256:33c62afd115c456b0cf1e890fe6753055effe0f31a28321efd4f787378d6f4ab",
|
||||
"sha256:666756e1d4cf161ed1486b82f65fdd386ac07dd20fb10f025abf4be54be12746",
|
||||
"sha256:9705ded5a0faa25c8f14c6afb7044002d66c9120ed7eadb4aa9ca4aad32bd00c",
|
||||
"sha256:af5bfdd164256118a0a306b3f7046e63207d1f8cba73a67dcc0bd858dcfcd3bc",
|
||||
"sha256:b80f44b99fa3c9b4530fcfa324a99b84843043c35b084e0b653566049974435d",
|
||||
"sha256:c67e105ec74b85c8cb666b6877569dee6f55b9548f982983b9bee80b3d47e6f3",
|
||||
"sha256:d15c6658de5b7783c2538407278fa062b079a46d5f814a133ae0f09bbb2cfbc4",
|
||||
"sha256:d611ebd1ef48498210b65486306e065fde031040a1f3c455ca1b6baa7bf32ad3",
|
||||
"sha256:dcc7e4dcec6b0012537b9f8a0726f8b111188894ab0f924b680d40b13d3298a0",
|
||||
"sha256:de8ef106e130b94ca143fdfc6f27cda1d8ba439462542377738af4d99d9f5dd2",
|
||||
"sha256:eb6f1405b607fff7e44168e3ceb5d3c8a8c5a2d3effe0a27f843b16ec047a6d7",
|
||||
"sha256:f0e2ac69cb709367400008cebccd5d48161dd146096a009a632a132babe5714c"
|
||||
"sha256:1a112a1fdf3802b7f2b182e22e51d71e4a8fa7387d0d38e79a268921b869e384",
|
||||
"sha256:33aa7c937ebaf063a860cbb0c263a771b33333a84965c6148eeafe64fb4e29ca",
|
||||
"sha256:550b4a0788500f6d00f41b7fdd9fcce6d78f99706a7b2f6f81d4d331c7ca468e",
|
||||
"sha256:601e8e83123b4d423a9dfddf7d6943f4f520651a78ffcd50c99d065136c7ff7b",
|
||||
"sha256:620f19ba7628b70b177f5c2e6a55a6fd6e7c8591cde38c3f8f52551733d31b66",
|
||||
"sha256:70d56c784da1239c89d39fefa166fd429306dada641178389be4184a9c04e501",
|
||||
"sha256:7de2c9e445a5d257935011268202338538abef1aaff341a4733eca56419ca6f6",
|
||||
"sha256:96bb80b659cc2bafa160f3f0c346ce7fc10de1ffec4908d7f9690797f155f658",
|
||||
"sha256:ae7501cc6a6c37b8d4774bf2218c37be47fe42019a2570e8510fc2044e59d573",
|
||||
"sha256:c833aa6f4c9ac3e3eb843e3d999bae51339ad33a937303f43ce78064e61cb4b6",
|
||||
"sha256:dd81d85a342edf3d2a388e2f24d9facebc9c04550043888f970ee2f228c93059",
|
||||
"sha256:f20deec7a3fbaec7b5eb7ad99878427ad2ee4cc16a46732b705e8121cbb3cc12",
|
||||
"sha256:f52e7287eb9286a1e91e4c67c207c2573147fbaddc68f70efb5aeee5d1992f2e",
|
||||
"sha256:fe7b2972ff7e779e812f974aa5695edc328ecf559ceeea887ac46f06f090ad4c",
|
||||
"sha256:ff1447c84a02b9cd5dd3a9332d1fb181a4386c3625765bb5caf1cfbc210ab3f9"
|
||||
],
|
||||
"version": "==2.2.5"
|
||||
"version": "==3.3.2"
|
||||
},
|
||||
"aiohttp-json-rpc": {
|
||||
"hashes": [
|
||||
"sha256:9ec69ea70ce49c4af445f0ac56ac728708ccfad8b214272d2cc7e75bc0b31327",
|
||||
"sha256:e2b8b49779d5d9b811f3a94e98092b1fa14af6d9adbf71c3afa6b20c641fa5d5"
|
||||
"sha256:970806a3b9887c389095d2bde84e2b540fefeddd0bae0efcae03c65f092ce00e",
|
||||
"sha256:d6f365067676e6089ac043ad31bcbabbf33d0343c42b57c36751a562fbe64fb6"
|
||||
],
|
||||
"version": "==0.8.7"
|
||||
"version": "==0.11.1"
|
||||
},
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
@@ -48,10 +50,18 @@
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:00cff4d2dce744607335cba84e9929c3165632da2d27970dbc55802a0c7873d0",
|
||||
"sha256:9093db5b8ddbe4b8f6885d1a6e0ad84ae3155464cbf6877c387605244c285f3c"
|
||||
"sha256:474d4bc64cee20603e225eb1ece15e248962958b45a3648a9f5cc29e827a610c",
|
||||
"sha256:b3c0ddc416736619bd4a95ca31de8da6920c3b9a140c64dbef2b2fa7bf521287"
|
||||
],
|
||||
"version": "==2.0.1"
|
||||
"markers": "python_version >= '3.5.3'",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
|
||||
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
|
||||
],
|
||||
"version": "==18.2.0"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -70,7 +80,7 @@
|
||||
"discord.py": {
|
||||
"editable": true,
|
||||
"git": "git://github.com/Rapptz/discord.py",
|
||||
"ref": "7eb918b19e3e60b56eb9039eb267f8f3477c5e17"
|
||||
"ref": "00a659c6526b2445162b52eaf970adbd22c6d35d"
|
||||
},
|
||||
"distro": {
|
||||
"hashes": [
|
||||
@@ -81,39 +91,107 @@
|
||||
},
|
||||
"e1839a8": {
|
||||
"editable": true,
|
||||
"extras": [
|
||||
"mongo",
|
||||
"voice"
|
||||
],
|
||||
"path": "."
|
||||
},
|
||||
"fuzzywuzzy": {
|
||||
"hashes": [
|
||||
"sha256:d40c22d2744dff84885b30bbfc07fab7875f641d070374331777a4d1808b8d4e",
|
||||
"sha256:ecf490216fb4d76b558a03042ff8f45a8782f17326caca1384d834cbaa2c7e6f"
|
||||
"sha256:5ac7c0b3f4658d2743aa17da53a55598144edbc5bee3c6863840636e6926f254",
|
||||
"sha256:6f49de47db00e1c71d40ad16da42284ac357936fa9b66bea1df63fed07122d62"
|
||||
],
|
||||
"version": "==0.16.0"
|
||||
"version": "==0.17.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
|
||||
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
],
|
||||
"version": "==2.6"
|
||||
"version": "==2.7"
|
||||
},
|
||||
"idna-ssl": {
|
||||
"hashes": [
|
||||
"sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"motor": {
|
||||
"hashes": [
|
||||
"sha256:462fbb824f4289481c158227a2579d6adaf1ec7c70cf7ebe60ed6ceb321e5869",
|
||||
"sha256:d035c09ab422bc50bf3efb134f7405694cae76268545bd21e14fb22e2638f84e"
|
||||
],
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"multidict": {
|
||||
"hashes": [
|
||||
"sha256:1a1d76374a1e7fe93acef96b354a03c1d7f83e7512e225a527d283da0d7ba5e0",
|
||||
"sha256:1d6e191965505652f194bc4c40270a842922685918a4f45e6936a6b15cc5816d",
|
||||
"sha256:295961a6a88f1199e19968e15d9b42f3a191c89ec13034dbc212bf9c394c3c82",
|
||||
"sha256:2be5af084de6c3b8e20d6421cb0346378a9c867dcf7c86030d6b0b550f9888e4",
|
||||
"sha256:2eb99617c7a0e9f2b90b64bc1fb742611718618572747d6f3d6532b7b78755ab",
|
||||
"sha256:4ba654c6b5ad1ae4a4d792abeb695b29ce981bb0f157a41d0fd227b385f2bef0",
|
||||
"sha256:5ba766433c30d703f6b2c17eb0b6826c6f898e5f58d89373e235f07764952314",
|
||||
"sha256:a59d58ee85b11f337b54933e8d758b2356fcdcc493248e004c9c5e5d11eedbe4",
|
||||
"sha256:a6e35d28900cf87bcc11e6ca9e474db0099b78f0be0a41d95bef02d49101b5b2",
|
||||
"sha256:b4df7ca9c01018a51e43937eaa41f2f5dce17a6382fda0086403bcb1f5c2cf8e",
|
||||
"sha256:bbd5a6bffd3ba8bfe75b16b5e28af15265538e8be011b0b9fddc7d86a453fd4a",
|
||||
"sha256:d870f399fcd58a1889e93008762a3b9a27cf7ea512818fc6e689f59495648355",
|
||||
"sha256:e9404e2e19e901121c3c5c6cffd5a8ae0d1d67919c970e3b3262231175713068"
|
||||
"sha256:112eeeddd226af681dc82b756ed34aa7b6d98f9c4a15760050298c21d715473d",
|
||||
"sha256:13b64ecb692effcabc5e29569ba9b5eb69c35112f990a16d6833ec3a9d9f8ec0",
|
||||
"sha256:1725373fb8f18c2166f8e0e5789851ccf98453c849b403945fa4ef59a16ca44e",
|
||||
"sha256:2061a50b7cae60a1f987503a995b2fc38e47027a937a355a124306ed9c629041",
|
||||
"sha256:35b062288a9a478f627c520fd27983160fc97591017d170f966805b428d17e07",
|
||||
"sha256:467b134bcc227b91b8e2ef8d2931f28b50bf7eb7a04c0403d102ded22e66dbfc",
|
||||
"sha256:475a3ece8bb450e49385414ebfae7f8fdb33f62f1ac0c12935c1cfb1b7c1076a",
|
||||
"sha256:49b885287e227a24545a1126d9ac17ae43138610713dc6219b781cc0ad5c6dfc",
|
||||
"sha256:4c95b2725592adb5c46642be2875c1234c32af841732c5504c17726b92082021",
|
||||
"sha256:4ea7ed00f4be0f7335c9a2713a65ac3d986be789ce5ebc10821da9664cbe6b85",
|
||||
"sha256:5e2d5e1d999e941b4a626aea46bdc4206877cf727107fdaa9d46a8a773a6e49b",
|
||||
"sha256:8039c520ef7bb9ec7c3db3df14c570be6362f43c200ae9854d2422d4ffe175a4",
|
||||
"sha256:81459a0ebcca09c1fcb8fe887ed13cf267d9b60fe33718fc5fd1a2a1ab49470a",
|
||||
"sha256:847c3b7b9ca3268e883685dc1347a4d09f84de7bd7597310044d847590447492",
|
||||
"sha256:8551d1db45f0ca4e8ec99130767009a29a4e0dc6558a4a6808491bcd3472d325",
|
||||
"sha256:8fa7679ffe615e0c1c7b80946ab4194669be74848719adf2d7867b5e861eb073",
|
||||
"sha256:a42a36f09f0f907579ff0fde547f2fde8a739a69efe4a2728835979d2bb5e17b",
|
||||
"sha256:a5fcad0070685c5b2d04b468bf5f4c735f5c176432f495ad055fcc4bc0a79b23",
|
||||
"sha256:ae22195b2a7494619b73c01129ddcddc0dfaa9e42727404b1d9a77253da3f420",
|
||||
"sha256:b360e82bdbbd862e1ce2a41cc3bbd0ab614350e813ca74801b34aac0f73465aa",
|
||||
"sha256:b96417899344c5e96bef757f4963a72d02e52653a4e0f99bbea3a531cedac59f",
|
||||
"sha256:b9e921140b797093edfc13ac08dc2a4fd016dd711dc42bb0e1aaf180e48425a7",
|
||||
"sha256:c5022b94fc330e6d177f3eb38097fb52c7df96ca0e04842c068cf0d9fc38b1e6",
|
||||
"sha256:cf2b117f2a8d951638efc7592fb72d3eeb2d38cc2194c26ba7f00e7190451d92",
|
||||
"sha256:d79620b542d9d0e23ae9790ca2fe44f1af40ffad9936efa37bd14954bc3e2818",
|
||||
"sha256:e2860691c11d10dac7c91bddae44f6211b3da4122d9a2ebb509c2247674d6070",
|
||||
"sha256:e3a293553715afecf7e10ea02da40593f9d7f48fe48a74fc5dd3ce08a0c46188",
|
||||
"sha256:e465be3fe7e992e5a6e16731afa6f41cb6ca53afccb4f28ea2fa6457783edf15",
|
||||
"sha256:e6d27895ef922bc859d969452f247bfbe5345d9aba69b9c8dbe1ea7704f0c5d9"
|
||||
],
|
||||
"version": "==4.3.1"
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"pymongo": {
|
||||
"hashes": [
|
||||
"sha256:08dea6dbff33363419af7af3bf2e9a373ff71eb22833dd7063f9b953f09a0bdf",
|
||||
"sha256:0949110db76eb1b54cecfc0c0f8468a8b9a7fd42ba23fd0d4a37d97e0b4ca203",
|
||||
"sha256:0c31a39f440801cc8603547ccaacf4cb1f02b81af6ba656621c13677b27f4426",
|
||||
"sha256:1e10b3fda5677d360440ebd12a1185944dc81d9ea9acf0c6b0681013b3fb9bc2",
|
||||
"sha256:1f59440b993666a417ba1954cfb1b7fb11cb4dea1a1d2777897009f688d000ee",
|
||||
"sha256:2b5a3806d9f656c14e9d9b693a344fc5684fdd045155594be0c505c6e9410a94",
|
||||
"sha256:4a14e2d7c2c0e07b5affcfbfc5c395d767f94bb1a822934a41a3b5371cde1458",
|
||||
"sha256:4cb50541225208b37786fdb0de632e475c4f00ec4792579df551ef48d6999d69",
|
||||
"sha256:52999666ad01de885653e1f74a86c2a6520d1004afec475180bebf3d7393a8fc",
|
||||
"sha256:562c353079e8ce7e2ad611fd7436a72f5df97be72bca59ae9ebf789a724afd5c",
|
||||
"sha256:5ce2a71f473f4703daa8d6c61a00b35ce625a7f5015b4371e3af728dafca296a",
|
||||
"sha256:6613e633676168a4500e5e6bb6e3e64d3fdb96d2dc472eb4b99235fb4141adb1",
|
||||
"sha256:8330406f294df118399c721f80979f2516447bcc73e4262826687872c864751e",
|
||||
"sha256:8e939dfa7d16609b99eb4d1fd2fc74f7a90f4fd0aaf31d611822daaff456236f",
|
||||
"sha256:8fa4303e1f50d9f0c8f2f7833b5a370a94d19d41449def62b34ae072126b4dfd",
|
||||
"sha256:966d987975aa3b4cfcdf1495930ff6ecb152fafe8e544e40633e41b24ca3e1c5",
|
||||
"sha256:aec4ea43a1b8e9782246a259410f66692f2d3aa0f03c54477e506193b0781cb6",
|
||||
"sha256:b73f889f032fbef05863f5056b46468a8262ae83628898e20b10bbbb79a3617e",
|
||||
"sha256:b752088a2f819f163d11dfdbbe627b27eef9d8478c7e57d42c5e7c600fee434e",
|
||||
"sha256:c8669f96277f140797e0ff99f80bd706271674942672a38ed694e2bfa66f3900",
|
||||
"sha256:ccf00549efaf6f8d5b35b654beb9aed2b788a5b33b05606eb818ddaa4e924ea3",
|
||||
"sha256:ce7c91463ad21ac72fc795188292b01c8366cf625e2d1e5ed473ce127b844f60",
|
||||
"sha256:d776d8d47884e6ad39ff8a301f1ae6b7d2186f209218cf024f43334dbba79c64",
|
||||
"sha256:dab0f63841aebb2b421fadb31f3c7eef27898f21274a8e5b45c4f2bccb40f9ed",
|
||||
"sha256:daedcfbf3b24b2b687e35b33252a9315425c2dd06a085a36906d516135bdd60e",
|
||||
"sha256:e7ad1ec621db2c5ad47924f63561f75abfd4fff669c62c8cc99c169c90432f59",
|
||||
"sha256:f14fb6c4058772a0d74d82874d3b89d7264d89b4ed7fa0413ea0ef8112b268b9",
|
||||
"sha256:f16c7b6b98bc400d180f05e65e2236ef4ee9d71f3815280558582670e1e67536",
|
||||
"sha256:f2d9eb92b26600ae6e8092f66da4bcede1b61a647c9080d6b44c148aff3a8ea4",
|
||||
"sha256:ffe94f9d17800610dda5282d7f6facfc216d79a93dd728a03d2f21cff3af7cc6"
|
||||
],
|
||||
"version": "==3.7.1"
|
||||
},
|
||||
"python-levenshtein": {
|
||||
"hashes": [
|
||||
@@ -123,87 +201,117 @@
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:0c507b7f74b3d2dd4d1322ec8a94794927305ab4cebbe89cc47fe5e81541e6e8",
|
||||
"sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736",
|
||||
"sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f",
|
||||
"sha256:326420cbb492172dec84b0f65c80942de6cedb5233c413dd824483989c000608",
|
||||
"sha256:4474f8ea030b5127225b8894d626bb66c01cda098d47a2b0d3429b6700af9fd8",
|
||||
"sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab",
|
||||
"sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7",
|
||||
"sha256:5f84523c076ad14ff5e6c037fe1c89a7f73a3e04cf0377cb4d017014976433f3",
|
||||
"sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1",
|
||||
"sha256:b4c423ab23291d3945ac61346feeb9a0dc4184999ede5e7c43e1ffb975130ae6",
|
||||
"sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8",
|
||||
"sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4",
|
||||
"sha256:ca233c64c6e40eaa6c66ef97058cdc80e8d0157a443655baa1b2966e812807ca",
|
||||
"sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269"
|
||||
"sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
|
||||
"sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
|
||||
"sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
|
||||
"sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
|
||||
"sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
|
||||
"sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
|
||||
"sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
|
||||
"sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
|
||||
"sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
|
||||
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
|
||||
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
|
||||
],
|
||||
"version": "==3.12"
|
||||
"version": "==3.13"
|
||||
},
|
||||
"raven": {
|
||||
"hashes": [
|
||||
"sha256:0adae40e004dfe2181d1f2883aa3d4ca1cf16dbe449ae4b445b011c6eb220a90",
|
||||
"sha256:84da75114739191bdf2388f296ffd6177e83567a7fbaf2701e034ad6026e4f3b"
|
||||
"sha256:3fd787d19ebb49919268f06f19310e8112d619ef364f7989246fc8753d469888",
|
||||
"sha256:95f44f3ea2c1b176d5450df4becdb96c15bf2632888f9ab193e9dd22300ce46a"
|
||||
],
|
||||
"version": "==6.5.0"
|
||||
"version": "==6.9.0"
|
||||
},
|
||||
"red-trivia": {
|
||||
"raven-aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:39413b9fb3f9b9362d6de1dcf69a4bf635b0f3518243f7178299b96d26cbb6a7"
|
||||
"sha256:1444a49c93a85b8bb57c6ee649e512368dce7a26ad64ac3a01d86aa5669d77f3",
|
||||
"sha256:6a34b6a9841ad0fd827eeb158edb5826c5c5bd7babe2cde2a3f23eb85313af04"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"red-lavalink": {
|
||||
"hashes": [
|
||||
"sha256:6a1a34471ccf4630eee537049568dd87e8e93614f1d1ce355dd74e5b10079782"
|
||||
],
|
||||
"version": "==0.1.2"
|
||||
},
|
||||
"websockets": {
|
||||
"hashes": [
|
||||
"sha256:09dfec40e9b73e8808c39ecdbc1733e33915a2b26b90c54566afc0af546a9ec3",
|
||||
"sha256:2aa6d52264cecb08d39741e8fda49f5ac4872aef02617230c84d02e861f3cc5a",
|
||||
"sha256:2f5b7f3920f29609086fb0b63552bb1f86a04b8cbdcc0dbf3775cc90d489dfc8",
|
||||
"sha256:3d38f76f71654268e5533b45df125ff208fee242a102d4b5ca958da5cf5fb345",
|
||||
"sha256:3fcc7dfb365e81ff8206f950c86d1e73accdf3be2f9110c0cb73be32d2e7a9a5",
|
||||
"sha256:4128212ab6f91afda03a0c697add261bdf6946b47928db83f07298ea2cd8d937",
|
||||
"sha256:43e5b9f51dd0000a4c6f646e2ade0c886bd14a784ffac08b9e079bd17a63bcc5",
|
||||
"sha256:4a932c17cb11c361c286c04842dc2385cc7157019bbba8b64808acbc89a95584",
|
||||
"sha256:5ddc5fc121eb76771e990f071071d9530e27d20e8cfb804d9f5823de055837af",
|
||||
"sha256:7347af28fcc70eb45be409760c2a428f8199e7f73c04a621916c3c219ed7ad27",
|
||||
"sha256:85ae1e4b36aa2e90de56d211d2de36d7c093d00277a9afdd9b4f81e69c0214ab",
|
||||
"sha256:8a29100079f5b91a72bcd25d35a7354db985d3babae42d00b9d629f9a0aaa8ac",
|
||||
"sha256:a7e7585c8e3c0f9277ad7d6ee6ccddc69649cd216255d5e255d68f90482aeefa",
|
||||
"sha256:aa42ecef3aed807e23218c264b1e82004cdd131a6698a10b57fc3d8af8f651fc",
|
||||
"sha256:b19e7ede1ba80ee9de6f5b8ccd31beee25402e68bef7c13eeb0b8bc46bc4b7b7",
|
||||
"sha256:c4c5b5ce2d66cb0cf193c14bc9726adca095febef0f7b2c04e5e3fa3487a97a4",
|
||||
"sha256:de743ef26b002efceea7d7756e99e5d38bf5d4f27563b8d27df2a9a5cc57340a",
|
||||
"sha256:e1e568136ad5cb6768504be36d470a136b072acbf3ea882303aee6361be01941",
|
||||
"sha256:e8992f1db371f2a1c5af59e032d9dc7c1aa92f16241efcda695b7d955b4de0c2",
|
||||
"sha256:e9c1cdbb591432c59d0b5ca64fd30b6d517024767f152fc169563b26e7bcc9da"
|
||||
"sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136",
|
||||
"sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6",
|
||||
"sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1",
|
||||
"sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538",
|
||||
"sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4",
|
||||
"sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908",
|
||||
"sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0",
|
||||
"sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d",
|
||||
"sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c",
|
||||
"sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d",
|
||||
"sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c",
|
||||
"sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb",
|
||||
"sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf",
|
||||
"sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e",
|
||||
"sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96",
|
||||
"sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584",
|
||||
"sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484",
|
||||
"sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d",
|
||||
"sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559",
|
||||
"sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff",
|
||||
"sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"
|
||||
],
|
||||
"version": "==3.4"
|
||||
"markers": "python_version >= '3.4'",
|
||||
"version": "==6.0"
|
||||
},
|
||||
"yarl": {
|
||||
"hashes": [
|
||||
"sha256:605480ee43eead69ec8e8c52cdfefc79cef6379cc0e87d908cf290408c1e49af",
|
||||
"sha256:7fad2530cb4ddf2b74c1e4f6f9f0e28eac482094c6542f98fd71ecf67fb4fded",
|
||||
"sha256:837d866a70f1ea03005914a740bddea89a253afabd6589db981b91738768bd25",
|
||||
"sha256:885e40812ff9fc80e6f28ef04ad6396e3ae583ab504b1a76301fdcec7fc9f30f",
|
||||
"sha256:a5457e075eab1170141774a8c69906c223ea0088eaebd6ef91b04b33527fa905",
|
||||
"sha256:baa0d3f7982fa0c03a55433109c405e79a597141f2e2d6ee7e16c03eabd74886",
|
||||
"sha256:beeefbe0edd47fc8b657bf7bf44791f7a6e5b14f3de1846daf999687cb68c156",
|
||||
"sha256:cf6a3d6fd3e79d3457d520c12d5d18b030d5ca5d0b205ca6481857804d8d944d",
|
||||
"sha256:d07d3dc6849345b7437dc58ea49ad2a1960017386d86288550728ca38e482ddc",
|
||||
"sha256:d81e45bedefccb97e4e8f7d32cfae0af1d9eadd1ae795fc420c8319c3dab2a28",
|
||||
"sha256:e1da2853a92fbc7e2d0248bbfa931cd621121e70ce6dda7c1eeef3516d51b46c",
|
||||
"sha256:f1201de3e93fb1efc3111c8928d9366875edefd65d77c0f6b847fe299e8e1122",
|
||||
"sha256:fe0390a29b5c7e90975feefe863e3d3a851be546bd797b23f338d24a15efa920"
|
||||
"sha256:2556b779125621b311844a072e0ed367e8409a18fa12cbd68eb1258d187820f9",
|
||||
"sha256:4aec0769f1799a9d4496827292c02a7b1f75c0bab56ab2b60dd94ebb57cbd5ee",
|
||||
"sha256:55369d95afaacf2fa6b49c84d18b51f1704a6560c432a0f9a1aeb23f7b971308",
|
||||
"sha256:6c098b85442c8fe3303e708bbb775afd0f6b29f77612e8892627bcab4b939357",
|
||||
"sha256:9182cd6f93412d32e009020a44d6d170d2093646464a88aeec2aef50592f8c78",
|
||||
"sha256:c8cbc21bbfa1dd7d5386d48cc814fe3d35b80f60299cdde9279046f399c3b0d8",
|
||||
"sha256:db6f70a4b09cde813a4807843abaaa60f3b15fb4a2a06f9ae9c311472662daa1",
|
||||
"sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4",
|
||||
"sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7"
|
||||
],
|
||||
"version": "==0.18.0"
|
||||
"markers": "python_version >= '3.4.1'",
|
||||
"version": "==1.2.6"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:1a112a1fdf3802b7f2b182e22e51d71e4a8fa7387d0d38e79a268921b869e384",
|
||||
"sha256:33aa7c937ebaf063a860cbb0c263a771b33333a84965c6148eeafe64fb4e29ca",
|
||||
"sha256:550b4a0788500f6d00f41b7fdd9fcce6d78f99706a7b2f6f81d4d331c7ca468e",
|
||||
"sha256:601e8e83123b4d423a9dfddf7d6943f4f520651a78ffcd50c99d065136c7ff7b",
|
||||
"sha256:620f19ba7628b70b177f5c2e6a55a6fd6e7c8591cde38c3f8f52551733d31b66",
|
||||
"sha256:70d56c784da1239c89d39fefa166fd429306dada641178389be4184a9c04e501",
|
||||
"sha256:7de2c9e445a5d257935011268202338538abef1aaff341a4733eca56419ca6f6",
|
||||
"sha256:96bb80b659cc2bafa160f3f0c346ce7fc10de1ffec4908d7f9690797f155f658",
|
||||
"sha256:ae7501cc6a6c37b8d4774bf2218c37be47fe42019a2570e8510fc2044e59d573",
|
||||
"sha256:c833aa6f4c9ac3e3eb843e3d999bae51339ad33a937303f43ce78064e61cb4b6",
|
||||
"sha256:dd81d85a342edf3d2a388e2f24d9facebc9c04550043888f970ee2f228c93059",
|
||||
"sha256:f20deec7a3fbaec7b5eb7ad99878427ad2ee4cc16a46732b705e8121cbb3cc12",
|
||||
"sha256:f52e7287eb9286a1e91e4c67c207c2573147fbaddc68f70efb5aeee5d1992f2e",
|
||||
"sha256:fe7b2972ff7e779e812f974aa5695edc328ecf559ceeea887ac46f06f090ad4c",
|
||||
"sha256:ff1447c84a02b9cd5dd3a9332d1fb181a4386c3625765bb5caf1cfbc210ab3f9"
|
||||
],
|
||||
"version": "==3.3.2"
|
||||
},
|
||||
"aiohttp-json-rpc": {
|
||||
"hashes": [
|
||||
"sha256:970806a3b9887c389095d2bde84e2b540fefeddd0bae0efcae03c65f092ce00e",
|
||||
"sha256:d6f365067676e6089ac043ad31bcbabbf33d0343c42b57c36751a562fbe64fb6"
|
||||
],
|
||||
"version": "==0.11.1"
|
||||
},
|
||||
"alabaster": {
|
||||
"hashes": [
|
||||
"sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732",
|
||||
"sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0"
|
||||
"sha256:674bb3bab080f598371f4443c5008cbfeb1a5e622dd312395d2d82af2c54c456",
|
||||
"sha256:b63b1f4dc77c074d386752ec4a8a7517600f6c0db8cd42980cae17ab7b3275d7"
|
||||
],
|
||||
"version": "==0.7.10"
|
||||
"version": "==0.7.11"
|
||||
},
|
||||
"appdirs": {
|
||||
"hashes": [
|
||||
@@ -212,19 +320,28 @@
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:474d4bc64cee20603e225eb1ece15e248962958b45a3648a9f5cc29e827a610c",
|
||||
"sha256:b3c0ddc416736619bd4a95ca31de8da6920c3b9a140c64dbef2b2fa7bf521287"
|
||||
],
|
||||
"markers": "python_version >= '3.5.3'",
|
||||
"version": "==3.0.0"
|
||||
},
|
||||
"atomicwrites": {
|
||||
"hashes": [
|
||||
"sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585",
|
||||
"sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6"
|
||||
"sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
|
||||
"sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
|
||||
],
|
||||
"version": "==1.1.5"
|
||||
"markers": "python_version != '3.2.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==1.2.1"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
|
||||
"sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
|
||||
"sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
|
||||
"sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
|
||||
],
|
||||
"version": "==18.1.0"
|
||||
"version": "==18.2.0"
|
||||
},
|
||||
"babel": {
|
||||
"hashes": [
|
||||
@@ -235,18 +352,17 @@
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:3efe92eafbde15f8ac06478de11cfb84e47504896ccdde64507e751d2f91ec3a",
|
||||
"sha256:fc26c4ab28c541fb824f59fa83d5702f75829495d5a1dee603b29bc4fbe79095"
|
||||
"sha256:22158b89c1a6b4eb333a1e65e791a3f8b998cf3b11ae094adb2570f31f769a44",
|
||||
"sha256:4b475bbd528acce094c503a3d2dbc2d05a4075f6d0ef7d9e7514518e14cc5191"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==18.6b2"
|
||||
"version": "==18.6b4"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
|
||||
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
|
||||
"sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638",
|
||||
"sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a"
|
||||
],
|
||||
"version": "==2018.4.16"
|
||||
"version": "==2018.8.24"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
@@ -262,6 +378,20 @@
|
||||
],
|
||||
"version": "==6.7"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:463f8483208e921368c9f306094eb6f725c6ca42b0f97e313cb5d5512459feda",
|
||||
"sha256:48eb22f4f8461b1df5734a074b57042430fb06e1d61bd1e11b078c0fe6d7a1f1"
|
||||
],
|
||||
"version": "==0.3.9"
|
||||
},
|
||||
"distro": {
|
||||
"hashes": [
|
||||
"sha256:224041cef9600e72d19ae41ba006e71c05c4dc802516da715d7fda55ba3d8742",
|
||||
"sha256:6ec8e539cf412830e5ccf521aecf879f2c7fcf60ce446e33cd16eef1ed8a0158"
|
||||
],
|
||||
"version": "==1.3.0"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
|
||||
@@ -270,19 +400,42 @@
|
||||
],
|
||||
"version": "==0.14"
|
||||
},
|
||||
"e1839a9": {
|
||||
"editable": true,
|
||||
"extras": [
|
||||
"docs",
|
||||
"test",
|
||||
"style"
|
||||
],
|
||||
"path": "."
|
||||
},
|
||||
"fuzzywuzzy": {
|
||||
"hashes": [
|
||||
"sha256:5ac7c0b3f4658d2743aa17da53a55598144edbc5bee3c6863840636e6926f254",
|
||||
"sha256:6f49de47db00e1c71d40ad16da42284ac357936fa9b66bea1df63fed07122d62"
|
||||
],
|
||||
"version": "==0.17.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
|
||||
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
|
||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
||||
],
|
||||
"version": "==2.6"
|
||||
"version": "==2.7"
|
||||
},
|
||||
"idna-ssl": {
|
||||
"hashes": [
|
||||
"sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"imagesize": {
|
||||
"hashes": [
|
||||
"sha256:3620cc0cadba3f7475f9940d22431fc4d407269f1be59ec9b8edcca26440cf18",
|
||||
"sha256:5b326e4678b6925158ccc66a9fa3122b6106d7c876ee32d7de6ce59385b96315"
|
||||
"sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
|
||||
"sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
|
||||
],
|
||||
"version": "==1.0.0"
|
||||
"markers": "python_version != '3.2.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
@@ -299,11 +452,45 @@
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8",
|
||||
"sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3",
|
||||
"sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0"
|
||||
"sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
|
||||
"sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
|
||||
"sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
|
||||
],
|
||||
"version": "==4.2.0"
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"multidict": {
|
||||
"hashes": [
|
||||
"sha256:112eeeddd226af681dc82b756ed34aa7b6d98f9c4a15760050298c21d715473d",
|
||||
"sha256:13b64ecb692effcabc5e29569ba9b5eb69c35112f990a16d6833ec3a9d9f8ec0",
|
||||
"sha256:1725373fb8f18c2166f8e0e5789851ccf98453c849b403945fa4ef59a16ca44e",
|
||||
"sha256:2061a50b7cae60a1f987503a995b2fc38e47027a937a355a124306ed9c629041",
|
||||
"sha256:35b062288a9a478f627c520fd27983160fc97591017d170f966805b428d17e07",
|
||||
"sha256:467b134bcc227b91b8e2ef8d2931f28b50bf7eb7a04c0403d102ded22e66dbfc",
|
||||
"sha256:475a3ece8bb450e49385414ebfae7f8fdb33f62f1ac0c12935c1cfb1b7c1076a",
|
||||
"sha256:49b885287e227a24545a1126d9ac17ae43138610713dc6219b781cc0ad5c6dfc",
|
||||
"sha256:4c95b2725592adb5c46642be2875c1234c32af841732c5504c17726b92082021",
|
||||
"sha256:4ea7ed00f4be0f7335c9a2713a65ac3d986be789ce5ebc10821da9664cbe6b85",
|
||||
"sha256:5e2d5e1d999e941b4a626aea46bdc4206877cf727107fdaa9d46a8a773a6e49b",
|
||||
"sha256:8039c520ef7bb9ec7c3db3df14c570be6362f43c200ae9854d2422d4ffe175a4",
|
||||
"sha256:81459a0ebcca09c1fcb8fe887ed13cf267d9b60fe33718fc5fd1a2a1ab49470a",
|
||||
"sha256:847c3b7b9ca3268e883685dc1347a4d09f84de7bd7597310044d847590447492",
|
||||
"sha256:8551d1db45f0ca4e8ec99130767009a29a4e0dc6558a4a6808491bcd3472d325",
|
||||
"sha256:8fa7679ffe615e0c1c7b80946ab4194669be74848719adf2d7867b5e861eb073",
|
||||
"sha256:a42a36f09f0f907579ff0fde547f2fde8a739a69efe4a2728835979d2bb5e17b",
|
||||
"sha256:a5fcad0070685c5b2d04b468bf5f4c735f5c176432f495ad055fcc4bc0a79b23",
|
||||
"sha256:ae22195b2a7494619b73c01129ddcddc0dfaa9e42727404b1d9a77253da3f420",
|
||||
"sha256:b360e82bdbbd862e1ce2a41cc3bbd0ab614350e813ca74801b34aac0f73465aa",
|
||||
"sha256:b96417899344c5e96bef757f4963a72d02e52653a4e0f99bbea3a531cedac59f",
|
||||
"sha256:b9e921140b797093edfc13ac08dc2a4fd016dd711dc42bb0e1aaf180e48425a7",
|
||||
"sha256:c5022b94fc330e6d177f3eb38097fb52c7df96ca0e04842c068cf0d9fc38b1e6",
|
||||
"sha256:cf2b117f2a8d951638efc7592fb72d3eeb2d38cc2194c26ba7f00e7190451d92",
|
||||
"sha256:d79620b542d9d0e23ae9790ca2fe44f1af40ffad9936efa37bd14954bc3e2818",
|
||||
"sha256:e2860691c11d10dac7c91bddae44f6211b3da4122d9a2ebb509c2247674d6070",
|
||||
"sha256:e3a293553715afecf7e10ea02da40593f9d7f48fe48a74fc5dd3ce08a0c46188",
|
||||
"sha256:e465be3fe7e992e5a6e16731afa6f41cb6ca53afccb4f28ea2fa6457783edf15",
|
||||
"sha256:e6d27895ef922bc859d969452f247bfbe5345d9aba69b9c8dbe1ea7704f0c5d9"
|
||||
],
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"packaging": {
|
||||
"hashes": [
|
||||
@@ -314,18 +501,19 @@
|
||||
},
|
||||
"pluggy": {
|
||||
"hashes": [
|
||||
"sha256:7f8ae7f5bdf75671a718d2daf0a64b7885f74510bcd98b1a0bb420eb9a9d0cff",
|
||||
"sha256:d345c8fe681115900d6da8d048ba67c25df42973bda370783cd58826442dcd7c",
|
||||
"sha256:e160a7fcf25762bb60efc7e171d4497ff1d8d2d75a3d0df7a21b76821ecbf5c5"
|
||||
"sha256:6e3836e39f4d36ae72840833db137f7b7d35105079aee6ec4a62d9f80d594dd1",
|
||||
"sha256:95eb8364a4708392bae89035f45341871286a333f749c3141c20573d2b3876e1"
|
||||
],
|
||||
"version": "==0.6.0"
|
||||
"markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*'",
|
||||
"version": "==0.7.1"
|
||||
},
|
||||
"py": {
|
||||
"hashes": [
|
||||
"sha256:29c9fab495d7528e80ba1e343b958684f4ace687327e6f789a94bf3d1915f881",
|
||||
"sha256:983f77f3331356039fdd792e9220b7b8ee1aa6bd2b25f567a963ff1de5a64f6a"
|
||||
"sha256:06a30435d058473046be836d3fc4f27167fd84c45b99704f2fb5509ef61f9af1",
|
||||
"sha256:50402e9d1c9005d759426988a492e0edaadb7f4e68bcddfea586bc7432d009c6"
|
||||
],
|
||||
"version": "==1.5.3"
|
||||
"markers": "python_version != '3.2.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.1.*'",
|
||||
"version": "==1.6.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
@@ -337,44 +525,74 @@
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:0832bcf47acd283788593e7a0f542407bd9550a55a8a8435214a1960e04bcb04",
|
||||
"sha256:281683241b25fe9b80ec9d66017485f6deff1af5cde372469134b56ca8447a07",
|
||||
"sha256:8f1e18d3fd36c6795bb7e02a39fd05c611ffc2596c1e0d995d34d67630426c18",
|
||||
"sha256:9e8143a3e15c13713506886badd96ca4b579a87fbdf49e550dbfc057d6cb218e",
|
||||
"sha256:b8b3117ed9bdf45e14dcc89345ce638ec7e0e29b2b579fa1ecf32ce45ebac8a5",
|
||||
"sha256:e4d45427c6e20a59bf4f88c639dcc03ce30d193112047f94012102f235853a58",
|
||||
"sha256:fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"pytest": {
|
||||
"hashes": [
|
||||
"sha256:26838b2bc58620e01675485491504c3aa7ee0faf335c37fcd5f8731ca4319591",
|
||||
"sha256:32c49a69566aa7c333188149ad48b58ac11a426d5352ea3d8f6ce843f88199cb"
|
||||
"sha256:2d7c49e931316cc7d1638a3e5f54f5d7b4e5225972b3c9838f3584788d27f349",
|
||||
"sha256:ad0c7db7b5d4081631e0155f5c61b80ad76ce148551aaafe3a718d65a7508b18"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.6.1"
|
||||
"version": "==3.7.4"
|
||||
},
|
||||
"pytest-asyncio": {
|
||||
"hashes": [
|
||||
"sha256:286b50773e996c80d894b95afaf45df6952408a67a59979ca9839f94693ec7fd",
|
||||
"sha256:f32804bb58a66e13a3eda11f8942a71b1b6a30466b0d2ffe9214787aab0e172e"
|
||||
"sha256:a962e8e1b6ec28648c8fe214edab4e16bacdb37b52df26eb9d63050af309b2a9",
|
||||
"sha256:fbd92c067c16111174a1286bfb253660f1e564e5146b39eeed1133315cf2c2cf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.8.0"
|
||||
"markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*'",
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"python-levenshtein": {
|
||||
"hashes": [
|
||||
"sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1"
|
||||
],
|
||||
"version": "==0.12.0"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:65ae0c8101309c45772196b21b74c46b2e5d11b6275c45d251b150d5da334555",
|
||||
"sha256:c06425302f2cf668f1bba7a0a03f3c1d34d4ebeef2c72003da308b3947c7f749"
|
||||
"sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
|
||||
"sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
|
||||
],
|
||||
"version": "==2018.4"
|
||||
"version": "==2018.5"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
|
||||
"sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
|
||||
"sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
|
||||
"sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
|
||||
"sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
|
||||
"sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
|
||||
"sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
|
||||
"sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
|
||||
"sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
|
||||
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
|
||||
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
|
||||
],
|
||||
"version": "==3.13"
|
||||
},
|
||||
"raven": {
|
||||
"hashes": [
|
||||
"sha256:3fd787d19ebb49919268f06f19310e8112d619ef364f7989246fc8753d469888",
|
||||
"sha256:95f44f3ea2c1b176d5450df4becdb96c15bf2632888f9ab193e9dd22300ce46a"
|
||||
],
|
||||
"version": "==6.9.0"
|
||||
},
|
||||
"raven-aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:1444a49c93a85b8bb57c6ee649e512368dce7a26ad64ac3a01d86aa5669d77f3",
|
||||
"sha256:6a34b6a9841ad0fd827eeb158edb5826c5c5bd7babe2cde2a3f23eb85313af04"
|
||||
],
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
|
||||
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
|
||||
"sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1",
|
||||
"sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a"
|
||||
],
|
||||
"version": "==2.18.4"
|
||||
"version": "==2.19.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
@@ -392,25 +610,22 @@
|
||||
},
|
||||
"sphinx": {
|
||||
"hashes": [
|
||||
"sha256:85f7e32c8ef07f4ba5aeca728e0f7717bef0789fba8458b8d9c5c294cad134f3",
|
||||
"sha256:d45480a229edf70d84ca9fae3784162b1bc75ee47e480ffe04a4b7f21a95d76d"
|
||||
"sha256:a07050845cc9a2f4026a6035cc8ed795a5ce7be6528bbc82032385c10807dfe7",
|
||||
"sha256:d719de667218d763e8fd144b7fcfeefd8d434a6201f76bf9f0f0c1fa6f47fcdb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.5"
|
||||
"version": "==1.7.8"
|
||||
},
|
||||
"sphinx-rtd-theme": {
|
||||
"hashes": [
|
||||
"sha256:aa3e190392e963551432de7df24b8a5fbe5b71a2f4fcd9d5b75808b52ad999e5",
|
||||
"sha256:de88d637a60371d4f923e06b79c4ba260490c57d2ab5a8316942ab5d9a6ce1bf"
|
||||
"sha256:3b49758a64f8a1ebd8a33cb6cc9093c3935a908b716edfaa5772fd86aac27ef6",
|
||||
"sha256:80e01ec0eb711abacb1fa507f3eae8b805ae8fa3e8b057abfdf497e3f644c82c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.4.0"
|
||||
"version": "==0.4.1"
|
||||
},
|
||||
"sphinxcontrib-asyncio": {
|
||||
"hashes": [
|
||||
"sha256:96627b1ec4eba08d09ad577ff9416c131910333ef37a2c82a2716e59646739f0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"sphinxcontrib-websupport": {
|
||||
@@ -418,6 +633,7 @@
|
||||
"sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
|
||||
"sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
|
||||
],
|
||||
"markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*'",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"toml": {
|
||||
@@ -428,25 +644,69 @@
|
||||
},
|
||||
"tox": {
|
||||
"hashes": [
|
||||
"sha256:96efa09710a3daeeb845561ebbe1497641d9cef2ee0aea30db6969058b2bda2f",
|
||||
"sha256:9ee7de958a43806402a38c0d2aa07fa8553f4d2c20a15b140e9f771c2afeade0"
|
||||
"sha256:37cf240781b662fb790710c6998527e65ca6851eace84d1595ee71f7af4e85f7",
|
||||
"sha256:eb61aa5bcce65325538686f09848f04ef679b5cd9b83cc491272099b28739600"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.0"
|
||||
"version": "==3.2.1"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
|
||||
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
|
||||
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
|
||||
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
|
||||
],
|
||||
"version": "==1.22"
|
||||
"markers": "python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version < '4' and python_version >= '2.6' and python_version != '3.1.*'",
|
||||
"version": "==1.23"
|
||||
},
|
||||
"virtualenv": {
|
||||
"hashes": [
|
||||
"sha256:2ce32cd126117ce2c539f0134eb89de91a8413a29baac49cbab3eb50e2026669",
|
||||
"sha256:ca07b4c0b54e14a91af9f34d0919790b016923d157afda5efdde55c96718f752"
|
||||
],
|
||||
"markers": "python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.1.*'",
|
||||
"version": "==16.0.0"
|
||||
},
|
||||
"websockets": {
|
||||
"hashes": [
|
||||
"sha256:0e2f7d6567838369af074f0ef4d0b802d19fa1fee135d864acc656ceefa33136",
|
||||
"sha256:2a16dac282b2fdae75178d0ed3d5b9bc3258dabfae50196cbb30578d84b6f6a6",
|
||||
"sha256:5a1fa6072405648cb5b3688e9ed3b94be683ce4a4e5723e6f5d34859dee495c1",
|
||||
"sha256:5c1f55a1274df9d6a37553fef8cff2958515438c58920897675c9bc70f5a0538",
|
||||
"sha256:669d1e46f165e0ad152ed8197f7edead22854a6c90419f544e0f234cc9dac6c4",
|
||||
"sha256:695e34c4dbea18d09ab2c258994a8bf6a09564e762655408241f6a14592d2908",
|
||||
"sha256:6b2e03d69afa8d20253455e67b64de1a82ff8612db105113cccec35d3f8429f0",
|
||||
"sha256:79ca7cdda7ad4e3663ea3c43bfa8637fc5d5604c7737f19a8964781abbd1148d",
|
||||
"sha256:7fd2dd9a856f72e6ed06f82facfce01d119b88457cd4b47b7ae501e8e11eba9c",
|
||||
"sha256:82c0354ac39379d836719a77ee360ef865377aa6fdead87909d50248d0f05f4d",
|
||||
"sha256:8f3b956d11c5b301206382726210dc1d3bee1a9ccf7aadf895aaf31f71c3716c",
|
||||
"sha256:91ec98640220ae05b34b79ee88abf27f97ef7c61cf525eec57ea8fcea9f7dddb",
|
||||
"sha256:952be9540d83dba815569d5cb5f31708801e0bbfc3a8c5aef1890b57ed7e58bf",
|
||||
"sha256:99ac266af38ba1b1fe13975aea01ac0e14bb5f3a3200d2c69f05385768b8568e",
|
||||
"sha256:9fa122e7adb24232247f8a89f2d9070bf64b7869daf93ac5e19546b409e47e96",
|
||||
"sha256:a0873eadc4b8ca93e2e848d490809e0123eea154aa44ecd0109c4d0171869584",
|
||||
"sha256:cb998bd4d93af46b8b49ecf5a72c0a98e5cc6d57fdca6527ba78ad89d6606484",
|
||||
"sha256:e02e57346f6a68523e3c43bbdf35dde5c440318d1f827208ae455f6a2ace446d",
|
||||
"sha256:e79a5a896bcee7fff24a788d72e5c69f13e61369d055f28113e71945a7eb1559",
|
||||
"sha256:ee55eb6bcf23ecc975e6b47c127c201b913598f38b6a300075f84eeef2d3baff",
|
||||
"sha256:f1414e6cbcea8d22843e7eafdfdfae3dd1aba41d1945f6ca66e4806c07c4f454"
|
||||
],
|
||||
"markers": "python_version >= '3.4'",
|
||||
"version": "==6.0"
|
||||
},
|
||||
"yarl": {
|
||||
"hashes": [
|
||||
"sha256:2556b779125621b311844a072e0ed367e8409a18fa12cbd68eb1258d187820f9",
|
||||
"sha256:4aec0769f1799a9d4496827292c02a7b1f75c0bab56ab2b60dd94ebb57cbd5ee",
|
||||
"sha256:55369d95afaacf2fa6b49c84d18b51f1704a6560c432a0f9a1aeb23f7b971308",
|
||||
"sha256:6c098b85442c8fe3303e708bbb775afd0f6b29f77612e8892627bcab4b939357",
|
||||
"sha256:9182cd6f93412d32e009020a44d6d170d2093646464a88aeec2aef50592f8c78",
|
||||
"sha256:c8cbc21bbfa1dd7d5386d48cc814fe3d35b80f60299cdde9279046f399c3b0d8",
|
||||
"sha256:db6f70a4b09cde813a4807843abaaa60f3b15fb4a2a06f9ae9c311472662daa1",
|
||||
"sha256:f17495e6fe3d377e3faac68121caef6f974fcb9e046bc075bcff40d8e5cc69a4",
|
||||
"sha256:f85900b9cca0c67767bb61b2b9bd53208aaa7373dae633dbe25d179b4bf38aa7"
|
||||
],
|
||||
"markers": "python_version >= '3.4.1'",
|
||||
"version": "==1.2.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
135
README.md
Normal file
135
README.md
Normal file
@@ -0,0 +1,135 @@
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/Cog-Creators/Red-DiscordBot/tree/V3/develop"><img src="https://imgur.com/pY1WUFX.png" alt="Red - Discord Bot"></a>
|
||||
<br>
|
||||
Red Discord Bot
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<h4 align="center">Music, Moderation, Trivia, Stream Alerts and Fully Modular.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://discord.gg/red">
|
||||
<img src="https://discordapp.com/api/guilds/133049272517001216/widget.png?style=shield" alt="Discord Server">
|
||||
</a>
|
||||
<a href="https://www.patreon.com/Red_Devs">
|
||||
<img src="https://img.shields.io/badge/Support-Red!-yellow.svg" alt="Support Red on Patreon!">
|
||||
</a>
|
||||
<a href="https://www.python.org/downloads/">
|
||||
<img src="https://img.shields.io/badge/Made%20With-Python%203-blue.svg?style=for-the-badge" alt="Made with Python 3">
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/red-discordbot">
|
||||
<img src="https://d322cqt584bo4o.cloudfront.net/red-discordbot/localized.svg" alt="Localized with Crowdin">
|
||||
</a>
|
||||
<a href="https://github.com/Rapptz/discord.py/tree/rewrite">
|
||||
<img src="https://img.shields.io/badge/discord-py-blue.svg" alt="discord.py">
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/Cog-Creators/Red-DiscordBot">
|
||||
<img src="https://api.travis-ci.org/Cog-Creators/Red-DiscordBot.svg?branch=V3/develop" alt="Travis CI">
|
||||
</a>
|
||||
<a href="http://red-discordbot.readthedocs.io/en/v3-develop/?badge=v3-develop">
|
||||
<img src="https://readthedocs.org/projects/red-discordbot/badge/?version=v3-develop" alt="Red on readthedocs.org">
|
||||
</a>
|
||||
<a href="https://github.com/ambv/black">
|
||||
<img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code Style: Black">
|
||||
</a>
|
||||
<a href="http://makeapullrequest.com">
|
||||
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#overview">Overview</a>
|
||||
•
|
||||
<a href="#installation">Installation</a>
|
||||
•
|
||||
<a href="http://red-discordbot.readthedocs.io/en/v3-develop/index.html">Documentation</a>
|
||||
•
|
||||
<a href="#plugins">Plugins</a>
|
||||
•
|
||||
<a href="#join-the-community">Community</a>
|
||||
•
|
||||
<a href="#license">License</a>
|
||||
</p>
|
||||
|
||||
# Overview
|
||||
|
||||
Red is a fully modular bot – meaning all features and commands can be enabled/disabled to your
|
||||
liking, making it completely customizable. This is also a *self-hosted bot* – meaning you will need
|
||||
to host and maintain your own instance. You can turn Red into an admin bot, music bot, trivia bot,
|
||||
new best friend or all of these together!
|
||||
|
||||
[Installation](#installation) is easy, and you do **NOT** need to know anything about coding! Aside
|
||||
from installation and updating, every part of the bot can be controlled from within Discord.
|
||||
|
||||
**The default set of modules includes and is not limited to:**
|
||||
|
||||
- Moderation features (kick/ban/softban/hackban, mod-log, filter, chat cleanup)
|
||||
- Trivia (lists are included and can be easily added)
|
||||
- Music features (YouTube, SoundCloud, local files, playlists, queues)
|
||||
- Stream alerts (Twitch, Youtube, Mixer, Hitbox, Picarto)
|
||||
- Bank (slot machine, user credits)
|
||||
- Custom commands
|
||||
- Imgur/gif search
|
||||
- Admin automation (self-role assignment, cross-server announcements, mod-mail reports)
|
||||
- Customisable command permissions
|
||||
|
||||
**Additionally, other [plugins](#plugins) (cogs) can be easily found and added from our growing
|
||||
community of cog repositories.**
|
||||
|
||||
# Installation
|
||||
|
||||
**The following platforms are officially supported:**
|
||||
|
||||
- [Windows](https://red-discordbot.readthedocs.io/en/v3-develop/install_windows.html)
|
||||
- [MacOS](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
- [Ubuntu](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
- [Debian Stretch](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
- [CentOS 7](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
- [Arch Linux](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
- [Raspbian Stretch](https://red-discordbot.readthedocs.io/en/v3-develop/install_linux_mac.html)
|
||||
|
||||
Already using **Red** V2? Take a look at the [Data Converter](https://red-discordbot.readthedocs.io/en/v3-develop/cog_dataconverter.html)
|
||||
to import your data to V3.
|
||||
|
||||
If after reading the guide you are still experiencing issues, feel free to join the
|
||||
[Official Discord Server](https://discord.gg/red) and ask in the **#v3-support** channel for help.
|
||||
|
||||
# Plugins
|
||||
|
||||
Red is fully modular, allowing you to load and unload plugins of your choice, and install 3rd party
|
||||
plugins directly from Discord! A few examples are:
|
||||
|
||||
- Cleverbot integration (talk to Red and she talks back)
|
||||
- Ban sync
|
||||
- Welcome messages
|
||||
- Casino
|
||||
- Reaction roles
|
||||
- Slow Mode
|
||||
- Anilist
|
||||
- And much, much more!
|
||||
|
||||
Feel free to take a [peek](https://github.com/Cog-Creators/Red-DiscordBot/issues/1398) at a list of
|
||||
available 3rd party cogs!
|
||||
|
||||
# Join the community!
|
||||
|
||||
**Red** is in continuous development, and it’s supported by an active community which produces new
|
||||
content (cogs/plugins) for everyone to enjoy. New features are constantly added. If you can’t
|
||||
[find](https://github.com/Cog-Creators/Red-DiscordBot/issues/1398) the cog you’re looking for,
|
||||
consult our [guide](https://red-discordbot.readthedocs.io/en/v3-develop/guide_cog_creation.html) on
|
||||
building your own cogs!
|
||||
|
||||
Join us on our [Official Discord Server](https://discord.gg/red)!
|
||||
|
||||
# License
|
||||
|
||||
Released under the [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html) license.
|
||||
|
||||
Red is named after the main character of "Transistor", a video game by
|
||||
[Super Giant Games](https://www.supergiantgames.com/games/transistor/).
|
||||
|
||||
Artwork created by [Sinlaire](https://sinlaire.deviantart.com/) on Deviant Art for the Red Discord
|
||||
Bot Project.
|
||||
97
README.rst
97
README.rst
@@ -1,97 +0,0 @@
|
||||
.. class:: center
|
||||
|
||||
.. image:: https://imgur.com/pY1WUFX.png
|
||||
:target: https://github.com/Cog-Creators/Red-DiscordBot/tree/V3/develop
|
||||
:alt: Red Discord Bot
|
||||
|
||||
|
||||
.. class:: center
|
||||
|
||||
Music, Moderation, Trivia, Stream Alerts and fully customizable.
|
||||
|
||||
.. class:: center
|
||||
|
||||
.. image:: https://readthedocs.org/projects/red-discordbot/badge/?version=v3-develop
|
||||
:target: http://red-discordbot.readthedocs.io/en/v3-develop/?badge=v3-develop
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/ambv/black
|
||||
:alt: Code style: black
|
||||
|
||||
.. image:: https://d322cqt584bo4o.cloudfront.net/red-discordbot/localized.svg
|
||||
:target: https://crowdin.com/project/red-discordbot
|
||||
:alt: Crowdin
|
||||
|
||||
.. image:: https://img.shields.io/badge/Support-Red!-orange.svg
|
||||
:target: https://www.patreon.com/Red_Devs
|
||||
:alt: Patreon
|
||||
|
||||
==========
|
||||
Overview
|
||||
==========
|
||||
|
||||
Red is a fully modular bot – meaning all features and commands can be enabled/disabled to your liking, making it completely customizable.
|
||||
This is also a *self-hosted bot* – meaning you will need to host and maintain your own instance. You can turn Red into an admin bot, music bot, trivia bot, new best friend or all of these together!
|
||||
|
||||
`Installation <#installation>`_ is easy, and you do **NOT** need to know anything about coding! Aside from installation and updating, every part of the bot can be controlled from within Discord.
|
||||
|
||||
**The default set of modules includes and is not limited to:**
|
||||
|
||||
- Moderation features (kick/ban/softban/hackban, mod-log, filter, chat cleanup)
|
||||
- Trivia (lists are included and can be easily added)
|
||||
- Music features (YouTube, SoundCloud, local files, playlists, queues)
|
||||
- Stream alerts (Twitch, Youtube, Mixer, Hitbox, Picarto)
|
||||
- Slot machine
|
||||
- Custom commands
|
||||
- Imgur/gif search
|
||||
|
||||
|
||||
**Additionally, other plugins (cogs) can be easily found and added from our growing community of cog repositories.**
|
||||
|
||||
- Cleverbot integration (talk to Red and she talks back)
|
||||
- Ban sync
|
||||
- Welcome messages
|
||||
- Casino
|
||||
- Reaction roles
|
||||
- Slow Mode
|
||||
- Anilist
|
||||
- And much, much more!
|
||||
|
||||
Feel free to take a `peek <https://github.com/Cog-Creators/Red-DiscordBot/issues/1398>`_!
|
||||
|
||||
==============
|
||||
Installation
|
||||
==============
|
||||
|
||||
**The following platforms are officially supported:**
|
||||
|
||||
- `Windows <https://red-discordbot.readthedocs.io/en/v3-develop/install_windows.html>`_
|
||||
- `MacOS <https://red-discordbot.readthedocs.io/en/v3-develop/install_mac.html>`_
|
||||
- `Ubuntu <https://red-discordbot.readthedocs.io/en/v3-develop/install_ubuntu.html>`_
|
||||
- `Debian Stretch <https://red-discordbot.readthedocs.io/en/v3-develop/install_debian.html>`_
|
||||
- `CentOS 7 <https://red-discordbot.readthedocs.io/en/v3-develop/install_centos.html>`_
|
||||
- `Arch Linux <https://red-discordbot.readthedocs.io/en/v3-develop/install_arch.html>`_
|
||||
- `Raspbian Stretch <https://red-discordbot.readthedocs.io/en/v3-develop/install_raspbian.html>`_
|
||||
|
||||
Already using **Red** V2? Take a look at the `Data Converter <https://red-discordbot.readthedocs.io/en/v3-develop/cog_dataconverter.html>`_ to import your data to V3.
|
||||
|
||||
If `after reading the guides <https://red-discordbot.readthedocs.io/en/v3-develop/>`_ you are still experiencing issues, feel free to join the `Official Server <https://discord.gg/red>`_ and ask in the **#support** channel for help.
|
||||
|
||||
=====================
|
||||
Join the community!
|
||||
=====================
|
||||
|
||||
**Red** is in continuous development, and it’s supported by an active community which produces new content (cogs/plugins) for everyone to enjoy. New features are constantly added. If you can’t `find <https://github.com/Cog-Creators/Red-DiscordBot/issues/1398>`_ what you’re looking for, consult our `guide <https://red-discordbot.readthedocs.io/en/v3-develop/guide_cog_creation.html>`_ on building your own cogs!
|
||||
|
||||
Join us on our `Official Discord Server <https://discord.gg/red>`_!
|
||||
|
||||
=========
|
||||
License
|
||||
=========
|
||||
|
||||
Released under the `GNU GPL v3 <#License>`_.
|
||||
|
||||
Red is named after the main character of "Transistor", a videogame by `Super Giant Games <https://www.supergiantgames.com/games/transistor/>`_
|
||||
|
||||
Artwork created by `Sinlaire <https://sinlaire.deviantart.com/>`_ on Deviant Art for the Red Bot Project.
|
||||
@@ -1,5 +1,5 @@
|
||||
api_key_env: CROWDIN_API_KEY
|
||||
project_identifier_env: CROWDIN_PROJECT_ID
|
||||
files:
|
||||
- source: /**/*.pot
|
||||
- source: /redbot/**/*.pot
|
||||
translation: /%original_path%/%locale%.po
|
||||
|
||||
1
dependency_links.txt
Normal file
1
dependency_links.txt
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/Rapptz/discord.py/tarball/00a659c6526b2445162b52eaf970adbd22c6d35d#egg=discord.py-1.0.0a0
|
||||
@@ -10,7 +10,7 @@ Creating the service file
|
||||
|
||||
Create the new service file:
|
||||
|
||||
:code:`sudo nano /etc/systemd/system/red@.service`
|
||||
:code:`sudo -e /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):
|
||||
|
||||
|
||||
101
docs/cog_customcom.rst
Normal file
101
docs/cog_customcom.rst
Normal file
@@ -0,0 +1,101 @@
|
||||
.. CustomCommands Cog Reference
|
||||
|
||||
============================
|
||||
CustomCommands Cog Reference
|
||||
============================
|
||||
|
||||
------------
|
||||
How it works
|
||||
------------
|
||||
|
||||
CustomCommands allows you to create simple commands for your bot without requiring you to code your own cog for Red.
|
||||
|
||||
If the command you attempt to create shares a name with an already loaded command, you cannot overwrite it with this cog.
|
||||
|
||||
------------------
|
||||
Context Parameters
|
||||
------------------
|
||||
|
||||
You can enhance your custom command's response by leaving spaces for the bot to substitute.
|
||||
|
||||
+-----------+----------------------------------------+
|
||||
| Argument | Substitute |
|
||||
+===========+========================================+
|
||||
| {message} | The message the bot is responding to. |
|
||||
+-----------+----------------------------------------+
|
||||
| {author} | The user who called the command. |
|
||||
+-----------+----------------------------------------+
|
||||
| {channel} | The channel the command was called in. |
|
||||
+-----------+----------------------------------------+
|
||||
| {server} | The server the command was called in. |
|
||||
+-----------+----------------------------------------+
|
||||
| {guild} | Same as with {server}. |
|
||||
+-----------+----------------------------------------+
|
||||
|
||||
You can further refine the response with dot notation. For example, {author.mention} will mention the user who called the command.
|
||||
|
||||
------------------
|
||||
Command Parameters
|
||||
------------------
|
||||
|
||||
You can further enhance your custom command's response by leaving spaces for the user to substitute.
|
||||
|
||||
To do this, simply put {#} in the response, replacing # with any number starting with 0. Each number will be replaced with what the user gave the command, in order.
|
||||
|
||||
You can refine the response with colon notation. For example, {0:Member} will accept members of the server, and {0:int} will accept a number. If no colon notation is provided, the argument will be returned unchanged.
|
||||
|
||||
+-----------------+--------------------------------+
|
||||
| Argument | Substitute |
|
||||
+=================+================================+
|
||||
| {#:Member} | A member of your server. |
|
||||
+-----------------+--------------------------------+
|
||||
| {#:TextChannel} | A text channel in your server. |
|
||||
+-----------------+--------------------------------+
|
||||
| {#:Role} | A role in your server. |
|
||||
+-----------------+--------------------------------+
|
||||
| {#:int} | A whole number. |
|
||||
+-----------------+--------------------------------+
|
||||
| {#:float} | A decimal number. |
|
||||
+-----------------+--------------------------------+
|
||||
| {#:bool} | True or False. |
|
||||
+-----------------+--------------------------------+
|
||||
|
||||
You can specify more than the above with colon notation, but those are the most common.
|
||||
|
||||
As with context parameters, you can use dot notation to further refine the response. For example, {0.mention:Member} will mention the Member specified.
|
||||
|
||||
----------------
|
||||
Example commands
|
||||
----------------
|
||||
|
||||
Showing your own avatar
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[p]customcom add simple avatar {author.avatar_url}
|
||||
[p]avatar
|
||||
https://cdn.discordapp.com/avatars/133801473317404673/be4c4a4fe47cb3e74c31a0504e7a295e.webp?size=1024
|
||||
|
||||
Repeating the user
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[p]customcom add simple say {0}
|
||||
[p]say Pete and Repeat
|
||||
Pete and Repeat
|
||||
|
||||
Greeting the specified member
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[p]customcom add simple greet Hello, {0.mention:Member}!
|
||||
[p]greet Twentysix
|
||||
Hello, @Twentysix!
|
||||
|
||||
Comparing two text channel's categories
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[p]customcom add simple comparecategory {0.category:TextChannel} | {1.category:TextChannel}
|
||||
[p]comparecategory #support #general
|
||||
Red | Community
|
||||
@@ -89,8 +89,10 @@ Locking Audio to specific voice channel(s) as a serverowner or admin:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
[p]permissions setguilddefault Audio deny
|
||||
[p]permissions addguildrule allow Audio [voice channel ID or name]
|
||||
[p]permissions setguilddefault deny play
|
||||
[p]permissions setguilddefault deny "playlist start"
|
||||
[p]permissions addguildrule allow play [voice channel ID or name]
|
||||
[p]permissions addguildrule allow "playlist start" [voice channel ID or name]
|
||||
|
||||
Allowing extra roles to use cleanup
|
||||
|
||||
|
||||
@@ -190,6 +190,13 @@ texinfo_documents = [
|
||||
]
|
||||
|
||||
|
||||
# -- Options for linkcheck builder ----------------------------------------
|
||||
|
||||
# A list of regular expressions that match URIs that should not be
|
||||
# checked when doing a linkcheck build.
|
||||
linkcheck_ignore = [r"https://java.com*"]
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {
|
||||
"python": ("https://docs.python.org/3.6", None),
|
||||
|
||||
@@ -5,8 +5,9 @@ Commands Package
|
||||
================
|
||||
|
||||
This package acts almost identically to :doc:`discord.ext.commands <dpy:ext/commands/api>`; i.e.
|
||||
they both have the same attributes. Some of these attributes, however, have been slightly modified,
|
||||
as outlined below.
|
||||
all of the attributes from discord.py's are also in ours.
|
||||
Some of these attributes, however, have been slightly modified, while others have been added to
|
||||
extend functionlities used throughout the bot, as outlined below.
|
||||
|
||||
.. autofunction:: redbot.core.commands.command
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ Keys common to both repo and cog info.json (case sensitive)
|
||||
- ``install_msg`` (string) - The message that gets displayed when a cog
|
||||
is installed or a repo is added
|
||||
|
||||
.. tip:: You can use the ``[p]`` key in your string to use the prefix
|
||||
used for installing.
|
||||
|
||||
- ``short`` (string) - A short description of the cog or repo. For cogs, this info
|
||||
is displayed when a user executes ``!cog list``
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
Utility Functions
|
||||
=================
|
||||
|
||||
General Utility
|
||||
===============
|
||||
|
||||
.. automodule:: redbot.core.utils
|
||||
:members: deduplicate_iterables, bounded_gather, bounded_gather_iter
|
||||
|
||||
Chat Formatting
|
||||
===============
|
||||
|
||||
@@ -39,3 +45,9 @@ Tunnel
|
||||
|
||||
.. automodule:: redbot.core.utils.tunnel
|
||||
:members: Tunnel
|
||||
|
||||
Common Filters
|
||||
==============
|
||||
|
||||
.. automodule:: redbot.core.utils.common_filters
|
||||
:members:
|
||||
|
||||
@@ -17,8 +17,7 @@ you in the process.
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
To start off, be sure that you have installed Python 3.5 or higher (if you
|
||||
are on Windows, stick with 3.5). Open a terminal or command prompt and type
|
||||
To start off, be sure that you have installed Python 3.6.2 or higher. Open a terminal or command prompt and type
|
||||
:code:`pip install --process-dependency-links -U git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=redbot[test]`
|
||||
(note that if you get an error with this, try again but put :code:`python -m` in front of the command
|
||||
This will install the latest version of V3.
|
||||
@@ -45,7 +44,7 @@ In that file, place the following code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from discord.ext import commands
|
||||
from redbot.core import commands
|
||||
|
||||
class Mycog:
|
||||
"""My custom cog"""
|
||||
|
||||
@@ -11,13 +11,8 @@ Welcome to Red - Discord Bot's documentation!
|
||||
:caption: Installation Guides:
|
||||
|
||||
install_windows
|
||||
install_mac
|
||||
install_ubuntu_xenial
|
||||
install_ubuntu_bionic
|
||||
install_debian
|
||||
install_centos
|
||||
install_arch
|
||||
install_raspbian
|
||||
install_linux_mac
|
||||
venv_guide
|
||||
cog_dataconverter
|
||||
autostart_systemd
|
||||
|
||||
@@ -25,6 +20,7 @@ Welcome to Red - Discord Bot's documentation!
|
||||
:maxdepth: 2
|
||||
:caption: Cog Reference:
|
||||
|
||||
cog_customcom
|
||||
cog_downloader
|
||||
cog_permissions
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
.. 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.
|
||||
@@ -1,55 +0,0 @@
|
||||
.. centos install guide
|
||||
|
||||
==========================
|
||||
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
|
||||
---------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
yum -y groupinstall development
|
||||
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
|
||||
yum -y install yum-utils wget which python36u python36u-pip python36u-devel openssl-devel libffi-devel git java-1.8.0-openjdk
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
--------------
|
||||
|
||||
Without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
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 an 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.
|
||||
@@ -1,70 +0,0 @@
|
||||
.. debian install guide
|
||||
|
||||
================================
|
||||
Installing Red on Debian Stretch
|
||||
================================
|
||||
|
||||
.. 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
|
||||
---------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev git unzip default-jre
|
||||
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
After that last command, you may see a warning about 'pyenv' not being in the load path. Follow the instructions given to fix that, then close and reopen your shell
|
||||
|
||||
Then run the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CONFIGURE_OPTS=--enable-optimizations pyenv install 3.6.5 -v
|
||||
|
||||
This may take a long time to complete.
|
||||
|
||||
After that is finished, run:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pyenv global 3.6.5
|
||||
|
||||
------------------
|
||||
Installing the bot
|
||||
------------------
|
||||
|
||||
To install without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot`
|
||||
|
||||
To install with audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
|
||||
|
||||
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`
|
||||
|
||||
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]`
|
||||
|
||||
------------------------
|
||||
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.
|
||||
203
docs/install_linux_mac.rst
Normal file
203
docs/install_linux_mac.rst
Normal file
@@ -0,0 +1,203 @@
|
||||
.. _linux-mac-install-guide:
|
||||
|
||||
==============================
|
||||
Installing Red on Linux or Mac
|
||||
==============================
|
||||
|
||||
.. warning::
|
||||
|
||||
For safety reasons, DO NOT install Red with a root user. If you are unsure how to create
|
||||
a new user, see the man page for the ``useradd`` command.
|
||||
|
||||
-------------------------------
|
||||
Installing the pre-requirements
|
||||
-------------------------------
|
||||
|
||||
Please install the pre-requirements using the commands listed for your operating system.
|
||||
|
||||
The pre-requirements are:
|
||||
- Python 3.6.2 or greater
|
||||
- pip 9.0 or greater
|
||||
- git
|
||||
- Java Runtime Environment 8 or later (for audio support)
|
||||
|
||||
~~~~~~~~~~
|
||||
Arch Linux
|
||||
~~~~~~~~~~
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo pacman -Syu python-pip git base-devel jre8-openjdk
|
||||
|
||||
~~~~~~~~
|
||||
CentOS 7
|
||||
~~~~~~~~
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
yum -y groupinstall development
|
||||
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
|
||||
yum -y install yum-utils wget which python36u python36u-pip python36u-devel openssl-devel libffi-devel git java-1.8.0-openjdk
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Debian and Raspbian Stretch
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. warning::
|
||||
|
||||
Audio will not work on Raspberry Pi's **below** 2B. This is a CPU problem and
|
||||
*cannot* be fixed.
|
||||
|
||||
We recommend installing pyenv as a method of installing non-native versions of python on
|
||||
Debian/Raspbian Stretch. This guide will tell you how. First, run the following commands:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev git unzip default-jre
|
||||
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
After that last command, you may see a warning about 'pyenv' not being in the load path. Follow the
|
||||
instructions given to fix that, then close and reopen your shell.
|
||||
|
||||
Then run the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CONFIGURE_OPTS=--enable-optimizations pyenv install 3.7.0 -v
|
||||
|
||||
This may take a long time to complete.
|
||||
|
||||
After that is finished, run:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pyenv global 3.7.0
|
||||
|
||||
Pyenv is now installed and your system should be configured to run Python 3.7.
|
||||
|
||||
~~~
|
||||
Mac
|
||||
~~~
|
||||
|
||||
Install Brew: in Finder or Spotlight, search for and open *Terminal*. In the terminal, paste the
|
||||
following, then press Enter:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
|
||||
After the installation, install the required packages by pasting the commands and pressing enter,
|
||||
one-by-one:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
brew install python3 --with-brewed-openssl
|
||||
brew install git
|
||||
brew tap caskroom/versions
|
||||
brew cask install java8
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Ubuntu 18.04 Bionic Beaver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install python3.6-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Ubuntu 16.04 Xenial Xerus
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We recommend adding the ``deadsnakes`` apt repository to install Python 3.6.2 or greater:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install software-properties-common
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt update
|
||||
|
||||
Now, install python, pip, git and java with the following commands:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install python3.6-dev build-essential libssl-dev libffi-dev git unzip default-jre wget -y
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python3.6 get-pip.py
|
||||
|
||||
------------------------------
|
||||
Creating a Virtual Environment
|
||||
------------------------------
|
||||
|
||||
We **strongly** recommend installing Red into a virtual environment. See the section
|
||||
`installing-in-virtual-environment`.
|
||||
|
||||
.. _installing-red-linux-mac:
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
--------------
|
||||
|
||||
Choose one of the following commands to install Red.
|
||||
|
||||
.. note::
|
||||
|
||||
If you're not inside an activated virtual environment, include the ``--user`` flag with all
|
||||
``pip3`` commands.
|
||||
|
||||
To install without audio support:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pip3 install -U --process-dependency-links --no-cache-dir Red-DiscordBot
|
||||
|
||||
Or, to install with audio support:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pip3 install -U --process-dependency-links --no-cache-dir Red-DiscordBot[voice]
|
||||
|
||||
Or, install with audio and MongoDB support:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pip3 install -U --process-dependency-links --no-cache-dir Red-DiscordBot[voice,mongo]
|
||||
|
||||
.. note::
|
||||
|
||||
To install the development version, replace ``Red-DiscordBot`` in the above commands with the
|
||||
following link:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=Red-DiscordBot
|
||||
|
||||
--------------------------
|
||||
Setting Up and Running Red
|
||||
--------------------------
|
||||
|
||||
After installation, set up your instance with the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot-setup
|
||||
|
||||
This will set the location where data will be stored, as well as your
|
||||
storage backend and the name of the instance (which will be used for
|
||||
running the bot).
|
||||
|
||||
Once done setting up the instance, run the following command to run Red:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot <your instance name>
|
||||
|
||||
It will walk through the initial setup, asking for your token and a prefix.
|
||||
|
||||
You may also run Red via the launcher, which allows you to restart the bot
|
||||
from discord, and enable auto-restart. You may also update the bot from the
|
||||
launcher menu. Use the following command to run the launcher:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot-launcher
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
.. mac install guide
|
||||
|
||||
=====================
|
||||
Installing Red on Mac
|
||||
=====================
|
||||
|
||||
---------------------------
|
||||
Installing pre-requirements
|
||||
---------------------------
|
||||
|
||||
* Install Brew
|
||||
* In Finder or Spotlight, search for and open terminal. In the window that will open, paste this:
|
||||
:code:`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
|
||||
and press enter.
|
||||
* 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 tap caskroom/versions`
|
||||
* :code:`brew cask install java8`
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
--------------
|
||||
|
||||
Without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot`
|
||||
|
||||
With audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot[voice]`
|
||||
|
||||
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`
|
||||
|
||||
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]`
|
||||
|
||||
----------------------
|
||||
Setting up an instance
|
||||
----------------------
|
||||
|
||||
To set up an instance, run :code:`redbot-setup` and follow the steps there, providing the requested information
|
||||
or accepting the defaults. Keep in mind that the instance name will be the one you use when running the bot, so
|
||||
make it something you can remember
|
||||
|
||||
-----------
|
||||
Running Red
|
||||
-----------
|
||||
|
||||
Run :code:`redbot <your instance name>` and go through the initial setup (it will ask for the token and a prefix).
|
||||
@@ -1,72 +0,0 @@
|
||||
.. raspbian install guide
|
||||
|
||||
==================================
|
||||
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 install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev git unzip default-jre
|
||||
curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
|
||||
|
||||
After that last command, you may see a warning about 'pyenv' not being in the load path. Follow the instructions given to fix that, then close and reopen your shell
|
||||
|
||||
Then run the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CONFIGURE_OPTS=--enable-optimizations pyenv install 3.6.5 -v
|
||||
|
||||
This may take a long time to complete.
|
||||
|
||||
After that is finished, run:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
pyenv global 3.6.5
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
--------------
|
||||
|
||||
Without audio:
|
||||
|
||||
:code:`pip3 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
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 an 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.
|
||||
|
||||
.. warning:: Audio will not work on Raspberry Pi's **below** 2B. This is a CPU problem and *cannot* be fixed.
|
||||
@@ -1,54 +0,0 @@
|
||||
.. ubuntu bionic install guide
|
||||
|
||||
==============================
|
||||
Installing Red on Ubuntu 18.04
|
||||
==============================
|
||||
|
||||
.. 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
|
||||
-------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install python3.6-dev python3-pip build-essential libssl-dev libffi-dev git unzip default-jre -y
|
||||
|
||||
|
||||
------------------
|
||||
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.
|
||||
@@ -1,59 +0,0 @@
|
||||
.. ubuntu xenial install guide
|
||||
|
||||
==============================
|
||||
Installing Red on Ubuntu 16.04
|
||||
==============================
|
||||
|
||||
.. 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
|
||||
-------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
sudo apt install software-properties-common
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt update
|
||||
sudo apt install python3.6-dev build-essential libssl-dev libffi-dev git unzip default-jre wget -y
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python3.6 get-pip.py
|
||||
|
||||
|
||||
------------------
|
||||
Installing the bot
|
||||
------------------
|
||||
|
||||
To install without audio:
|
||||
|
||||
:code:`pip3.6 install -U --process-dependency-links red-discordbot --user`
|
||||
|
||||
To install with audio:
|
||||
|
||||
:code:`pip3.6 install -U --process-dependency-links red-discordbot[voice] --user`
|
||||
|
||||
To install the development version (without audio):
|
||||
|
||||
:code:`pip3.6 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.6 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.
|
||||
@@ -1,4 +1,4 @@
|
||||
.. windows installation docs
|
||||
.. _windows-install-guide:
|
||||
|
||||
=========================
|
||||
Installing Red on Windows
|
||||
@@ -8,7 +8,7 @@ Installing Red on Windows
|
||||
Needed Software
|
||||
---------------
|
||||
|
||||
* `Python <https://python.org/downloads/>`_ - Red needs Python 3.6
|
||||
* `Python <https://www.python.org/downloads/>`_ - Red needs Python 3.6.2 or greater
|
||||
|
||||
.. note:: Please make sure that the box to add Python to PATH is CHECKED, otherwise
|
||||
you may run into issues when trying to run Red
|
||||
@@ -21,23 +21,74 @@ Needed Software
|
||||
|
||||
.. attention:: Please choose the "Windows Online" installer
|
||||
|
||||
.. _installing-red-windows:
|
||||
|
||||
--------------
|
||||
Installing Red
|
||||
--------------
|
||||
|
||||
1. Open a command prompt (open Start, search for "command prompt", then click it)
|
||||
2. Run the appropriate command, depending on if you want audio or not
|
||||
2. Create and activate a virtual environment (strongly recommended), see the section `using-venv`
|
||||
3. Run **one** of the following commands, depending on what extras you want installed
|
||||
|
||||
* No audio: :code:`python -m pip install -U --process-dependency-links Red-DiscordBot`
|
||||
* Audio: :code:`python -m pip install -U --process-dependency-links Red-DiscordBot[voice]`
|
||||
* Development version (without audio): :code:`python -m pip install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot`
|
||||
* Development version (with audio): :code:`python -m pip install -U --process-dependency-links git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=red-discordbot[voice]`
|
||||
.. note::
|
||||
|
||||
3. Once that has completed, run :code:`redbot-setup` to set up your instance
|
||||
If you're not inside an activated virtual environment, include the ``--user`` flag with all
|
||||
``pip`` commands.
|
||||
|
||||
* This will set the location where data will be stored, as well as your
|
||||
storage backend and the name of the instance (which will be used for
|
||||
running the bot)
|
||||
* No audio:
|
||||
|
||||
4. Once done setting up the instance, run :code:`redbot <your instance name>` to run Red.
|
||||
It will walk through the initial setup, asking for your token and a prefix
|
||||
.. code-block:: none
|
||||
|
||||
python -m pip install -U --process-dependency-links --no-cache-dir Red-DiscordBot
|
||||
|
||||
* With audio:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
python -m pip install -U --process-dependency-links --no-cache-dir Red-DiscordBot[voice]
|
||||
|
||||
* With audio and MongoDB support:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
python -m pip install -U --process-dependency-links --no-cache-dir Red-DiscordBot[voice,mongo]
|
||||
|
||||
.. note::
|
||||
|
||||
To install the development version, replace ``Red-DiscordBot`` in the above commands with the
|
||||
following link:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
git+https://github.com/Cog-Creators/Red-DiscordBot@V3/develop#egg=Red-DiscordBot
|
||||
|
||||
--------------------------
|
||||
Setting Up and Running Red
|
||||
--------------------------
|
||||
|
||||
After installation, set up your instance with the following command:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot-setup
|
||||
|
||||
This will set the location where data will be stored, as well as your
|
||||
storage backend and the name of the instance (which will be used for
|
||||
running the bot).
|
||||
|
||||
Once done setting up the instance, run the following command to run Red:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot <your instance name>
|
||||
|
||||
It will walk through the initial setup, asking for your token and a prefix.
|
||||
|
||||
You may also run Red via the launcher, which allows you to restart the bot
|
||||
from discord, and enable auto-restart. You may also update the bot from the
|
||||
launcher menu. Use the following command to run the launcher:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
redbot-launcher
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
-i https://pypi.org/simple
|
||||
alabaster==0.7.10
|
||||
appdirs==1.4.3
|
||||
atomicwrites==1.1.5
|
||||
attrs==18.1.0
|
||||
babel==2.6.0
|
||||
black==18.6b2
|
||||
certifi==2018.4.16
|
||||
chardet==3.0.4
|
||||
click==6.7
|
||||
docutils==0.14
|
||||
idna==2.6
|
||||
imagesize==1.0.0
|
||||
jinja2==2.10
|
||||
markupsafe==1.0
|
||||
more-itertools==4.2.0
|
||||
packaging==17.1
|
||||
pluggy==0.6.0
|
||||
py==1.5.3
|
||||
pygments==2.2.0
|
||||
pyparsing==2.2.0
|
||||
pytest-asyncio==0.8.0
|
||||
pytest==3.6.1
|
||||
pytz==2018.4
|
||||
requests==2.18.4
|
||||
six==1.11.0
|
||||
snowballstemmer==1.2.1
|
||||
sphinx-rtd-theme==0.4.0
|
||||
sphinx==1.7.5
|
||||
sphinxcontrib-asyncio==0.2.0
|
||||
sphinxcontrib-websupport==1.1.0
|
||||
toml==0.9.4
|
||||
tox==3.0.0
|
||||
urllib3==1.22
|
||||
virtualenv==16.0.0
|
||||
yarl==0.18.0
|
||||
git+https://github.com/Rapptz/discord.py@7eb918b19e3e60b56eb9039eb267f8f3477c5e17#egg=discord.py-1.0
|
||||
132
docs/venv_guide.rst
Normal file
132
docs/venv_guide.rst
Normal file
@@ -0,0 +1,132 @@
|
||||
.. _installing-in-virtual-environment:
|
||||
|
||||
=======================================
|
||||
Installing Red in a Virtual Environment
|
||||
=======================================
|
||||
Virtual environments allow you to isolate red's library dependencies, cog dependencies and python
|
||||
binaries from the rest of your system. It is strongly recommended you use this if you use python
|
||||
for more than just Red.
|
||||
|
||||
.. _using-venv:
|
||||
|
||||
--------------
|
||||
Using ``venv``
|
||||
--------------
|
||||
This is the quickest way to get your virtual environment up and running, as `venv` is shipped with
|
||||
python.
|
||||
|
||||
First, choose a directory where you would like to create your virtual environment. It's a good idea
|
||||
to keep it in a location which is easy to type out the path to. From now, we'll call it
|
||||
``path/to/venv/`` (or ``path\to\venv\`` on Windows).
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
``venv`` on Linux or Mac
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Create your virtual environment with the following command::
|
||||
|
||||
python3 -m venv path/to/venv/
|
||||
|
||||
And activate it with the following command::
|
||||
|
||||
source path/to/venv/bin/activate
|
||||
|
||||
.. important::
|
||||
|
||||
You must activate the virtual environment with the above command every time you open a new
|
||||
shell to run, install or update Red.
|
||||
|
||||
Continue reading `below <after-activating-virtual-environment>`.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
``venv`` on Windows
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Create your virtual environment with the following command::
|
||||
|
||||
python -m venv path\to\venv\
|
||||
|
||||
And activate it with the following command::
|
||||
|
||||
path\to\venv\Scripts\activate.bat
|
||||
|
||||
.. important::
|
||||
|
||||
You must activate the virtual environment with the above command every time you open a new
|
||||
Command Prompt to run, install or update Red.
|
||||
|
||||
Continue reading `below <after-activating-virtual-environment>`.
|
||||
|
||||
.. _using-pyenv-virtualenv:
|
||||
|
||||
--------------------------
|
||||
Using ``pyenv virtualenv``
|
||||
--------------------------
|
||||
|
||||
.. note::
|
||||
|
||||
This is for non-Windows users only.
|
||||
|
||||
Using ``pyenv virtualenv`` saves you the headache of remembering where you installed your virtual
|
||||
environments. If you haven't already, install pyenv with `pyenv-installer`_.
|
||||
|
||||
First, ensure your pyenv interpreter is set to python 3.6.2 or greater with the following command::
|
||||
|
||||
pyenv version
|
||||
|
||||
Now, create a virtual environment with the following command::
|
||||
|
||||
pyenv virtualenv <name>
|
||||
|
||||
Replace ``<name>`` with whatever you like. If you forget what you named it, use the command ``pyenv
|
||||
versions``.
|
||||
|
||||
Now activate your virtualenv with the following command::
|
||||
|
||||
pyenv shell <name>
|
||||
|
||||
.. important::
|
||||
|
||||
You must activate the virtual environment with the above command every time you open a new
|
||||
shell to run, install or update Red.
|
||||
|
||||
Continue reading `below <after-activating-virtual-environment>`.
|
||||
|
||||
.. _pyenv-installer: https://github.com/pyenv/pyenv-installer/blob/master/README.rst
|
||||
|
||||
----
|
||||
|
||||
.. _after-activating-virtual-environment:
|
||||
|
||||
Once activated, your ``PATH`` environment variable will be modified to use the virtual
|
||||
environment's python executables, as well as other executables like ``pip``.
|
||||
|
||||
From here, install Red using the commands listed on your installation guide (`Windows
|
||||
<installing-red-windows>` or `Non-Windows <installing-red-linux-mac>`).
|
||||
|
||||
.. note::
|
||||
|
||||
The alternative to activating the virtual environment each time you open a new shell is to
|
||||
provide the full path to the executable. This will automatically use the virtual environment's
|
||||
python interpreter and installed libraries.
|
||||
|
||||
--------------------------------------------
|
||||
Virtual Environments with Multiple Instances
|
||||
--------------------------------------------
|
||||
If you are running multiple instances of Red on the same machine, you have the option of either
|
||||
using the same virtual environment for all of them, or creating separate ones.
|
||||
|
||||
.. note::
|
||||
|
||||
This only applies for multiple instances of V3. If you are running a V2 instance as well,
|
||||
You **must** use separate virtual environments.
|
||||
|
||||
The advantages of using a *single* virtual environment for all of your V3 instances are:
|
||||
|
||||
- When updating Red, you will only need to update it once for all instances (however you will still need to restart all instances for the changes to take effect)
|
||||
- It will save space on your hard drive
|
||||
|
||||
On the other hand, you may wish to update each of your instances individually.
|
||||
|
||||
.. important::
|
||||
|
||||
Windows users with multiple instances should create *separate* virtual environments, as
|
||||
updating multiple running instances at once is likely to cause errors.
|
||||
@@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
interpreter = sys.executable
|
||||
print(interpreter)
|
||||
root_dir = os.getcwd()
|
||||
cogs = [i for i in os.listdir("redbot/cogs") if os.path.isdir(os.path.join("redbot/cogs", i))]
|
||||
for d in cogs:
|
||||
if "locales" in os.listdir(os.path.join("redbot/cogs", d)):
|
||||
os.chdir(os.path.join("redbot/cogs", d, "locales"))
|
||||
if "regen_messages.py" not in os.listdir(os.getcwd()):
|
||||
print(
|
||||
f"Directory 'locales' exists for {d} but no 'regen_messages.py' is available!"
|
||||
)
|
||||
return 1
|
||||
else:
|
||||
print("Running 'regen_messages.py' for {}".format(d))
|
||||
retval = subprocess.run([interpreter, "regen_messages.py"])
|
||||
if retval.returncode != 0:
|
||||
return 1
|
||||
os.chdir(root_dir)
|
||||
os.chdir("redbot/core/locales")
|
||||
print("Running 'regen_messages.py' for core")
|
||||
retval = subprocess.run([interpreter, "regen_messages.py"])
|
||||
if retval.returncode != 0:
|
||||
return 1
|
||||
os.chdir(root_dir)
|
||||
subprocess.run(["crowdin", "upload"])
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -1,6 +1,7 @@
|
||||
import sys
|
||||
import warnings
|
||||
import discord
|
||||
from colorama import init, Back
|
||||
from colorama import init
|
||||
|
||||
init()
|
||||
# Let's do all the dumb version checking in one place.
|
||||
@@ -13,11 +14,5 @@ if discord.version_info.major < 1:
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
if sys.version_info < (3, 6, 0):
|
||||
print(Back.RED + "[DEPRECATION WARNING]")
|
||||
print(
|
||||
Back.RED + "You are currently running Python 3.5."
|
||||
" Support for Python 3.5 will end with the release of beta 16."
|
||||
" Please update your environment to Python 3.6 as soon as possible to avoid"
|
||||
" any interruptions after the beta 16 release."
|
||||
)
|
||||
# Filter fuzzywuzzy slow sequence matcher warning
|
||||
warnings.filterwarnings("ignore", module=r"fuzzywuzzy.*")
|
||||
|
||||
@@ -6,7 +6,7 @@ import sys
|
||||
import discord
|
||||
from redbot.core.bot import Red, ExitCodes
|
||||
from redbot.core.cog_manager import CogManagerUI
|
||||
from redbot.core.data_manager import load_basic_configuration, config_file
|
||||
from redbot.core.data_manager import create_temp_config, load_basic_configuration, config_file
|
||||
from redbot.core.json_io import JsonIO
|
||||
from redbot.core.global_checks import init_global_checks
|
||||
from redbot.core.events import init_events
|
||||
@@ -19,6 +19,18 @@ import logging.handlers
|
||||
import logging
|
||||
import os
|
||||
|
||||
# Let's not force this dependency, uvloop is much faster on cpython
|
||||
if sys.implementation.name == "cpython":
|
||||
try:
|
||||
import uvloop
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
||||
|
||||
if sys.platform == "win32":
|
||||
asyncio.set_event_loop(asyncio.ProactorEventLoop())
|
||||
|
||||
|
||||
#
|
||||
# Red - Discord Bot v3
|
||||
@@ -51,7 +63,7 @@ def init_loggers(cli_flags):
|
||||
os.environ["PYTHONASYNCIODEBUG"] = "1"
|
||||
logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
logger.setLevel(logging.WARNING)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
from redbot.core.data_manager import core_data_path
|
||||
|
||||
@@ -106,9 +118,17 @@ def main():
|
||||
elif cli_flags.version:
|
||||
print(description)
|
||||
sys.exit(0)
|
||||
elif not cli_flags.instance_name:
|
||||
elif not cli_flags.instance_name and not cli_flags.no_instance:
|
||||
print("Error: No instance name was provided!")
|
||||
sys.exit(1)
|
||||
if cli_flags.no_instance:
|
||||
print(
|
||||
"\033[1m"
|
||||
"Warning: The data will be placed in a temporary folder and removed on next system reboot."
|
||||
"\033[0m"
|
||||
)
|
||||
cli_flags.instance_name = "temporary_red"
|
||||
create_temp_config()
|
||||
load_basic_configuration(cli_flags.instance_name)
|
||||
log, sentry_log = init_loggers(cli_flags)
|
||||
red = Red(cli_flags=cli_flags, description=description, pm_help=None)
|
||||
@@ -122,6 +142,8 @@ def main():
|
||||
tmp_data = {}
|
||||
loop.run_until_complete(_get_prefix_and_token(red, tmp_data))
|
||||
token = os.environ.get("RED_TOKEN", tmp_data["token"])
|
||||
if cli_flags.token:
|
||||
token = cli_flags.token
|
||||
prefix = cli_flags.prefix or tmp_data["prefix"]
|
||||
if not (token and prefix):
|
||||
if cli_flags.no_prompt is False:
|
||||
@@ -139,14 +161,9 @@ def main():
|
||||
if tmp_data["enable_sentry"]:
|
||||
red.enable_sentry()
|
||||
try:
|
||||
loop.run_until_complete(red.start(token, bot=not cli_flags.not_bot))
|
||||
loop.run_until_complete(red.start(token, bot=True))
|
||||
except discord.LoginFailure:
|
||||
log.critical(
|
||||
"This token doesn't seem to be valid. If it belongs to "
|
||||
"a user account, remember that the --not-bot flag "
|
||||
"must be used. For self-bot functionalities instead, "
|
||||
"--self-bot"
|
||||
)
|
||||
log.critical("This token doesn't seem to be valid.")
|
||||
db_token = loop.run_until_complete(red.db.token())
|
||||
if db_token and not cli_flags.no_prompt:
|
||||
print("\nDo you want to reset the token? (y/n)")
|
||||
|
||||
@@ -127,8 +127,8 @@ class Admin:
|
||||
self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None
|
||||
):
|
||||
"""
|
||||
Adds a role to a user. If user is left blank it defaults to the
|
||||
author of the command.
|
||||
Adds a role to a user.
|
||||
If user is left blank it defaults to the author of the command.
|
||||
"""
|
||||
if user is None:
|
||||
user = ctx.author
|
||||
@@ -136,7 +136,7 @@ class Admin:
|
||||
# noinspection PyTypeChecker
|
||||
await self._addrole(ctx, user, rolename)
|
||||
else:
|
||||
await self.complain(ctx, USER_HIERARCHY_ISSUE, member=ctx.author)
|
||||
await self.complain(ctx, USER_HIERARCHY_ISSUE, member=ctx.author, role=rolename)
|
||||
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@@ -145,8 +145,8 @@ class Admin:
|
||||
self, ctx: commands.Context, rolename: discord.Role, *, user: MemberDefaultAuthor = None
|
||||
):
|
||||
"""
|
||||
Removes a role from a user. If user is left blank it defaults to the
|
||||
author of the command.
|
||||
Removes a role from a user.
|
||||
If user is left blank it defaults to the author of the command.
|
||||
"""
|
||||
if user is None:
|
||||
user = ctx.author
|
||||
@@ -156,7 +156,7 @@ class Admin:
|
||||
else:
|
||||
await self.complain(ctx, USER_HIERARCHY_ISSUE)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def editrole(self, ctx: commands.Context):
|
||||
@@ -291,11 +291,11 @@ class Admin:
|
||||
# noinspection PyTypeChecker
|
||||
return valid_roles
|
||||
|
||||
@commands.guild_only()
|
||||
@commands.group(invoke_without_command=True)
|
||||
async def selfrole(self, ctx: commands.Context, *, selfrole: SelfRole):
|
||||
"""
|
||||
Add a role to yourself that server admins have configured as
|
||||
user settable.
|
||||
Add a role to yourself that server admins have configured as user settable.
|
||||
|
||||
NOTE: The role is case sensitive!
|
||||
"""
|
||||
@@ -313,7 +313,7 @@ class Admin:
|
||||
await self._removerole(ctx, ctx.author, selfrole)
|
||||
|
||||
@selfrole.command(name="add")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def selfrole_add(self, ctx: commands.Context, *, role: discord.Role):
|
||||
"""
|
||||
Add a role to the list of available selfroles.
|
||||
@@ -327,7 +327,7 @@ class Admin:
|
||||
await ctx.send("The selfroles list has been successfully modified.")
|
||||
|
||||
@selfrole.command(name="delete")
|
||||
@commands.has_permissions(manage_roles=True)
|
||||
@checks.admin_or_permissions(manage_roles=True)
|
||||
async def selfrole_delete(self, ctx: commands.Context, *, role: SelfRole):
|
||||
"""
|
||||
Removes a role from the list of available selfroles.
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../admin.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -170,13 +170,13 @@ class Alias:
|
||||
new_message.content = "{}{} {}".format(prefix, alias.command, args)
|
||||
await self.bot.process_commands(new_message)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
async def alias(self, ctx: commands.Context):
|
||||
"""Manage per-server aliases for commands"""
|
||||
pass
|
||||
|
||||
@alias.group(name="global", autohelp=True)
|
||||
@alias.group(name="global")
|
||||
async def global_(self, ctx: commands.Context):
|
||||
"""
|
||||
Manage global aliases.
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../alias.py:129
|
||||
msgid "No prefix found."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:198
|
||||
msgid "You attempted to create a new alias with the name {} but that name is already a command on this bot."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:205
|
||||
msgid "You attempted to create a new alias with the name {} but that alias already exists on this server."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:212
|
||||
msgid "You attempted to create a new alias with the name {} but that name is an invalid alias name. Alias names may not contain spaces."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:224
|
||||
msgid "A new alias with the trigger `{}` has been created."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:236
|
||||
msgid "You attempted to create a new global alias with the name {} but that name is already a command on this bot."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:243
|
||||
msgid "You attempted to create a new global alias with the name {} but that alias already exists on this server."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:250
|
||||
msgid "You attempted to create a new global alias with the name {} but that name is an invalid alias name. Alias names may not contain spaces."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:259
|
||||
msgid "A new global alias with the trigger `{}` has been created."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:274
|
||||
msgid "No such alias exists."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:283
|
||||
msgid "The `{}` alias will execute the command `{}`"
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:286
|
||||
msgid "There is no alias with the name `{}`"
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:298
|
||||
msgid "There are no aliases on this guild."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:302 ../alias.py:320
|
||||
msgid "Alias with the name `{}` was successfully deleted."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:305 ../alias.py:323
|
||||
msgid "Alias with name `{}` was not found."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:316
|
||||
msgid "There are no aliases on this bot."
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:331 ../alias.py:342
|
||||
msgid "Aliases:"
|
||||
msgstr ""
|
||||
|
||||
#: ../alias.py:333 ../alias.py:344
|
||||
msgid "There are no aliases on this server."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../alias.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -19,7 +19,7 @@ LAVALINK_DOWNLOAD_DIR = cog_data_path(raw_name="Audio")
|
||||
LAVALINK_JAR_FILE = LAVALINK_DOWNLOAD_DIR / "Lavalink.jar"
|
||||
|
||||
APP_YML_FILE = LAVALINK_DOWNLOAD_DIR / "application.yml"
|
||||
BUNDLED_APP_YML_FILE = Path(__file__).parent / "application.yml"
|
||||
BUNDLED_APP_YML_FILE = Path(__file__).parent / "data/application.yml"
|
||||
|
||||
|
||||
async def download_lavalink(session):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ lavalink:
|
||||
vimeo: true
|
||||
mixer: true
|
||||
http: true
|
||||
local: false
|
||||
local: true
|
||||
sentryDsn: ""
|
||||
bufferDurationMs: 400
|
||||
youtubePlaylistLoadLimit: 10000
|
||||
@@ -1,41 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\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,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../audio.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -1,9 +1,11 @@
|
||||
import shlex
|
||||
import shutil
|
||||
import asyncio
|
||||
from subprocess import Popen, DEVNULL, PIPE
|
||||
import asyncio.subprocess
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
from subprocess import Popen, DEVNULL
|
||||
from typing import Optional, Tuple
|
||||
|
||||
_JavaVersion = Tuple[int, int]
|
||||
@@ -45,23 +47,42 @@ async def has_java(loop) -> Tuple[bool, Optional[_JavaVersion]]:
|
||||
return False, None
|
||||
|
||||
version = await get_java_version(loop)
|
||||
return version >= (1, 8), version
|
||||
return (2, 0) > version >= (1, 8) or version >= (8, 0), version
|
||||
|
||||
|
||||
async def get_java_version(loop) -> _JavaVersion:
|
||||
"""
|
||||
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()
|
||||
_proc: asyncio.subprocess.Process = await asyncio.create_subprocess_exec(
|
||||
"java",
|
||||
"-version",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
loop=loop,
|
||||
)
|
||||
# java -version outputs to stderr
|
||||
_, err = await _proc.communicate()
|
||||
|
||||
version_info = str(err, encoding="utf-8")
|
||||
version_info: str = err.decode("utf-8")
|
||||
# We expect the output to look something like:
|
||||
# $ java -version
|
||||
# ...
|
||||
# ... version "MAJOR.MINOR.PATCH[_BUILD]" ...
|
||||
# ...
|
||||
# We only care about the major and minor parts though.
|
||||
version_line_re = re.compile(r'version "(?P<major>\d+).(?P<minor>\d+).\d+(?:_\d+)?"')
|
||||
|
||||
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)
|
||||
lines = version_info.splitlines()
|
||||
for line in lines:
|
||||
match = version_line_re.search(line)
|
||||
if match:
|
||||
return int(match["major"]), int(match["minor"])
|
||||
|
||||
raise RuntimeError(
|
||||
"The output of `java -version` was unexpected. Please report this issue on Red's "
|
||||
"issue tracker."
|
||||
)
|
||||
|
||||
|
||||
async def start_lavalink_server(loop):
|
||||
|
||||
@@ -17,13 +17,15 @@ def check_global_setting_guildowner():
|
||||
|
||||
async def pred(ctx: commands.Context):
|
||||
author = ctx.author
|
||||
if await ctx.bot.is_owner(author):
|
||||
return True
|
||||
if not await bank.is_global():
|
||||
if not isinstance(ctx.channel, discord.abc.GuildChannel):
|
||||
return False
|
||||
if await ctx.bot.is_owner(author):
|
||||
return True
|
||||
permissions = ctx.channel.permissions_for(author)
|
||||
return author == ctx.guild.owner or permissions.administrator
|
||||
else:
|
||||
return await ctx.bot.is_owner(author)
|
||||
|
||||
return commands.check(pred)
|
||||
|
||||
@@ -36,15 +38,17 @@ def check_global_setting_admin():
|
||||
|
||||
async def pred(ctx: commands.Context):
|
||||
author = ctx.author
|
||||
if await ctx.bot.is_owner(author):
|
||||
return True
|
||||
if not await bank.is_global():
|
||||
if not isinstance(ctx.channel, discord.abc.GuildChannel):
|
||||
return False
|
||||
if await ctx.bot.is_owner(author):
|
||||
return True
|
||||
permissions = ctx.channel.permissions_for(author)
|
||||
is_guild_owner = author == ctx.guild.owner
|
||||
admin_role = await ctx.bot.db.guild(ctx.guild).admin_role()
|
||||
return admin_role in author.roles or is_guild_owner or permissions.manage_guild
|
||||
else:
|
||||
return await ctx.bot.is_owner(author)
|
||||
|
||||
return commands.check(pred)
|
||||
|
||||
@@ -58,8 +62,9 @@ class Bank:
|
||||
|
||||
# SECTION commands
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@check_global_setting_guildowner()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@commands.group(autohelp=True)
|
||||
async def bankset(self, ctx: commands.Context):
|
||||
"""Base command for bank settings"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../bank.py:68
|
||||
msgid "global"
|
||||
msgstr ""
|
||||
|
||||
#: ../bank.py:68
|
||||
msgid "per-guild"
|
||||
msgstr ""
|
||||
|
||||
#: ../bank.py:70
|
||||
msgid "The bank is now {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../bank.py:77
|
||||
msgid "Bank's name has been set to {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../bank.py:84
|
||||
msgid "Currency name has been set to {}"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../bank.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -1,4 +1,6 @@
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Union, List, Callable
|
||||
|
||||
import discord
|
||||
|
||||
@@ -49,50 +51,58 @@ class Cleanup:
|
||||
|
||||
@staticmethod
|
||||
async def get_messages_for_deletion(
|
||||
ctx: commands.Context,
|
||||
*,
|
||||
channel: discord.TextChannel,
|
||||
number,
|
||||
check=lambda x: True,
|
||||
limit=100,
|
||||
before=None,
|
||||
after=None,
|
||||
delete_pinned=False,
|
||||
) -> list:
|
||||
number: int = None,
|
||||
check: Callable[[discord.Message], bool] = lambda x: True,
|
||||
before: Union[discord.Message, datetime] = None,
|
||||
after: Union[discord.Message, datetime] = None,
|
||||
delete_pinned: bool = False,
|
||||
) -> List[discord.Message]:
|
||||
"""
|
||||
Gets a list of messages meeting the requirements to be deleted.
|
||||
|
||||
Generally, the requirements are:
|
||||
- We don't have the number of messages to be deleted already
|
||||
- The message passes a provided check (if no check is provided,
|
||||
this is automatically true)
|
||||
- The message is less than 14 days old
|
||||
- The message is not pinned
|
||||
|
||||
Warning: Due to the way the API hands messages back in chunks,
|
||||
passing after and a number together is not advisable.
|
||||
If you need to accomplish this, you should filter messages on
|
||||
the entire applicable range, rather than use this utility.
|
||||
"""
|
||||
to_delete = []
|
||||
too_old = False
|
||||
|
||||
while not too_old and len(to_delete) - 1 < number:
|
||||
message = None
|
||||
async for message in channel.history(limit=limit, before=before, after=after):
|
||||
if (
|
||||
(not number or len(to_delete) - 1 < number)
|
||||
and check(message)
|
||||
and (ctx.message.created_at - message.created_at).days < 14
|
||||
# This isn't actually two weeks ago to allow some wiggle room on API limits
|
||||
two_weeks_ago = datetime.utcnow() - timedelta(days=14, minutes=-5)
|
||||
|
||||
def message_filter(message):
|
||||
return (
|
||||
check(message)
|
||||
and message.created_at > two_weeks_ago
|
||||
and (delete_pinned or not message.pinned)
|
||||
):
|
||||
to_delete.append(message)
|
||||
elif (ctx.message.created_at - message.created_at).days >= 14:
|
||||
too_old = True
|
||||
break
|
||||
elif number and len(to_delete) >= number:
|
||||
break
|
||||
if message is None:
|
||||
break
|
||||
else:
|
||||
before = message
|
||||
return to_delete
|
||||
)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
if after:
|
||||
if isinstance(after, discord.Message):
|
||||
after = after.created_at
|
||||
after = max(after, two_weeks_ago)
|
||||
|
||||
collected = []
|
||||
async for message in channel.history(
|
||||
limit=None, before=before, after=after, reverse=False
|
||||
):
|
||||
if message.created_at < two_weeks_ago:
|
||||
break
|
||||
if check(message):
|
||||
collected.append(message)
|
||||
if number and number <= len(collected):
|
||||
break
|
||||
|
||||
return collected
|
||||
|
||||
@commands.group()
|
||||
@checks.mod_or_permissions(manage_messages=True)
|
||||
async def cleanup(self, ctx: commands.Context):
|
||||
"""Deletes messages."""
|
||||
@@ -100,7 +110,6 @@ class Cleanup:
|
||||
|
||||
@cleanup.command()
|
||||
@commands.guild_only()
|
||||
@commands.bot_has_permissions(manage_messages=True)
|
||||
async def text(
|
||||
self, ctx: commands.Context, text: str, number: int, delete_pinned: bool = False
|
||||
):
|
||||
@@ -112,8 +121,11 @@ class Cleanup:
|
||||
Remember to use double quotes."""
|
||||
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).manage_messages:
|
||||
await ctx.send("I need the Manage Messages permission to do this.")
|
||||
return
|
||||
|
||||
author = ctx.author
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if number > 100:
|
||||
cont = await self.check_100_plus(ctx, number)
|
||||
@@ -129,11 +141,9 @@ class Cleanup:
|
||||
return False
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx,
|
||||
channel,
|
||||
number,
|
||||
channel=channel,
|
||||
number=number,
|
||||
check=check,
|
||||
limit=1000,
|
||||
before=ctx.message,
|
||||
delete_pinned=delete_pinned,
|
||||
)
|
||||
@@ -143,14 +153,10 @@ class Cleanup:
|
||||
)
|
||||
log.info(reason)
|
||||
|
||||
if is_bot:
|
||||
await mass_purge(to_delete, channel)
|
||||
else:
|
||||
await slow_deletion(to_delete)
|
||||
|
||||
@cleanup.command()
|
||||
@commands.guild_only()
|
||||
@commands.bot_has_permissions(manage_messages=True)
|
||||
async def user(
|
||||
self, ctx: commands.Context, user: str, number: int, delete_pinned: bool = False
|
||||
):
|
||||
@@ -159,6 +165,10 @@ class Cleanup:
|
||||
Examples:
|
||||
cleanup user @\u200bTwentysix 2
|
||||
cleanup user Red 6"""
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).manage_messages:
|
||||
await ctx.send("I need the Manage Messages permission to do this.")
|
||||
return
|
||||
|
||||
member = None
|
||||
try:
|
||||
@@ -171,9 +181,7 @@ class Cleanup:
|
||||
else:
|
||||
_id = member.id
|
||||
|
||||
channel = ctx.channel
|
||||
author = ctx.author
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if number > 100:
|
||||
cont = await self.check_100_plus(ctx, number)
|
||||
@@ -189,11 +197,9 @@ class Cleanup:
|
||||
return False
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx,
|
||||
channel,
|
||||
number,
|
||||
channel=channel,
|
||||
number=number,
|
||||
check=check,
|
||||
limit=1000,
|
||||
before=ctx.message,
|
||||
delete_pinned=delete_pinned,
|
||||
)
|
||||
@@ -204,15 +210,10 @@ class Cleanup:
|
||||
)
|
||||
log.info(reason)
|
||||
|
||||
if is_bot:
|
||||
# For whatever reason the purge endpoint requires manage_messages
|
||||
await mass_purge(to_delete, channel)
|
||||
else:
|
||||
await slow_deletion(to_delete)
|
||||
|
||||
@cleanup.command()
|
||||
@commands.guild_only()
|
||||
@commands.bot_has_permissions(manage_messages=True)
|
||||
async def after(self, ctx: commands.Context, message_id: int, delete_pinned: bool = False):
|
||||
"""Deletes all messages after specified message.
|
||||
|
||||
@@ -224,21 +225,18 @@ class Cleanup:
|
||||
"""
|
||||
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).manage_messages:
|
||||
await ctx.send("I need the Manage Messages permission to do this.")
|
||||
return
|
||||
author = ctx.author
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if not is_bot:
|
||||
await ctx.send(_("This command can only be used on bots with bot accounts."))
|
||||
return
|
||||
|
||||
try:
|
||||
after = await channel.get_message(message_id)
|
||||
|
||||
if not after:
|
||||
await ctx.send(_("Message not found."))
|
||||
return
|
||||
except discord.NotFound:
|
||||
return await ctx.send(_("Message not found."))
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx, channel, 0, limit=None, after=after, delete_pinned=delete_pinned
|
||||
channel=channel, number=None, after=after, delete_pinned=delete_pinned
|
||||
)
|
||||
|
||||
reason = "{}({}) deleted {} messages in channel {}.".format(
|
||||
@@ -250,7 +248,6 @@ class Cleanup:
|
||||
|
||||
@cleanup.command()
|
||||
@commands.guild_only()
|
||||
@commands.bot_has_permissions(manage_messages=True)
|
||||
async def messages(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
|
||||
"""Deletes last X messages.
|
||||
|
||||
@@ -258,17 +255,18 @@ class Cleanup:
|
||||
cleanup messages 26"""
|
||||
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).manage_messages:
|
||||
await ctx.send("I need the Manage Messages permission to do this.")
|
||||
return
|
||||
author = ctx.author
|
||||
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if number > 100:
|
||||
cont = await self.check_100_plus(ctx, number)
|
||||
if not cont:
|
||||
return
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx, channel, number, limit=1000, before=ctx.message, delete_pinned=delete_pinned
|
||||
channel=channel, number=number, before=ctx.message, delete_pinned=delete_pinned
|
||||
)
|
||||
to_delete.append(ctx.message)
|
||||
|
||||
@@ -277,20 +275,18 @@ class Cleanup:
|
||||
)
|
||||
log.info(reason)
|
||||
|
||||
if is_bot:
|
||||
await mass_purge(to_delete, channel)
|
||||
else:
|
||||
await slow_deletion(to_delete)
|
||||
|
||||
@cleanup.command(name="bot")
|
||||
@commands.guild_only()
|
||||
@commands.bot_has_permissions(manage_messages=True)
|
||||
async def cleanup_bot(self, ctx: commands.Context, number: int, delete_pinned: bool = False):
|
||||
"""Cleans up command messages and messages from the bot."""
|
||||
|
||||
channel = ctx.message.channel
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).manage_messages:
|
||||
await ctx.send("I need the Manage Messages permission to do this.")
|
||||
return
|
||||
author = ctx.message.author
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if number > 100:
|
||||
cont = await self.check_100_plus(ctx, number)
|
||||
@@ -317,11 +313,9 @@ class Cleanup:
|
||||
return False
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx,
|
||||
channel,
|
||||
number,
|
||||
channel=channel,
|
||||
number=number,
|
||||
check=check,
|
||||
limit=1000,
|
||||
before=ctx.message,
|
||||
delete_pinned=delete_pinned,
|
||||
)
|
||||
@@ -334,10 +328,7 @@ class Cleanup:
|
||||
)
|
||||
log.info(reason)
|
||||
|
||||
if is_bot:
|
||||
await mass_purge(to_delete, channel)
|
||||
else:
|
||||
await slow_deletion(to_delete)
|
||||
|
||||
@cleanup.command(name="self")
|
||||
async def cleanup_self(
|
||||
@@ -359,7 +350,6 @@ class Cleanup:
|
||||
"""
|
||||
channel = ctx.channel
|
||||
author = ctx.message.author
|
||||
is_bot = self.bot.user.bot
|
||||
|
||||
if number > 100:
|
||||
cont = await self.check_100_plus(ctx, number)
|
||||
@@ -399,20 +389,14 @@ class Cleanup:
|
||||
return False
|
||||
|
||||
to_delete = await self.get_messages_for_deletion(
|
||||
ctx,
|
||||
channel,
|
||||
number,
|
||||
channel=channel,
|
||||
number=number,
|
||||
check=check,
|
||||
limit=1000,
|
||||
before=ctx.message,
|
||||
delete_pinned=delete_pinned,
|
||||
)
|
||||
|
||||
# Selfbot convenience, delete trigger message
|
||||
if author == self.bot.user:
|
||||
to_delete.append(ctx.message)
|
||||
|
||||
if channel.name:
|
||||
if ctx.guild:
|
||||
channel_name = "channel " + channel.name
|
||||
else:
|
||||
channel_name = str(channel)
|
||||
@@ -424,7 +408,7 @@ class Cleanup:
|
||||
)
|
||||
log.info(reason)
|
||||
|
||||
if is_bot and can_mass_purge:
|
||||
if can_mass_purge:
|
||||
await mass_purge(to_delete, channel)
|
||||
else:
|
||||
await slow_deletion(to_delete)
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../cleanup.py:150
|
||||
msgid "This command can only be used on bots with bot accounts."
|
||||
msgstr ""
|
||||
|
||||
#: ../cleanup.py:157
|
||||
msgid "Message not found."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../cleanup.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -2,6 +2,9 @@ import os
|
||||
import re
|
||||
import random
|
||||
from datetime import datetime
|
||||
from inspect import Parameter
|
||||
from collections import OrderedDict
|
||||
from typing import Mapping
|
||||
|
||||
import discord
|
||||
|
||||
@@ -24,6 +27,10 @@ class AlreadyExists(CCError):
|
||||
pass
|
||||
|
||||
|
||||
class ArgParseError(CCError):
|
||||
pass
|
||||
|
||||
|
||||
class CommandObj:
|
||||
def __init__(self, **kwargs):
|
||||
config = kwargs.get("config")
|
||||
@@ -51,6 +58,7 @@ class CommandObj:
|
||||
return m.channel == ctx.channel and m.author == ctx.message.author
|
||||
|
||||
responses = []
|
||||
args = None
|
||||
while True:
|
||||
await ctx.send(_("Add a random response:"))
|
||||
msg = await self.bot.wait_for("message", check=check)
|
||||
@@ -58,6 +66,15 @@ class CommandObj:
|
||||
if msg.content.lower() == "exit()":
|
||||
break
|
||||
else:
|
||||
try:
|
||||
this_args = ctx.cog.prepare_args(msg.content)
|
||||
except ArgParseError as e:
|
||||
await ctx.send(e.args[0])
|
||||
continue
|
||||
if args and args != this_args:
|
||||
await ctx.send(_("Random responses must take the same arguments!"))
|
||||
continue
|
||||
args = args or this_args
|
||||
responses.append(msg.content)
|
||||
return responses
|
||||
|
||||
@@ -69,7 +86,7 @@ class CommandObj:
|
||||
async def get(self, message: discord.Message, command: str) -> str:
|
||||
ccinfo = await self.db(message.guild).commands.get_raw(command, default=None)
|
||||
if not ccinfo:
|
||||
raise NotFound
|
||||
raise NotFound()
|
||||
else:
|
||||
return ccinfo["response"]
|
||||
|
||||
@@ -78,6 +95,8 @@ class CommandObj:
|
||||
# Check if this command is already registered as a customcommand
|
||||
if await self.db(ctx.guild).commands.get_raw(command, default=None):
|
||||
raise AlreadyExists()
|
||||
# test to raise
|
||||
ctx.cog.prepare_args(response if isinstance(response, str) else response[0])
|
||||
author = ctx.message.author
|
||||
ccinfo = {
|
||||
"author": {"id": author.id, "name": author.name},
|
||||
@@ -110,6 +129,9 @@ class CommandObj:
|
||||
await ctx.send(_("What response do you want?"))
|
||||
response = (await self.bot.wait_for("message", check=check)).content
|
||||
|
||||
# test to raise
|
||||
ctx.cog.prepare_args(response if isinstance(response, str) else response[0])
|
||||
|
||||
ccinfo["response"] = response
|
||||
ccinfo["edited_at"] = self.get_now()
|
||||
|
||||
@@ -141,29 +163,20 @@ class CustomCommands:
|
||||
self.config.register_guild(commands={})
|
||||
self.commandobj = CommandObj(config=self.config, bot=self.bot)
|
||||
|
||||
@commands.group(aliases=["cc"], autohelp=True)
|
||||
@commands.group(aliases=["cc"])
|
||||
@commands.guild_only()
|
||||
async def customcom(self, ctx: commands.Context):
|
||||
"""Custom commands management"""
|
||||
pass
|
||||
|
||||
@customcom.group(name="add", autohelp=True)
|
||||
@customcom.group(name="add")
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
async def cc_add(self, ctx: commands.Context):
|
||||
"""
|
||||
Adds a new custom command
|
||||
|
||||
CCs can be enhanced with arguments:
|
||||
|
||||
Argument What it will be substituted with
|
||||
|
||||
{message} message
|
||||
|
||||
{author} message.author
|
||||
|
||||
{channel} message.channel
|
||||
|
||||
{guild} message.guild
|
||||
|
||||
{server} message.guild
|
||||
https://red-discordbot.readthedocs.io/en/v3-develop/cog_customcom.html
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -175,7 +188,6 @@ class CustomCommands:
|
||||
|
||||
Note: This is interactive
|
||||
"""
|
||||
channel = ctx.channel
|
||||
responses = []
|
||||
|
||||
responses = await self.commandobj.get_responses(ctx=ctx)
|
||||
@@ -199,7 +211,6 @@ class CustomCommands:
|
||||
Example:
|
||||
[p]customcom add simple yourcommand Text you want
|
||||
"""
|
||||
guild = ctx.guild
|
||||
command = command.lower()
|
||||
if command in self.bot.all_commands:
|
||||
await ctx.send(_("That command is already a standard command."))
|
||||
@@ -213,6 +224,8 @@ class CustomCommands:
|
||||
"{}customcom edit".format(ctx.prefix)
|
||||
)
|
||||
)
|
||||
except ArgParseError as e:
|
||||
await ctx.send(e.args[0])
|
||||
|
||||
@customcom.command(name="edit")
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
@@ -222,7 +235,6 @@ class CustomCommands:
|
||||
Example:
|
||||
[p]customcom edit yourcommand Text you want
|
||||
"""
|
||||
guild = ctx.message.guild
|
||||
command = command.lower()
|
||||
|
||||
try:
|
||||
@@ -234,6 +246,8 @@ class CustomCommands:
|
||||
"{}customcom add".format(ctx.prefix)
|
||||
)
|
||||
)
|
||||
except ArgParseError as e:
|
||||
await ctx.send(e.args[0])
|
||||
|
||||
@customcom.command(name="delete")
|
||||
@checks.mod_or_permissions(administrator=True)
|
||||
@@ -241,7 +255,6 @@ class CustomCommands:
|
||||
"""Deletes a custom command
|
||||
Example:
|
||||
[p]customcom delete yourcommand"""
|
||||
guild = ctx.message.guild
|
||||
command = command.lower()
|
||||
try:
|
||||
await self.commandobj.delete(ctx=ctx, command=command)
|
||||
@@ -286,49 +299,145 @@ class CustomCommands:
|
||||
|
||||
async def on_message(self, message):
|
||||
is_private = isinstance(message.channel, discord.abc.PrivateChannel)
|
||||
if len(message.content) < 2 or is_private:
|
||||
return
|
||||
|
||||
guild = message.guild
|
||||
prefixes = await self.bot.db.guild(guild).get_raw("prefix", default=[])
|
||||
|
||||
if len(prefixes) < 1:
|
||||
def_prefixes = await self.bot.get_prefix(message)
|
||||
for prefix in def_prefixes:
|
||||
prefixes.append(prefix)
|
||||
|
||||
# user_allowed check, will be replaced with self.bot.user_allowed or
|
||||
# something similar once it's added
|
||||
|
||||
user_allowed = True
|
||||
|
||||
for prefix in prefixes:
|
||||
if message.content.startswith(prefix):
|
||||
break
|
||||
else:
|
||||
if len(message.content) < 2 or is_private or not user_allowed or message.author.bot:
|
||||
return
|
||||
|
||||
ctx = await self.bot.get_context(message)
|
||||
|
||||
if ctx.prefix is None or ctx.valid:
|
||||
return
|
||||
|
||||
if user_allowed:
|
||||
cmd = message.content[len(prefix) :]
|
||||
try:
|
||||
c = await self.commandobj.get(message=message, command=cmd)
|
||||
if isinstance(c, list):
|
||||
command = random.choice(c)
|
||||
elif isinstance(c, str):
|
||||
command = c
|
||||
raw_response = await self.commandobj.get(message=message, command=ctx.invoked_with)
|
||||
if isinstance(raw_response, list):
|
||||
raw_response = random.choice(raw_response)
|
||||
elif isinstance(raw_response, str):
|
||||
pass
|
||||
else:
|
||||
raise NotFound()
|
||||
except NotFound:
|
||||
return
|
||||
response = self.format_cc(command, message)
|
||||
await message.channel.send(response)
|
||||
await self.call_cc_command(ctx, raw_response, message)
|
||||
|
||||
def format_cc(self, command, message) -> str:
|
||||
results = re.findall("\{([^}]+)\}", command)
|
||||
async def call_cc_command(self, ctx, raw_response, message) -> None:
|
||||
# wrap the command here so it won't register with the bot
|
||||
fake_cc = commands.Command(ctx.invoked_with, self.cc_callback)
|
||||
fake_cc.params = self.prepare_args(raw_response)
|
||||
ctx.command = fake_cc
|
||||
await self.bot.invoke(ctx)
|
||||
if not ctx.command_failed:
|
||||
await self.cc_command(*ctx.args, **ctx.kwargs, raw_response=raw_response)
|
||||
|
||||
async def cc_callback(self, *args, **kwargs) -> None:
|
||||
"""
|
||||
Custom command.
|
||||
|
||||
Created via the CustomCom cog. See `[p]customcom` for more details.
|
||||
"""
|
||||
# fake command to take advantage of discord.py's parsing and events
|
||||
pass
|
||||
|
||||
async def cc_command(self, ctx, *cc_args, raw_response, **cc_kwargs) -> None:
|
||||
cc_args = (*cc_args, *cc_kwargs.values())
|
||||
results = re.findall(r"\{([^}]+)\}", raw_response)
|
||||
for result in results:
|
||||
param = self.transform_parameter(result, message)
|
||||
command = command.replace("{" + result + "}", param)
|
||||
return command
|
||||
param = self.transform_parameter(result, ctx.message)
|
||||
raw_response = raw_response.replace("{" + result + "}", param)
|
||||
results = re.findall(r"\{((\d+)[^\.}]*(\.[^:}]+)?[^}]*)\}", raw_response)
|
||||
if results:
|
||||
low = min(int(result[1]) for result in results)
|
||||
for result in results:
|
||||
index = int(result[1]) - low
|
||||
arg = self.transform_arg(result[0], result[2], cc_args[index])
|
||||
raw_response = raw_response.replace("{" + result[0] + "}", arg)
|
||||
await ctx.send(raw_response)
|
||||
|
||||
def prepare_args(self, raw_response) -> Mapping[str, Parameter]:
|
||||
args = re.findall(r"\{(\d+)[^:}]*(:[^\.}]*)?[^}]*\}", raw_response)
|
||||
default = [["ctx", Parameter("ctx", Parameter.POSITIONAL_OR_KEYWORD)]]
|
||||
if not args:
|
||||
return OrderedDict(default)
|
||||
allowed_builtins = {
|
||||
"bool": bool,
|
||||
"complex": complex,
|
||||
"float": float,
|
||||
"frozenset": frozenset,
|
||||
"int": int,
|
||||
"list": list,
|
||||
"set": set,
|
||||
"str": str,
|
||||
"tuple": tuple,
|
||||
}
|
||||
indices = [int(a[0]) for a in args]
|
||||
low = min(indices)
|
||||
indices = [a - low for a in indices]
|
||||
high = max(indices)
|
||||
if high > 9:
|
||||
raise ArgParseError(_("Too many arguments!"))
|
||||
gaps = set(indices).symmetric_difference(range(high + 1))
|
||||
if gaps:
|
||||
raise ArgParseError(
|
||||
_("Arguments must be sequential. Missing arguments: {}.").format(
|
||||
", ".join(str(i + low) for i in gaps)
|
||||
)
|
||||
)
|
||||
fin = [Parameter("_" + str(i), Parameter.POSITIONAL_OR_KEYWORD) for i in range(high + 1)]
|
||||
for arg in args:
|
||||
index = int(arg[0]) - low
|
||||
anno = arg[1][1:] # strip initial colon
|
||||
if anno.lower().endswith("converter"):
|
||||
anno = anno[:-9]
|
||||
if not anno or anno.startswith("_"): # public types only
|
||||
name = "{}_{}".format("text", index if index < high else "final")
|
||||
fin[index] = fin[index].replace(name=name)
|
||||
continue
|
||||
# allow type hinting only for discord.py and builtin types
|
||||
try:
|
||||
anno = getattr(discord, anno)
|
||||
# force an AttributeError if there's no discord.py converter
|
||||
getattr(commands.converter, anno.__name__ + "Converter")
|
||||
except AttributeError:
|
||||
anno = allowed_builtins.get(anno.lower(), Parameter.empty)
|
||||
if (
|
||||
anno is not Parameter.empty
|
||||
and fin[index].annotation is not Parameter.empty
|
||||
and anno != fin[index].annotation
|
||||
):
|
||||
raise ArgParseError(
|
||||
_('Conflicting colon notation for argument {}: "{}" and "{}".').format(
|
||||
index + low, fin[index].annotation.__name__, anno.__name__
|
||||
)
|
||||
)
|
||||
if anno is not Parameter.empty:
|
||||
fin[index] = fin[index].replace(annotation=anno)
|
||||
# consume rest
|
||||
fin[-1] = fin[-1].replace(kind=Parameter.KEYWORD_ONLY)
|
||||
# name the parameters for the help text
|
||||
for i, param in enumerate(fin):
|
||||
anno = param.annotation
|
||||
name = "{}_{}".format(
|
||||
"text" if anno is Parameter.empty else anno.__name__.lower(),
|
||||
i if i < high else "final",
|
||||
)
|
||||
fin[i] = fin[i].replace(name=name)
|
||||
# insert ctx parameter for discord.py parsing
|
||||
fin = default + [(p.name, p) for p in fin]
|
||||
return OrderedDict(fin)
|
||||
|
||||
def transform_arg(self, result, attr, obj) -> str:
|
||||
attr = attr[1:] # strip initial dot
|
||||
if not attr:
|
||||
return str(obj)
|
||||
raw_result = "{" + result + "}"
|
||||
# forbid private members and nested attr lookups
|
||||
if attr.startswith("_") or "." in attr:
|
||||
return raw_result
|
||||
return str(getattr(obj, attr, raw_result))
|
||||
|
||||
def transform_parameter(self, result, message) -> str:
|
||||
"""
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../customcom.py:44
|
||||
msgid ""
|
||||
"Welcome to the interactive random {} maker!\n"
|
||||
"Every message you send will be added as one of the random response to choose from once this {} is triggered. To exit this interactive menu, type `{}`"
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:56
|
||||
msgid "Add a random response:"
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:119
|
||||
msgid "Do you want to create a 'randomized' cc? {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:126
|
||||
msgid "What response do you want?"
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:205 ../customcom.py:235
|
||||
msgid "Custom command successfully added."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:207 ../customcom.py:237
|
||||
msgid "This command already exists. Use `{}` to edit it."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:229
|
||||
msgid "That command is already a standard command."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:261
|
||||
msgid "Custom command successfully edited."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:263
|
||||
msgid "That command doesn't exist. Use `{}` to add it."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:282
|
||||
msgid "Custom command successfully deleted."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:284
|
||||
msgid "That command doesn't exist."
|
||||
msgstr ""
|
||||
|
||||
#: ../customcom.py:294
|
||||
msgid "There are no custom commands in this guild. Use `{}` to start adding some."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../customcom.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -1,43 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-03-12 04:35+EDT\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../dataconverter.py:38
|
||||
msgid "There don't seem to be any data files I know how to handle here. Are you sure you gave me the base installation path?"
|
||||
msgstr ""
|
||||
|
||||
#: ../dataconverter.py:43
|
||||
msgid "Please select a set of data to import by number, or 'exit' to exit"
|
||||
msgstr ""
|
||||
|
||||
#: ../dataconverter.py:59
|
||||
msgid "Try this again when you are more ready"
|
||||
msgstr ""
|
||||
|
||||
#: ../dataconverter.py:70
|
||||
msgid "That wasn't a valid choice."
|
||||
msgstr ""
|
||||
|
||||
#: ../dataconverter.py:76
|
||||
msgid "{} converted."
|
||||
msgstr ""
|
||||
|
||||
#: ../dataconverter.py:80
|
||||
msgid ""
|
||||
"There isn't anything else I know how to convert here.\n"
|
||||
"There might be more things I can convert in the future."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../dataconverter.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -204,7 +204,7 @@ class Downloader:
|
||||
)
|
||||
)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@checks.is_owner()
|
||||
async def repo(self, ctx):
|
||||
"""
|
||||
@@ -234,7 +234,7 @@ class Downloader:
|
||||
else:
|
||||
await ctx.send(_("Repo `{}` successfully added.").format(name))
|
||||
if repo.install_msg is not None:
|
||||
await ctx.send(repo.install_msg)
|
||||
await ctx.send(repo.install_msg.replace("[p]", ctx.prefix))
|
||||
|
||||
@repo.command(name="delete")
|
||||
async def _repo_del(self, ctx, repo_name: Repo):
|
||||
@@ -272,7 +272,7 @@ class Downloader:
|
||||
msg = _("Information on {}:\n{}").format(repo_name.name, repo_name.description or "")
|
||||
await ctx.send(box(msg))
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@checks.is_owner()
|
||||
async def cog(self, ctx):
|
||||
"""
|
||||
@@ -295,12 +295,10 @@ class Downloader:
|
||||
return
|
||||
elif cog.min_python_version > sys.version_info:
|
||||
await ctx.send(
|
||||
_(
|
||||
"This cog requires at least python version {}, aborting install.".format(
|
||||
_("This cog requires at least python version {}, aborting install.").format(
|
||||
".".join([str(n) for n in cog.min_python_version])
|
||||
)
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if not await repo_name.install_requirements(cog, self.LIB_PATH):
|
||||
@@ -319,7 +317,7 @@ class Downloader:
|
||||
|
||||
await ctx.send(_("`{}` cog successfully installed.").format(cog_name))
|
||||
if cog.install_msg is not None:
|
||||
await ctx.send(cog.install_msg)
|
||||
await ctx.send(cog.install_msg.replace("[p]", ctx.prefix))
|
||||
|
||||
@cog.command(name="uninstall")
|
||||
async def _cog_uninstall(self, ctx, cog_name: InstalledCog):
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../downloader.py:215
|
||||
msgid "That git repo has already been added under another name."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:217 ../downloader.py:218
|
||||
msgid "Something went wrong during the cloning process."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:220
|
||||
msgid "Repo `{}` successfully added."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:229
|
||||
msgid "The repo `{}` has been deleted successfully."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:237
|
||||
msgid ""
|
||||
"Installed Repos:\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:258
|
||||
msgid "Error, there is no cog by the name of `{}` in the `{}` repo."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:263
|
||||
msgid "Failed to install the required libraries for `{}`: `{}`"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:273
|
||||
msgid "`{}` cog successfully installed."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:289
|
||||
msgid "`{}` was successfully removed."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:291
|
||||
msgid "That cog was installed but can no longer be located. You may need to remove it's files manually if it is still usable."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:315
|
||||
msgid "Cog update completed successfully."
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:323
|
||||
msgid ""
|
||||
"Available Cogs:\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:335
|
||||
msgid "There is no cog `{}` in the repo `{}`"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:340
|
||||
msgid ""
|
||||
"Information on {}:\n"
|
||||
"{}"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:381
|
||||
msgid "Missing from info.json"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:390
|
||||
msgid ""
|
||||
"Command: {}\n"
|
||||
"Made by: {}\n"
|
||||
"Repo: {}\n"
|
||||
"Cog name: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../downloader.py:422
|
||||
msgid "That command doesn't seem to exist."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../downloader.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -9,7 +9,8 @@ import discord
|
||||
from redbot.cogs.bank import check_global_setting_guildowner, check_global_setting_admin
|
||||
from redbot.core import Config, bank, commands
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
from redbot.core.utils.chat_formatting import pagify, box
|
||||
from redbot.core.utils.chat_formatting import box
|
||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||||
|
||||
from redbot.core.bot import Red
|
||||
|
||||
@@ -137,7 +138,8 @@ class Economy:
|
||||
self.config.register_role(**self.default_role_settings)
|
||||
self.slot_register = defaultdict(dict)
|
||||
|
||||
@commands.group(name="bank", autohelp=True)
|
||||
@guild_only_check()
|
||||
@commands.group(name="bank")
|
||||
async def _bank(self, ctx: commands.Context):
|
||||
"""Bank operations"""
|
||||
pass
|
||||
@@ -209,7 +211,6 @@ class Economy:
|
||||
)
|
||||
|
||||
@_bank.command()
|
||||
@guild_only_check()
|
||||
@check_global_setting_guildowner()
|
||||
async def reset(self, ctx, confirmation: bool = False):
|
||||
"""Deletes bank accounts"""
|
||||
@@ -230,8 +231,8 @@ class Economy:
|
||||
)
|
||||
)
|
||||
|
||||
@commands.command()
|
||||
@guild_only_check()
|
||||
@commands.command()
|
||||
async def payday(self, ctx: commands.Context):
|
||||
"""Get some free currency"""
|
||||
author = ctx.author
|
||||
@@ -251,7 +252,7 @@ class Economy:
|
||||
_(
|
||||
"{0.mention} Here, take some {1}. Enjoy! (+{2} {1}!)\n\n"
|
||||
"You currently have {3} {1}.\n\n"
|
||||
"You are currently #{4} on the leaderboard!"
|
||||
"You are currently #{4} on the global leaderboard!"
|
||||
).format(
|
||||
author,
|
||||
credits_name,
|
||||
@@ -309,8 +310,8 @@ class Economy:
|
||||
"""Prints out the leaderboard
|
||||
|
||||
Defaults to top 10"""
|
||||
# Originally coded by Airenkun - edited by irdumb, rewritten by Palm__ for v3
|
||||
guild = ctx.guild
|
||||
author = ctx.author
|
||||
if top < 1:
|
||||
top = 10
|
||||
if (
|
||||
@@ -320,25 +321,25 @@ class Economy:
|
||||
bank_sorted = await bank.get_leaderboard(positions=top, guild=guild)
|
||||
if len(bank_sorted) < top:
|
||||
top = len(bank_sorted)
|
||||
highscore = ""
|
||||
for pos, acc in enumerate(bank_sorted, 1):
|
||||
pos = pos
|
||||
poswidth = 2
|
||||
name = acc[1]["name"]
|
||||
namewidth = 35
|
||||
balance = acc[1]["balance"]
|
||||
balwidth = 2
|
||||
highscore += "{pos: <{poswidth}} {name: <{namewidth}s} {balance: >{balwidth}}\n".format(
|
||||
pos=pos,
|
||||
poswidth=poswidth,
|
||||
name=name,
|
||||
namewidth=namewidth,
|
||||
balance=balance,
|
||||
balwidth=balwidth,
|
||||
header = f"{f'#':4}{f'Name':36}{f'Score':2}\n"
|
||||
highscores = [
|
||||
(
|
||||
f"{f'{pos}.': <{3 if pos < 10 else 2}} {acc[1]['name']: <{35}s} "
|
||||
f"{acc[1]['balance']: >{2 if pos < 10 else 1}}\n"
|
||||
)
|
||||
if highscore != "":
|
||||
for page in pagify(highscore, shorten_by=12):
|
||||
await ctx.send(box(page, lang="py"))
|
||||
if acc[0] != author.id
|
||||
else (
|
||||
f"{f'{pos}.': <{3 if pos < 10 else 2}} <<{acc[1]['name'] + '>>': <{33}s} "
|
||||
f"{acc[1]['balance']: >{2 if pos < 10 else 1}}\n"
|
||||
)
|
||||
for pos, acc in enumerate(bank_sorted, 1)
|
||||
]
|
||||
if highscores:
|
||||
pages = [
|
||||
f"```md\n{header}{''.join(''.join(highscores[x:x + 10]))}```"
|
||||
for x in range(0, len(highscores), 10)
|
||||
]
|
||||
await menu(ctx, pages, DEFAULT_CONTROLS)
|
||||
else:
|
||||
await ctx.send(_("There are no accounts in the bank."))
|
||||
|
||||
@@ -438,7 +439,7 @@ class Economy:
|
||||
)
|
||||
)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@guild_only_check()
|
||||
@check_global_setting_admin()
|
||||
async def economyset(self, ctx: commands.Context):
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../economy.py:40
|
||||
msgid "JACKPOT! 226! Your bid has been multiplied * 2500!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:44
|
||||
msgid "4LC! +1000!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:48
|
||||
msgid "Three cherries! +800!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:52
|
||||
msgid "2 6! Your bid has been multiplied * 4!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:56
|
||||
msgid "Two cherries! Your bid has been multiplied * 3!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:60
|
||||
msgid "Three symbols! +500!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:64
|
||||
msgid "Two consecutive symbols! Your bid has been multiplied * 2!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:68
|
||||
msgid ""
|
||||
"Slot machine payouts:\n"
|
||||
"{two.value} {two.value} {six.value} Bet * 2500\n"
|
||||
"{flc.value} {flc.value} {flc.value} +1000\n"
|
||||
"{cherries.value} {cherries.value} {cherries.value} +800\n"
|
||||
"{two.value} {six.value} Bet * 4\n"
|
||||
"{cherries.value} {cherries.value} Bet * 3\n"
|
||||
"\n"
|
||||
"Three symbols: +500\n"
|
||||
"Two symbols: Bet * 2"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:157
|
||||
msgid "{}'s balance is {} {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:171
|
||||
msgid "{} transferred {} {} to {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:191
|
||||
msgid "{} added {} {} to {}'s account."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:196
|
||||
msgid "{} removed {} {} from {}'s account."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:201
|
||||
msgid "{} set {}'s account to {} {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:212
|
||||
msgid ""
|
||||
"This will delete all bank accounts for {}.\n"
|
||||
"If you're sure, type `{}bank reset yes`"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:229
|
||||
msgid "All bank accounts of this guild have been deleted."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:248 ../economy.py:268
|
||||
msgid "{} Here, take some {}. Enjoy! (+{} {}!)"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:258 ../economy.py:276
|
||||
msgid "{} Too soon. For your next payday you have to wait {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:313
|
||||
msgid "There are no accounts in the bank."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:339
|
||||
msgid "You're on cooldown, try again in a bit."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:342
|
||||
msgid "That's an invalid bid amount, sorry :/"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:345
|
||||
msgid "You ain't got enough money, friend."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:391
|
||||
msgid ""
|
||||
"{}\n"
|
||||
"{} {}\n"
|
||||
"\n"
|
||||
"Your bid: {}\n"
|
||||
"{} → {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:398
|
||||
msgid ""
|
||||
"{}\n"
|
||||
"{} Nothing!\n"
|
||||
"Your bid: {}\n"
|
||||
"{} → {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:423
|
||||
msgid ""
|
||||
"Minimum slot bid: {}\n"
|
||||
"Maximum slot bid: {}\n"
|
||||
"Slot cooldown: {}\n"
|
||||
"Payday amount: {}\n"
|
||||
"Payday cooldown: {}\n"
|
||||
"Amount given at account registration: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:433
|
||||
msgid "Current Economy settings:"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:441
|
||||
msgid "Invalid min bid amount."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:449
|
||||
msgid "Minimum bid is now {} {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:456
|
||||
msgid "Invalid slotmax bid amount. Must be greater than slotmin."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:465
|
||||
msgid "Maximum bid is now {} {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:475
|
||||
msgid "Cooldown is now {} seconds."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:485
|
||||
msgid "Value modified. At least {} seconds must pass between each payday."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:494
|
||||
msgid "Har har so funny."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:500
|
||||
msgid "Every payday will now give {} {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:511
|
||||
msgid "Registering an account will now give {} {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:517
|
||||
msgid "weeks"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:518
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:519
|
||||
msgid "hours"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:520
|
||||
msgid "minutes"
|
||||
msgstr ""
|
||||
|
||||
#: ../economy.py:521
|
||||
msgid "seconds"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../economy.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -39,7 +39,7 @@ class Filter:
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
@commands.group(name="filter", autohelp=True)
|
||||
@commands.group(name="filter")
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(manage_messages=True)
|
||||
async def _filter(self, ctx: commands.Context):
|
||||
@@ -78,13 +78,13 @@ class Filter:
|
||||
word_list.append(word)
|
||||
else:
|
||||
if word.startswith('"'):
|
||||
tmp += word[1:]
|
||||
tmp += word[1:] + " "
|
||||
elif word.endswith('"'):
|
||||
tmp += word[:-1]
|
||||
word_list.append(tmp)
|
||||
tmp = ""
|
||||
else:
|
||||
tmp += word
|
||||
tmp += word + " "
|
||||
added = await self.add_to_filter(server, word_list)
|
||||
if added:
|
||||
await ctx.send(_("Words added to filter."))
|
||||
@@ -108,13 +108,13 @@ class Filter:
|
||||
word_list.append(word)
|
||||
else:
|
||||
if word.startswith('"'):
|
||||
tmp += word[1:]
|
||||
tmp += word[1:] + " "
|
||||
elif word.endswith('"'):
|
||||
tmp += word[:-1]
|
||||
word_list.append(tmp)
|
||||
tmp = ""
|
||||
else:
|
||||
tmp += word
|
||||
tmp += word + " "
|
||||
removed = await self.remove_from_filter(server, word_list)
|
||||
if removed:
|
||||
await ctx.send(_("Words removed from filter."))
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../filter.py:62
|
||||
msgid "Filtered in this server:"
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:67
|
||||
msgid "I can't send direct messages to you."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:96
|
||||
msgid "Words added to filter."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:98
|
||||
msgid "Words already in the filter."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:127
|
||||
msgid "Words removed from filter."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:129
|
||||
msgid "Those words weren't in the filter."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:142
|
||||
msgid "Names and nicknames will no longer be checked against the filter"
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:147
|
||||
msgid "Names and nicknames will now be checked against the filter"
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:160
|
||||
msgid "The name to use on filtered names has been set"
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:171
|
||||
msgid "Count and timeframe either both need to be 0 or both need to be greater than 0!"
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:179
|
||||
msgid "Autoban disabled."
|
||||
msgstr ""
|
||||
|
||||
#: ../filter.py:183
|
||||
msgid "Count and time have been set."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../filter.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -3,12 +3,11 @@ import time
|
||||
from enum import Enum
|
||||
from random import randint, choice
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import aiohttp
|
||||
import discord
|
||||
from redbot.core import commands
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
|
||||
from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
|
||||
from redbot.core.utils.chat_formatting import escape, italics, pagify
|
||||
|
||||
_ = Translator("General", __file__)
|
||||
@@ -164,7 +163,9 @@ class General:
|
||||
@commands.command()
|
||||
async def lmgtfy(self, ctx, *, search_terms: str):
|
||||
"""Creates a lmgtfy link"""
|
||||
search_terms = escape(search_terms.replace(" ", "+"), mass_mentions=True)
|
||||
search_terms = escape(
|
||||
search_terms.replace("+", "%2B").replace(" ", "+"), mass_mentions=True
|
||||
)
|
||||
await ctx.send("https://lmgtfy.com/?q={}".format(search_terms))
|
||||
|
||||
@commands.command(hidden=True)
|
||||
@@ -199,11 +200,7 @@ class General:
|
||||
created_at = _("Since {}. That's over {} days ago!").format(
|
||||
guild.created_at.strftime("%d %b %Y %H:%M"), passed
|
||||
)
|
||||
|
||||
colour = "".join([choice("0123456789ABCDEF") for x in range(6)])
|
||||
colour = randint(0, 0xFFFFFF)
|
||||
|
||||
data = discord.Embed(description=created_at, colour=discord.Colour(value=colour))
|
||||
data = discord.Embed(description=created_at, colour=(await ctx.embed_colour()))
|
||||
data.add_field(name=_("Region"), value=str(guild.region))
|
||||
data.add_field(name=_("Users"), value="{}/{}".format(online, total_users))
|
||||
data.add_field(name=_("Text Channels"), value=text_channels)
|
||||
@@ -224,49 +221,90 @@ class General:
|
||||
await ctx.send(_("I need the `Embed links` permission to send this."))
|
||||
|
||||
@commands.command()
|
||||
async def urban(self, ctx, *, search_terms: str, definition_number: int = 1):
|
||||
"""Urban Dictionary search
|
||||
async def urban(self, ctx, *, word):
|
||||
"""Searches urban dictionary entries using the unofficial api"""
|
||||
|
||||
Definition number must be between 1 and 10"""
|
||||
|
||||
def encode(s):
|
||||
return quote_plus(s, encoding="utf-8", errors="replace")
|
||||
|
||||
# definition_number is just there to show up in the help
|
||||
# all this mess is to avoid forcing double quotes on the user
|
||||
|
||||
search_terms = search_terms.split(" ")
|
||||
try:
|
||||
if len(search_terms) > 1:
|
||||
pos = int(search_terms[-1]) - 1
|
||||
search_terms = search_terms[:-1]
|
||||
else:
|
||||
pos = 0
|
||||
if pos not in range(0, 11): # API only provides the
|
||||
pos = 0 # top 10 definitions
|
||||
except ValueError:
|
||||
pos = 0
|
||||
url = "https://api.urbandictionary.com/v0/define?term=" + str(word).lower()
|
||||
|
||||
headers = {"content-type": "application/json"}
|
||||
|
||||
search_terms = {"term": "+".join([s for s in search_terms])}
|
||||
url = "http://api.urbandictionary.com/v0/define"
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url, params=search_terms) as r:
|
||||
result = await r.json()
|
||||
item_list = result["list"]
|
||||
if item_list:
|
||||
definition = item_list[pos]["definition"]
|
||||
example = item_list[pos]["example"]
|
||||
defs = len(item_list)
|
||||
msg = "**Definition #{} out of {}:\n**{}\n\n**Example:\n**{}".format(
|
||||
pos + 1, defs, definition, example
|
||||
)
|
||||
msg = pagify(msg, ["\n"])
|
||||
for page in msg:
|
||||
await ctx.send(page)
|
||||
else:
|
||||
await ctx.send(_("Your search terms gave no results."))
|
||||
except IndexError:
|
||||
await ctx.send(_("There is no definition #{}").format(pos + 1))
|
||||
async with session.get(url, headers=headers) as response:
|
||||
data = await response.json()
|
||||
|
||||
except:
|
||||
await ctx.send(_("Error."))
|
||||
await ctx.send(
|
||||
_("No Urban dictionary entries were found or there was an error in the process")
|
||||
)
|
||||
|
||||
if data.get("error") != 404:
|
||||
|
||||
if await ctx.embed_requested():
|
||||
# a list of embeds
|
||||
embeds = []
|
||||
for ud in data["list"]:
|
||||
embed = discord.Embed()
|
||||
embed.title = _("{} by {}").format(ud["word"].capitalize(), ud["author"])
|
||||
embed.url = ud["permalink"]
|
||||
|
||||
description = "{} \n \n **Example : ** {}".format(
|
||||
ud["definition"], ud.get("example", "N/A")
|
||||
)
|
||||
if len(description) > 2048:
|
||||
description = "{}...".format(description[:2045])
|
||||
embed.description = description
|
||||
|
||||
embed.set_footer(
|
||||
text=_("{} Down / {} Up , Powered by urban dictionary").format(
|
||||
ud["thumbs_down"], ud["thumbs_up"]
|
||||
)
|
||||
)
|
||||
embeds.append(embed)
|
||||
|
||||
if embeds is not None and len(embeds) > 0:
|
||||
await menu(
|
||||
ctx,
|
||||
pages=embeds,
|
||||
controls=DEFAULT_CONTROLS,
|
||||
message=None,
|
||||
page=0,
|
||||
timeout=30,
|
||||
)
|
||||
else:
|
||||
messages = []
|
||||
for ud in data["list"]:
|
||||
description = _("{} \n \n **Example : ** {}").format(
|
||||
ud["definition"], ud.get("example", "N/A")
|
||||
)
|
||||
if len(description) > 2048:
|
||||
description = "{}...".format(description[:2045])
|
||||
description = description
|
||||
|
||||
message = _(
|
||||
"<{}> \n {} by {} \n \n {} \n \n {} Down / {} Up, Powered by urban "
|
||||
"dictionary"
|
||||
).format(
|
||||
ud["permalink"],
|
||||
ud["word"].capitalize(),
|
||||
ud["author"],
|
||||
description,
|
||||
ud["thumbs_down"],
|
||||
ud["thumbs_up"],
|
||||
)
|
||||
messages.append(message)
|
||||
|
||||
if messages is not None and len(messages) > 0:
|
||||
await menu(
|
||||
ctx,
|
||||
pages=messages,
|
||||
controls=DEFAULT_CONTROLS,
|
||||
message=None,
|
||||
page=0,
|
||||
timeout=30,
|
||||
)
|
||||
else:
|
||||
await ctx.send(
|
||||
_("No Urban dictionary entries were found or there was an error in the process")
|
||||
)
|
||||
return
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../general.py:42
|
||||
msgid "As I see it, yes"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:42
|
||||
msgid "It is certain"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:42
|
||||
msgid "It is decidedly so"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:43
|
||||
msgid "Most likely"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:43
|
||||
msgid "Outlook good"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:43
|
||||
msgid "Signs point to yes"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:44
|
||||
msgid "Without a doubt"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:44
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:44
|
||||
msgid "Yes – definitely"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:44
|
||||
msgid "You may rely on it"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:45
|
||||
msgid "Ask again later"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:45
|
||||
msgid "Reply hazy, try again"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:46
|
||||
msgid "Better not tell you now"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:46
|
||||
msgid "Cannot predict now"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:47
|
||||
msgid "Concentrate and ask again"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:47
|
||||
msgid "Don't count on it"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:47
|
||||
msgid "My reply is no"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:48
|
||||
msgid "My sources say no"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:48
|
||||
msgid "Outlook not so good"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:48
|
||||
msgid "Very doubtful"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:64
|
||||
msgid "Not enough choices to pick from."
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:78
|
||||
msgid "{} :game_die: {} :game_die:"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:81
|
||||
msgid "{} Maybe higher than 1? ;P"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:93
|
||||
msgid ""
|
||||
"Nice try. You think this is funny?How about *this* instead:\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:106
|
||||
msgid "*flips a coin and... "
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:106
|
||||
msgid "HEADS!*"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:106
|
||||
msgid "TAILS!*"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:130
|
||||
msgid "{} You win {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:134
|
||||
msgid "{} You lose {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:138
|
||||
msgid "{} We're square {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:151
|
||||
msgid "That doesn't look like a question."
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:159
|
||||
msgid " Stopwatch started!"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:163
|
||||
msgid " Stopwatch stopped! Time: **"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:216 ../general.py:217
|
||||
msgid ""
|
||||
"{}\n"
|
||||
"({} days ago)"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:219
|
||||
msgid "Chilling in {} status"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:223
|
||||
msgid "Playing {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:225
|
||||
msgid "Streaming [{}]({})"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:227
|
||||
msgid "Listening to {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:229
|
||||
msgid "Watching {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:234
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:237
|
||||
msgid "Joined Discord on"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:238
|
||||
msgid "Joined this guild on"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:239 ../general.py:286
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:240
|
||||
msgid "Member #{} | User ID: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:257 ../general.py:299
|
||||
msgid "I need the `Embed links` permission to send this."
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:272
|
||||
msgid "Since {}. That's over {} days ago!"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:282
|
||||
msgid "Region"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:283
|
||||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:284
|
||||
msgid "Text Channels"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:285
|
||||
msgid "Voice Channels"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:287
|
||||
msgid "Owner"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:288
|
||||
msgid "Guild ID: "
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:343
|
||||
msgid "Your search terms gave no results."
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:345
|
||||
msgid "There is no definition #{}"
|
||||
msgstr ""
|
||||
|
||||
#: ../general.py:347
|
||||
msgid "Error."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../general.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -24,9 +24,9 @@ class Image:
|
||||
self.imgur_base_url = "https://api.imgur.com/3/"
|
||||
|
||||
def __unload(self):
|
||||
self.session.close()
|
||||
self.session.detach()
|
||||
|
||||
@commands.group(name="imgur", autohelp=True)
|
||||
@commands.group(name="imgur")
|
||||
async def _imgur(self, ctx):
|
||||
"""Retrieves pictures from imgur
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../image.py:49
|
||||
msgid "Your search returned no results"
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:52
|
||||
msgid ""
|
||||
"Search results...\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:58 ../image.py:100
|
||||
msgid "Something went wrong. Error code is {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:70
|
||||
msgid "Only 'new' and 'top' are a valid sort type."
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:98 ../image.py:135 ../image.py:157
|
||||
msgid "No results found."
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:115
|
||||
msgid "Set the imgur client id!"
|
||||
msgstr ""
|
||||
|
||||
#: ../image.py:137 ../image.py:159
|
||||
msgid "Error contacting the API"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../image.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -1,286 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../mod.py:209
|
||||
msgid "Role hierarchy will be checked when moderation commands are issued."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:213
|
||||
msgid "Role hierarchy will be ignored when moderation commands are issued."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:228
|
||||
msgid "Autoban for mention spam enabled. Anyone mentioning {} or more different people in a single message will be autobanned."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:239
|
||||
msgid "Autoban for mention spam disabled."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:249
|
||||
msgid "Messages repeated up to 3 times will be deleted."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:253
|
||||
msgid "Repeated messages will be ignored."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:267
|
||||
msgid "Command deleting disabled."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:270
|
||||
msgid "Delete delay set to {} seconds."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:275
|
||||
msgid "Bot will delete command messages after {} seconds. Set this value to -1 to stop deleting messages"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:279
|
||||
msgid "I will not delete command messages."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:292
|
||||
msgid "Users unbanned with {} will be reinvited."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:295
|
||||
msgid "Users unbanned with {} will not be reinvited."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:309 ../mod.py:349 ../mod.py:506
|
||||
msgid "I cannot let you do that. Self-harm is bad {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:313 ../mod.py:353 ../mod.py:510
|
||||
msgid "I cannot let you do that. You are not higher than the user in the role hierarchy."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:323 ../mod.py:379 ../mod.py:570
|
||||
msgid "I'm not allowed to do that."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:327
|
||||
msgid "Done. That felt good."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:369
|
||||
msgid "Invalid days. Must be between 0 and 7."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:384
|
||||
msgid "Done. It was about time."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:413
|
||||
msgid "User is already banned."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:429
|
||||
msgid "User not found. Have you provided the correct user ID?"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:433
|
||||
msgid "I lack the permissions to do this."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:435
|
||||
msgid "Done. The user will not be able to join this guild."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:472
|
||||
msgid "You have been temporarily banned from {} until {}. Here is an invite for when your ban expires: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:481
|
||||
msgid "I can't do that for some reason."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:483
|
||||
msgid "Something went wrong while banning"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:485
|
||||
msgid "Done. Enough chaos for now"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:525
|
||||
msgid ""
|
||||
"You have been banned and then unbanned as a quick way to delete your messages.\n"
|
||||
"You can now join the guild again. {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:537
|
||||
msgid "My role is not high enough to softban that user."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:553
|
||||
msgid "Done. Enough chaos."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:587
|
||||
msgid "Couldn't find a user with that ID!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:593
|
||||
msgid "It seems that user isn't banned!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:601
|
||||
msgid "Something went wrong while attempting to unban that user"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:604
|
||||
msgid "Unbanned that user from this guild"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:619
|
||||
msgid ""
|
||||
"You've been unbanned from {}.\n"
|
||||
"Here is an invite for that guild: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:623
|
||||
msgid ""
|
||||
"I failed to send an invite to that user. Perhaps you may be able to send it for me?\n"
|
||||
"Here's the invite link: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:629
|
||||
msgid "Something went wrong when attempting to send that useran invite. Here's the link so you can try: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:673 ../mod.py:710
|
||||
msgid "No voice state for that user!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:687
|
||||
msgid "That user is already muted and deafened guild-wide!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:690
|
||||
msgid "User has been banned from speaking or listening in voice channels"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:722
|
||||
msgid "That user isn't muted or deafened by the guild!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:725
|
||||
msgid "User is now allowed to speak and listen in voice channels"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:754
|
||||
msgid "I cannot do that, I lack the '{}' permission."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:783
|
||||
msgid "Muted {}#{} in channel {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:797
|
||||
msgid "That user is already muted in {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:800 ../mod.py:932
|
||||
msgid "That user is not in a voice channel right now!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:802 ../mod.py:934
|
||||
msgid "No voice state for the target!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:822
|
||||
msgid "User has been muted in this channel."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:858
|
||||
msgid "User has been muted in this guild."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:919
|
||||
msgid "Unmuted {}#{} in channel {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:929
|
||||
msgid "That user is already unmuted in {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:949
|
||||
msgid "User unmuted in this channel."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:958
|
||||
msgid "Unmute failed. Reason: {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:981
|
||||
msgid "User has been unmuted in this guild."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1045
|
||||
msgid "Channel added to ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1047
|
||||
msgid "Channel already in ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1055
|
||||
msgid "This guild has been added to the ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1057
|
||||
msgid "This guild is already being ignored."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1078
|
||||
msgid "Channel removed from ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1080
|
||||
msgid "That channel is not in the ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1088
|
||||
msgid "This guild has been removed from the ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1090
|
||||
msgid "This guild is not in the ignore list."
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1102
|
||||
msgid ""
|
||||
"Currently ignoring:\n"
|
||||
"{} channels\n"
|
||||
"{} guilds\n"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1133
|
||||
msgid "**Past 20 names**:"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1140
|
||||
msgid "**Past 20 nicknames**:"
|
||||
msgstr ""
|
||||
|
||||
#: ../mod.py:1146
|
||||
msgid "That user doesn't have any recorded name or nickname change."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../mod.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -12,6 +12,8 @@ from .checks import mod_or_voice_permissions, admin_or_voice_permissions, bot_ha
|
||||
from redbot.core.utils.mod import is_mod_or_superior, is_allowed_by_hierarchy, get_audit_reason
|
||||
from .log import log
|
||||
|
||||
from redbot.core.utils.common_filters import filter_invites, filter_various_mentions
|
||||
|
||||
_ = Translator("Mod", __file__)
|
||||
|
||||
|
||||
@@ -161,13 +163,13 @@ class Mod:
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
async def modset(self, ctx: commands.Context):
|
||||
"""Manages server administration settings."""
|
||||
if ctx.invoked_subcommand is None:
|
||||
|
||||
guild = ctx.guild
|
||||
# Display current settings
|
||||
delete_repeats = await self.settings.guild(guild).delete_repeats()
|
||||
ban_mention_spam = await self.settings.guild(guild).ban_mention_spam()
|
||||
@@ -628,7 +630,6 @@ class Mod:
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(ban_members=True)
|
||||
@commands.bot_has_permissions(ban_members=True)
|
||||
async def unban(self, ctx: commands.Context, user_id: int, *, reason: str = None):
|
||||
"""Unbans the target user.
|
||||
|
||||
@@ -636,13 +637,17 @@ class Mod:
|
||||
1. Copy it from the mod log case (if one was created), or
|
||||
2. enable developer mode, go to Bans in this server's settings, right-
|
||||
click the user and select 'Copy ID'."""
|
||||
channel = ctx.channel
|
||||
if not channel.permissions_for(ctx.guild.me).ban_members:
|
||||
await ctx.send("I need the Ban Members permission to do this.")
|
||||
return
|
||||
guild = ctx.guild
|
||||
author = ctx.author
|
||||
user = await self.bot.get_user_info(user_id)
|
||||
if not user:
|
||||
await ctx.send(_("Couldn't find a user with that ID!"))
|
||||
return
|
||||
reason = get_audit_reason(ctx.author, reason)
|
||||
audit_reason = get_audit_reason(ctx.author, reason)
|
||||
bans = await guild.bans()
|
||||
bans = [be.user for be in bans]
|
||||
if user not in bans:
|
||||
@@ -651,7 +656,7 @@ class Mod:
|
||||
queue_entry = (guild.id, user.id)
|
||||
self.unban_queue.append(queue_entry)
|
||||
try:
|
||||
await guild.unban(user, reason=reason)
|
||||
await guild.unban(user, reason=audit_reason)
|
||||
except discord.HTTPException:
|
||||
self.unban_queue.remove(queue_entry)
|
||||
await ctx.send(_("Something went wrong while attempting to unban that user"))
|
||||
@@ -832,7 +837,7 @@ class Mod:
|
||||
_("I cannot do that, I lack the '{}' permission.").format("Manage Nicknames")
|
||||
)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(manage_channel=True)
|
||||
async def mute(self, ctx: commands.Context):
|
||||
@@ -998,7 +1003,7 @@ class Mod:
|
||||
await self.settings.member(user).perms_cache.set(perms_cache)
|
||||
return True, None
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(manage_channel=True)
|
||||
async def unmute(self, ctx: commands.Context):
|
||||
@@ -1164,13 +1169,12 @@ class Mod:
|
||||
await self.settings.member(user).perms_cache.set(perms_cache)
|
||||
return True, None
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(manage_channels=True)
|
||||
async def ignore(self, ctx: commands.Context):
|
||||
"""Adds servers/channels to ignorelist"""
|
||||
if ctx.invoked_subcommand is None:
|
||||
await ctx.send_help()
|
||||
await ctx.send(await self.count_ignored())
|
||||
|
||||
@ignore.command(name="channel")
|
||||
@@ -1187,7 +1191,7 @@ class Mod:
|
||||
await ctx.send(_("Channel already in ignore list."))
|
||||
|
||||
@ignore.command(name="server", aliases=["guild"])
|
||||
@commands.has_permissions(manage_guild=True)
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def ignore_guild(self, ctx: commands.Context):
|
||||
"""Ignores current server"""
|
||||
guild = ctx.guild
|
||||
@@ -1197,7 +1201,7 @@ class Mod:
|
||||
else:
|
||||
await ctx.send(_("This server is already being ignored."))
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.admin_or_permissions(manage_channels=True)
|
||||
async def unignore(self, ctx: commands.Context):
|
||||
@@ -1220,7 +1224,7 @@ class Mod:
|
||||
await ctx.send(_("That channel is not in the ignore list."))
|
||||
|
||||
@unignore.command(name="server", aliases=["guild"])
|
||||
@commands.has_permissions(manage_guild=True)
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
async def unignore_guild(self, ctx: commands.Context):
|
||||
"""Removes current guild from ignore list"""
|
||||
guild = ctx.message.guild
|
||||
@@ -1264,7 +1268,14 @@ class Mod:
|
||||
@commands.command()
|
||||
@commands.guild_only()
|
||||
async def userinfo(self, ctx, *, user: discord.Member = None):
|
||||
"""Shows users's informations"""
|
||||
"""Shows information for a user.
|
||||
|
||||
This includes fields for status, discord join date, server
|
||||
join date, voice state and previous names/nicknames.
|
||||
|
||||
If the user has none of roles, previous names or previous
|
||||
nicknames, these fields will be omitted.
|
||||
"""
|
||||
author = ctx.author
|
||||
guild = ctx.guild
|
||||
|
||||
@@ -1304,16 +1315,21 @@ class Mod:
|
||||
if roles:
|
||||
roles = ", ".join([x.name for x in roles])
|
||||
else:
|
||||
roles = _("None")
|
||||
roles = None
|
||||
|
||||
data = discord.Embed(description=activity, colour=user.colour)
|
||||
data.add_field(name=_("Joined Discord on"), value=created_on)
|
||||
data.add_field(name=_("Joined this server on"), value=joined_on)
|
||||
if roles is not None:
|
||||
data.add_field(name=_("Roles"), value=roles, inline=False)
|
||||
if names:
|
||||
data.add_field(name=_("Previous Names"), value=", ".join(names), inline=False)
|
||||
# May need sanitizing later, but mentions do not ping in embeds currently
|
||||
val = filter_invites(", ".join(names))
|
||||
data.add_field(name=_("Previous Names"), value=val, inline=False)
|
||||
if nicks:
|
||||
data.add_field(name=_("Previous Nicknames"), value=", ".join(nicks), inline=False)
|
||||
# May need sanitizing later, but mentions do not ping in embeds currently
|
||||
val = filter_invites(", ".join(nicks))
|
||||
data.add_field(name=_("Previous Nicknames"), value=val, inline=False)
|
||||
if voice_state and voice_state.channel:
|
||||
data.add_field(
|
||||
name=_("Current voice channel"),
|
||||
@@ -1324,6 +1340,7 @@ class Mod:
|
||||
|
||||
name = str(user)
|
||||
name = " ~ ".join((name, user.nick)) if user.nick else name
|
||||
name = filter_invites(name)
|
||||
|
||||
if user.avatar:
|
||||
avatar = user.avatar_url
|
||||
@@ -1354,6 +1371,7 @@ class Mod:
|
||||
msg += "\n"
|
||||
msg += ", ".join(nicks)
|
||||
if msg:
|
||||
msg = filter_various_mentions(msg)
|
||||
await ctx.send(msg)
|
||||
else:
|
||||
await ctx.send(_("That user doesn't have any recorded name or nickname change."))
|
||||
@@ -1362,9 +1380,9 @@ class Mod:
|
||||
names = await self.settings.user(user).past_names()
|
||||
nicks = await self.settings.member(user).past_nicks()
|
||||
if names:
|
||||
names = [escape(name, mass_mentions=True) for name in names]
|
||||
names = [escape(name, mass_mentions=True) for name in names if name]
|
||||
if nicks:
|
||||
nicks = [escape(nick, mass_mentions=True) for nick in nicks]
|
||||
nicks = [escape(nick, mass_mentions=True) for nick in nicks if nick]
|
||||
return names, nicks
|
||||
|
||||
async def check_tempban_expirations(self):
|
||||
@@ -1602,18 +1620,22 @@ class Mod:
|
||||
if entry.target == target:
|
||||
return entry
|
||||
|
||||
async def on_member_update(self, before, after):
|
||||
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||
if before.name != after.name:
|
||||
async with self.settings.user(before).past_names() as name_list:
|
||||
if after.nick in name_list:
|
||||
while None in name_list: # clean out null entries from a bug
|
||||
name_list.remove(None)
|
||||
if after.name in name_list:
|
||||
# Ensure order is maintained without duplicates occuring
|
||||
name_list.remove(after.nick)
|
||||
name_list.append(after.nick)
|
||||
name_list.remove(after.name)
|
||||
name_list.append(after.name)
|
||||
while len(name_list) > 20:
|
||||
name_list.pop(0)
|
||||
|
||||
if before.nick != after.nick and after.nick is not None:
|
||||
async with self.settings.member(before).past_nicks() as nick_list:
|
||||
while None in nick_list: # clean out null entries from a bug
|
||||
nick_list.remove(None)
|
||||
if after.nick in nick_list:
|
||||
nick_list.remove(after.nick)
|
||||
nick_list.append(after.nick)
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
#: ../modlog.py:36
|
||||
msgid "Mod events will be sent to {}"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:42
|
||||
msgid "I do not have permissions to send messages in {}!"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:52
|
||||
msgid "Mod log deactivated."
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:63
|
||||
msgid "Current settings:"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:75
|
||||
msgid "That action is not registered"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:82
|
||||
msgid "Case creation for {} actions is now {}."
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:94
|
||||
msgid "Cases have been reset."
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:103
|
||||
msgid "That case does not exist for that guild"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:122
|
||||
msgid "That case does not exist!"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:146
|
||||
msgid "You are not authorized to modify that case!"
|
||||
msgstr ""
|
||||
|
||||
#: ../modlog.py:155
|
||||
msgid "Reason has been updated."
|
||||
msgstr ""
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../modlog.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -15,7 +15,7 @@ class ModLog:
|
||||
def __init__(self, bot: Red):
|
||||
self.bot = bot
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
async def modlogset(self, ctx: commands.Context):
|
||||
"""Settings for the mod log"""
|
||||
@@ -95,19 +95,29 @@ class ModLog:
|
||||
await ctx.send(_("That case does not exist for that server"))
|
||||
return
|
||||
else:
|
||||
await ctx.send(embed=await case.get_case_msg_content())
|
||||
if await ctx.embed_requested():
|
||||
await ctx.send(embed=await case.message_content(embed=True))
|
||||
else:
|
||||
await ctx.send(await case.message_content(embed=False))
|
||||
|
||||
@commands.command()
|
||||
@commands.command(usage="[case] <reason>")
|
||||
@commands.guild_only()
|
||||
async def reason(self, ctx: commands.Context, case: int, *, reason: str = ""):
|
||||
async def reason(self, ctx: commands.Context, *, reason: str):
|
||||
"""Lets you specify a reason for mod-log's cases
|
||||
|
||||
Please note that you can only edit cases you are
|
||||
the owner of unless you are a mod/admin or the server owner"""
|
||||
the owner of unless you are a mod/admin or the server owner.
|
||||
|
||||
If no number is specified, the latest case will be used."""
|
||||
author = ctx.author
|
||||
guild = ctx.guild
|
||||
if not reason:
|
||||
await ctx.send_help()
|
||||
return
|
||||
potential_case = reason.split()[0]
|
||||
if potential_case.isdigit():
|
||||
case = int(potential_case)
|
||||
reason = reason.replace(potential_case, "")
|
||||
else:
|
||||
case = str(int(await modlog.get_next_case_number(guild)) - 1)
|
||||
# latest case
|
||||
try:
|
||||
case_before = await modlog.get_case(case, guild, self.bot)
|
||||
except RuntimeError:
|
||||
|
||||
@@ -27,3 +27,18 @@ class RuleType(commands.Converter):
|
||||
raise commands.BadArgument(
|
||||
'"{arg}" is not a valid rule. Valid rules are "allow" or "deny"'.format(arg=arg)
|
||||
)
|
||||
|
||||
|
||||
class ClearableRuleType(commands.Converter):
|
||||
async def convert(self, ctx: commands.Context, arg: str) -> str:
|
||||
if arg.lower() in ("allow", "whitelist", "allowed"):
|
||||
return "allow"
|
||||
if arg.lower() in ("deny", "blacklist", "denied"):
|
||||
return "deny"
|
||||
if arg.lower() in ("clear", "reset"):
|
||||
return "clear"
|
||||
|
||||
raise commands.BadArgument(
|
||||
'"{arg}" is not a valid rule. Valid rules are "allow" or "deny", or "clear" to remove the rule'
|
||||
"".format(arg=arg)
|
||||
)
|
||||
|
||||
102
redbot/cogs/permissions/mass_resolution.py
Normal file
102
redbot/cogs/permissions/mass_resolution.py
Normal file
@@ -0,0 +1,102 @@
|
||||
from redbot.core import commands
|
||||
from redbot.core.config import Config
|
||||
from .resolvers import entries_from_ctx, resolve_lists
|
||||
|
||||
# This has optimizations in it that may not hold True if other parts of the permission
|
||||
# model are changed from the state they are in currently.
|
||||
# (commit hash ~ 3bcf375204c22271ad3ed1fc059b598b751aa03f)
|
||||
#
|
||||
# This is primarily to help with the performance of the help formatter
|
||||
|
||||
# This is less efficient if only checking one command,
|
||||
# but is much faster for checking all of them.
|
||||
|
||||
|
||||
async def mass_resolve(*, ctx: commands.Context, config: Config):
|
||||
"""
|
||||
Get's all the permission cog interactions for all loaded commands
|
||||
in the given context.
|
||||
"""
|
||||
|
||||
owner_settings = await config.owner_models()
|
||||
guild_owner_settings = await config.guild(ctx.guild).owner_models() if ctx.guild else None
|
||||
|
||||
ret = {"allowed": [], "denied": [], "default": []}
|
||||
|
||||
for cogname, cog in ctx.bot.cogs.items():
|
||||
|
||||
cog_setting = resolve_cog_or_command(
|
||||
objname=cogname, models=owner_settings, ctx=ctx, typ="cogs"
|
||||
)
|
||||
if cog_setting is None and guild_owner_settings:
|
||||
cog_setting = resolve_cog_or_command(
|
||||
objname=cogname, models=guild_owner_settings, ctx=ctx, typ="cogs"
|
||||
)
|
||||
|
||||
for command in [c for c in ctx.bot.all_commands.values() if c.instance is cog]:
|
||||
resolution = recursively_resolve(
|
||||
com_or_group=command,
|
||||
o_models=owner_settings,
|
||||
g_models=guild_owner_settings,
|
||||
ctx=ctx,
|
||||
)
|
||||
|
||||
for com, resolved in resolution:
|
||||
if resolved is None:
|
||||
resolved = cog_setting
|
||||
if resolved is True:
|
||||
ret["allowed"].append(com)
|
||||
elif resolved is False:
|
||||
ret["denied"].append(com)
|
||||
else:
|
||||
ret["default"].append(com)
|
||||
|
||||
ret = {k: set(v) for k, v in ret.items()}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def recursively_resolve(*, com_or_group, o_models, g_models, ctx, override=False):
|
||||
ret = []
|
||||
if override:
|
||||
current = False
|
||||
else:
|
||||
current = resolve_cog_or_command(
|
||||
typ="commands", objname=com_or_group.qualified_name, ctx=ctx, models=o_models
|
||||
)
|
||||
if current is None and g_models:
|
||||
current = resolve_cog_or_command(
|
||||
typ="commands", objname=com_or_group.qualified_name, ctx=ctx, models=o_models
|
||||
)
|
||||
ret.append((com_or_group, current))
|
||||
if isinstance(com_or_group, commands.Group):
|
||||
for com in com_or_group.commands:
|
||||
ret.extend(
|
||||
recursively_resolve(
|
||||
com_or_group=com,
|
||||
o_models=o_models,
|
||||
g_models=g_models,
|
||||
ctx=ctx,
|
||||
override=(current is False),
|
||||
)
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
def resolve_cog_or_command(*, typ, ctx, objname, models: dict) -> bool:
|
||||
"""
|
||||
Resolves models in order.
|
||||
"""
|
||||
|
||||
resolved = None
|
||||
|
||||
if objname in models.get(typ, {}):
|
||||
blacklist = models[typ][objname].get("deny", [])
|
||||
whitelist = models[typ][objname].get("allow", [])
|
||||
resolved = resolve_lists(ctx=ctx, whitelist=whitelist, blacklist=blacklist)
|
||||
if resolved is not None:
|
||||
return resolved
|
||||
resolved = models[typ][objname].get("default", None)
|
||||
if resolved is not None:
|
||||
return resolved
|
||||
return None
|
||||
@@ -7,16 +7,19 @@ from redbot.core.bot import Red
|
||||
from redbot.core import checks
|
||||
from redbot.core.config import Config
|
||||
from redbot.core.i18n import Translator, cog_i18n
|
||||
from redbot.core.utils.caching import LRUDict
|
||||
|
||||
from .resolvers import val_if_check_is_valid, resolve_models
|
||||
from .resolvers import val_if_check_is_valid, resolve_models, entries_from_ctx
|
||||
from .yaml_handler import yamlset_acl, yamlget_acl
|
||||
from .converters import CogOrCommand, RuleType
|
||||
from .converters import CogOrCommand, RuleType, ClearableRuleType
|
||||
from .mass_resolution import mass_resolve
|
||||
|
||||
_models = ["owner", "guildowner", "admin", "mod", "all"]
|
||||
|
||||
_ = Translator("Permissions", __file__)
|
||||
|
||||
REACTS = {"\N{WHITE HEAVY CHECK MARK}": True, "\N{NEGATIVE SQUARED CROSS MARK}": False}
|
||||
Y_OR_N = {"y": True, "yes": True, "n": False, "no": False}
|
||||
|
||||
|
||||
@cog_i18n(_)
|
||||
@@ -34,8 +37,32 @@ class Permissions:
|
||||
self.config = Config.get_conf(self, identifier=78631113035100160, force_registration=True)
|
||||
self.config.register_global(owner_models={})
|
||||
self.config.register_guild(owner_models={})
|
||||
self.cache = LRUDict(size=25000) # This can be tuned later
|
||||
|
||||
async def __global_check(self, ctx):
|
||||
async def get_user_ctx_overrides(self, ctx: commands.Context) -> dict:
|
||||
"""
|
||||
This takes a context object, and returns a dict of
|
||||
|
||||
allowed: list of commands
|
||||
denied: list of commands
|
||||
default: list of commands
|
||||
|
||||
representing how permissions interacts with the
|
||||
user, channel, guild, and (possibly) voice channel
|
||||
for all commands on the bot (not just the one in the context object)
|
||||
|
||||
This mainly exists for use by the help formatter,
|
||||
but others may find it useful
|
||||
|
||||
Unlike the rest of the permission system, if other models are added later,
|
||||
due to optimizations made for this, this needs to be adjusted accordingly
|
||||
|
||||
This does not account for before and after permission hooks,
|
||||
these need to be checked seperately
|
||||
"""
|
||||
return await mass_resolve(ctx=ctx, config=self.config)
|
||||
|
||||
async def __global_check(self, ctx: commands.Context) -> bool:
|
||||
"""
|
||||
Yes, this is needed on top of hooking into checks.py
|
||||
to ensure that unchecked commands can still be managed by permissions
|
||||
@@ -68,12 +95,6 @@ class Permissions:
|
||||
"""
|
||||
if await ctx.bot.is_owner(ctx.author):
|
||||
return True
|
||||
voice_channel = None
|
||||
with contextlib.suppress(Exception):
|
||||
voice_channel = ctx.author.voice.voice_channel
|
||||
entries = [x for x in (ctx.author, voice_channel, ctx.channel) if x]
|
||||
roles = sorted(ctx.author.roles, reverse=True) if ctx.guild else []
|
||||
entries.extend([x.id for x in roles])
|
||||
|
||||
before = [
|
||||
getattr(cog, "_{0.__class__.__name__}__red_permissions_before".format(cog), None)
|
||||
@@ -86,11 +107,26 @@ class Permissions:
|
||||
if override is not None:
|
||||
return override
|
||||
|
||||
# checked ids + configureable to be checked against
|
||||
cache_tup = entries_from_ctx(ctx) + (
|
||||
ctx.cog.__class__.__name__,
|
||||
ctx.command.qualified_name,
|
||||
)
|
||||
if cache_tup in self.cache:
|
||||
override = self.cache[cache_tup]
|
||||
if override is not None:
|
||||
return override
|
||||
else:
|
||||
for model in self.resolution_order[level]:
|
||||
if ctx.guild is None and model != "owner":
|
||||
break
|
||||
override_model = getattr(self, model + "_model", None)
|
||||
override = await override_model(ctx) if override_model else None
|
||||
if override is not None:
|
||||
self.cache[cache_tup] = override
|
||||
return override
|
||||
# This is intentional not being in an else block
|
||||
self.cache[cache_tup] = None
|
||||
|
||||
after = [
|
||||
getattr(cog, "_{0.__class__.__name__}__red_permissions_after".format(cog), None)
|
||||
@@ -115,7 +151,8 @@ class Permissions:
|
||||
"""
|
||||
Handles guild level overrides
|
||||
"""
|
||||
|
||||
if ctx.guild is None:
|
||||
return None
|
||||
async with self.config.guild(ctx.guild).owner_models() as models:
|
||||
return resolve_models(ctx=ctx, models=models)
|
||||
|
||||
@@ -125,7 +162,7 @@ class Permissions:
|
||||
# async def admin_model(self, ctx: commands.Context) -> bool:
|
||||
# async def mod_model(self, ctx: commands.Context) -> bool:
|
||||
|
||||
@commands.group(aliases=["p"], autohelp=True)
|
||||
@commands.group(aliases=["p"])
|
||||
async def permissions(self, ctx: commands.Context):
|
||||
"""
|
||||
Permission management tools
|
||||
@@ -223,6 +260,7 @@ class Permissions:
|
||||
return await ctx.send(_("Invalid syntax."))
|
||||
else:
|
||||
await ctx.send(_("Rules set."))
|
||||
self.invalidate_cache()
|
||||
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="getglobalacl")
|
||||
@@ -249,6 +287,7 @@ class Permissions:
|
||||
return await ctx.send(_("Invalid syntax."))
|
||||
else:
|
||||
await ctx.send(_("Rules set."))
|
||||
self.invalidate_cache(ctx.guild.id)
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@@ -278,6 +317,7 @@ class Permissions:
|
||||
return await ctx.send(_("Invalid syntax."))
|
||||
else:
|
||||
await ctx.send(_("Rules set."))
|
||||
self.invalidate_cache(ctx.guild.id)
|
||||
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="updateglobalacl")
|
||||
@@ -297,6 +337,7 @@ class Permissions:
|
||||
return await ctx.send(_("Invalid syntax."))
|
||||
else:
|
||||
await ctx.send(_("Rules set."))
|
||||
self.invalidate_cache()
|
||||
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="addglobalrule")
|
||||
@@ -340,6 +381,7 @@ class Permissions:
|
||||
data[model_type][type_name][allow_or_deny].append(obj)
|
||||
models.update(data)
|
||||
await ctx.send(_("Rule added."))
|
||||
self.invalidate_cache(type_name, obj)
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@@ -384,6 +426,7 @@ class Permissions:
|
||||
data[model_type][type_name][allow_or_deny].append(obj)
|
||||
models.update(data)
|
||||
await ctx.send(_("Rule added."))
|
||||
self.invalidate_cache(type_name, obj)
|
||||
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="removeglobalrule")
|
||||
@@ -427,6 +470,7 @@ class Permissions:
|
||||
data[model_type][type_name][allow_or_deny].remove(obj)
|
||||
models.update(data)
|
||||
await ctx.send(_("Rule removed."))
|
||||
self.invalidate_cache(obj, type_name)
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@@ -471,23 +515,18 @@ class Permissions:
|
||||
data[model_type][type_name][allow_or_deny].remove(obj)
|
||||
models.update(data)
|
||||
await ctx.send(_("Rule removed."))
|
||||
self.invalidate_cache(obj, type_name)
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@permissions.command(name="setdefaultguildrule")
|
||||
async def set_default_guild_rule(
|
||||
self, ctx: commands.Context, cog_or_command: CogOrCommand, allow_or_deny: RuleType = None
|
||||
self, ctx: commands.Context, allow_or_deny: ClearableRuleType, cog_or_command: CogOrCommand
|
||||
):
|
||||
"""
|
||||
Sets the default behavior for a cog or command if no rule is set
|
||||
|
||||
Use with a cog or command and no setting to clear the default and defer to
|
||||
normal check logic
|
||||
"""
|
||||
if allow_or_deny:
|
||||
val_to_set = {"allow": True, "deny": False}.get(allow_or_deny)
|
||||
else:
|
||||
val_to_set = None
|
||||
val_to_set = {"allow": True, "deny": False, "clear": None}.get(allow_or_deny)
|
||||
|
||||
model_type, type_name = cog_or_command
|
||||
async with self.config.guild(ctx.guild).owner_models() as models:
|
||||
@@ -501,23 +540,17 @@ class Permissions:
|
||||
|
||||
models.update(data)
|
||||
await ctx.send(_("Default set."))
|
||||
self.invalidate_cache(type_name)
|
||||
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="setdefaultglobalrule")
|
||||
async def set_default_global_rule(
|
||||
self, ctx: commands.Context, cog_or_command: CogOrCommand, allow_or_deny: RuleType = None
|
||||
self, ctx: commands.Context, allow_or_deny: ClearableRuleType, cog_or_command: CogOrCommand
|
||||
):
|
||||
"""
|
||||
Sets the default behavior for a cog or command if no rule is set
|
||||
|
||||
Use with a cog or command and no setting to clear the default and defer to
|
||||
normal check logic
|
||||
"""
|
||||
|
||||
if allow_or_deny:
|
||||
val_to_set = {"allow": True, "deny": False}.get(allow_or_deny)
|
||||
else:
|
||||
val_to_set = None
|
||||
val_to_set = {"allow": True, "deny": False, "clear": None}.get(allow_or_deny)
|
||||
|
||||
model_type, type_name = cog_or_command
|
||||
async with self.config.owner_models() as models:
|
||||
@@ -531,32 +564,17 @@ class Permissions:
|
||||
|
||||
models.update(data)
|
||||
await ctx.send(_("Default set."))
|
||||
self.invalidate_cache(type_name)
|
||||
|
||||
@commands.bot_has_permissions(add_reactions=True)
|
||||
@checks.is_owner()
|
||||
@permissions.command(name="clearglobalsettings")
|
||||
async def clear_globals(self, ctx: commands.Context):
|
||||
"""
|
||||
Clears all global rules.
|
||||
"""
|
||||
await self._confirm_then_clear_rules(ctx, is_guild=False)
|
||||
self.invalidate_cache()
|
||||
|
||||
m = await ctx.send("Are you sure?")
|
||||
for r in REACTS.keys():
|
||||
await m.add_reaction(r)
|
||||
try:
|
||||
reaction, user = await self.bot.wait_for(
|
||||
"reaction_add", check=lambda r, u: u == ctx.author and str(r) in REACTS, timeout=30
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
return await ctx.send(_("Ok, try responding with an emoji next time."))
|
||||
|
||||
if REACTS.get(str(reaction)):
|
||||
await self.config.owner_models.clear()
|
||||
await ctx.send(_("Global settings cleared."))
|
||||
else:
|
||||
await ctx.send(_("Okay."))
|
||||
|
||||
@commands.bot_has_permissions(add_reactions=True)
|
||||
@commands.guild_only()
|
||||
@checks.guildowner_or_permissions(administrator=True)
|
||||
@permissions.command(name="clearguildsettings")
|
||||
@@ -564,23 +582,61 @@ class Permissions:
|
||||
"""
|
||||
Clears all guild rules.
|
||||
"""
|
||||
await self._confirm_then_clear_rules(ctx, is_guild=True)
|
||||
self.invalidate_cache(ctx.guild.id)
|
||||
|
||||
m = await ctx.send("Are you sure?")
|
||||
async def _confirm_then_clear_rules(self, ctx: commands.Context, is_guild: bool):
|
||||
if ctx.guild.me.permissions_in(ctx.channel).add_reactions:
|
||||
m = await ctx.send(_("Are you sure?"))
|
||||
for r in REACTS.keys():
|
||||
await m.add_reaction(r)
|
||||
try:
|
||||
reaction, user = await self.bot.wait_for(
|
||||
"reaction_add", check=lambda r, u: u == ctx.author and str(r) in REACTS, timeout=30
|
||||
"reaction_add",
|
||||
check=lambda r, u: u == ctx.author and str(r) in REACTS,
|
||||
timeout=30,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
return await ctx.send(_("Ok, try responding with an emoji next time."))
|
||||
|
||||
if REACTS.get(str(reaction)):
|
||||
agreed = REACTS.get(str(reaction))
|
||||
else:
|
||||
await ctx.send(_("Are you sure? (y/n)"))
|
||||
try:
|
||||
message = await self.bot.wait_for(
|
||||
"message",
|
||||
check=lambda m: m.author == ctx.author and m.content in Y_OR_N,
|
||||
timeout=30,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
return await ctx.send(_("Ok, try responding with yes or no next time."))
|
||||
|
||||
agreed = Y_OR_N.get(message.content.lower())
|
||||
|
||||
if agreed:
|
||||
if is_guild:
|
||||
await self.config.guild(ctx.guild).owner_models.clear()
|
||||
await ctx.send(_("Guild settings cleared."))
|
||||
else:
|
||||
await self.config.owner_models.clear()
|
||||
await ctx.send(_("Global settings cleared."))
|
||||
else:
|
||||
await ctx.send(_("Okay."))
|
||||
|
||||
def invalidate_cache(self, *to_invalidate):
|
||||
"""
|
||||
Either invalidates the entire cache (if given no objects)
|
||||
or does a partial invalidation based on passed objects
|
||||
"""
|
||||
if len(to_invalidate) == 0:
|
||||
self.cache.clear()
|
||||
return
|
||||
# LRUDict inherits from ordered dict, hence the syntax below
|
||||
stil_valid = [
|
||||
(k, v) for k, v in self.cache.items() if not any(obj in k for obj in to_invalidate)
|
||||
]
|
||||
self.cache = LRUDict(stil_valid, size=self.cache.size)
|
||||
|
||||
def find_object_uniquely(self, info: str) -> int:
|
||||
"""
|
||||
Finds an object uniquely, returns it's id or returns None
|
||||
|
||||
@@ -7,6 +7,23 @@ from redbot.core import commands
|
||||
log = logging.getLogger("redbot.cogs.permissions.resolvers")
|
||||
|
||||
|
||||
def entries_from_ctx(ctx: commands.Context) -> tuple:
|
||||
voice_channel = None
|
||||
with contextlib.suppress(Exception):
|
||||
voice_channel = ctx.author.voice.voice_channel
|
||||
entries = [x.id for x in (ctx.author, voice_channel, ctx.channel) if x]
|
||||
roles = sorted(ctx.author.roles, reverse=True) if ctx.guild else []
|
||||
entries.extend([x.id for x in roles])
|
||||
# entries now contains the following (in order) (if applicable)
|
||||
# author.id
|
||||
# author.voice.voice_channel.id
|
||||
# channel.id
|
||||
# role.id for each role (highest to lowest)
|
||||
# (implicitly) guild.id because
|
||||
# the @everyone role shares an id with the guild
|
||||
return tuple(entries)
|
||||
|
||||
|
||||
async def val_if_check_is_valid(*, ctx: commands.Context, check: object, level: str) -> bool:
|
||||
"""
|
||||
Returns the value from a check if it is valid
|
||||
@@ -56,23 +73,7 @@ def resolve_lists(*, ctx: commands.Context, whitelist: list, blacklist: list) ->
|
||||
"""
|
||||
resolves specific lists
|
||||
"""
|
||||
|
||||
voice_channel = None
|
||||
with contextlib.suppress(Exception):
|
||||
voice_channel = ctx.author.voice.voice_channel
|
||||
|
||||
entries = [x.id for x in (ctx.author, voice_channel, ctx.channel) if x]
|
||||
roles = sorted(ctx.author.roles, reverse=True) if ctx.guild else []
|
||||
entries.extend([x.id for x in roles])
|
||||
# entries now contains the following (in order) (if applicable)
|
||||
# author.id
|
||||
# author.voice.voice_channel.id
|
||||
# channel.id
|
||||
# role.id for each role (highest to lowest)
|
||||
# (implicitly) guild.id because
|
||||
# the @everyone role shares an id with the guild
|
||||
|
||||
for entry in entries:
|
||||
for entry in entries_from_ctx(ctx):
|
||||
if entry in whitelist:
|
||||
return True
|
||||
if entry in blacklist:
|
||||
|
||||
@@ -56,32 +56,32 @@ class Reports:
|
||||
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
@commands.guild_only()
|
||||
@commands.group(name="reportset", autohelp=True)
|
||||
@commands.group(name="reportset")
|
||||
async def reportset(self, ctx: commands.Context):
|
||||
"""
|
||||
settings for reports
|
||||
Settings for the report system.
|
||||
"""
|
||||
pass
|
||||
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
@reportset.command(name="output")
|
||||
async def setoutput(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||
"""sets the output channel"""
|
||||
"""Set the channel where reports will show up"""
|
||||
await self.config.guild(ctx.guild).output_channel.set(channel.id)
|
||||
await ctx.send(_("Report Channel Set."))
|
||||
await ctx.send(_("The report channel has been set."))
|
||||
|
||||
@checks.admin_or_permissions(manage_guild=True)
|
||||
@reportset.command(name="toggleactive")
|
||||
@reportset.command(name="toggle", aliases=["toggleactive"])
|
||||
async def report_toggle(self, ctx: commands.Context):
|
||||
"""Toggles whether the Reporting tool is enabled or not"""
|
||||
"""Enables or Disables reporting for the server"""
|
||||
|
||||
active = await self.config.guild(ctx.guild).active()
|
||||
active = not active
|
||||
await self.config.guild(ctx.guild).active.set(active)
|
||||
if active:
|
||||
await ctx.send(_("Reporting now enabled"))
|
||||
await ctx.send(_("Reporting is now enabled"))
|
||||
else:
|
||||
await ctx.send(_("Reporting disabled."))
|
||||
await ctx.send(_("Reporting is now disabled."))
|
||||
|
||||
async def internal_filter(self, m: discord.Member, mod=False, perms=None):
|
||||
ret = False
|
||||
@@ -105,7 +105,7 @@ class Reports:
|
||||
*,
|
||||
mod: bool = False,
|
||||
permissions: Union[discord.Permissions, dict] = None,
|
||||
prompt: str = ""
|
||||
prompt: str = "",
|
||||
):
|
||||
"""
|
||||
discovers which of shared guilds between the bot
|
||||
@@ -175,7 +175,10 @@ class Reports:
|
||||
if await self.bot.embed_requested(channel, author):
|
||||
em = discord.Embed(description=report)
|
||||
em.set_author(
|
||||
name=_("Report from {0.display_name}").format(author), icon_url=author.avatar_url
|
||||
name=_("Report from {author}{maybe_nick}").format(
|
||||
author=author, maybe_nick=(f" ({author.nick})" if author.nick else "")
|
||||
),
|
||||
icon_url=author.avatar_url,
|
||||
)
|
||||
em.set_footer(text=_("Report #{}").format(ticket_number))
|
||||
send_content = None
|
||||
@@ -201,10 +204,10 @@ class Reports:
|
||||
@commands.group(name="report", invoke_without_command=True)
|
||||
async def report(self, ctx: commands.Context, *, _report: str = ""):
|
||||
"""
|
||||
Follow the prompts to make a report
|
||||
Send a report.
|
||||
|
||||
optionally use with a report message
|
||||
to use it non interactively
|
||||
Use without arguments for interactive reporting, or do
|
||||
[p]report <text> to use it non-interactively.
|
||||
"""
|
||||
author = ctx.author
|
||||
guild = ctx.guild
|
||||
@@ -224,14 +227,17 @@ class Reports:
|
||||
if self.antispam[guild.id][author.id].spammy:
|
||||
return await author.send(
|
||||
_(
|
||||
"You've sent a few too many of these recently. "
|
||||
"Contact a server admin to resolve this, or try again "
|
||||
"later."
|
||||
"You've sent too many reports recently. "
|
||||
"Please contact a server admin if this is important matter, "
|
||||
"or please wait and try again later."
|
||||
)
|
||||
)
|
||||
if author.id in self.user_cache:
|
||||
return await author.send(
|
||||
_("Please finish making your prior report before making an additional one")
|
||||
_(
|
||||
"Please finish making your prior report before trying to make an "
|
||||
"additional one!"
|
||||
)
|
||||
)
|
||||
self.user_cache.append(author.id)
|
||||
|
||||
@@ -263,7 +269,9 @@ class Reports:
|
||||
|
||||
with contextlib.suppress(discord.Forbidden, discord.HTTPException):
|
||||
if val is None:
|
||||
await author.send(_("There was an error sending your report."))
|
||||
await author.send(
|
||||
_("There was an error sending your report, please contact a server admin.")
|
||||
)
|
||||
else:
|
||||
await author.send(_("Your report was submitted. (Ticket #{})").format(val))
|
||||
self.antispam[guild.id][author.id].stamp()
|
||||
@@ -309,17 +317,19 @@ class Reports:
|
||||
if msgs:
|
||||
self.tunnel_store[k]["msgs"] = msgs
|
||||
|
||||
@commands.guild_only()
|
||||
@checks.mod_or_permissions(manage_members=True)
|
||||
@report.command(name="interact")
|
||||
async def response(self, ctx, ticket_number: int):
|
||||
"""
|
||||
opens a message tunnel between things you say in this channel
|
||||
and the ticket opener's direct messages
|
||||
Open a message tunnel.
|
||||
|
||||
tunnels do not persist across bot restarts
|
||||
This tunnel will forward things you say in this channel
|
||||
to the ticket opener's direct messages.
|
||||
|
||||
Tunnels do not persist across bot restarts.
|
||||
"""
|
||||
|
||||
# note, mod_or_permissions is an implicit guild_only
|
||||
guild = ctx.guild
|
||||
rec = await self.config.custom("REPORT", guild.id, ticket_number).report()
|
||||
|
||||
@@ -342,14 +352,15 @@ class Reports:
|
||||
)
|
||||
|
||||
big_topic = _(
|
||||
"{who} opened a 2-way communication."
|
||||
"{who} opened a 2-way communication "
|
||||
"about ticket number {ticketnum}. Anything you say or upload here "
|
||||
"(8MB file size limitation on uploads) "
|
||||
"will be forwarded to them until the communication is closed.\n"
|
||||
"You can close a communication at any point "
|
||||
"by reacting with the X to the last message recieved. "
|
||||
"\nAny message succesfully forwarded will be marked with a check."
|
||||
"\nTunnels are not persistent across bot restarts."
|
||||
"You can close a communication at any point by reacting with "
|
||||
"the \N{NEGATIVE SQUARED CROSS MARK} to the last message recieved.\n"
|
||||
"Any message succesfully forwarded will be marked with "
|
||||
"\N{WHITE HEAVY CHECK MARK}.\n"
|
||||
"Tunnels are not persistent across bot restarts."
|
||||
)
|
||||
topic = big_topic.format(
|
||||
ticketnum=ticket_number, who=_("A moderator in `{guild.name}` has").format(guild=guild)
|
||||
@@ -357,8 +368,7 @@ class Reports:
|
||||
try:
|
||||
m = await tun.communicate(message=ctx.message, topic=topic, skip_message_content=True)
|
||||
except discord.Forbidden:
|
||||
await ctx.send(_("User has disabled DMs."))
|
||||
tun.close()
|
||||
await ctx.send(_("That user has DMs disabled."))
|
||||
else:
|
||||
self.tunnel_store[(guild, ticket_number)] = {"tun": tun, "msgs": m}
|
||||
await ctx.send(big_topic.format(who=_("You have"), ticketnum=ticket_number))
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR ORGANIZATION
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2018-02-18 14:42+AKST\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: ENCODING\n"
|
||||
"Generated-By: pygettext.py 1.5\n"
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
TO_TRANSLATE = ["../mod.py"]
|
||||
|
||||
|
||||
def regen_messages():
|
||||
subprocess.run(["pygettext", "-n"] + TO_TRANSLATE)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
regen_messages()
|
||||
@@ -75,14 +75,14 @@ class Streams:
|
||||
|
||||
@commands.command()
|
||||
async def twitch(self, ctx: commands.Context, channel_name: str):
|
||||
"""Checks if a Twitch channel is streaming"""
|
||||
"""Checks if a Twitch channel is live"""
|
||||
token = await self.db.tokens.get_raw(TwitchStream.__name__, default=None)
|
||||
stream = TwitchStream(name=channel_name, token=token)
|
||||
await self.check_online(ctx, stream)
|
||||
|
||||
@commands.command()
|
||||
async def youtube(self, ctx: commands.Context, channel_id_or_name: str):
|
||||
"""Checks if a Youtube channel is streaming"""
|
||||
"""Checks if a Youtube channel is live"""
|
||||
apikey = await self.db.tokens.get_raw(YoutubeStream.__name__, default=None)
|
||||
is_name = self.check_name_or_id(channel_id_or_name)
|
||||
if is_name:
|
||||
@@ -93,19 +93,19 @@ class Streams:
|
||||
|
||||
@commands.command()
|
||||
async def hitbox(self, ctx: commands.Context, channel_name: str):
|
||||
"""Checks if a Hitbox channel is streaming"""
|
||||
"""Checks if a Hitbox channel is live"""
|
||||
stream = HitboxStream(name=channel_name)
|
||||
await self.check_online(ctx, stream)
|
||||
|
||||
@commands.command()
|
||||
async def mixer(self, ctx: commands.Context, channel_name: str):
|
||||
"""Checks if a Mixer channel is streaming"""
|
||||
"""Checks if a Mixer channel is live"""
|
||||
stream = MixerStream(name=channel_name)
|
||||
await self.check_online(ctx, stream)
|
||||
|
||||
@commands.command()
|
||||
async def picarto(self, ctx: commands.Context, channel_name: str):
|
||||
"""Checks if a Picarto channel is streaming"""
|
||||
"""Checks if a Picarto channel is live"""
|
||||
stream = PicartoStream(name=channel_name)
|
||||
await self.check_online(ctx, stream)
|
||||
|
||||
@@ -113,9 +113,9 @@ class Streams:
|
||||
try:
|
||||
embed = await stream.is_online()
|
||||
except OfflineStream:
|
||||
await ctx.send(_("The stream is offline."))
|
||||
await ctx.send(_("That user is offline."))
|
||||
except StreamNotFound:
|
||||
await ctx.send(_("The channel doesn't seem to exist."))
|
||||
await ctx.send(_("That channel doesn't seem to exist."))
|
||||
except InvalidTwitchCredentials:
|
||||
await ctx.send(
|
||||
_("The twitch token is either invalid or has not been set. See `{}`.").format(
|
||||
@@ -124,7 +124,7 @@ class Streams:
|
||||
)
|
||||
except InvalidYoutubeCredentials:
|
||||
await ctx.send(
|
||||
_("The Youtube API key is either invalid or has not been set. See {}.").format(
|
||||
_("Your Youtube API key is either invalid or has not been set. See {}.").format(
|
||||
"`{}streamset youtubekey`".format(ctx.prefix)
|
||||
)
|
||||
)
|
||||
@@ -135,51 +135,56 @@ class Streams:
|
||||
else:
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@commands.guild_only()
|
||||
@checks.mod()
|
||||
async def streamalert(self, ctx: commands.Context):
|
||||
pass
|
||||
|
||||
@streamalert.group(name="twitch", autohelp=True)
|
||||
async def _twitch(self, ctx: commands.Context):
|
||||
@streamalert.group(name="twitch", invoke_without_command=True)
|
||||
async def _twitch(self, ctx: commands.Context, channel_name: str = None):
|
||||
"""Twitch stream alerts"""
|
||||
pass
|
||||
if channel_name is not None:
|
||||
await ctx.invoke(self.twitch_alert_channel, channel_name)
|
||||
else:
|
||||
await ctx.send_help()
|
||||
|
||||
@_twitch.command(name="channel")
|
||||
async def twitch_alert_channel(self, ctx: commands.Context, channel_name: str):
|
||||
"""Sets a Twitch stream alert notification in the channel"""
|
||||
"""Sets a Twitch alert notification in the channel"""
|
||||
if re.fullmatch(r"<#\d+>", channel_name):
|
||||
await ctx.send("Please supply the name of a *Twitch* channel, not a Discord channel.")
|
||||
return
|
||||
await self.stream_alert(ctx, TwitchStream, channel_name.lower())
|
||||
|
||||
@_twitch.command(name="community")
|
||||
async def twitch_alert_community(self, ctx: commands.Context, community: str):
|
||||
"""Sets a Twitch stream alert notification in the channel for the specified community."""
|
||||
"""Sets an alert notification in the channel for the specified twitch community."""
|
||||
await self.community_alert(ctx, TwitchCommunity, community.lower())
|
||||
|
||||
@streamalert.command(name="youtube")
|
||||
async def youtube_alert(self, ctx: commands.Context, channel_name_or_id: str):
|
||||
"""Sets a Youtube stream alert notification in the channel"""
|
||||
"""Sets a Youtube alert notification in the channel"""
|
||||
await self.stream_alert(ctx, YoutubeStream, channel_name_or_id)
|
||||
|
||||
@streamalert.command(name="hitbox")
|
||||
async def hitbox_alert(self, ctx: commands.Context, channel_name: str):
|
||||
"""Sets a Hitbox stream alert notification in the channel"""
|
||||
"""Sets a Hitbox alert notification in the channel"""
|
||||
await self.stream_alert(ctx, HitboxStream, channel_name)
|
||||
|
||||
@streamalert.command(name="mixer")
|
||||
async def mixer_alert(self, ctx: commands.Context, channel_name: str):
|
||||
"""Sets a Mixer stream alert notification in the channel"""
|
||||
"""Sets a Mixer alert notification in the channel"""
|
||||
await self.stream_alert(ctx, MixerStream, channel_name)
|
||||
|
||||
@streamalert.command(name="picarto")
|
||||
async def picarto_alert(self, ctx: commands.Context, channel_name: str):
|
||||
"""Sets a Picarto stream alert notification in the channel"""
|
||||
"""Sets a Picarto alert notification in the channel"""
|
||||
await self.stream_alert(ctx, PicartoStream, channel_name)
|
||||
|
||||
@streamalert.command(name="stop")
|
||||
async def streamalert_stop(self, ctx: commands.Context, _all: bool = False):
|
||||
"""Stops all stream notifications in the channel
|
||||
|
||||
Adding 'yes' will disable all notifications in the server"""
|
||||
streams = self.streams.copy()
|
||||
local_channel_ids = [c.id for c in ctx.guild.channels]
|
||||
@@ -202,7 +207,7 @@ class Streams:
|
||||
self.streams = streams
|
||||
await self.save_streams()
|
||||
|
||||
msg = _("All {}'s stream alerts have been disabled.").format(
|
||||
msg = _("All the alerts in the {} have been disabled.").format(
|
||||
"server" if _all else "channel"
|
||||
)
|
||||
|
||||
@@ -210,9 +215,10 @@ class Streams:
|
||||
|
||||
@streamalert.command(name="list")
|
||||
async def streamalert_list(self, ctx: commands.Context):
|
||||
"""List all active stream alerts in this server."""
|
||||
streams_list = defaultdict(list)
|
||||
guild_channels_ids = [c.id for c in ctx.guild.channels]
|
||||
msg = _("Active stream alerts:\n\n")
|
||||
msg = _("Active alerts:\n\n")
|
||||
|
||||
for stream in self.streams:
|
||||
for channel_id in stream.channels:
|
||||
@@ -220,7 +226,7 @@ class Streams:
|
||||
streams_list[channel_id].append(stream.name.lower())
|
||||
|
||||
if not streams_list:
|
||||
await ctx.send(_("There are no active stream alerts in this server."))
|
||||
await ctx.send(_("There are no active alerts in this server."))
|
||||
return
|
||||
|
||||
for channel_id, streams in streams_list.items():
|
||||
@@ -243,16 +249,16 @@ class Streams:
|
||||
exists = await self.check_exists(stream)
|
||||
except InvalidTwitchCredentials:
|
||||
await ctx.send(
|
||||
_("The twitch token is either invalid or has not been set. See {}.").format(
|
||||
_("Your twitch token is either invalid or has not been set. See {}.").format(
|
||||
"`{}streamset twitchtoken`".format(ctx.prefix)
|
||||
)
|
||||
)
|
||||
return
|
||||
except InvalidYoutubeCredentials:
|
||||
await ctx.send(
|
||||
_("The Youtube API key is either invalid or has not been set. See {}.").format(
|
||||
"`{}streamset youtubekey`".format(ctx.prefix)
|
||||
)
|
||||
_(
|
||||
"Your Youtube API key is either invalid or has not been set. See {}."
|
||||
).format("`{}streamset youtubekey`".format(ctx.prefix))
|
||||
)
|
||||
return
|
||||
except APIError:
|
||||
@@ -294,7 +300,7 @@ class Streams:
|
||||
|
||||
await self.add_or_remove_community(ctx, community)
|
||||
|
||||
@commands.group(autohelp=True)
|
||||
@commands.group()
|
||||
@checks.mod()
|
||||
async def streamset(self, ctx: commands.Context):
|
||||
pass
|
||||
@@ -303,7 +309,6 @@ class Streams:
|
||||
@checks.is_owner()
|
||||
async def twitchtoken(self, ctx: commands.Context, token: str):
|
||||
"""Set the Client ID for twitch.
|
||||
|
||||
To do this, follow these steps:
|
||||
1. Go to this page: https://dev.twitch.tv/dashboard/apps.
|
||||
2. Click *Register Your Application*
|
||||
@@ -311,7 +316,6 @@ class Streams:
|
||||
select an Application Category of your choosing.
|
||||
4. Click *Register*, and on the following page, copy the Client ID.
|
||||
5. Paste the Client ID into this command. Done!
|
||||
|
||||
"""
|
||||
await self.db.tokens.set_raw("TwitchStream", value=token)
|
||||
await self.db.tokens.set_raw("TwitchCommunity", value=token)
|
||||
@@ -321,22 +325,19 @@ class Streams:
|
||||
@checks.is_owner()
|
||||
async def youtubekey(self, ctx: commands.Context, key: str):
|
||||
"""Sets the API key for Youtube.
|
||||
|
||||
To get one, do the following:
|
||||
|
||||
1. Create a project (see https://support.google.com/googleapi/answer/6251787 for details)
|
||||
2. Enable the Youtube Data API v3 (see https://support.google.com/googleapi/answer/6158841 for instructions)
|
||||
3. Set up your API key (see https://support.google.com/googleapi/answer/6158862 for instructions)
|
||||
4. Copy your API key and paste it into this command. Done!
|
||||
|
||||
"""
|
||||
await self.db.tokens.set_raw("YoutubeStream", value=key)
|
||||
await ctx.send(_("Youtube key set."))
|
||||
|
||||
@streamset.group(autohelp=True)
|
||||
@streamset.group()
|
||||
@commands.guild_only()
|
||||
async def mention(self, ctx: commands.Context):
|
||||
"""Sets mentions for stream alerts."""
|
||||
"""Sets mentions for alerts."""
|
||||
pass
|
||||
|
||||
@mention.command(aliases=["everyone"])
|
||||
@@ -348,15 +349,16 @@ class Streams:
|
||||
if current_setting:
|
||||
await self.db.guild(guild).mention_everyone.set(False)
|
||||
await ctx.send(
|
||||
_("{} will no longer be mentioned for a stream alert.").format("@\u200beveryone")
|
||||
_("{} will no longer be mentioned when a stream or community is live").format(
|
||||
"@\u200beveryone"
|
||||
)
|
||||
)
|
||||
else:
|
||||
await self.db.guild(guild).mention_everyone.set(True)
|
||||
await ctx.send(
|
||||
_(
|
||||
"When a stream configured for stream alerts "
|
||||
"comes online, {} will be mentioned."
|
||||
).format("@\u200beveryone")
|
||||
_("When a stream or community " "is live, {} will be mentioned.").format(
|
||||
"@\u200beveryone"
|
||||
)
|
||||
)
|
||||
|
||||
@mention.command(aliases=["here"])
|
||||
@@ -367,16 +369,13 @@ class Streams:
|
||||
current_setting = await self.db.guild(guild).mention_here()
|
||||
if current_setting:
|
||||
await self.db.guild(guild).mention_here.set(False)
|
||||
await ctx.send(
|
||||
_("{} will no longer be mentioned for a stream alert.").format("@\u200bhere")
|
||||
)
|
||||
await ctx.send(_("{} will no longer be mentioned for an alert.").format("@\u200bhere"))
|
||||
else:
|
||||
await self.db.guild(guild).mention_here.set(True)
|
||||
await ctx.send(
|
||||
_(
|
||||
"When a stream configured for stream alerts "
|
||||
"comes online, {} will be mentioned."
|
||||
).format("@\u200bhere")
|
||||
_("When a stream or community " "is live, {} will be mentioned.").format(
|
||||
"@\u200bhere"
|
||||
)
|
||||
)
|
||||
|
||||
@mention.command()
|
||||
@@ -390,18 +389,16 @@ class Streams:
|
||||
if current_setting:
|
||||
await self.db.role(role).mention.set(False)
|
||||
await ctx.send(
|
||||
_("{} will no longer be mentioned for a stream alert.").format(
|
||||
_("{} will no longer be mentioned for an alert.").format(
|
||||
"@\u200b{}".format(role.name)
|
||||
)
|
||||
)
|
||||
else:
|
||||
await self.db.role(role).mention.set(True)
|
||||
await ctx.send(
|
||||
_(
|
||||
"When a stream configured for stream alerts "
|
||||
"comes online, {} will be mentioned."
|
||||
""
|
||||
).format("@\u200b{}".format(role.name))
|
||||
_("When a stream or community " "is live, {} will be mentioned." "").format(
|
||||
"@\u200b{}".format(role.name)
|
||||
)
|
||||
)
|
||||
|
||||
@streamset.command()
|
||||
@@ -420,7 +417,7 @@ class Streams:
|
||||
if stream not in self.streams:
|
||||
self.streams.append(stream)
|
||||
await ctx.send(
|
||||
_("I'll send a notification in this channel when {} is online.").format(
|
||||
_("I'll now send a notification in this channel when {} is live.").format(
|
||||
stream.name
|
||||
)
|
||||
)
|
||||
@@ -444,7 +441,7 @@ class Streams:
|
||||
await ctx.send(
|
||||
_(
|
||||
"I'll send a notification in this channel when a "
|
||||
"channel is streaming to the {} community."
|
||||
"channel is live in the {} community."
|
||||
""
|
||||
).format(community.name)
|
||||
)
|
||||
@@ -455,7 +452,7 @@ class Streams:
|
||||
await ctx.send(
|
||||
_(
|
||||
"I won't send notifications about channels streaming "
|
||||
"to the {} community in this channel anymore."
|
||||
"in the {} community in this channel anymore."
|
||||
""
|
||||
).format(community.name)
|
||||
)
|
||||
@@ -475,7 +472,7 @@ class Streams:
|
||||
return stream
|
||||
elif not self.check_name_or_id(name) and stream.id == name:
|
||||
return stream
|
||||
if stream.type == _class.__name__ and stream.name.lower() == name.lower():
|
||||
elif stream.type == _class.__name__ and stream.name.lower() == name.lower():
|
||||
return stream
|
||||
|
||||
def get_community(self, _class, name):
|
||||
@@ -511,6 +508,8 @@ class Streams:
|
||||
try:
|
||||
embed = await stream.is_online()
|
||||
except OfflineStream:
|
||||
if not stream._messages_cache:
|
||||
continue
|
||||
for message in stream._messages_cache:
|
||||
try:
|
||||
autodelete = await self.db.guild(message.guild).autodelete()
|
||||
@@ -530,9 +529,9 @@ class Streams:
|
||||
mention_str = await self._get_mention_str(channel.guild)
|
||||
|
||||
if mention_str:
|
||||
content = "{}, {} is online!".format(mention_str, stream.name)
|
||||
content = "{}, {} is live!".format(mention_str, stream.name)
|
||||
else:
|
||||
content = "{} is online!".format(stream.name)
|
||||
content = "{} is live!".format(stream.name)
|
||||
|
||||
try:
|
||||
m = await channel.send(content, embed=embed)
|
||||
@@ -558,9 +557,11 @@ class Streams:
|
||||
try:
|
||||
stream_list = await community.get_community_streams()
|
||||
except CommunityNotFound:
|
||||
print(_("Community {} not found!").format(community.name))
|
||||
print(_("The Community {} was not found!").format(community.name))
|
||||
continue
|
||||
except OfflineCommunity:
|
||||
if not community._messages_cache:
|
||||
continue
|
||||
for message in community._messages_cache:
|
||||
try:
|
||||
autodelete = await self.db.guild(message.guild).autodelete()
|
||||
@@ -618,16 +619,12 @@ class Streams:
|
||||
chn = self.bot.get_channel(raw_msg["channel"])
|
||||
msg = await chn.get_message(raw_msg["message"])
|
||||
raw_stream["_messages_cache"].append(msg)
|
||||
token = await self.db.tokens.get_raw(_class.__name__)
|
||||
streams.append(_class(token=token, **raw_stream))
|
||||
token = await self.db.tokens.get_raw(_class.__name__, default=None)
|
||||
if token is not None:
|
||||
raw_stream["token"] = token
|
||||
streams.append(_class(**raw_stream))
|
||||
|
||||
# issue 1191 extended resolution: Remove this after suitable period
|
||||
# Fast dedupe below
|
||||
seen = set()
|
||||
seen_add = seen.add
|
||||
return [x for x in streams if not (x.name.lower() in seen or seen_add(x.name.lower()))]
|
||||
|
||||
# return streams
|
||||
return streams
|
||||
|
||||
async def load_communities(self):
|
||||
communities = []
|
||||
|
||||
@@ -152,8 +152,14 @@ class YoutubeStream(Stream):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
async def is_online(self):
|
||||
if not self._token:
|
||||
raise InvalidYoutubeCredentials("YouTube API key is not set.")
|
||||
|
||||
if not self.id:
|
||||
self.id = await self.fetch_id()
|
||||
elif not self.name:
|
||||
self.name = await self.fetch_name()
|
||||
|
||||
url = YOUTUBE_SEARCH_ENDPOINT
|
||||
params = {
|
||||
"key": self._token,
|
||||
@@ -188,7 +194,20 @@ class YoutubeStream(Stream):
|
||||
return embed
|
||||
|
||||
async def fetch_id(self):
|
||||
params = {"key": self._token, "forUsername": self.name, "part": "id"}
|
||||
return await self._fetch_channel_resource("id")
|
||||
|
||||
async def fetch_name(self):
|
||||
snippet = await self._fetch_channel_resource("snippet")
|
||||
return snippet["title"]
|
||||
|
||||
async def _fetch_channel_resource(self, resource: str):
|
||||
|
||||
params = {"key": self._token, "part": resource}
|
||||
if resource == "id":
|
||||
params["forUsername"] = self.name
|
||||
else:
|
||||
params["id"] = self.id
|
||||
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(YOUTUBE_CHANNELS_ENDPOINT, params=params) as r:
|
||||
data = await r.json()
|
||||
@@ -202,7 +221,7 @@ class YoutubeStream(Stream):
|
||||
elif "items" in data and len(data["items"]) == 0:
|
||||
raise StreamNotFound()
|
||||
elif "items" in data:
|
||||
return data["items"][0]["id"]
|
||||
return data["items"][0][resource]
|
||||
raise APIError()
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
190
redbot/cogs/trivia/data/lists/2015.yaml
Normal file
190
redbot/cogs/trivia/data/lists/2015.yaml
Normal file
@@ -0,0 +1,190 @@
|
||||
AUTHOR: JennJenn
|
||||
"\"L.A. Love (La La)\" is the title of a January 2015 Top Ten Smash hit for which singer?":
|
||||
- fergie
|
||||
"'Dismaland' was the temporary theme park/exhibition of which famous 'anonymous' artist?":
|
||||
- Banksy
|
||||
"'Egoportrait' (a Quebecois word) was added to the 2015 French dictionary, meaning what more popular new English word?":
|
||||
- Selfie
|
||||
A 2015 intensive listening study discovered that giraffes actually?:
|
||||
- Hum
|
||||
A 2015 study found that what percentage of former American Football players had degenerative brain damage?:
|
||||
- ninety-six
|
||||
- 96
|
||||
- 96%
|
||||
According to 2015 survey what fruit was most popular among USA children?:
|
||||
- Apples
|
||||
- apple
|
||||
At auction in 2015, $1.2m was paid for Don McLean's original handrwitten lyrics for which 1971 big hit song?:
|
||||
- American Pie
|
||||
Blackberry's new phone for 2015 was called the...?:
|
||||
- Priv
|
||||
Brazil began to nationalise its (What?) in 2015?:
|
||||
- Rainforest
|
||||
Celebrity chef Gordon Ramsey celebrated what birthday in 2015?:
|
||||
- 49
|
||||
- fourty-nine
|
||||
- fourty nine
|
||||
- 49th
|
||||
Christian is the lead character in the film 2015 adaptation of what extraordinarily successful book?:
|
||||
- Fifty Shades of Grey
|
||||
- 50 shades of grey
|
||||
Due to a 2015 contamination scandal in India/Afica, which corporation destroyed 400 million packets of Maggi noodles?:
|
||||
- Nestle
|
||||
Eddie Jones was appointed head coach of which English sporting team in 2015?:
|
||||
- Rugby Union
|
||||
- rugby
|
||||
Facebook's new music sharing/streaming feature launched in 2015 was called "Music... "?:
|
||||
- Stories
|
||||
Facebook's news service launched in 2015 was called?:
|
||||
- Notify
|
||||
Finance minister Yanis Yaroufakis caused comment for not wearing a tie in February 2015 when negotiating the debts for which nation?:
|
||||
- Greece
|
||||
Ford claimed to launch the first 'e-(What?)' at the 2015 Mobile World Congress Show?:
|
||||
- Bike
|
||||
Frank Sinatra would have celebrated which birthday in 2015?:
|
||||
- 100
|
||||
- hundred
|
||||
How many new iPhones were released this year?:
|
||||
- 2
|
||||
- two
|
||||
How many years old was the McDonalds fast food company in 2015?:
|
||||
- 60
|
||||
- sixty
|
||||
In 2015 Japan lowered its voting age to what?:
|
||||
- 18
|
||||
- eighteen
|
||||
In 2015 Ronda Rousey lost to Holly Holm in what brutal sporting discipline?:
|
||||
- UFC
|
||||
- Ultimate Fighting Championship
|
||||
In 2015 a new North Korean schools curriculum reportedly included that leader Kim Jong-un learnt to drive at age?:
|
||||
- 3
|
||||
- three
|
||||
In 2015 evidence of water was found on which planet?:
|
||||
- Mars
|
||||
In 2015 the Sinabug volcano erupted in what country?:
|
||||
- Indonesia
|
||||
In 2015 the World Anti-Doping Agency suggested banning which nation from the 2016 Olympics?:
|
||||
- Russia
|
||||
In 2015 the first ever colour/color photographs were obtained of which celestial body?:
|
||||
- Pluto
|
||||
In 2015 what global contest ruled against the use of swimsuits for its 114 competitors, for the first time since 1951 inception?:
|
||||
- Miss World
|
||||
In China in 2015 the record for the longest mating session between two giant pandas was broken at?:
|
||||
- 18 minutes
|
||||
- 18 mins
|
||||
It was announced in 2015 that Alexander Hamilton would be replaced on?:
|
||||
- $10 bill
|
||||
- $10
|
||||
- tendollars
|
||||
- ten dollar bill
|
||||
- ten dollar
|
||||
Jay Z and Beyonce launched a music streaming service in 2015 called?:
|
||||
- Tidal
|
||||
Jon Snow was killed off in what TV series in 2015, adapted from GRR Martin's 'A Song of Ice and Fire'?:
|
||||
- Game of Thrones
|
||||
Lars Lokke led his centre-right party to 2015 government election victory in what country?:
|
||||
- Denmark
|
||||
Lord Coe ceased working for which brand in 2015 due to conflict of interest?:
|
||||
- Nike
|
||||
Matthais Muller was made chief of which troubled car company in 2015?:
|
||||
- Volkswagen
|
||||
- vw
|
||||
Mauricio Marci was elected president of which South American nation in 2015?:
|
||||
- Argentina
|
||||
Microsoft announced which new operating system in January 2015?:
|
||||
- windows 10
|
||||
Name Adele's record-breaking 2015 album?:
|
||||
- 25
|
||||
Name the Princess born 4th in succession to the British throne in 2015, to Britain's Duke and Duchess of Cambridge?:
|
||||
- Charlotte
|
||||
Name the head of FIFA subject to criminal process in 2015?:
|
||||
- Sepp Blatter
|
||||
- blatter
|
||||
Name the last US president to meet the leader of Cuba before Barack Obama did in 2015?:
|
||||
- Eisenhower
|
||||
Olav Bjortmont became 2015 world champion in?:
|
||||
- Quizzing
|
||||
- quiz
|
||||
On what sprung mechanism did Bristolian Jack Sexty break the world record in 2015 achieving 88,047 bounces in 10hrs 21mins?:
|
||||
- Pogo stick
|
||||
Published in 2015, Go Set a Watchman, written before her only prior and enduringly popular book of 1960, was written by whom?:
|
||||
- Harper Lee
|
||||
The 2015 Mad Max movie is sub-titled?:
|
||||
- Fury Road
|
||||
- "mad max: fury road"
|
||||
- mad max fury road
|
||||
The 2015 Tour de France began in what country?:
|
||||
- The Netherlands
|
||||
- netherlands
|
||||
The Magna Carta, signed in London, and inspiring constitutional rights globally thereafter, was how many years old in 2015?:
|
||||
- eight hundred
|
||||
- 800
|
||||
The abbreviation MERS, significantly impacting South Korea 2015, is otherwise known as?:
|
||||
- Camel Flu
|
||||
The game of Monopoly celebrated what anniversary in 2015?:
|
||||
- eighty
|
||||
- 80
|
||||
- 80th
|
||||
The movie Toy Story was how many years old in 2015?:
|
||||
- 20
|
||||
- 20 years
|
||||
- twenty
|
||||
The space transport company launched in 2015 by Jeff Bezos is called?:
|
||||
- Blue Origin
|
||||
What company launched the S6 Edge smartphone?:
|
||||
- Samsung
|
||||
What country in May 2015 became the first to legalize gay marriage by national referendum?:
|
||||
- Ireland
|
||||
What dating app caused problems for itself in 2015 when increasing its charges?:
|
||||
- Tinder
|
||||
What iconic equine-alluding company, in countless books/films/cowboy holsters, filed for bankruptcy in 2015?:
|
||||
- Colt
|
||||
What is the title of the animated superhero Disney film released in January 2015?:
|
||||
- big hero 6
|
||||
- big hero six
|
||||
What is the year 2015 in Roman numerals?:
|
||||
- MMXV
|
||||
What nation hosted the 2015 Women's World (soccer) Cup?:
|
||||
- Canada
|
||||
Which 'BRIC' country launched the Astrosat space lab in 2015?:
|
||||
- India
|
||||
Which car company launched the Avensis model in 2015?:
|
||||
- Toyota
|
||||
Which company suffered a major scandal in 2015 for widescale unethical 'inertia' charging for its 'Prime' service?:
|
||||
- Amazon
|
||||
Which country won the 2015 Davis Cup (world team tennis)?:
|
||||
- Great Britain
|
||||
Which leading professional networking tech corporation, whose main revenue is selling user access/details to recruiters, bought the Lynda learning company for $1.5bn in 2015?:
|
||||
- Linkedin
|
||||
- linked in
|
||||
Which singer surpassed Elvis in 2015 in terms of all time US album sales?:
|
||||
- garth brooks
|
||||
Which vast tech corporation opened its first 'Nest' branded intelligent home store in Palo Alto California in 2015?:
|
||||
- Google
|
||||
Who had the most liked Instagram photo of 2015?:
|
||||
- Kendall Jenner
|
||||
Who remained in the Top 10 of the music charts around the world with the song "Blank Space" in January 2015?:
|
||||
- taylor swift
|
||||
Who stepped down as chief of 21st Century Fox in 2015?:
|
||||
- Rupert Murdoch
|
||||
- murdoch
|
||||
Who won the 2015 Superbowl?:
|
||||
- New England Patriots
|
||||
- Patriots
|
||||
- the patriots
|
||||
Who won the 2015 men's tennis French Open?:
|
||||
- Stan Warwinka
|
||||
- warwinka
|
||||
Who won the Premier League in 2015?:
|
||||
- Chelsea
|
||||
- chelsea f.c.
|
||||
Who won the Rugby World Cup in 2015?:
|
||||
- New zealand
|
||||
Who won the men's World Ice Hockey Championship in 2015?:
|
||||
- Canada
|
||||
Whose 2015 album is 'Purpose'?:
|
||||
- Justin Bieber
|
||||
- bieber
|
||||
Whose controversial US presidential campaigning greatly increased his popularity within his party in 2015, yet increased party fears that it would unelectable should he lead it?:
|
||||
- Donald Trump
|
||||
- trump
|
||||
423
redbot/cogs/trivia/data/lists/2016.yaml
Normal file
423
redbot/cogs/trivia/data/lists/2016.yaml
Normal file
@@ -0,0 +1,423 @@
|
||||
AUTHOR: JennJenn
|
||||
"'Twilight' author Stephenie Meyer released an adult novel in 2016 called...?":
|
||||
- The Chemist
|
||||
A magnitude 6.2 earthquake hit which country on August 25 killing at least 247 people?:
|
||||
- Italy
|
||||
After which primary did Jeb Bush drop out of the presidential race?:
|
||||
- South Carolina
|
||||
April 19 - Patricio Aylwin passed away. He was the 32nd President of what country?:
|
||||
- Chile
|
||||
April 23 – Banharn Silpa-archa passed away. He was the 21st Prime Minister of what country?:
|
||||
- Thailand
|
||||
Based on a book by Rudyard Kipling, this 2016 film features Mowgli, an orphaned human boy who was raised by wolves since birth.:
|
||||
- The Jungle Book
|
||||
Both big hits in 2016, the songs "Sorry" and "Love Yourself" were released by which Canadian singer and songwriter?:
|
||||
- Justin Bieber
|
||||
- Bieber
|
||||
Boxing great "Muhammad Ali" died in 2016 at what age?:
|
||||
- 74
|
||||
Chris Pratt won Best Action Performance at the 2016 MTV Movie Awards for his role as Owen Grady in which science fiction film?:
|
||||
- Jurassic World
|
||||
Complete the title of the 2016 Kanye West album "The Life of ..."?:
|
||||
- Pablo
|
||||
Complete the title of this 2016 Stephen King novel "End of ..."?:
|
||||
- Watch
|
||||
Created in America, what 2016 science fiction drama TV series features the actors Josh Holloway and Sarah Wayne Callies?:
|
||||
- Colony
|
||||
December 10 - Bombing in what city killed 38 people?:
|
||||
- Istanbul
|
||||
December 13 - Thomas Schelling passed away. He was known for being awarded the Nobel prize in what?:
|
||||
- Economic Sciences
|
||||
December 18 - Zsa Zsa Gabor, Hungarian-American actress and socialite, died at what age?:
|
||||
- 99
|
||||
December 19 - An ambassador from which country is assassinated in Ankara, Turkey?:
|
||||
- Russia
|
||||
December 22 – A vaccine is discovered for which deadly virus?:
|
||||
- Ebola Virus
|
||||
- Ebola
|
||||
December 26 – Ashot Anastasian a chess grandmaster from which country passed away.:
|
||||
- Armenia
|
||||
December 27 - This American actress and writer known for her role in the Star Wars francise passed away.:
|
||||
- Carrie Fisher
|
||||
December 28 - Gregorio Conrado Álvarez passed away. He was the President of which country?:
|
||||
- Uruguay
|
||||
December 7 - An earthquake claimed around 100 lives in which country?:
|
||||
- Indonesia
|
||||
February 19 - This famous American author who wrote 'To Kill a Mockingbird' passed away.:
|
||||
- Harper Lee
|
||||
For playing the role of troubled mother "Joy Newsome," who won the 2016 Academy Award for Best Actress?:
|
||||
- Brie Larson
|
||||
How did Hillary Clinton announce that she was running for president?:
|
||||
- Youtube
|
||||
How many American presidential debates were there in 2016?:
|
||||
- Three
|
||||
- 3
|
||||
How many brand new shades of Liptensity lip color did MAC release this year?:
|
||||
- 24
|
||||
How many medals did Michael Phelps end his Olympic career with?:
|
||||
- 28
|
||||
How many medals did U.S. women athletes take at the Rio Olympics?:
|
||||
- 61
|
||||
How many new original series did Netflix premiere this year?:
|
||||
- 50
|
||||
- fifty
|
||||
How many seasonal red cups did Starbucks introduce for the 2016 holidays?:
|
||||
- 13
|
||||
- thirteen
|
||||
How many seasons of 'Fuller House' did Netflix release in 2016?:
|
||||
- 2
|
||||
- two
|
||||
How much did Estee Lauder buy Too Faced for in November 2016?:
|
||||
- 1.45 billion
|
||||
How old was English singer "David Bowie" when he died two days after his birthday on January 10th 2016?:
|
||||
- 69
|
||||
How old was Gene Wilder when he sadly passed away in August 2016?:
|
||||
- 83
|
||||
How old was Prince when he passed?:
|
||||
- 57
|
||||
In a post-apocalyptic world, Cassie Sullivan will do whatever it takes to find her brother Sam. Name the 2016 film.:
|
||||
- The 5th Wave
|
||||
In what month did Latvia become the 35th member of the OECD?:
|
||||
- July
|
||||
In which city did Uber launch self-driving cars?:
|
||||
- Pittsburgh
|
||||
In which month did the U.K. vote to leave the EU?:
|
||||
- June
|
||||
Instagram Stories are most like which social media app's signature characteristic?:
|
||||
- Snapchat
|
||||
January 14 - This famous English actor and director passed away.:
|
||||
- Alan Rickman
|
||||
January 7 - Princess Ashraf of which country passed away?:
|
||||
- Iran
|
||||
July 2 - This Romanian-born American, Nobel writer, and political activist passed away. He was especially known for writing 'Night', a book about Auschwitz.:
|
||||
- Elie Wiesel
|
||||
- Wiesel
|
||||
June 1 - Gotthard Base Tunnel, the world's longest and deepest railway tunnel, is opened following two decades of construction work in which country?:
|
||||
- Switzerland
|
||||
June 8 - Qahhor Mahkamov passed away. He was the 1st President of what country?:
|
||||
- Tajikistan
|
||||
Making its 32nd season debut in February of 2016, Survivor was filmed in Koh Rong, which is located in which country?:
|
||||
- Cambodia
|
||||
Making its debut in January of 2016, Jennifer Lopez plays the role of New York detective Harlee Santos on which crime drama TV show?:
|
||||
- Shades of Blue
|
||||
May 19 – What airline had a flight crash with 66 people on board over the Mediterranean en route from Paris to Cairo?:
|
||||
- EgyptAir
|
||||
May 26 - Arturo Pomar passed away. He was famous for being awarded what title (first Spanish person to be awarded this title)?:
|
||||
- Grandmaster
|
||||
NASA's "Juno" became the second craft to orbit which planet in 2016?:
|
||||
- Jupiter
|
||||
November 18 - Denton Cooley passed away. He was known for performing the first implantation of what?:
|
||||
- artificial heart
|
||||
November 2 - Oleg Popov passed away. What was his profession?:
|
||||
- Clown
|
||||
November 20 - A train derails in what country killing more than 140 people?:
|
||||
- India
|
||||
November 25 - This man passed away. He was the 16th Prime Minister and 17th President of Cuba.:
|
||||
- Fidel Castro
|
||||
November 8 - What country began to demonetize 500 and 1000 banknotes?:
|
||||
- India
|
||||
Often referred to as the "Fifth Beatle", which English record producer, that worked with the Beatles, died on March 8th, 2016?:
|
||||
- George Martin
|
||||
On April 2, Amber Rayne, American pornographic actress, passed away at what age?:
|
||||
- 31
|
||||
On February 12, 2016, Pope Francis and Patriarch Kirill signed an Ecumenical Declaration in the first such meeting between leaders of the Catholic and Russian Orthodox Churches since their split in what year?:
|
||||
- 1054
|
||||
On January 28th, 2016, what virus outbreak was announced by the World Health Organization?:
|
||||
- Zika Virus
|
||||
- Zika
|
||||
On March 14 – The ExoMars Trace Gas Orbiter was launched on a mission to what planet?:
|
||||
- Mars
|
||||
On March 22 – Three coordinated bombings in what city killed at least 32 and injured at least 250?:
|
||||
- Brussels, Belgium
|
||||
- Brussels
|
||||
Released in February of 2016, name British singer-songwriter Elton John's 32nd studio album.:
|
||||
- Wonderful Crazy Night
|
||||
Rihanna hit number one on the Billboard 200 in March of 2016 with what album?:
|
||||
- Anti
|
||||
September 16 - Carlo Azeglio Ciampi passed away. He was the 10th President and 49th Prime Minister of what country?:
|
||||
- Italy
|
||||
September 2 - Islam Karimov passed away. He was the 1st President of which country?:
|
||||
- Uzbekistan
|
||||
September 25 - This famous American golfer passed away. He was also known for the drink named after him which combines sweet iced tea and lemonade.:
|
||||
- Arnold Palmer
|
||||
September 28 - Shimon Peres, 9th President and 8th Prime Minister of Israel, passed away. He was also known for winning which Nobel Prize?:
|
||||
- Nobel Peace Prize
|
||||
September 30 – Two paintings worth $100 million by this artist were recovered.:
|
||||
- Vincent Van Gogh
|
||||
- Van gogh
|
||||
- vangogh
|
||||
September 5 - Phyllis Schlafly, American writer and political activist, was what age when she passed away?:
|
||||
- 92
|
||||
September 8 – NASA launches OSIRIS-REx, its first asteroid sample return mission. The probe will visit Bennu and is expected to return with samples in what year?:
|
||||
- 2023
|
||||
Taking place from March 28 to April 3, which female skater won the gold medal at the 2016 World Figure Skating Championships?:
|
||||
- Evgenia Medvedeva
|
||||
- Medvedeva
|
||||
The 2016 Summer Olympics will took place in which South American city?:
|
||||
- Rio de Janeiro
|
||||
The Rolling Stones made rock 'n' roll history with a free concert in which country in March of 2016?:
|
||||
- Cuba
|
||||
The movie 'Fantastic Beasts and Where To Find Them' was inspired by a Harry Potter textbook written by which fictional character?:
|
||||
- Newt Scamander
|
||||
The sixth edition of the ICC World Twenty20 in March was held in what country?:
|
||||
- India
|
||||
This 2016 hit by Tim McGraw opens with the lyric - "You know there's a light that glows by the front door. Don't forget the key's under the mat".:
|
||||
- Humble and Kind
|
||||
This 2016 superhero film sees our hero Wade Wilson hunting down the man who gave him a scarred physical appearance.:
|
||||
- Deadpool
|
||||
This American actress and former First Lady of the United States passed away on March 6.:
|
||||
- Nancy Reagan
|
||||
This heavy metal band had a hit with a cover of the 1964 Simon and Garfunkel hit song "The Sound of Silence".:
|
||||
- Disturbed
|
||||
To whom was Donald Trump referring when he said "I like people who weren't captured"?:
|
||||
- John McCain
|
||||
What Broadway star wrote the music for 'Moana'?:
|
||||
- Lin-Manuel Miranda
|
||||
- Lin Manuel Miranda
|
||||
- Miranda
|
||||
What Star Wars movie is 'Rogue One' set before?:
|
||||
- A New Hope
|
||||
- Episode iv
|
||||
What actor plays Grindelwald in 'Fantastic Beasts and Where to Find Them'?:
|
||||
- Johnny Depp
|
||||
What animal is Blake Lively fighting in 'The Shallows'?:
|
||||
- Shark
|
||||
What anniversary of Shakespeare's death was widely celebrated in 2016?:
|
||||
- 400
|
||||
What color was Ryan Lochte's hair at the Rio Olympics?:
|
||||
- Blue
|
||||
What did John Oliver christen Donald Trump?:
|
||||
- Donald Drumpf
|
||||
What did Kylie Jenner name her Kylie Cosmetics eyeshadow palette?:
|
||||
- Kyshadow
|
||||
What did Michael Phelps and Nicole Johnson name their son?:
|
||||
- Boomer
|
||||
What did Obama and Raul Castro watch together in Cuba?:
|
||||
- Baseball
|
||||
What did Rob Kardashian and Blac Chyna name their daughter?:
|
||||
- Dream
|
||||
What do they call the robots on 'Westworld'?:
|
||||
- Hosts
|
||||
What fast food place announced it will start delivering soon?:
|
||||
- Mcdonald's
|
||||
- Mcdonalds
|
||||
What iconic cartoon character did Colourpop do a collaboration with in 2016?:
|
||||
- Hello Kitty
|
||||
What is 2016 in Roman numerals?:
|
||||
- MMXVI
|
||||
What is Hermione Granger's job in 'Harry Potter and The Cursed Child'?:
|
||||
- Minister of Magic
|
||||
What is it called when an ex or former crush pops back up?:
|
||||
- zombieing
|
||||
What is the Mannequin Challenge song?:
|
||||
- Black Beatles
|
||||
What is the name of Beyoncé's athleisure line at Topshop?:
|
||||
- Ivy Park
|
||||
What is the name of the 2015 best-selling book about the Clinton Foundation?:
|
||||
- Clinton Cash
|
||||
What kind of shoes did the 'Damn Daniel' guy wear?:
|
||||
- White Vans
|
||||
- Vans
|
||||
What magnitude was the earthquake that hit Ecuador on April 16 and killed more than 600 people?:
|
||||
- "7.8"
|
||||
What month were the Panama Papers leaked?:
|
||||
- April
|
||||
What popular social media app announced that it was shutting down in 2016?:
|
||||
- Vine
|
||||
What type of product are MAC's Shadescents?:
|
||||
- Perfume
|
||||
What villain joined 'The Walking Dead,' along with his signature baseball bat weapon?:
|
||||
- Negan
|
||||
What was Amazon's best-selling book of 2016?:
|
||||
- Harry Potter and the Cursed Child
|
||||
What was the most-searched meme of 2016?:
|
||||
- Harambe
|
||||
What was the name of the Hurricane that hit the Western Atlantic in September and October?:
|
||||
- Matthew
|
||||
What was the name of the U.K. referendum to leave the European Union?:
|
||||
- Brexit
|
||||
What was the name of the hashtag that went viral after Brock Turner's trial?:
|
||||
- "#thingslongerthanbrockturnerrapes"
|
||||
- thingslongerthanbrockturnerrapes
|
||||
What was the record-setting Powerball jackpot amount in January 2016?:
|
||||
- 1.5 billion
|
||||
What was the theme of the 2016 Met Gala?:
|
||||
- Manus x machina
|
||||
What was the top Google search for 2016?:
|
||||
- Powerball
|
||||
What's Deadpool's real name?:
|
||||
- Wade Wilson
|
||||
What's Jennifer Lawrence's character's name in 'Passengers'?:
|
||||
- Aurora
|
||||
What's the name of the rapper at the center of 'Atlanta'?:
|
||||
- Paper Boi
|
||||
When was the last time the Cubs had won the World Series before 2016?:
|
||||
- 1908
|
||||
Where did Chewbacca Mom buy her mask?:
|
||||
- Kohl's
|
||||
- Kohls
|
||||
Where did the Democratic National Convention take place?:
|
||||
- Philadelphia
|
||||
"Where is Black Panther from in 'Captain America: Civil War'?":
|
||||
- Wakanda
|
||||
Where was Hillary Clinton's campaign headquarters?:
|
||||
- Brooklyn
|
||||
Where was the 2016 Victoria's Secret Fashion Show held?:
|
||||
- Paris
|
||||
Which 'Hamilton' star addressed Mike Pence after a show?:
|
||||
- Brandon Dixon
|
||||
- Dixon
|
||||
Which American reality competition came to an end in 2016?:
|
||||
- American Idol
|
||||
Which Obama did Carpool Karaoke with James Corden?:
|
||||
- Michelle Obama
|
||||
- Michelle
|
||||
Which TV show won "Outstanding Drama Series" at the 2016 Emmys?:
|
||||
- Game of Thrones
|
||||
Which actor won Best Male Performance for his role as Hugh Glass in the film "The Revenant" at the 2016 MTV Movie Awards?:
|
||||
- Leonardo DiCaprio
|
||||
- Dicaprio
|
||||
Which animal was the star of 'Zootopia'?:
|
||||
- Bunny
|
||||
- Rabbit
|
||||
Which artist won Female Vocalist of the Year at the 2016 Academy of Country Music Awards?:
|
||||
- Miranda Lambert
|
||||
Which artist won the Grammy for Album of the Year with her album "1989" at the 2016 Grammy Awards?:
|
||||
- Taylor Swift
|
||||
Which author became the first American to win the Man Booker Award?:
|
||||
- Paul Beatty
|
||||
- Beatty
|
||||
Which author became the first black woman to write for Marvel in 2016?:
|
||||
- Roxane Gay
|
||||
Which author topped Forbes' list of the World's Highest Paid Authors in 2016?:
|
||||
- James Patterson
|
||||
- Patterson
|
||||
Which book sold 2 million copies in the two days after its release?:
|
||||
- Harry Potter and the Cursed Child
|
||||
Which book won the National Book Award for young people's literature?:
|
||||
- "March: Book Three"
|
||||
- march:book three
|
||||
- march book three
|
||||
- "march: book 3"
|
||||
- march book 3
|
||||
Which book won the Pulitzer Prize for fiction in 2016?:
|
||||
- The Sympathizer
|
||||
Which book, written by Stephen King's son, won a 2016 Goodreads Choice Award for Best Horror Novel?:
|
||||
- The Fireman
|
||||
Which celebrity had the most Instagram followers in 2016?:
|
||||
- Selena Gomez
|
||||
Which celebrity interviewed El Chapo for 'Rolling Stone'?:
|
||||
- Sean Penn
|
||||
Which country announced its decision to withdraw from the Commonwealth of Nations on October 13th, 2016?:
|
||||
- The Maldives
|
||||
- Maldives
|
||||
- republic of maldives
|
||||
Which country carried out its fifth and biggest nuclear test in September of 2016?:
|
||||
- North Korea
|
||||
Which country's president did Donald Trump meet with during his campaign?:
|
||||
- Mexico
|
||||
Which dating app added a feature to help you find a BFF?:
|
||||
- Bumble
|
||||
Which dating app now lets you swipe on Apple TV?:
|
||||
- Tinder
|
||||
Which designer did Michelle Obama wear to the final Obama White House State Dinner?:
|
||||
- Versace
|
||||
Which dictator did Donald Trump say we should "give credit" to?:
|
||||
- Kim Jong-Un
|
||||
- Kim Jong Un
|
||||
- kimjongun
|
||||
Which evil meme took over Twitter at the end of the year?:
|
||||
- Evil Kermit
|
||||
Which famed fashion street style photographer died in 2016?:
|
||||
- Bill Cunningham
|
||||
- Cunningham
|
||||
Which famous British author would have celebrated their 100th birthday in September 2016?:
|
||||
- Roald Dahl
|
||||
- Dahl
|
||||
Which famous children's author surprised everyone by joining Tumblr in 2016?:
|
||||
- Judy Blume
|
||||
Which fast-food brand saw sales tank after an E. coli crisis?:
|
||||
- Chipotle
|
||||
Which film won the most Oscars at the 2016 Academy Awards with six?:
|
||||
- Mad Max - Fury Road
|
||||
- Mad max fury road
|
||||
- "mad max: fury road"
|
||||
Which first generation Pokémon wasn't initially able to be caught in 'Pokémon Go,' but has since been added?:
|
||||
- Ditto
|
||||
Which fruit did Too Faced feature in their most popular eyeshadow palette of 2016?:
|
||||
- Peach
|
||||
Which group won Vocal Group of the Year at the 2016 Academy of Country Music Awards?:
|
||||
- Little Big Town
|
||||
Which luxury fashion brand held a major fashion show in Cuba in 2016?:
|
||||
- Chanel
|
||||
Which main character was shot in the 'Pretty Little Liars' Season 7 summer finale?:
|
||||
- Spencer
|
||||
Which movie won the Oscar for Best Picture at the 2016 Academy Awards ceremony?:
|
||||
- Spotlight
|
||||
Which network premiered Beyoncé's 'Lemonade'?:
|
||||
- HBO
|
||||
Which novel won the 2016 National Book Award for fiction?:
|
||||
- The Underground Railroad
|
||||
Which novel won the Man Booker International Prize?:
|
||||
- The Vegetarian
|
||||
Which pop star did Kylie Jenner dress up as for Halloween?:
|
||||
- Christina Aguilera
|
||||
Which popular dating app added a Super Like feature?:
|
||||
- Tinder
|
||||
Which season of Yeezy did Kanye show at New York Fashion Week in September 2016?:
|
||||
- 4
|
||||
- Four
|
||||
Which singer's merch sold more than $1 million in two days at a single pop-up shop?:
|
||||
- Kanye West
|
||||
- Kanye
|
||||
Which symbolic color did Hillary Clinton and her allies wear during her concession speech?:
|
||||
- Purple
|
||||
Which team took gold in Women's Hockey at the Rio 2016 Olympic Games?:
|
||||
- Great Britain
|
||||
Which team won the CFL Grey Cup in November of 2016?:
|
||||
- Ottawa Redblacks
|
||||
- Redblacks
|
||||
Which team won the MLB (Major League Baseball) 2016 World Series?:
|
||||
- Chicago Cubs
|
||||
- Cubs
|
||||
Which team won the UEFA European Championships in 2016?:
|
||||
- Portugal
|
||||
Which woman's name made Batman and Superman stop fighting in 'Batman v Superman'?:
|
||||
- Martha
|
||||
Who did Obama nominate to replace Antonin Scalia?:
|
||||
- Merrick Garland
|
||||
- Garland
|
||||
Who endorsed Trump after Trump called his wife ugly and his father a murderer?:
|
||||
- Ted Cruz
|
||||
- Cruz
|
||||
Who finished second in the medals table to USA at the Rio 2016 Olympic Games?:
|
||||
- Great Britain
|
||||
Who is Emma Stone's co-star in 'La La Land'?:
|
||||
- Ryan Gosling
|
||||
Who is Harley Quinn in love with in 'Suicide Squad'?:
|
||||
- The Joker
|
||||
- Joker
|
||||
"Who played Apocalypse In 'X-Men: Apocalypse'?":
|
||||
- Oscar Isaac
|
||||
Who was Jennifer Lawrence reportedly dating in 2016?:
|
||||
- Darren Aronofsky
|
||||
Who was the only woman to host a late-night talk show on network TV in 2016?:
|
||||
- Samantha Bee
|
||||
Who was the top person searched on Google in 2016?:
|
||||
- Donald Trump
|
||||
- Trump
|
||||
Who won the Favorite Pop/Rock Female Artist Award at the 2016 American Music Awards?:
|
||||
- Selena Gomez
|
||||
Who won the Nobel Peace Prize?:
|
||||
- Juan Manuel Santos
|
||||
Who won the Nobel Prize For Literature?:
|
||||
- Bob Dylan
|
||||
Who won the final season (15) of American Idol on April 7, 2016?:
|
||||
- Trent Harmon
|
||||
- Harmon
|
||||
With a vote of 61 to 20, the Brazilian Senate impeached which President of Brazil on August 31st, 2016?:
|
||||
- Dilma Rousseff
|
||||
- Rousseff
|
||||
With the release of the album "The Life of Pablo," which artist saw eight of their songs debut on the Billboard Hot 100 in April of 2006?:
|
||||
- Kanye West
|
||||
- Kanye
|
||||
1314
redbot/cogs/trivia/data/lists/anime.yaml
Normal file
1314
redbot/cogs/trivia/data/lists/anime.yaml
Normal file
File diff suppressed because it is too large
Load Diff
1028
redbot/cogs/trivia/data/lists/artandliterature.yaml
Normal file
1028
redbot/cogs/trivia/data/lists/artandliterature.yaml
Normal file
File diff suppressed because it is too large
Load Diff
362
redbot/cogs/trivia/data/lists/boombeach.yaml
Normal file
362
redbot/cogs/trivia/data/lists/boombeach.yaml
Normal file
@@ -0,0 +1,362 @@
|
||||
AUTHOR: zmoTbb
|
||||
A group of islands is called a(n)___?:
|
||||
- Archipelago
|
||||
During the tutorial how many diamonds does it cost to complete the sniper tower?:
|
||||
- 0
|
||||
- zero
|
||||
Every player in Boom Beach starts with this IGN?:
|
||||
- Commander
|
||||
How fast does Robot Overlord spawn critters when maxed?:
|
||||
- 4.3 seconds
|
||||
- 4.3s
|
||||
- "4.3"
|
||||
How intel much would 3 sabotages cost?:
|
||||
- 15
|
||||
- fifteen
|
||||
How long does a maxed flare last for?:
|
||||
- 30 seconds
|
||||
- 30s
|
||||
- 30
|
||||
- thirty seconds
|
||||
How long does a maxed shock bomb last for?:
|
||||
- 10 seconds
|
||||
- 10s
|
||||
- 10
|
||||
How long does the level 6 critter upgrade take (in days):
|
||||
- 3
|
||||
- three
|
||||
How many Force Points are possible in Curtain Call?:
|
||||
- 1110
|
||||
How many Force Points are possible in Mambo?:
|
||||
- 475
|
||||
How many Hero Tokens are in this crate? http://i.imgur.com/fSYlcgi.jpg:
|
||||
- one
|
||||
- 1
|
||||
How many boom cannons can a level 20 HQ build?:
|
||||
- Four
|
||||
- 4
|
||||
How many dives must you complete to get the Submariner achievement?:
|
||||
- 500
|
||||
How many explorable islands are there with a level 20 radar?:
|
||||
- 233
|
||||
How many hours between supply chests?:
|
||||
- 20
|
||||
- twenty
|
||||
How many intel does a player with the rank Legend III receive with their supply chest?:
|
||||
- 5
|
||||
- five
|
||||
How many missiles are in a barrage?:
|
||||
- 15
|
||||
- fifteen
|
||||
How many ranks are there in a Task Force?:
|
||||
- 4
|
||||
- four
|
||||
How many resource bases must you control to obtain the War Production achievement?:
|
||||
- 35
|
||||
- thirty five
|
||||
- thirtyfive
|
||||
How many rockets does a rocket launcher fire in two volleys?:
|
||||
- 12
|
||||
- twelve
|
||||
How many seconds does a maxed smoke cover for?:
|
||||
- 13 seconds
|
||||
- 13
|
||||
- 13s
|
||||
How many statues can a level 4 statue storage hold?:
|
||||
- 4
|
||||
- four
|
||||
How many statues can a level 6 sculptor have?:
|
||||
- 8
|
||||
- eight
|
||||
How many tiles is a scorcher's death radius?:
|
||||
- 3 tiles
|
||||
- 3
|
||||
- three
|
||||
How many tiles wide is a barrage?:
|
||||
- six
|
||||
- 6
|
||||
How many tokens does it cost to upgrade Battle Orders to max level?:
|
||||
- 120
|
||||
- one hundred and twenty
|
||||
How many victory points are required to obtain the Supply Chest?:
|
||||
- 5
|
||||
- five
|
||||
How much DPS does a maxed zooka do?:
|
||||
- 538
|
||||
How much GBE does artillery increase by for each shot?:
|
||||
- 2
|
||||
- two
|
||||
How much GBE does the third Universal Remote cost?:
|
||||
- 22
|
||||
- twenty two
|
||||
- twentytwo
|
||||
How much GBE does three artillery cost?:
|
||||
- 15
|
||||
- fifteen
|
||||
How much GBE is 3 shocks?:
|
||||
- 36
|
||||
- thirty six
|
||||
- thirtysix
|
||||
How much HPS do medics *really* do?:
|
||||
- 28
|
||||
- twenty eight
|
||||
- twentyeight
|
||||
How much damage does a maxed level 22 mine do?:
|
||||
- 296
|
||||
How much does one barrage and one artillery cost?:
|
||||
- 13
|
||||
- thirteen
|
||||
How much gold can a maxed residence hold?:
|
||||
- 130,000
|
||||
- 130000
|
||||
How much gold is the max grenadier upgrade?:
|
||||
- 8700000
|
||||
- 8,700,000
|
||||
How much health does a maxed heavy have?:
|
||||
- 5034
|
||||
- 5,034
|
||||
How much health does a maxed medkit heal?:
|
||||
- 1075
|
||||
- 1,075
|
||||
How much intel does it cost a 50 man TF to start Forlorn Hope?:
|
||||
- 682
|
||||
How much intel does it cost for a 10 member TF to start Sour Grapes?:
|
||||
- 113
|
||||
How much intel does it cost for a 25 member TF to start Dead End?:
|
||||
- 408
|
||||
How much intel does it cost for a 5 member TF to start Foxtrot?:
|
||||
- 93
|
||||
If you crushed two Ice Masterpieces how much powder would you have?:
|
||||
- 14
|
||||
- fourteen
|
||||
If you had a perfect Wood Production Masterpiece and you boosted it, what percent would you be getting?:
|
||||
- 124%
|
||||
- 124
|
||||
If you have 1209 VP and beat 4 NPC bases what will your VP be when you are done?:
|
||||
- 1213
|
||||
If you have level 5 critters how many critters will be in each crate?:
|
||||
- 10
|
||||
- ten
|
||||
In game you can be invaded by Blackguard and what?:
|
||||
- mercenary
|
||||
- mercenaries
|
||||
"Name this prototype module: https://goo.gl/DXrKtM":
|
||||
- Complex Gear
|
||||
Sgt Brick has three abilities. Iron Will, Battle Orders, and___?:
|
||||
- Cluster Grenade
|
||||
There's a gunboat on your map and it's Monday, what event is it?:
|
||||
- Hammerman Strikes Back
|
||||
This mortar has no blindspot, what is it called? https://goo.gl/5Ekjop:
|
||||
- Super Mortar 3000
|
||||
- Super Mortar Three Thousand
|
||||
War Factory comes on which day of the week?:
|
||||
- Thursday
|
||||
- thurs
|
||||
War Time… what? https://goo.gl/JIwbAK:
|
||||
- epaulets
|
||||
- Epaulettes
|
||||
What HQ is required to unlock Mega Crab:
|
||||
- 7
|
||||
- seven
|
||||
- hq7
|
||||
What HQ level are tanks unlocked at?:
|
||||
- 11
|
||||
- eleven
|
||||
What HQ level is smoke unlocked at?:
|
||||
- 14
|
||||
- fourteen
|
||||
What Landing Craft level is required to hold two tanks?:
|
||||
- 12
|
||||
- twelve
|
||||
What XP level is the HQ on Stage 6 of Dr.T Volcano?:
|
||||
- 60
|
||||
- sixty
|
||||
What can you buy with Trader Tickets?:
|
||||
- Trader Crates
|
||||
- crates
|
||||
What colour are Ice Stones?:
|
||||
- Blue
|
||||
What is a Cryoneer's weapon called?:
|
||||
- Freeze Beam
|
||||
What is smaller than a Shard?:
|
||||
- fragment
|
||||
- frag
|
||||
What is the fastest shooting defensive building?:
|
||||
- MMG 9000
|
||||
- MMG9000
|
||||
What is the final defensive building to be unlocked?:
|
||||
- Shock Launcher
|
||||
- sl
|
||||
What is the first splash damage defense unlocked in the game?:
|
||||
- mortar
|
||||
What is the intel cap on a 25 member Task Force?:
|
||||
- 600
|
||||
- six hundred
|
||||
What is the largest possible tree called?:
|
||||
- Mangrove Grove
|
||||
- Grove
|
||||
- Pine Grove
|
||||
What is the maximum % of a PSC Masterpiece?:
|
||||
- 75%
|
||||
- 75
|
||||
- seventy five
|
||||
- seventyfive
|
||||
What is the maximum depth of the Submarine?:
|
||||
- 1500 meters
|
||||
- 1500m
|
||||
- 1,500
|
||||
- 1,500m
|
||||
- 1500 m
|
||||
- 1,500 m
|
||||
What is the maximum level for a Boom Mine?:
|
||||
- 18
|
||||
- eighteen
|
||||
What is the maximum percentage chance of an invasion the Radar can display?:
|
||||
- 17
|
||||
- 17%
|
||||
What is the maxiumum boosted GBE for someone with 6 GBE statues?:
|
||||
- 185
|
||||
What is the most expensive troop to fully load a landing craft with?:
|
||||
- Cryoneer
|
||||
What is the name of the Achievement for salvaging 3,000 statues?:
|
||||
- perfectionist
|
||||
What is the name of the Friday event?:
|
||||
- Imitation Game
|
||||
- IG
|
||||
What is the name of the achievement for upgrading the Gold Storage to level 10?:
|
||||
- War Chest
|
||||
What is the name of the enemy force in Boom Beach?:
|
||||
- Blackguard
|
||||
What is the name of the rank you receive when you hit 1000 VP?:
|
||||
- Brigadier III
|
||||
- Brigadier 3
|
||||
What is the name of this building? https://goo.gl/arvmiT:
|
||||
- Dream Pipes
|
||||
What is the name of this prototype? https://goo.gl/MWmygA:
|
||||
- Field Capacitor
|
||||
What is the name of zmoT's Task Force?:
|
||||
- Triangle Nine
|
||||
- T9
|
||||
- Triangle 9
|
||||
What is the nickname for a rifleman?:
|
||||
- Johnson
|
||||
What is the official name for Purple Stones?:
|
||||
- Dark Stones
|
||||
- Dark
|
||||
What is the official name for Red Stones?:
|
||||
- Magma Stones
|
||||
- Magma
|
||||
What is the only building whose last upgrade doesn't cost Wood?:
|
||||
- Sawmill
|
||||
What is the only unit that can move and attack at the same time?:
|
||||
- Heavy
|
||||
What is the seventh troop to unlock?:
|
||||
- Grenadier
|
||||
What is the smallest size for a Task Force?:
|
||||
- 5
|
||||
- five
|
||||
What is this building called? https://goo.gl/KZWP1X:
|
||||
- Bunker
|
||||
What is this building called? https://goo.gl/kWHKZz:
|
||||
- Ominous Hatch
|
||||
What is this building called? https://goo.gl/vkh43J:
|
||||
- Factory Supplies
|
||||
What is this prototype called? https://goo.gl/UQYkeo:
|
||||
- Power Rod
|
||||
What is used to upgrade Hero Abilities:
|
||||
- Hero Tokens
|
||||
What level War Factory must you beat to unlock Everspark?:
|
||||
- 45
|
||||
- forty five
|
||||
- fortyfive
|
||||
What level must Everspark be to unlock the Universal Remote?:
|
||||
- 3
|
||||
- three
|
||||
What percent chance do you have of getting intel when you defeat an NPC base?:
|
||||
- 25%
|
||||
- 25
|
||||
- twenty five
|
||||
What rank is obtained at 450 VP?:
|
||||
- Major I
|
||||
- Major 1
|
||||
What rate does a building frozen by a Cryoneer shoot?:
|
||||
- 50%
|
||||
- half
|
||||
- "0.5"
|
||||
What sign is on the front of the Operation Reward boat?:
|
||||
- "No smoking: http://i.imgur.com/Tk49o1E.jpg"
|
||||
- No smoking
|
||||
What time does the Trader arrive?:
|
||||
- 7pm
|
||||
- "19:00"
|
||||
- 7:00pm
|
||||
- 1900
|
||||
- 7 pm
|
||||
What type of statue do you get when you combine 7 fragments?:
|
||||
- idol
|
||||
What variety of tree grows on ice bases?:
|
||||
- Pine
|
||||
What was the name of the update that contained the first Mega Crab?:
|
||||
- The Last Crustacean
|
||||
- Last Crustacean
|
||||
What word does the troop name 'Zooka' come from?:
|
||||
- Bazooka
|
||||
What's the lowest possible level of a resource base?:
|
||||
- 3
|
||||
- three
|
||||
What's the most GBE that can be returned (from destroyed buildings) using a single artillery shot?:
|
||||
- 12
|
||||
- twelve
|
||||
When you beat an NPC what percent chance do you have of getting a prototype part?:
|
||||
- 8%
|
||||
- 8
|
||||
- eight
|
||||
Which Economy building is primarily built below the ground?:
|
||||
- Vault
|
||||
Which HQ level is required to repair the Derelict Hut?:
|
||||
- 4
|
||||
- Four
|
||||
Which HQ level is the Cryoneer unlocked?:
|
||||
- 20
|
||||
- twenty
|
||||
Which Mega Crab defence is this? https://goo.gl/IFcaHL:
|
||||
- cryo bomb
|
||||
- cryobomb
|
||||
Which building releases a pink blast which increases the speed of all troops and buildings nearby?:
|
||||
- speed serum
|
||||
Which company makes Boom Beach?:
|
||||
- SuperCell
|
||||
- Super Cell
|
||||
Which defense has the largest blindspot?:
|
||||
- rocket launcher
|
||||
- rl
|
||||
- rls
|
||||
Which defense is orange and was added for Halloween Mega Crab?:
|
||||
- Scary mortar
|
||||
Which defense reduces attack and movement speed by 75%?:
|
||||
- cryo bomb
|
||||
Which is the only defense that is manned by a troop?:
|
||||
- Sniper Tower
|
||||
- sniper
|
||||
Which of Dr.T's islands appears first in the event cycle?:
|
||||
- Tropical
|
||||
Which one default (non prototype) defense can not be found on resource bases?:
|
||||
- Shock Launcher
|
||||
- sl
|
||||
Which single shot defense has the same range as a machine gun?:
|
||||
- cannon
|
||||
Which storage does not change appearance when filling up?:
|
||||
- Gold Storage
|
||||
- Gold
|
||||
Which troop has more DPS than health?:
|
||||
- Zooka
|
||||
Who controls the War Factory?:
|
||||
- Colonel Gearheart
|
||||
- Gearheart
|
||||
Who is currently (April 2017) the community manager for Boom Beach?:
|
||||
- Rlight
|
||||
- ryan
|
||||
- ryan lighton
|
||||
Who is the commander of the enemy?:
|
||||
- Lt. Hammerman
|
||||
- Hammerman
|
||||
264
redbot/cogs/trivia/data/lists/cars.yaml
Normal file
264
redbot/cogs/trivia/data/lists/cars.yaml
Normal file
@@ -0,0 +1,264 @@
|
||||
AUTHOR: lumpycustard & mikel392
|
||||
What car is this? http://i.imgur.com/00lgfBA.jpg:
|
||||
- Hummer H3
|
||||
- H3
|
||||
What car is this? http://i.imgur.com/08RU3gg.jpg:
|
||||
- BMW 740i
|
||||
- BMW 740li
|
||||
- 740i
|
||||
- 740li
|
||||
What car is this? http://i.imgur.com/0hiabXk.jpg:
|
||||
- Bugatti Veyron
|
||||
- Veyron
|
||||
What car is this? http://i.imgur.com/23aME2z.jpg:
|
||||
- BMW M3 E46
|
||||
- BMW M3
|
||||
- M3
|
||||
- E46 M3
|
||||
- M3 E46
|
||||
- E46
|
||||
What car is this? http://i.imgur.com/2RloUuq.jpg:
|
||||
- Alfa Romeo Spider
|
||||
- Spider
|
||||
What car is this? http://i.imgur.com/34W6ivD.jpg:
|
||||
- Mercedes GLS 63
|
||||
- GLS 63
|
||||
What car is this? http://i.imgur.com/4Dxe2wr.jpg:
|
||||
- Ferrari F40
|
||||
- F40
|
||||
What car is this? http://i.imgur.com/4NeysNc.jpg:
|
||||
- Lotus Elise
|
||||
- Elise
|
||||
What car is this? http://i.imgur.com/6hEIMPv.jpg:
|
||||
- Holden Commodore
|
||||
- Commodore
|
||||
What car is this? http://i.imgur.com/6l2WugR.jpg:
|
||||
- Mini Cooper S
|
||||
- Cooper S
|
||||
What car is this? http://i.imgur.com/7yJctRM.jpg:
|
||||
- Aston Martin Vulcan
|
||||
- Vulcan
|
||||
What car is this? http://i.imgur.com/91Qr2qU.jpg:
|
||||
- Ariel Atom
|
||||
- Atom
|
||||
What car is this? http://i.imgur.com/98oRdwe.jpg:
|
||||
- Mazda 6
|
||||
What car is this? http://i.imgur.com/ByN5HvO.jpg:
|
||||
- Jaguar F-TYPE
|
||||
- Jaguar F TYPE
|
||||
- F-TYPE
|
||||
- F TYPE
|
||||
What car is this? http://i.imgur.com/Em4lvkt.jpg:
|
||||
- Dodge Viper
|
||||
- Viper
|
||||
What car is this? http://i.imgur.com/F1dO1Zv.jpg:
|
||||
- Jeep Wrangler
|
||||
- Wrangler
|
||||
What car is this? http://i.imgur.com/FUhK0aW.jpg:
|
||||
- Honda Civic
|
||||
- Civic
|
||||
What car is this? http://i.imgur.com/Fnnqpek.jpg:
|
||||
- Nissan Fairlady Z
|
||||
- Fairlady Z
|
||||
What car is this? http://i.imgur.com/GdfZKwg.jpg:
|
||||
- Pagani Zonda R
|
||||
- Zonda R
|
||||
- Zonda
|
||||
What car is this? http://i.imgur.com/H3SK6uq.jpg:
|
||||
- Nissan R35 GTR
|
||||
- R35 GTR
|
||||
- R35
|
||||
What car is this? http://i.imgur.com/JJb0DEN.jpg:
|
||||
- Ford Mustang
|
||||
- Mustang
|
||||
What car is this? http://i.imgur.com/KCd50kw.jpg:
|
||||
- Rolls Royce Wraith
|
||||
- Rolls Wraith
|
||||
- Wraith
|
||||
What car is this? http://i.imgur.com/KGCsWGo.jpg:
|
||||
- Lamborghini Aventador
|
||||
- Lambo Avendator
|
||||
- Avendator
|
||||
What car is this? http://i.imgur.com/Khv7UOz.jpg:
|
||||
- Peugeot RCZ
|
||||
- RCZ
|
||||
What car is this? http://i.imgur.com/LpEAyAJ.jpg:
|
||||
- Ford Focus ST
|
||||
- Focus ST
|
||||
What car is this? http://i.imgur.com/LwMyFVe.jpg:
|
||||
- Mazda Miata
|
||||
- Miata
|
||||
- Mazda MX5
|
||||
- MX5
|
||||
What car is this? http://i.imgur.com/MT6vGov.jpg:
|
||||
- Subaru WRX STI
|
||||
- WRX STI
|
||||
- WRX
|
||||
What car is this? http://i.imgur.com/Mo38uCR.jpg:
|
||||
- Renult Clio
|
||||
- Clio
|
||||
What car is this? http://i.imgur.com/Mq9brzi.jpg:
|
||||
- Ferrari FF
|
||||
- FF
|
||||
What car is this? http://i.imgur.com/OJZeJJL.jpg:
|
||||
- Mercedes Sprinter
|
||||
- Sprinter
|
||||
What car is this? http://i.imgur.com/PlnDBzc.jpg:
|
||||
- Honda S2000
|
||||
- S2000
|
||||
What car is this? http://i.imgur.com/SGDwuza.jpg:
|
||||
- Volkswagen Golf R32
|
||||
- VW Golf R32
|
||||
- VW Golf
|
||||
- VW 32
|
||||
- Golf
|
||||
- R32
|
||||
What car is this? http://i.imgur.com/Sx277Np.jpg:
|
||||
- Jeep Grand Cherokee
|
||||
- Grand Cherokee
|
||||
- Cherokee
|
||||
What car is this? http://i.imgur.com/UDNVozm.jpg:
|
||||
- BMW 135i
|
||||
- 135i
|
||||
- E82 135i
|
||||
- 135i E82
|
||||
What car is this? http://i.imgur.com/WRwLTEi.jpg:
|
||||
- Mercedes Benz C63 AMG
|
||||
- Mercedes C63 AMG
|
||||
- C63 AMG
|
||||
- C63
|
||||
What car is this? http://i.imgur.com/XDczAbn.jpg:
|
||||
- Audi R8
|
||||
- R8
|
||||
What car is this? http://i.imgur.com/Xfvt15w.jpg:
|
||||
- Nissan Skyline R34 GTR
|
||||
- Skyline R34 GTR
|
||||
- R34 GTR
|
||||
- R34
|
||||
What car is this? http://i.imgur.com/Y1npBzd.jpg:
|
||||
- Porsche Cayenne
|
||||
- Cayenne
|
||||
What car is this? http://i.imgur.com/YYmMMp6.jpg:
|
||||
- BMW M3
|
||||
- M3
|
||||
What car is this? http://i.imgur.com/Z359mLS.jpg:
|
||||
- Mercedes Benz A45 AMG
|
||||
- Mercedes A45 AMG
|
||||
- A45 AMG
|
||||
- A45
|
||||
What car is this? http://i.imgur.com/ZLzZkiQ.jpg:
|
||||
- Ferrari 451 Italia
|
||||
- 451 Italia
|
||||
- 451
|
||||
What car is this? http://i.imgur.com/ZRW6msa.jpg:
|
||||
- Audi TT
|
||||
- TT
|
||||
What car is this? http://i.imgur.com/adKTlrb.jpg:
|
||||
- Honda Integra Type R
|
||||
- Integra Type R
|
||||
- Honda Integra
|
||||
- Integra
|
||||
What car is this? http://i.imgur.com/bCq4ePD.jpg:
|
||||
- Mclaren P1
|
||||
- P1
|
||||
What car is this? http://i.imgur.com/cOXNsmp.jpg:
|
||||
- Mitsubishi 3000GT, 3000GT
|
||||
What car is this? http://i.imgur.com/cyLaOzo.jpg:
|
||||
- Ford GT40
|
||||
- GT40
|
||||
What car is this? http://i.imgur.com/drWpps4.jpg:
|
||||
- Aston Martin DBS
|
||||
- DBS
|
||||
What car is this? http://i.imgur.com/dy9Czy9.jpg:
|
||||
- Chevrolet Camaro Z28
|
||||
- Camaro Z28
|
||||
- Z28
|
||||
What car is this? http://i.imgur.com/ePOQioV.jpg:
|
||||
- Ford GT
|
||||
What car is this? http://i.imgur.com/ehK34nf.jpg:
|
||||
- BMW X5
|
||||
- X5
|
||||
What car is this? http://i.imgur.com/j9YLUhp.jpg:
|
||||
- Hennessey Venom GT
|
||||
- Venom GT
|
||||
What car is this? http://i.imgur.com/kYXfqli.jpg:
|
||||
- Mazda 3
|
||||
What car is this? http://i.imgur.com/lEqHceK.jpg:
|
||||
- BMW M5
|
||||
- M5
|
||||
What car is this? http://i.imgur.com/oORkbPu.jpg:
|
||||
- BMW Z8
|
||||
- Z8
|
||||
What car is this? http://i.imgur.com/oVr6FPH.jpg:
|
||||
- Subaru BRZ
|
||||
- BRZ
|
||||
What car is this? http://i.imgur.com/pwAIBeS.jpg:
|
||||
- Honda NSX
|
||||
- NSX
|
||||
What car is this? http://i.imgur.com/pzkLMpQ.jpg:
|
||||
- Porsche 911
|
||||
- 911
|
||||
What car is this? http://i.imgur.com/qiHToqo.jpg:
|
||||
- Ford Falcon XR8
|
||||
- Falcon XR8
|
||||
- Falcon
|
||||
- XR8
|
||||
What car is this? http://i.imgur.com/qxG9gDx.jpg:
|
||||
- Shelby Cobra
|
||||
- Cobra
|
||||
What car is this? http://i.imgur.com/qyWZlNp.jpg:
|
||||
- Toyota FT86
|
||||
- FT86
|
||||
What car is this? http://i.imgur.com/rl6uDya.jpg:
|
||||
- Nissan Skyline R33 GTR
|
||||
- Skyline R33 GTR
|
||||
- R33 GTR
|
||||
- R33
|
||||
What car is this? http://i.imgur.com/sScLnok.jpg:
|
||||
- BMW Z4
|
||||
- Z4
|
||||
What car is this? http://i.imgur.com/sUklkcm.jpg:
|
||||
- Nissan Silvia
|
||||
- Silvia
|
||||
What car is this? http://i.imgur.com/taY3NLJ.jpg:
|
||||
- McLaren F1
|
||||
- F1
|
||||
What car is this? http://i.imgur.com/tfmqVrR.jpg:
|
||||
- Mitsubishi Lancer Evolution
|
||||
- Lancer Evolution
|
||||
- Lancer Evo
|
||||
- Evo
|
||||
What car is this? http://i.imgur.com/tz6AaI5.jpg:
|
||||
- Holden Marloo
|
||||
- Marloo
|
||||
What car is this? http://i.imgur.com/u18TuTM.jpg:
|
||||
- Honda Odyssey
|
||||
- Odyssey
|
||||
What car is this? http://i.imgur.com/uuirrWV.jpg:
|
||||
- Chevrolet Corvette C7 Z06
|
||||
- Corvette C7 Z06
|
||||
- C7 Z06
|
||||
- Corvette Z06
|
||||
- Z06
|
||||
What car is this? http://i.imgur.com/xODGOOa.jpg:
|
||||
- BMW M1 Procar
|
||||
- M1 Procar
|
||||
- M1
|
||||
What car is this? http://i.imgur.com/yUzmtGU.jpg:
|
||||
- Toyota Landcruiser
|
||||
- Landcruiser
|
||||
What car is this? http://i.imgur.com/yXgbowC.jpg:
|
||||
- Toyota Celica
|
||||
- Celica
|
||||
What car is this? http://i.imgur.com/yzmQqoz.jpg:
|
||||
- Ferrari 250 GTO
|
||||
- 250 GTO
|
||||
- 250
|
||||
What car is this? http://i.imgur.com/ze0s5Kl.jpg:
|
||||
- Nissan 350Z
|
||||
- Nissan 350 Z
|
||||
- 350Z
|
||||
- 350 Z
|
||||
What car is this? https://i.imgur.com/STHmXOc.jpg:
|
||||
- Factory Five
|
||||
- 818C
|
||||
395
redbot/cogs/trivia/data/lists/clashroyale.yaml
Normal file
395
redbot/cogs/trivia/data/lists/clashroyale.yaml
Normal file
@@ -0,0 +1,395 @@
|
||||
AUTHOR: Tajniak96
|
||||
"\"Roses are red, ....... are blue, they can fly, and will crush you!\" Who is this about?":
|
||||
- Minions
|
||||
- minion
|
||||
- 3 minions
|
||||
- three minions
|
||||
A pile of bones?:
|
||||
- Skeletons
|
||||
- skellies
|
||||
- skeleton
|
||||
- skelly
|
||||
Annnnnd...?:
|
||||
- Fireball!
|
||||
- fireball
|
||||
At which Arena can you unlock Balloon?:
|
||||
- Arena 2
|
||||
- 2
|
||||
- Bone Pit
|
||||
At which Arena can you unlock Fire Spirits?:
|
||||
- Arena 5
|
||||
- 5
|
||||
- Spell Valley
|
||||
At which Arena can you unlock Fireball?:
|
||||
- Arena 0
|
||||
- 0
|
||||
- Training Camp
|
||||
At which Arena can you unlock Furnace?:
|
||||
- Arena 5
|
||||
- Spell Valley
|
||||
- 5
|
||||
At which Arena can you unlock Golem?:
|
||||
- Arena 6
|
||||
- 6
|
||||
- Builder's Workshop
|
||||
At which Arena can you unlock Hog Rider?:
|
||||
- Arena 4
|
||||
- 4
|
||||
- P.E.K.K.A's Playhouse
|
||||
At which Arena can you unlock Ice Spirit?:
|
||||
- Arena 8
|
||||
- 8
|
||||
- Frozen Peak
|
||||
At which Arena can you unlock Poison?:
|
||||
- Arena 5
|
||||
- 5
|
||||
- Spell Valley
|
||||
At which Arena can you unlock Rocket?:
|
||||
- Arena 3
|
||||
- 3
|
||||
- Barbarian Bowl
|
||||
At which Arena can you unlock Royal Giant?:
|
||||
- Arena 7
|
||||
- 7
|
||||
- Royal Arena
|
||||
At which Arena can you unlock Valkyrie?:
|
||||
- Arena 1
|
||||
- 1
|
||||
- Goblin Stadium
|
||||
At which Arena can you unlock X-Bow?:
|
||||
- Arena 3
|
||||
- Barbarian Bowl
|
||||
- 3
|
||||
At which Arena do you get a chance for Legendary cards to appear in the shop?:
|
||||
- Legendary Arena
|
||||
- Legendary
|
||||
- Legend
|
||||
- A9
|
||||
- 9
|
||||
- Arena 9
|
||||
Disrespecting the Three Musketeers is a...?:
|
||||
- mistake
|
||||
- cardinal sin
|
||||
How long is Overtime in tournaments?:
|
||||
- 3 minutes
|
||||
- 3min
|
||||
- 3mins
|
||||
- 3 mins
|
||||
How many Gems does a Bucket of Gold cost?:
|
||||
- 500
|
||||
- five hundred
|
||||
How many Gems does a Wagon contain?:
|
||||
- 6500
|
||||
- 6,500
|
||||
- 6'500
|
||||
- "6.500"
|
||||
- 6.5k
|
||||
- six thousand five hundred
|
||||
- sixtyfive hundred
|
||||
How many Gems does a Wagon of Gold cost?:
|
||||
- 4500
|
||||
- 4 500
|
||||
- 4,500
|
||||
- "4.500"
|
||||
- 4.5k
|
||||
- 4,5k
|
||||
- 4'500
|
||||
- Four Thousand Five Hundred
|
||||
How many cards are you rewarded for winning a 200 player tournament?:
|
||||
- 120
|
||||
- one hundred and twenty
|
||||
How many cards are you rewarded for winning a 500 player tournament?:
|
||||
- 1200
|
||||
- 1 200
|
||||
- 1,200
|
||||
- 1'200
|
||||
- "1.200"
|
||||
- 1.2k
|
||||
- one thousand two hundred
|
||||
- twelve hundred
|
||||
How many cards do you get for taking the 1st place in the largest tournament?:
|
||||
- two thousand
|
||||
- 2000
|
||||
- 2,000
|
||||
- 2k
|
||||
How many different cards is available in shop on Sunday?:
|
||||
- 6
|
||||
- six
|
||||
How many gems does a Pouch of Gold cost?:
|
||||
- 60
|
||||
- sixty
|
||||
How many gems does it cost to create the largest tournament?:
|
||||
- 250000
|
||||
- 250'000
|
||||
- 250 000
|
||||
- "250.000"
|
||||
- 250,000
|
||||
- two hundred and fifty thousand
|
||||
How many make a crowd?:
|
||||
- Three
|
||||
- 3
|
||||
How many make a horde?:
|
||||
- Six
|
||||
- 6
|
||||
How many trophies do you need to get into Barbarian Bowl?:
|
||||
- 800
|
||||
- eight hundred
|
||||
How many trophies do you need to get into Bone Pit?:
|
||||
- 400
|
||||
- four hundred
|
||||
How many trophies do you need to get into Builder's Workshop?:
|
||||
- 1700
|
||||
- 1,700
|
||||
- 1'700
|
||||
- "1.700"
|
||||
- seventeen hundred
|
||||
- one thousand seven hundred
|
||||
How many trophies do you need to get into Frozen Peak?:
|
||||
- 2300
|
||||
- 2,300
|
||||
- "2.300"
|
||||
- 2'300
|
||||
- two thousand three hundred
|
||||
- twenty three hundred
|
||||
How many trophies do you need to get into Goblin Stadium?:
|
||||
- 0
|
||||
- zero
|
||||
How many trophies do you need to get into Legendary Arena?:
|
||||
- 3000
|
||||
- 3,000
|
||||
- "3.000"
|
||||
- 3'000
|
||||
- 3k
|
||||
- three thousand
|
||||
How many trophies do you need to get into P.E.K.K.A's Playhouse?:
|
||||
- 1100
|
||||
- 1'100
|
||||
- 1,000
|
||||
- "1.100"
|
||||
- one thousand one hundred
|
||||
- eleven hundred
|
||||
How many trophies do you need to get into Royal Arena?:
|
||||
- 2000
|
||||
- 2,000
|
||||
- 2'000
|
||||
- "2.000"
|
||||
- 2k
|
||||
- two thousand
|
||||
How many trophies do you need to get into Spell Valley?:
|
||||
- 1400
|
||||
- 1'400
|
||||
- 1,400
|
||||
- "1.400"
|
||||
- fourteen hundred
|
||||
- one thousand four hundred
|
||||
How many trophies do you need to get into Training Camp?:
|
||||
- none
|
||||
- 0
|
||||
- zero
|
||||
How much Gold does a Bucket of Gold contain?:
|
||||
- 10000
|
||||
- 10 000
|
||||
- 10k
|
||||
- "10.000"
|
||||
- 10,000
|
||||
- 10'000
|
||||
- ten thousand
|
||||
- 10 thousand
|
||||
How much Gold does a Wagon of Gold contain?:
|
||||
- 100 000
|
||||
- 100000
|
||||
- 100k
|
||||
- 100'000
|
||||
- 100,000
|
||||
- "100.000"
|
||||
- one hundred thousand
|
||||
- 100 thousand
|
||||
How much damage does a tournament level Freeze deal?:
|
||||
- 0
|
||||
- none
|
||||
How much gold does a Pouch of Gold contain?:
|
||||
- 1000
|
||||
- 1k
|
||||
- 1,000
|
||||
- "1.000"
|
||||
- 1 000
|
||||
- 1'000
|
||||
- one thousand
|
||||
- a thousand
|
||||
How much gold does the 2nd Legendary cost in the shop?:
|
||||
- 80000
|
||||
- 80k
|
||||
- 80,000
|
||||
- 80'000
|
||||
- "80.000"
|
||||
- 80 000
|
||||
- eighty thousand
|
||||
Larry, Harry, Terry, Mary, Leedoot and friends together make a...?:
|
||||
- Skeleton Army
|
||||
- skarmy
|
||||
Miner doesn't use magic,but a...?:
|
||||
- Shovel
|
||||
- shovel
|
||||
Name one Legendary card that is unlocked at Builder's Workshop.:
|
||||
- Sparky Miner or The Log
|
||||
- Sparky
|
||||
- Miner
|
||||
- The Log
|
||||
- log
|
||||
The Wizard will blow you away with his...?:
|
||||
- handsomeness
|
||||
- fireball
|
||||
What appreciates your tower?:
|
||||
- X-bow
|
||||
- xbow
|
||||
What does the Bowler like the most?:
|
||||
- Dark Elixir drinks
|
||||
- throwing rocks
|
||||
- dark elixir
|
||||
What does the Lumberjack do at night?:
|
||||
- Hunts The Log
|
||||
- hunts
|
||||
- hunts log
|
||||
- Hunt the log
|
||||
- He is hunting the log
|
||||
What does the hog say?:
|
||||
- Hog Riderrrrr
|
||||
- Hog Rider
|
||||
- Hog Ridah
|
||||
- Hog Riderr
|
||||
What is The Log seeking for?:
|
||||
- Revenge
|
||||
- revenge
|
||||
What is The Log's favourite song?:
|
||||
- They see me rollin'
|
||||
- they see me rollin
|
||||
What is adorable, but on fire?:
|
||||
- Fire Spirits
|
||||
- firespirits
|
||||
- fs
|
||||
What is the Furnace's specialty?:
|
||||
- Pancakes
|
||||
- pancake
|
||||
What is the Royal Giant's passion?:
|
||||
- his beard
|
||||
- beard
|
||||
What is the best distraction for the Mini P.E.K.K.A?:
|
||||
- A Butterfly
|
||||
- Butterfly
|
||||
What is the creepiest building according to its descripton?:
|
||||
- Tombstone
|
||||
- tomb
|
||||
- tombst
|
||||
- tmbstne
|
||||
- tstone
|
||||
What is the max level of Common Cards?:
|
||||
- 13
|
||||
- thirteen
|
||||
What is the max level of Epic Cards?:
|
||||
- 8
|
||||
- eight
|
||||
What is the max level of Legendary cards?:
|
||||
- 5
|
||||
- five
|
||||
What is the max level of Rare Cards?:
|
||||
- 11
|
||||
- eleven
|
||||
What is the max level of the King?:
|
||||
- 13
|
||||
- thirteen
|
||||
What is the most known victim of Clash Royale?:
|
||||
- Clash of Clans
|
||||
- CoC
|
||||
- clashofclans
|
||||
What is the motto of the Ice Spirit?:
|
||||
- Stay frosty
|
||||
What is the name of the first Arena?:
|
||||
- Training Camp
|
||||
What makes everybody chill?:
|
||||
- Freeze Spell
|
||||
- freeze
|
||||
What makes everyone say "Chaaaarge!":
|
||||
- Rage Spell
|
||||
- Rage
|
||||
What uses the power of Electrickery?:
|
||||
- Tesla
|
||||
What's the only thing in the game that isn't affected by Poison?:
|
||||
- The grass
|
||||
- grass
|
||||
What's too hot for TV?:
|
||||
- Ice wizard's mustache
|
||||
- iwmustache
|
||||
- ice wiz mustache
|
||||
- handlebar mustache
|
||||
- ice wizard
|
||||
When do you have less that 8 cards in your deck?:
|
||||
- In tutorial
|
||||
- tutorial
|
||||
- training camp
|
||||
Where is the 4th Skeleton?:
|
||||
- in the army
|
||||
- In the army
|
||||
- In the army now
|
||||
- skeleton army
|
||||
- skarmy
|
||||
Where you shouldn't look inside?:
|
||||
- Goblin Hut
|
||||
- gob hut
|
||||
Which Legendary card is unlocked at Frozen Peak?:
|
||||
- Lumberjack
|
||||
- lj
|
||||
Which Legendary card is unlocked at P.E.K.K.A's Playhouse?:
|
||||
- Lava Hound
|
||||
- lavahound
|
||||
- lh
|
||||
Which Legendary card is unlocked at Royal Arena?:
|
||||
- Princess
|
||||
Which Legendary card is unlocked at Spell Valley?:
|
||||
- Ice Wizard
|
||||
- icewizard
|
||||
- iw
|
||||
Who are the Guards without their shields?:
|
||||
- Three ruthless bone brothers
|
||||
Who carries around a drink on the Arena?:
|
||||
- Lumberjack
|
||||
- lj
|
||||
Who doesn't know what "Overkill" means?:
|
||||
- Sparky
|
||||
Who has a coil of iron and wheels of wood?:
|
||||
- Sparky
|
||||
Who has delicately coiffed hair?:
|
||||
- Musketeer
|
||||
- musket
|
||||
- musky
|
||||
- musket
|
||||
- musk
|
||||
Who has eyes that unfortunately don't shoot lasers?:
|
||||
- Witch
|
||||
Who is the Knight for the barbarian?:
|
||||
- Cousin
|
||||
Who shoots destructo beams?:
|
||||
- Witch
|
||||
Who sounds like he has a bucket on his head?:
|
||||
- Dark Prince
|
||||
- dp
|
||||
- darkp
|
||||
- dark p
|
||||
Who won't help you colour your hair thus often doing it?:
|
||||
- Archers
|
||||
Who's a majestic flying beast?:
|
||||
- Lava Hound
|
||||
- lavahound
|
||||
- lh
|
||||
Who's a one-man wrecking crew?:
|
||||
- Giant
|
||||
Who's born ready for a barbeque?:
|
||||
- Baby Dragon
|
||||
- baby drag
|
||||
Who's stunning?:
|
||||
- Princess
|
||||
Why is it bad for you if you feel warm feelings towards the Princess?:
|
||||
- Because you're probably on fire!
|
||||
- cuz ur on fire
|
||||
- because your probably on fire
|
||||
- You are on fire
|
||||
- you are probably on fire
|
||||
386
redbot/cogs/trivia/data/lists/computers.yaml
Normal file
386
redbot/cogs/trivia/data/lists/computers.yaml
Normal file
@@ -0,0 +1,386 @@
|
||||
AUTHOR: JennJenn
|
||||
A compact disc containing permanently stored data that cannot be altered?:
|
||||
- Compact Disc Read-Only Memory
|
||||
- CD-ROM
|
||||
- CD ROM
|
||||
- Compact Disc-Read-Only Memory
|
||||
- Compact Disk Read-Only Memory
|
||||
- Compact Disc Read Only Memory
|
||||
- Compact Disk Read Only Memory
|
||||
A computer that is on the network is a...?:
|
||||
- Node
|
||||
A computer which links several PCs together in a network is called a...?:
|
||||
- Server
|
||||
A computer's cache will hold data that is used most often to make it faster to access. There are various levels of cache, the first of which is a small amount of memory found inside the what?:
|
||||
- CPU
|
||||
- Central processing unit
|
||||
A network technician is configuring port security on switches. The interfaces on the switches are configured in such a way that when a violation occurs, packets with unknown source address are dropped and no notification is sent. Which violation mode is configured on the interfaces?:
|
||||
- Protect
|
||||
A server that can perform no other task besides network services is called...?:
|
||||
- Dedicated server
|
||||
According to ISO, HDLC means...?:
|
||||
- High-level Data Link Control
|
||||
- highlevel data link control
|
||||
- high level data link control
|
||||
Amount of data a Floppy Disk can store?:
|
||||
- 1.4 MB
|
||||
Between CRT and LCD monitors, which uses less power?:
|
||||
- LCD
|
||||
Blank optical disk where you can save only once, even when not the whole space available is used?:
|
||||
- Compact Disc-Recordable
|
||||
- CD-R
|
||||
- cd r
|
||||
- Compact Disk-Recordable
|
||||
- Compact Disc RecordableCompact Disk Recordable
|
||||
Business-oriented social networking service, co-founded by Reid Hoffman in 2003?:
|
||||
- LinkedIn
|
||||
Crowdfunding platform founded in 2009 by Perry Chen, Yancey Strickler and Charles Adler?:
|
||||
- Kickstarter
|
||||
Data can come from information stored in the computer's permanent storage, or it can come from peripheral devices, such as keyboards. Regardless of whether it is input through a peripheral device or taken from storage, which type of memory does most data go through first?:
|
||||
- RAM
|
||||
E-commerce business founded in 1998 and focuses on money transfers to be made through the Internet?:
|
||||
- PayPal
|
||||
Early web search engine founded in 1995. Purchased by Yahoo! in 2003 which shut it down in 2013?:
|
||||
- AltaVista
|
||||
How many layers are present in TCP/IP model?:
|
||||
- Seven
|
||||
- 7
|
||||
How many logical drives is it possible to fit onto a physical disk?:
|
||||
- Twenty-four
|
||||
- twentyfour
|
||||
- 24
|
||||
- twenty four
|
||||
How much information can a CD (Compact Disc) usually store?:
|
||||
- 650 Mb
|
||||
IP Addresses have ________ bytes?:
|
||||
- Four
|
||||
- 4
|
||||
If one of your peripherals is not functioning properly, where in the Windows XP operating system would you check its status?:
|
||||
- device manager
|
||||
In one pixel, how many different colours of light are there?:
|
||||
- Three
|
||||
- 3
|
||||
In what year did ARPANET became operational?:
|
||||
- 1969
|
||||
In what year was DOS created?:
|
||||
- 1981
|
||||
In what year was the "@" chosen for its use in e-mail addresses?:
|
||||
- 1972
|
||||
In what year was the Domain Name System created?:
|
||||
- 1983
|
||||
In which year was ASCII formed?:
|
||||
- 1963
|
||||
In which year was MIDI introduced?:
|
||||
- 1983
|
||||
In which year was the Personal Computer featured as the Times 'Man of the Year'?:
|
||||
- 1982
|
||||
Inside the hard disk drive, where is the data actually stored?:
|
||||
- platter
|
||||
Internet domain registrar and web hosting company, founded by Bob Parsons in 1997?:
|
||||
- Go Daddy
|
||||
Internet-based network of content, providing articles and videos about various topics, authored by experts. Founded in 1997?:
|
||||
- About.com
|
||||
Often blocked file sharing site using the BitTorrent protocol, founded in Sweden in 2003?:
|
||||
- The Pirate Bay
|
||||
Older networks often use another type of cable, called ...?:
|
||||
- Coaxial cable
|
||||
One of the most important performance-enhancing concepts of a modern processor is called speculative execution. What other concept is this tightly associated with?:
|
||||
- Pipelining
|
||||
Provider of on-demand Internet streaming media since 1997. Started its own original programming in 2011 with the series House of Cards?:
|
||||
- Netflix
|
||||
Quattro Pro, Paradox and Trellix are part of which office suite?:
|
||||
- Corel WordPerfect
|
||||
RAM stands for random access memory and it can be static (SRAM) or dynamic (DRAM). SRAM stores a bit of data using which type of circuit?:
|
||||
- Flip-Flop
|
||||
- flip flop
|
||||
- flipflop
|
||||
Removable and rewritable electronic data storage device that can be plugged into almost any PC?:
|
||||
- USB
|
||||
Rewritable optical disk where you can save and erase data several times?:
|
||||
- Compact Disc-Rewritable
|
||||
- CD-RW
|
||||
- CD RW
|
||||
- Compact Disc Rewritable
|
||||
- Compact Disk Rewritable
|
||||
- Compact Disk-Rewritable
|
||||
Secondary storage, like the hard drive, isn't directly accessible to the CPU like primary storage. What is another name for secondary storage?:
|
||||
- auxiliary storage
|
||||
- auxiliary
|
||||
Small portable disk inside a plastic cover. It’s thicker than the floppy and needs a special drive connected to the computer?:
|
||||
- Zip Disk
|
||||
- zip drive
|
||||
- zip disc
|
||||
Social and visual discovery tool, founded by Ben Silbermann, Evan Sharp and Paul Sciarra in 2010?:
|
||||
- Pinterest
|
||||
Social networking service co-founded by Mark Zuckerberg in 2004?:
|
||||
- Facebook
|
||||
Solid electronic data storage device used in cameras, telephones, laptops, music players and video games consoles?:
|
||||
- Memory Card
|
||||
Static routes are configured by the use of the global configuration command...?:
|
||||
- IP Route
|
||||
TCP port number 80 is usually reserved for?:
|
||||
- HTTP
|
||||
The OSPF Type 1 packet is the _________ packet.:
|
||||
- Hello
|
||||
The buffers for packet processing and the running configuration file are temporarily stored in which type of router memory?:
|
||||
- RAM
|
||||
The cabinet containing the computer’s working parts is known as the...?:
|
||||
- Workstation
|
||||
- Case
|
||||
The default administrative distance for a static route is...?:
|
||||
- One
|
||||
- 1
|
||||
The first hard disks, created in the 1950s, could be up to 20 inches in diameter. Which company invented the hard disk?:
|
||||
- IBM
|
||||
The input device that has the monitor screen covered with a flexible layer is the...?:
|
||||
- Touch Screen
|
||||
- touchscreen
|
||||
The input device that rolls on a desktop and controls the position of the cursor on then on the screen is called a...?:
|
||||
- Mouse
|
||||
The memory stored in the capacitor in a __ circuit has to be constantly refreshed, and this happens several times in a second because the capacitor leaks.:
|
||||
- DRAM
|
||||
The moment you turn on your computer, it begins to access its memory. BIOS, the software that boots up your computer, is located in which type of memory?:
|
||||
- ROM
|
||||
The scanning technology, used in banks, to read the numbers at the bottom of checks is...?:
|
||||
- MICR
|
||||
The small program which allows a piece of computer hardware to work with the operating system is called what?:
|
||||
- driver
|
||||
This unit of a computer system is the unit where the actual execution of instructions takes place during processing operation?:
|
||||
- Arithmetic Logic Unit
|
||||
- Arithmetic Logic
|
||||
To enable RIP routing for a specific subnet, the configuration command network 192.168.5.64 was entered by the network administrator. What address, if any, appears in the running configuration file to identify this network?:
|
||||
- 192.168.5.0
|
||||
Video-sharing site that was founded by three former PayPal employees in February 2005.:
|
||||
- YouTube
|
||||
Virtual memory acts like RAM, but it is actually a process or program that creates a paging file to move items from RAM into that file. Where does it create the paging file?:
|
||||
- hard disk
|
||||
- hard drive
|
||||
- hard disc
|
||||
What do you call "suction like cups for attaching a phone handset to computer equipment"?:
|
||||
- acoustic coupler
|
||||
What does CE in Windows CE, OS from Microsoft for palmtops, stand for?:
|
||||
- Consumer Electronics
|
||||
What does HTML stand for?:
|
||||
- Hyper text markup language
|
||||
What does UPS stand for?:
|
||||
- Uninterruptible Power Supply
|
||||
What error is "Internal error/server-configuration problems"?:
|
||||
- Error 500
|
||||
- 500
|
||||
What error is "Site Access Forbidden/Password Protected"?:
|
||||
- Error 403
|
||||
- 403
|
||||
What error is "Site not found -in HTTP"?:
|
||||
- Error 404
|
||||
- 404
|
||||
What is CIH also known as?:
|
||||
- Chernobyl Virus
|
||||
What is a program which translates from one high-level to a machine level?:
|
||||
- Compiler
|
||||
What is a rigid, magnetically sensitive disk that spins rapidly and continuously inside the computer chassis or in a separate box connected to the computer housing?:
|
||||
- Hard Disk
|
||||
- hard drive
|
||||
- hard disc
|
||||
What is commonly regarded as the first inexpensive and commercially available computer with GUI and Mouse?:
|
||||
- Apple Lisa
|
||||
What is the address given to a computer connected to a network called?:
|
||||
- IP Address
|
||||
- IP
|
||||
What is the basic unit of measurement storage in computer science?:
|
||||
- Byte
|
||||
What is the battery used to change date/time of system?:
|
||||
- BIOS battery
|
||||
- BIOS
|
||||
What is the internal storage of a computer?:
|
||||
- Hard Disk
|
||||
- hard drive
|
||||
- hard disc
|
||||
What is the largest piece of the computer; it is also the one that has the fewest electronic components?:
|
||||
- Case
|
||||
What is the maximum number of peripheral devices which can be connected through a single USB port?:
|
||||
- 127
|
||||
What is the name of Linux's Mascot?:
|
||||
- Tux
|
||||
What is the name of the software that allows us to browse through web pages called?:
|
||||
- Browser
|
||||
What is the phrase for how often your screen's image is redrawn?:
|
||||
- Refresh Rate
|
||||
What numeric base system was used by the Honeywell-800?:
|
||||
- octal
|
||||
What password is cleared by changing the jumper setting in the motherboard?:
|
||||
- CMOS
|
||||
What type of keyboard is used to transmit digital signals which correspond to sample sounds?:
|
||||
- MIDI
|
||||
What was the first ARPANET message?:
|
||||
- lo
|
||||
What was the original name of Netscape Navigator?:
|
||||
- Mozilla
|
||||
When a key is pressed on the keyboard, which standard is used for converting the keystroke into the corresponding bits?:
|
||||
- ANSI
|
||||
When an application fires up, the application is loaded into...?:
|
||||
- RAM
|
||||
When looking at your computer's memory, you will come across the storage hierarchy, which separates storage into primary, secondary, and tertiary. Primary storage refers to memory that is directly accessible to the CPU. What is another name for primary storage?:
|
||||
- Main Memory
|
||||
- Main
|
||||
When you look at a processor, you normally see a plastic or ceramic case with metal pins and possibly other metal parts. However, the active component inside is made of a different material - which one?:
|
||||
- silicon
|
||||
Which company first manufactured CDs?:
|
||||
- Philips
|
||||
Which company first produced the 3 1/2 inch floppy disk?:
|
||||
- Sony
|
||||
Which company invented the floppy disk?:
|
||||
- IBM
|
||||
Which device allows your computer to talk to other computers over a telephone line as well as access the internet?:
|
||||
- Modem
|
||||
Which subnet mask would be used as the classful mask for the IP address 128.107.52.27?:
|
||||
- 255.255.0.0
|
||||
Which subnet mask would be used as the classful mask for the IP address 192.135.250.27?:
|
||||
- 255.255.255.0
|
||||
Which value represents the “trustworthiness” of a route and is used to determine which route to install into the routing table when there are multiple routes toward the same destination?:
|
||||
- Administrative distance
|
||||
Who invented the computer mouse?:
|
||||
- Douglas Engelbart
|
||||
"[Acronyms]What does CD-R stand for?":
|
||||
- Compact Disc-Recordable
|
||||
- Compact Disc Recordable
|
||||
- Compact Disk-Recordable
|
||||
- Compact Disk Recordable
|
||||
"[Acronyms]What does CD-ROM stand for?":
|
||||
- Compact Disc-Read Only Memory
|
||||
- Compact Disc Read Only Memory
|
||||
- Compact Disk-Read Only Memory
|
||||
- Compact Disk Read Only Memory
|
||||
"[Acronyms]What does CD-RW stand for?":
|
||||
- Compact Disc-Rewritable
|
||||
- Compact Disc Rewritable
|
||||
- Compact Disk-Rewritable
|
||||
- Compact Disk Rewritable
|
||||
"[Acronyms]What does CPU stand for?":
|
||||
- Central Processing Unit
|
||||
"[Acronyms]What does CRT stand for?":
|
||||
- Cathode Ray Tube
|
||||
"[Acronyms]What does DVI stand for?":
|
||||
- Digital Visual Interface
|
||||
"[Acronyms]What does EOF stand for?":
|
||||
- End of File
|
||||
"[Acronyms]What does IP stand for?":
|
||||
- Internet Protocol
|
||||
"[Acronyms]What does ISO stand for?":
|
||||
- International Standard Organization
|
||||
"[Acronyms]What does ISP stand for?":
|
||||
- Internet Service Provider
|
||||
"[Acronyms]What does LCD stand for?":
|
||||
- Liquid Crystal Display
|
||||
"[Acronyms]What does LPT stand for?":
|
||||
- Line Printer
|
||||
"[Acronyms]What does MTBF stand for?":
|
||||
- Mean Time Between Failures
|
||||
"[Acronyms]What does NIC stand for?":
|
||||
- Network Interface Card
|
||||
"[Acronyms]What does PAN stand for?":
|
||||
- Personal Area Network
|
||||
"[Acronyms]What does RAM stand for?":
|
||||
- Random Access Memory
|
||||
"[Acronyms]What does ROM stand for?":
|
||||
- Read Only Memory
|
||||
"[Acronyms]What does SCSI port (pronounced skuzzy) stand for?":
|
||||
- Small Computer System Interface
|
||||
"[Acronyms]What does SCSI stand for?":
|
||||
- Small Computer System Interface
|
||||
"[Acronyms]What does SDLC stand for in Networking protocol?":
|
||||
- Synchronous Data Link Control
|
||||
"[Acronyms]What does SDRAM stand for?":
|
||||
- Synchronous Dynamic Random Access Memory
|
||||
"[Acronyms]What does Spool stand for?":
|
||||
- Simultaneous Peripheral Output On-Line
|
||||
- Simultaneous Peripheral Output On Line
|
||||
"[Acronyms]What does TCP stand for?":
|
||||
- Transmission Control Protocol
|
||||
"[Acronyms]What does USB stand for?":
|
||||
- Universal Serial Bus
|
||||
"[Acronyms]What does VDU stand for?":
|
||||
- Visual Display Unit
|
||||
"[Acronyms]What does modem stand for?":
|
||||
- Modulator Demodulater
|
||||
"[Acronyms]What does www stand for?":
|
||||
- World Wide Web
|
||||
"[Input/Output]Digital Camera?":
|
||||
- Input
|
||||
"[Input/Output]Graphics Tablet?":
|
||||
- Input
|
||||
"[Input/Output]Inkjet Printer?":
|
||||
- Output
|
||||
"[Input/Output]Keyboard?":
|
||||
- Input
|
||||
"[Input/Output]Laser Printer?":
|
||||
- Output
|
||||
"[Input/Output]Monitor?":
|
||||
- Output
|
||||
"[Input/Output]Mouse?":
|
||||
- Input
|
||||
"[Input/Output]Scanner?":
|
||||
- Input
|
||||
"[Input/Output]Speakers?":
|
||||
- Output
|
||||
"[Input/Output]Touchpad?":
|
||||
- Input
|
||||
"[Input/Output]Trackball?":
|
||||
- Input
|
||||
"[Programming Languages]A popular scripting language for computers, often run in web browsers to create or alter dynamic content. It was developed by Brendan Eich for Netscape in 1995.":
|
||||
- Javascript
|
||||
"[Programming Languages]Compiled computer programming language created in 1959 and primarily used in business, finance, and administrative systems.":
|
||||
- COBOL
|
||||
"[Programming Languages]Computer language since 1982 for creating vector graphics, best known for its use as a page description language in the electronic and desktop publishing areas.":
|
||||
- Postscript
|
||||
"[Programming Languages]Computer scripting language originally developed by Macromedia Inc., now primarily used in Adobe Flash Player":
|
||||
- ActionScript
|
||||
"[Programming Languages]Dynamic, object-oriented, general-purpose programming language with a focus on shortness and ease of use. It was influenced by Perl, Ada and Lisp and designed by Yukihiro Matsumoto in 1995.":
|
||||
- Ruby
|
||||
"[Programming Languages]Educational programming language, designed in 1967 and modeled on the LISP programming language.":
|
||||
- Logo
|
||||
"[Programming Languages]General-purpose, object-oriented programming language designed by Brad Cox and Tom Love. It is the main programming language used by Apple for the OS X and iOS operating systems,and their application programming interfaces.":
|
||||
- Objective-C
|
||||
- objective c
|
||||
- objectivec
|
||||
"[Programming Languages]Influential programming language, published in 1970 by Niklaus Wirth as a small and efficient language intended to encourage good programming practices using structured programming and data structuring.":
|
||||
- Pascal
|
||||
"[Programming Languages]Interpreted programming language for text processing and data extraction and was very popular in the late 1970s and 1980s. It is a standard feature of most Unix-like operating systems.":
|
||||
- AWK
|
||||
"[Programming Languages]Language originally developed by Borland as a rapid application development tool for Windows as a successor to Borland Pascal.":
|
||||
- Delphi
|
||||
"[Programming Languages]Language that appeared in 1985, originally to create database and business programs operated primarily under DOS.":
|
||||
- Clipper
|
||||
"[Programming Languages]Multi-paradigm numerical computing environment and fourth-generation programming language since the late 70s, primarily intended for numerical computing.":
|
||||
- MATLAB
|
||||
"[Programming Languages]Multi-paradigm, high level programming language launched by Microsoft in 2002 to make programs for Windows in a an 'drag-and-drop' interface.":
|
||||
- Visual Basic .NET
|
||||
"[Programming Languages]Not a programming language, but a popular group of interrelated client-side web development techniques to exchange data without full webpage reloads.":
|
||||
- Ajax
|
||||
"[Programming Languages]One of the first programming languages, designed by Kemeny and Kurtz in 1964. Its design philosophy emphasizes ease of use and became widespread on microcomputers in the mid-1970s and 1980s.":
|
||||
- BASIC
|
||||
"[Programming Languages]One of the most popular programming languages, created by James Gosling at Sun Microsystems in 1995. It is platform independent and based upon C and C++.":
|
||||
- Java
|
||||
"[Programming Languages]One of the most widely used and influentual programming languages of all time. It is an imperative and compiled language, initially developed by Dennis Ritchie and Ken Thompson between 1969 and 1973 at AT&T Bell Labs.":
|
||||
- C
|
||||
"[Programming Languages]One of the oldest high-level programming languages in widespread use today. It was designed by John McCarthy in 1958 and quickly became a favored programming language for artificial intelligence":
|
||||
- LISP
|
||||
"[Programming Languages]Popular high-level, general-purpose, interpreted, dynamic programming language created by Larry Wall in 1987. It is often used in CGI and text processing (e.g. parsing).":
|
||||
- Perl
|
||||
"[Programming Languages]Programming language and software environment for statistical computing and graphics. It was introduced in 1993 and has become popular among statisticians and data miners.":
|
||||
- R
|
||||
"[Programming Languages]Programming language and web application development platform invented in 1995 and purchased by Adobe in 2006. It was originally designed to connect simple HTML pages to a database.":
|
||||
- ColdFusion
|
||||
"[Programming Languages]Purely functional programming language since 1990. It was named after US mathematician and logican H. Curry and uses the Greek letter lambda as its logo.":
|
||||
- Haskell
|
||||
"[Programming Languages]Scripting and object-oriented programming language developed by John H. Thompson for use in Adobe Director":
|
||||
- Lingo
|
||||
"[Programming Languages]Server-side script engine that uses the VBScript or JScript languages for dynamically generated web pages. It was created by Microsoft in the mid 1990s and succeeded by a .NET version in 2002.":
|
||||
- ASP
|
||||
"[Programming Languages]The most widespread logic programming language, desgined by Alain Colmerauer in 1972. Unlike many programming languages, it's declarative.":
|
||||
- Prolog
|
||||
"[Programming Languages]Very popular general-purpose, imperative programming language in high-performance computing (e.g. scientific use and supercomputers). It was initiated by John Backus and IBM in 1957.":
|
||||
- Fortran
|
||||
"[Programming Languages]Widely used general-purpose, high-level programming language created by Guido van Rossum in 1991. Its design philosophy emphasizes code readability and its syntax allows to express concepts in relatively few lines of code.":
|
||||
- Python
|
||||
"[Programming Languages]Widely used programming language designed for managing data held in a relational database management system. It was initially developed Chamberlin and Boyce at IBM in the early 1970s.":
|
||||
- SQL
|
||||
2189
redbot/cogs/trivia/data/lists/disney.yaml
Normal file
2189
redbot/cogs/trivia/data/lists/disney.yaml
Normal file
File diff suppressed because it is too large
Load Diff
1106
redbot/cogs/trivia/data/lists/dota2abilities.yaml
Normal file
1106
redbot/cogs/trivia/data/lists/dota2abilities.yaml
Normal file
File diff suppressed because it is too large
Load Diff
414
redbot/cogs/trivia/data/lists/dota2items.yaml
Normal file
414
redbot/cogs/trivia/data/lists/dota2items.yaml
Normal file
@@ -0,0 +1,414 @@
|
||||
AUTHOR: JennJenn
|
||||
What item is this? (removed from game) https://i.imgur.com/hze6GhN.png:
|
||||
- Poor Man's Shield
|
||||
- PMS
|
||||
What item is this? (removed from game) https://i.imgur.com/vXFECRh.png:
|
||||
- Iron Talon
|
||||
What item is this? https://i.imgur.com/0Li6O8N.png:
|
||||
- Refresher Orb
|
||||
What item is this? https://i.imgur.com/0nQt3on.png:
|
||||
- Flying Courier (Dire)
|
||||
- Flying Courier Dire
|
||||
What item is this? https://i.imgur.com/11IYBpl.png:
|
||||
- Power Treads (Intelligence)
|
||||
- Power Treads Intelligence
|
||||
What item is this? https://i.imgur.com/1DjDKYH.png:
|
||||
- Yasha
|
||||
What item is this? https://i.imgur.com/1GWm8o6.png:
|
||||
- Necronomicon 3
|
||||
What item is this? https://i.imgur.com/1aGrpuH.png:
|
||||
- Wraith Band
|
||||
What item is this? https://i.imgur.com/1dXNyaw.png:
|
||||
- Observer and Sentry Wards
|
||||
What item is this? https://i.imgur.com/1eXRfIg.png:
|
||||
- Smoke of Deceit
|
||||
What item is this? https://i.imgur.com/226lkTR.png:
|
||||
- Buckler
|
||||
What item is this? https://i.imgur.com/2XowFK1.png:
|
||||
- Band of Elvenskin
|
||||
What item is this? https://i.imgur.com/3KCIBDO.png:
|
||||
- Veil of Discord
|
||||
What item is this? https://i.imgur.com/3bVcC3l.png:
|
||||
- Nullifier
|
||||
What item is this? https://i.imgur.com/3dx0MLj.png:
|
||||
- Satanic
|
||||
What item is this? https://i.imgur.com/3hwvY3U.png:
|
||||
- Infused Raindrop
|
||||
What item is this? https://i.imgur.com/3u7l2pR.png:
|
||||
- Belf of Strength
|
||||
What item is this? https://i.imgur.com/430kekp.png:
|
||||
- Hand of Midas
|
||||
What item is this? https://i.imgur.com/4EIKWON.png:
|
||||
- Boots of Travel 2
|
||||
What item is this? https://i.imgur.com/5dfDXym.png:
|
||||
- Aegis of the Immortal
|
||||
What item is this? https://i.imgur.com/5eeAXJC.png:
|
||||
- Aghanim's Scepter
|
||||
What item is this? https://i.imgur.com/5hZUcQQ.png:
|
||||
- Magic Wand
|
||||
What item is this? https://i.imgur.com/6Bj6Eiz.png:
|
||||
- Maelstrom
|
||||
What item is this? https://i.imgur.com/6YGgKGH.png:
|
||||
- Ring of Protection
|
||||
What item is this? https://i.imgur.com/6aJkxtG.png:
|
||||
- Mekansm
|
||||
What item is this? https://i.imgur.com/6uNaTtD.png:
|
||||
- Faerie Fire
|
||||
What item is this? https://i.imgur.com/77S9U75.png:
|
||||
- Tome of Knowledge
|
||||
What item is this? https://i.imgur.com/7MQvg5g.png:
|
||||
- Boots of Travel 1
|
||||
What item is this? https://i.imgur.com/7Sp3W66.png:
|
||||
- Eul's Scepter of Divinity
|
||||
What item is this? https://i.imgur.com/7SvVqRK.png:
|
||||
- Ring of Basilius (Active)
|
||||
- Ring of Basilius Active
|
||||
What item is this? https://i.imgur.com/7eicbbk.png:
|
||||
- Meteor Hammer
|
||||
What item is this? https://i.imgur.com/8X9936w.png:
|
||||
- Blades of Attack
|
||||
What item is this? https://i.imgur.com/8nT3p2e.png:
|
||||
- Manta Style
|
||||
What item is this? https://i.imgur.com/9VtRTBl.png:
|
||||
- Crimson Guard
|
||||
What item is this? https://i.imgur.com/9eAs1dm.png:
|
||||
- Sange and Yasha
|
||||
What item is this? https://i.imgur.com/9g6jw0X.png:
|
||||
- Dagon 3
|
||||
What item is this? https://i.imgur.com/AG7Ii56.png:
|
||||
- Helm of the Dominator
|
||||
What item is this? https://i.imgur.com/ASNIrpm.png:
|
||||
- Demon Edge
|
||||
What item is this? https://i.imgur.com/AWxOnXw.png:
|
||||
- Solar Crest
|
||||
What item is this? https://i.imgur.com/B4AJKcj.png:
|
||||
- Bottle (Medium)
|
||||
- Bottle Medium
|
||||
What item is this? https://i.imgur.com/BqXyEWi.png:
|
||||
- Eaglesong
|
||||
What item is this? https://i.imgur.com/C6Ch4mV.png:
|
||||
- Eye of Skadi
|
||||
What item is this? https://i.imgur.com/C6vL76q.png:
|
||||
- Force Staff
|
||||
What item is this? https://i.imgur.com/CEkN0FS.png:
|
||||
- Abyssal Blade
|
||||
What item is this? https://i.imgur.com/CqtxuPE.png:
|
||||
- Gloves of Haste
|
||||
What item is this? https://i.imgur.com/DEZQLXo.png:
|
||||
- Medallion of Courage
|
||||
What item is this? https://i.imgur.com/DHILKex.png:
|
||||
- Stout Shield
|
||||
What item is this? https://i.imgur.com/DHqdudG.png:
|
||||
- Mithril Hammer
|
||||
What item is this? https://i.imgur.com/DKAS0kV.png:
|
||||
- Slippers of Agility
|
||||
What item is this? https://i.imgur.com/DmlQ31Y.png:
|
||||
- Blight Stone
|
||||
What item is this? https://i.imgur.com/E2tg3xE.png:
|
||||
- Ring of Health
|
||||
What item is this? https://i.imgur.com/E9OmVm3.png:
|
||||
- Daedelus
|
||||
What item is this? https://i.imgur.com/EdJKpKH.png:
|
||||
- Bloodthorn
|
||||
What item is this? https://i.imgur.com/EuIAVjM.png:
|
||||
- Vitality Booster
|
||||
What item is this? https://i.imgur.com/FBRqnb9.png:
|
||||
- Bottle (Arcane)
|
||||
- Bottle Arcane
|
||||
What item is this? https://i.imgur.com/FGLZkBq.png:
|
||||
- Tranquil Boots (Inactive)
|
||||
- Tranquil Boots Inactive
|
||||
What item is this? https://i.imgur.com/Fk2AqPs.png:
|
||||
- Iron Branch
|
||||
What item is this? https://i.imgur.com/FlVerQT.png:
|
||||
- Headdress
|
||||
What item is this? https://i.imgur.com/Fmnkr53.png:
|
||||
- Claymore
|
||||
What item is this? https://i.imgur.com/GsgTiUw.png:
|
||||
- Shadow Blade
|
||||
What item is this? https://i.imgur.com/GvtjXIF.png:
|
||||
- Assault Cuirass
|
||||
What item is this? https://i.imgur.com/H5nRu05.png:
|
||||
- Quelling Blade
|
||||
What item is this? https://i.imgur.com/HDu0rAD.png:
|
||||
- Bloodstone
|
||||
What item is this? https://i.imgur.com/HLr6SQb.png:
|
||||
- Diffusal Blade 2
|
||||
What item is this? https://i.imgur.com/HgJHyfk.png:
|
||||
- Void Stone
|
||||
What item is this? https://i.imgur.com/HikbhwT.png:
|
||||
- Ethereal Blade
|
||||
What item is this? https://i.imgur.com/Hm7z9Xn.png:
|
||||
- Bottle (Empty)
|
||||
- Bottle Empty
|
||||
What item is this? https://i.imgur.com/HrKThmN.png:
|
||||
- Orchid Malevolence
|
||||
What item is this? https://i.imgur.com/HuUqvIf.png:
|
||||
- Scythe of Vyse
|
||||
What item is this? https://i.imgur.com/IL1hH1m.png:
|
||||
- Crystalys
|
||||
What item is this? https://i.imgur.com/JUbevw4.png:
|
||||
- Staff of Wizardry
|
||||
What item is this? https://i.imgur.com/JYBiGVx.png:
|
||||
- Ring of Aquila (Inactive)
|
||||
- Ring of Aquila Inactive
|
||||
What item is this? https://i.imgur.com/JbKeDUc.png:
|
||||
- Urn of Shadows
|
||||
What item is this? https://i.imgur.com/JpqHPSA.png:
|
||||
- Bracer
|
||||
What item is this? https://i.imgur.com/KFBNr2l.png:
|
||||
- Soul Ring
|
||||
What item is this? https://i.imgur.com/KFNb72Y.png:
|
||||
- Reaver
|
||||
What item is this? https://i.imgur.com/KL6jON7.png:
|
||||
- Mask of Madness
|
||||
What item is this? https://i.imgur.com/KLGzvMb.png:
|
||||
- Bottle (Small)
|
||||
- Bottle Small
|
||||
What item is this? https://i.imgur.com/KcW7edy.png:
|
||||
- Town Portal Scroll
|
||||
- TP Scroll
|
||||
What item is this? https://i.imgur.com/LSVesWo.png:
|
||||
- Guardian Greaves
|
||||
What item is this? https://i.imgur.com/LVpcOnf.png:
|
||||
- Quarterstaff
|
||||
What item is this? https://i.imgur.com/LkabC8q.png:
|
||||
- Hyperstone
|
||||
What item is this? https://i.imgur.com/M6EbZFP.png:
|
||||
- Hurricane Pike
|
||||
What item is this? https://i.imgur.com/M9fRKkB.png:
|
||||
- Perseverance
|
||||
What item is this? https://i.imgur.com/MIDqGCz.png:
|
||||
- Cheese
|
||||
What item is this? https://i.imgur.com/MQ6pxQd.png:
|
||||
- Helm of Iron Will
|
||||
What item is this? https://i.imgur.com/MudmQ6R.png:
|
||||
- Heart of Tarrasque
|
||||
What item is this? https://i.imgur.com/NUeLPgT.png:
|
||||
- Dragon Lance
|
||||
What item is this? https://i.imgur.com/NbeuShM.png:
|
||||
- Flying Courier (Radiant)
|
||||
- Flying Courier Radiant
|
||||
What item is this? https://i.imgur.com/NhzX71W.png:
|
||||
- Octarine Core
|
||||
What item is this? https://i.imgur.com/NkYZgr5.png:
|
||||
- Tango (Shared)
|
||||
- Tango Shared
|
||||
- Shared Tango
|
||||
What item is this? https://i.imgur.com/Nl1u43a.png:
|
||||
- Echo Sabre
|
||||
What item is this? https://i.imgur.com/NrEdGsn.png:
|
||||
- Heaven's Halberd
|
||||
What item is this? https://i.imgur.com/O4E1IR5.png:
|
||||
- Desolator
|
||||
What item is this? https://i.imgur.com/Ov7Vjle.png:
|
||||
- Blade of Alacrity
|
||||
What item is this? https://i.imgur.com/OzcxrY5.png:
|
||||
- Black King Bar
|
||||
- BKB
|
||||
What item is this? https://i.imgur.com/Pote0DA.png:
|
||||
- Point Booster
|
||||
What item is this? https://i.imgur.com/QNFFGLh.png:
|
||||
- Silver Edge
|
||||
What item is this? https://i.imgur.com/RGlRQJe.png:
|
||||
- Bottle (Invisibility)
|
||||
- Bottle Invisibility
|
||||
What item is this? https://i.imgur.com/RM3sSIz.png:
|
||||
- Kaya
|
||||
What item is this? https://i.imgur.com/Re67cR1.png:
|
||||
- Monkey King Bar
|
||||
- MKB
|
||||
What item is this? https://i.imgur.com/TNrZvq8.png:
|
||||
- Shadow Amulet
|
||||
What item is this? https://i.imgur.com/TmZVLYT.png:
|
||||
- Lotus Orb
|
||||
What item is this? https://i.imgur.com/Tqg4c3O.png:
|
||||
- Bottle (Illusion)
|
||||
- Bottle Illusion
|
||||
What item is this? https://i.imgur.com/U9f6T8O.png:
|
||||
- Mantle of Intelligence
|
||||
What item is this? https://i.imgur.com/UJ52OSo.png:
|
||||
- Diffusal Blade 1
|
||||
What item is this? https://i.imgur.com/UhHdUrz.png:
|
||||
- Energy Booster
|
||||
What item is this? https://i.imgur.com/V6kBeNh.png:
|
||||
- Dagon 2
|
||||
What item is this? https://i.imgur.com/VFdPRUD.png:
|
||||
- Divine Rapier
|
||||
What item is this? https://i.imgur.com/VNmfB2T.png:
|
||||
- Shiva's Guard
|
||||
What item is this? https://i.imgur.com/VtNBM6g.png:
|
||||
- Animal Courier (Radiant)
|
||||
- Courier Radiant
|
||||
- Animal Courier Radiant
|
||||
What item is this? https://i.imgur.com/Vu3eNfk.png:
|
||||
- Sentry Ward
|
||||
What item is this? https://i.imgur.com/VwXSKr8.png:
|
||||
- Wind Lace
|
||||
What item is this? https://i.imgur.com/W2F2SUd.png:
|
||||
- Radiance (Active)
|
||||
- Radiance Active
|
||||
What item is this? https://i.imgur.com/WaKy1Pj.png:
|
||||
- Tango
|
||||
What item is this? https://i.imgur.com/WwEfwWi.png:
|
||||
- Necronomicon 1
|
||||
What item is this? https://i.imgur.com/XGkphzs.png:
|
||||
- Observer and Sentry Wards
|
||||
What item is this? https://i.imgur.com/XYIEKMi.png:
|
||||
- Power Treads (Agility)
|
||||
- Power Treads Agility
|
||||
What item is this? https://i.imgur.com/YsrEZDL.png:
|
||||
- Moon Shard
|
||||
What item is this? https://i.imgur.com/ZidkeLE.png:
|
||||
- Javelin
|
||||
What item is this? https://i.imgur.com/ZjhX5T8.png:
|
||||
- Aether Lens
|
||||
What item is this? https://i.imgur.com/ZoIjUQF.png:
|
||||
- Dagon 4
|
||||
What item is this? https://i.imgur.com/aQ4ZSIi.png:
|
||||
- Sage's Mask
|
||||
What item is this? https://i.imgur.com/atVJCS9.png:
|
||||
- Rod of Atos
|
||||
What item is this? https://i.imgur.com/bdVdrp3.png:
|
||||
- Ring of Aquila (Active)
|
||||
- Ring of Aquila Active
|
||||
What item is this? https://i.imgur.com/cJ3dEwh.png:
|
||||
- Oblivion Staff
|
||||
What item is this? https://i.imgur.com/cLS2cZD.png:
|
||||
- Vanguard
|
||||
What item is this? https://i.imgur.com/cYj1mr0.png:
|
||||
- Talisman of Evasion
|
||||
What item is this? https://i.imgur.com/cmeeK2C.png:
|
||||
- Bottle (Double Damage)
|
||||
- Bottle Double Damage
|
||||
What item is this? https://i.imgur.com/cpjr5Ez.png:
|
||||
- Butterfly
|
||||
What item is this? https://i.imgur.com/cznlrpv.png:
|
||||
- Orb of Venom
|
||||
What item is this? https://i.imgur.com/dAe8dFK.png:
|
||||
- Chainmail
|
||||
What item is this? https://i.imgur.com/dDdmPAV.png:
|
||||
- Boots of Speed
|
||||
What item is this? https://i.imgur.com/dLhmL5W.png:
|
||||
- Sacred Relic
|
||||
What item is this? https://i.imgur.com/dVDWnth.png:
|
||||
- Dust of Appearance
|
||||
What item is this? https://i.imgur.com/dvk1MCM.png:
|
||||
- Tranquil Boots (Active)
|
||||
- Tranquil Boots Active
|
||||
What item is this? https://i.imgur.com/eOSLFWz.png:
|
||||
- Cloak
|
||||
What item is this? https://i.imgur.com/f8opJQc.png:
|
||||
- Battle Fury
|
||||
What item is this? https://i.imgur.com/fcLcZyE.png:
|
||||
- Sange
|
||||
What item is this? https://i.imgur.com/fhAoSOC.png:
|
||||
- Ogre Club
|
||||
What item is this? https://i.imgur.com/gjofxoF.png:
|
||||
- Necronomicon 2
|
||||
What item is this? https://i.imgur.com/h4dZ64X.png:
|
||||
- Dagon 1
|
||||
What item is this? https://i.imgur.com/h5Gu48S.png:
|
||||
- Observer Ward
|
||||
What item is this? https://i.imgur.com/hF3mjT1.png:
|
||||
- Drum of Endurance
|
||||
What item is this? https://i.imgur.com/haXACou.png:
|
||||
- Power Treads
|
||||
What item is this? https://i.imgur.com/iYzaR71.png:
|
||||
- Bottle (Full)
|
||||
- Bottle Full
|
||||
What item is this? https://i.imgur.com/ibmZmvS.png:
|
||||
- Banana
|
||||
What item is this? https://i.imgur.com/jvUNnd1.png:
|
||||
- Pipe of Insight
|
||||
What item is this? https://i.imgur.com/kC1KzdQ.png:
|
||||
- Soul Booster
|
||||
What item is this? https://i.imgur.com/kMypuTg.png:
|
||||
- Ring of Regen
|
||||
What item is this? https://i.imgur.com/kW9IHvM.png:
|
||||
- Blink Dagger
|
||||
What item is this? https://i.imgur.com/kWErZRY.png:
|
||||
- Bottle (Regeneration)
|
||||
- Bottle Regeneration
|
||||
What item is this? https://i.imgur.com/kiXFzsz.png:
|
||||
- Spirit Vessel
|
||||
What item is this? https://i.imgur.com/ks3ysLe.png:
|
||||
- Aeon Disk
|
||||
What item is this? https://i.imgur.com/lNuWIWP.png:
|
||||
- Mjollnir
|
||||
What item is this? https://i.imgur.com/lkyWMvx.png:
|
||||
- Ultimate Orb
|
||||
What item is this? https://i.imgur.com/lpyKT7r.png:
|
||||
- Glimmer Cape
|
||||
What item is this? https://i.imgur.com/lzdpgK0.png:
|
||||
- Animal Courier (Dire)
|
||||
- Courier Dire
|
||||
- Animal Courier Dire
|
||||
What item is this? https://i.imgur.com/m0U0nlL.png:
|
||||
- Platemail
|
||||
What item is this? https://i.imgur.com/m2UA7a8.png:
|
||||
- Radiance (Inactive)
|
||||
- Radiance Inactive
|
||||
What item is this? https://i.imgur.com/mGZEMpC.png:
|
||||
- Circlet
|
||||
What item is this? https://i.imgur.com/my0MEtj.png:
|
||||
- Morbid Mask
|
||||
What item is this? https://i.imgur.com/nXn8KhO.png:
|
||||
- Power Treads (Strength)
|
||||
- Power Treads Strength
|
||||
What item is this? https://i.imgur.com/oKhuvbG.png:
|
||||
- Gauntlets of Strength
|
||||
What item is this? https://i.imgur.com/oLgqHaR.png:
|
||||
- Linken's Sphere
|
||||
What item is this? https://i.imgur.com/oentyyC.png:
|
||||
- Null Talisman
|
||||
What item is this? https://i.imgur.com/owoQWNV.png:
|
||||
- Armlet of Mordiggian (Inactive)
|
||||
- Armlet of Mordiggian
|
||||
What item is this? https://i.imgur.com/pNmAlAl.png:
|
||||
- Skull Basher
|
||||
What item is this? https://i.imgur.com/paO69Se.png:
|
||||
- Clarity
|
||||
What item is this? https://i.imgur.com/qM0dRmS.png:
|
||||
- Dagon 5
|
||||
What item is this? https://i.imgur.com/rUKqmWD.png:
|
||||
- Bottle (Bounty)
|
||||
- Bottle Bounty
|
||||
What item is this? https://i.imgur.com/rr3OllO.png:
|
||||
- Ghost Scepter
|
||||
What item is this? https://i.imgur.com/sxkItEZ.png:
|
||||
- Gem of True Sight
|
||||
What item is this? https://i.imgur.com/u9psKe0.png:
|
||||
- Mystic Staff
|
||||
What item is this? https://i.imgur.com/uk7Z8tt.png:
|
||||
- Blade Mail
|
||||
What item is this? https://i.imgur.com/unPnQTi.png:
|
||||
- Magic Stick
|
||||
What item is this? https://i.imgur.com/unPvR9W.png:
|
||||
- Ring of Basilius (Inactive)
|
||||
- Ring of Basilius Inactive
|
||||
What item is this? https://i.imgur.com/vAEHlcZ.png:
|
||||
- Robe of the Magi
|
||||
What item is this? https://i.imgur.com/vDCqBu6.png:
|
||||
- Hood of Defiance
|
||||
What item is this? https://i.imgur.com/vg0KnIq.png:
|
||||
- Recipe Scroll
|
||||
- Recipe
|
||||
What item is this? https://i.imgur.com/vvn8qPb.png:
|
||||
- Armlet of Mordiggian (Active)
|
||||
- Armlet of Mordiggian
|
||||
What item is this? https://i.imgur.com/w6qAscb.png:
|
||||
- Healing Salve
|
||||
What item is this? https://i.imgur.com/wHK4Bio.png:
|
||||
- Phase Boots
|
||||
What item is this? https://i.imgur.com/xemeapR.png:
|
||||
- Arcane Boots
|
||||
What item is this? https://i.imgur.com/xw7yLKw.png:
|
||||
- Broadsword
|
||||
What item is this? https://i.imgur.com/y8uW7V1.png:
|
||||
- Vladimir's Offering
|
||||
What item is this? https://i.imgur.com/ycsTV7m.png:
|
||||
- Enchanted Mango
|
||||
What item is this? https://i.imgur.com/z2OZqwa.png:
|
||||
- Bottle (Haste)
|
||||
- Bottle Haste
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user