mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
publish: 5.8.0
This commit is contained in:
parent
59bb841678
commit
fe815aaa2f
56 changed files with 391 additions and 722 deletions
222
README.md
222
README.md
|
@ -1,204 +1,22 @@
|
||||||
<!--This documentation was autogenerated with `python -m royalnet.generate -f markdown`.-->
|
|
||||||
|
|
||||||
# `royalpack`
|
# `royalpack`
|
||||||
|
|
||||||
## Commands
|
## Required configuration options
|
||||||
|
|
||||||
### `ciaoruozi`
|
```toml
|
||||||
|
Imgur.token =
|
||||||
Saluta Ruozi, un leggendario essere che una volta era in User Games.
|
Telegram.main_group_id =
|
||||||
|
Discord.main_channel_id =
|
||||||
### `color`
|
Dota.updater =
|
||||||
|
Peertube.instance_url =
|
||||||
Invia un colore in chat...?
|
Peertube.feed_update_timeout =
|
||||||
|
Funkwhale.instance_url =
|
||||||
### `cv`
|
Cv.displayed_role_id =
|
||||||
|
Lol.token =
|
||||||
Elenca le persone attualmente connesse alla chat vocale.
|
Lol.region =
|
||||||
|
Lol.updater =
|
||||||
### `diario`
|
Play.max_song_duration =
|
||||||
|
Steam.web_api_key =
|
||||||
Aggiungi una citazione al Diario.
|
Brawlhalla.api_key =
|
||||||
|
Brawlhalla.updater =
|
||||||
### `rage`
|
Matchmaking.mm_chat_id =
|
||||||
|
```
|
||||||
Arrabbiati per qualcosa, come una software house californiana.
|
|
||||||
|
|
||||||
> Aliases: `balurage` `madden`
|
|
||||||
|
|
||||||
### `reminder`
|
|
||||||
|
|
||||||
Ti ricorda di fare qualcosa dopo un po' di tempo.
|
|
||||||
|
|
||||||
> Aliases: `calendar`
|
|
||||||
|
|
||||||
### `ship`
|
|
||||||
|
|
||||||
Crea una ship tra due nomi.
|
|
||||||
|
|
||||||
### `smecds`
|
|
||||||
|
|
||||||
Secondo me, è colpa dello stagista...
|
|
||||||
|
|
||||||
> Aliases: `secondomeecolpadellostagista`
|
|
||||||
|
|
||||||
### `videochannel`
|
|
||||||
|
|
||||||
Converti il canale vocale in un canale video.
|
|
||||||
|
|
||||||
> Aliases: `golive` `live` `video`
|
|
||||||
|
|
||||||
### `pause`
|
|
||||||
|
|
||||||
Metti in pausa o riprendi la riproduzione di un file.
|
|
||||||
|
|
||||||
> Aliases: `resume`
|
|
||||||
|
|
||||||
### `play`
|
|
||||||
|
|
||||||
Aggiunge un url alla coda della chat vocale.
|
|
||||||
|
|
||||||
> Aliases: `p`
|
|
||||||
|
|
||||||
### `queue`
|
|
||||||
|
|
||||||
Visualizza la coda di riproduzione attuale..
|
|
||||||
|
|
||||||
> Aliases: `q`
|
|
||||||
|
|
||||||
### `skip`
|
|
||||||
|
|
||||||
Salta il file attualmente in riproduzione.
|
|
||||||
|
|
||||||
> Aliases: `s`
|
|
||||||
|
|
||||||
### `summon`
|
|
||||||
|
|
||||||
Evoca il bot in un canale vocale.
|
|
||||||
|
|
||||||
> Aliases: `cv`
|
|
||||||
|
|
||||||
### `youtube`
|
|
||||||
|
|
||||||
Cerca un video su YouTube e lo aggiunge alla coda della chat vocale.
|
|
||||||
|
|
||||||
> Aliases: `yt`
|
|
||||||
|
|
||||||
### `soundcloud`
|
|
||||||
|
|
||||||
Cerca un video su SoundCloud e lo aggiunge alla coda della chat vocale.
|
|
||||||
|
|
||||||
> Aliases: `sc`
|
|
||||||
|
|
||||||
### `emojify`
|
|
||||||
|
|
||||||
Converti un messaggio in emoji.
|
|
||||||
|
|
||||||
### `leagueoflegends`
|
|
||||||
|
|
||||||
Connetti un account di League of Legends a un account Royalnet, e visualizzane le statistiche.
|
|
||||||
|
|
||||||
> Aliases: `lol` `league`
|
|
||||||
|
|
||||||
### `diarioquote`
|
|
||||||
|
|
||||||
Cita una riga del diario.
|
|
||||||
|
|
||||||
> Aliases: `dq` `quote` `dquote`
|
|
||||||
|
|
||||||
### `peertube`
|
|
||||||
|
|
||||||
Guarda quando è uscito l'ultimo video su RoyalTube.
|
|
||||||
|
|
||||||
### `googlevideo`
|
|
||||||
|
|
||||||
Cerca un video su Google Video e lo aggiunge alla coda della chat vocale.
|
|
||||||
|
|
||||||
> Aliases: `gv`
|
|
||||||
|
|
||||||
### `yahoovideo`
|
|
||||||
|
|
||||||
Cerca un video su Yahoo Video e lo aggiunge alla coda della chat vocale.
|
|
||||||
|
|
||||||
> Aliases: `yv`
|
|
||||||
|
|
||||||
### `userinfo`
|
|
||||||
|
|
||||||
Visualizza informazioni su un utente.
|
|
||||||
|
|
||||||
> Aliases: `uinfo` `ui` `useri`
|
|
||||||
|
|
||||||
### `spell`
|
|
||||||
|
|
||||||
Genera casualmente una spell!
|
|
||||||
|
|
||||||
### `ahnonlosoio`
|
|
||||||
|
|
||||||
Ah, non lo so io!
|
|
||||||
|
|
||||||
### `eat`
|
|
||||||
|
|
||||||
Mangia qualcosa!
|
|
||||||
|
|
||||||
### `pmots`
|
|
||||||
|
|
||||||
Confondi Proto!
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
### `discord_cv`
|
|
||||||
|
|
||||||
### `discord_summon`
|
|
||||||
|
|
||||||
### `discord_play`
|
|
||||||
|
|
||||||
### `discord_skip`
|
|
||||||
|
|
||||||
### `discord_queue`
|
|
||||||
|
|
||||||
### `discord_pause`
|
|
||||||
|
|
||||||
## Page Stars
|
|
||||||
|
|
||||||
### `/api/user/list`
|
|
||||||
|
|
||||||
### `/api/user/get/{uid_str}`
|
|
||||||
|
|
||||||
### `/api/diario/list`
|
|
||||||
|
|
||||||
### `/api/diario/get/{diario_id}`
|
|
||||||
|
|
||||||
## Exception Stars
|
|
||||||
|
|
||||||
## Tables
|
|
||||||
|
|
||||||
### `diario`
|
|
||||||
|
|
||||||
### `aliases`
|
|
||||||
|
|
||||||
### `wikipages`
|
|
||||||
|
|
||||||
Wiki page properties.
|
|
||||||
|
|
||||||
Warning:
|
|
||||||
Requires PostgreSQL!
|
|
||||||
|
|
||||||
### `wikirevisions`
|
|
||||||
|
|
||||||
A wiki page revision.
|
|
||||||
|
|
||||||
Warning:
|
|
||||||
Requires PostgreSQL!
|
|
||||||
|
|
||||||
### `bios`
|
|
||||||
|
|
||||||
### `reminder`
|
|
||||||
|
|
||||||
### `triviascores`
|
|
||||||
|
|
||||||
### `mmevents`
|
|
||||||
|
|
||||||
### `mmresponse`
|
|
||||||
|
|
||||||
### `leagueoflegends`
|
|
||||||
|
|
308
poetry.lock
generated
308
poetry.lock
generated
|
@ -233,7 +233,7 @@ description = "Coroutine-based network library"
|
||||||
name = "gevent"
|
name = "gevent"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
|
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
|
||||||
version = "20.4.0"
|
version = "20.5.0"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
cffi = ">=1.12.2"
|
cffi = ">=1.12.2"
|
||||||
|
@ -275,26 +275,6 @@ optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "HTTP/2 State-Machine based protocol implementation"
|
|
||||||
name = "h2"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.2.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
hpack = ">=3.0,<4"
|
|
||||||
hyperframe = ">=5.2.0,<6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Pure-Python HPACK header compression"
|
|
||||||
name = "hpack"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.0.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "A collection of framework independent HTTP protocol utils."
|
description = "A collection of framework independent HTTP protocol utils."
|
||||||
|
@ -315,14 +295,6 @@ version = "8.2"
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyreadline = "*"
|
pyreadline = "*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "HTTP/2 framing layer for Python"
|
|
||||||
name = "hyperframe"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "5.2.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||||
|
@ -331,68 +303,6 @@ optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "2.9"
|
version = "2.9"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "An implementation of JSON Schema validation for Python"
|
|
||||||
name = "jsonschema"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "3.2.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
attrs = ">=17.4.0"
|
|
||||||
pyrsistent = ">=0.14.0"
|
|
||||||
setuptools = "*"
|
|
||||||
six = ">=1.11.0"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
|
|
||||||
format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A logging replacement for Python"
|
|
||||||
name = "logbook"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.5.3"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
all = ["redis", "brotli", "pytest (>4.0)", "execnet (>=1.0.9)", "cython", "pyzmq", "pytest-cov (>=2.6)", "sqlalchemy", "jinja2"]
|
|
||||||
compression = ["brotli"]
|
|
||||||
dev = ["pytest-cov (>=2.6)", "pytest (>4.0)", "cython"]
|
|
||||||
execnet = ["execnet (>=1.0.9)"]
|
|
||||||
jinja = ["jinja2"]
|
|
||||||
redis = ["redis"]
|
|
||||||
sqlalchemy = ["sqlalchemy"]
|
|
||||||
test = ["pytest-cov (>=2.6)", "pytest (>4.0)"]
|
|
||||||
zmq = ["pyzmq"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "A Python Matrix client library, designed according to sans I/O principles."
|
|
||||||
name = "matrix-nio"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.6"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
attrs = "*"
|
|
||||||
future = "*"
|
|
||||||
h11 = "*"
|
|
||||||
h2 = "*"
|
|
||||||
jsonschema = "*"
|
|
||||||
logbook = "*"
|
|
||||||
pycryptodome = "*"
|
|
||||||
unpaddedbase64 = "*"
|
|
||||||
|
|
||||||
[package.dependencies.aiohttp]
|
|
||||||
python = ">=3.6"
|
|
||||||
version = "*"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
e2e = ["python-olm (>=3.1.0)", "peewee (>=3.9.5)", "cachetools", "atomicwrites"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "multidict implementation"
|
description = "multidict implementation"
|
||||||
|
@ -441,14 +351,6 @@ optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
version = "2.20"
|
version = "2.20"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Cryptographic library for Python"
|
|
||||||
name = "pycryptodome"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
version = "3.9.7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Python binding to the Networking and Cryptography (NaCl) library"
|
description = "Python binding to the Networking and Cryptography (NaCl) library"
|
||||||
|
@ -482,17 +384,6 @@ optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2.1"
|
version = "2.1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Persistent/Functional/Immutable data structures"
|
|
||||||
name = "pyrsistent"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "0.16.0"
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "Extensions to the standard Python datetime module"
|
description = "Extensions to the standard Python datetime module"
|
||||||
|
@ -521,7 +412,7 @@ description = "We have made you a wrapper you can't refuse"
|
||||||
name = "python-telegram-bot"
|
name = "python-telegram-bot"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "12.6.1"
|
version = "12.7"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
certifi = "*"
|
certifi = "*"
|
||||||
|
@ -548,7 +439,7 @@ description = "Alternative regular expression module, to replace re."
|
||||||
name = "regex"
|
name = "regex"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2020.4.4"
|
version = "2020.5.7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
|
@ -588,7 +479,7 @@ description = "A multipurpose bot and web framework"
|
||||||
name = "royalnet"
|
name = "royalnet"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8,<4.0"
|
python-versions = ">=3.8,<4.0"
|
||||||
version = "5.7.7"
|
version = "5.8.7"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
dateparser = ">=0.7.2,<0.8.0"
|
dateparser = ">=0.7.2,<0.8.0"
|
||||||
|
@ -614,10 +505,6 @@ version = ">=0.9,<0.10"
|
||||||
optional = true
|
optional = true
|
||||||
version = ">=0.2.0,<0.3.0"
|
version = ">=0.2.0,<0.3.0"
|
||||||
|
|
||||||
[package.dependencies.matrix-nio]
|
|
||||||
optional = true
|
|
||||||
version = ">=0.6,<0.7"
|
|
||||||
|
|
||||||
[package.dependencies.psycopg2_binary]
|
[package.dependencies.psycopg2_binary]
|
||||||
optional = true
|
optional = true
|
||||||
version = ">=2.8.4,<3.0.0"
|
version = ">=2.8.4,<3.0.0"
|
||||||
|
@ -782,19 +669,11 @@ description = "tzinfo object for the local timezone"
|
||||||
name = "tzlocal"
|
name = "tzlocal"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2.0.0"
|
version = "2.1"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pytz = "*"
|
pytz = "*"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "main"
|
|
||||||
description = "Unpadded Base64"
|
|
||||||
name = "unpaddedbase64"
|
|
||||||
optional = false
|
|
||||||
python-versions = "*"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
|
@ -866,10 +745,10 @@ description = "YouTube video downloader"
|
||||||
name = "youtube-dl"
|
name = "youtube-dl"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2020.3.24"
|
version = "2020.5.8"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "c05aace99f49203f824c7f6cdc5ed816fd139935673d8b01c4275eb14f45e590"
|
content-hash = "d8d544d6f79b7389ef160d65a596fd18e07ab31bd035d1ebfc2cf3dbb9c36a0f"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
|
@ -1019,30 +898,28 @@ future = [
|
||||||
{file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
|
{file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"},
|
||||||
]
|
]
|
||||||
gevent = [
|
gevent = [
|
||||||
{file = "gevent-20.4.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1ef086264e846371beb5742ebaeb148dc96adf72da2ff350ae5603421cdc2ad9"},
|
{file = "gevent-20.5.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:efd9546468502a30ddd4699c3124ccb9d3099130f9b5ae1e2a54ad5b46e86120"},
|
||||||
{file = "gevent-20.4.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:2070c65896f89a85b39f49427d6132f7abd047129fc4da88b3670f0ba13b0cf7"},
|
{file = "gevent-20.5.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3ff477b6d275396123faf8ce2d5b82f96d85ba264e0b9d4b56a2bac49d1b9adc"},
|
||||||
{file = "gevent-20.4.0-cp27-cp27m-win32.whl", hash = "sha256:de6c0cbcb890d0a79323961d3b593a0f2f54dcb9fe38ee5167f2d514e69e3c8c"},
|
{file = "gevent-20.5.0-cp27-cp27m-win32.whl", hash = "sha256:92edc18a357473e01a4e4a82c073ed3c99ceca6e3ce93c23668dd4a2401f07dc"},
|
||||||
{file = "gevent-20.4.0-cp27-cp27m-win_amd64.whl", hash = "sha256:3b4c4d99f87c0d04b825879c5a91fbfa2b66da7c25b8689e9bdd9f4741d5f80d"},
|
{file = "gevent-20.5.0-cp27-cp27m-win_amd64.whl", hash = "sha256:1dd95433be45e1115053878366e3f5332ae99c39cb345be23851327c062b9f4a"},
|
||||||
{file = "gevent-20.4.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:8cca7ffd58559f8d51e5605ad73afcc6f348f9747d2fa539b336e70851b69b79"},
|
{file = "gevent-20.5.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:fcb64f3a28420d1b872b7ef41b12e8a1a4dcadfc8eff3c09993ab0cdf52584a1"},
|
||||||
{file = "gevent-20.4.0-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:b46399f6c9eccc2e6de1dc1057d362be840443e5439b06cce8b01d114ba1a7ec"},
|
{file = "gevent-20.5.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:4d2729dd4bf9c4d0f29482f53cdf9fc90a498aebb5cd7ae8b45d35657437d2ac"},
|
||||||
{file = "gevent-20.4.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:ee39caf14d66e619709cdfe3962bc68a234518e43ea8c811c0d67a864bc7c196"},
|
{file = "gevent-20.5.0-cp35-cp35m-win32.whl", hash = "sha256:00b03601b8dd1ee2aa07811cb60a4befe36173b15d91c6e207e37f8d77dd6fac"},
|
||||||
{file = "gevent-20.4.0-cp35-cp35m-win32.whl", hash = "sha256:8a9aba59a3268f20c7b584119215bdc589cb81500d93dad4dab428eb02f72944"},
|
{file = "gevent-20.5.0-cp35-cp35m-win_amd64.whl", hash = "sha256:937d36730f2b0dee3387712074b1f15b802e2e074a3d7c6dcaf70521236d607c"},
|
||||||
{file = "gevent-20.4.0-cp35-cp35m-win_amd64.whl", hash = "sha256:6088bedd8b6bcdb815be322304a5d1c028ffa837d84e93b349928dadac62f354"},
|
{file = "gevent-20.5.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:929c33df8e9bcbe31906024fcd21580bd018196dbd3249eb5b2f19d63e11092d"},
|
||||||
{file = "gevent-20.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0b38a654c8fde5b9d9bd27ea3261aeefe36bc9244b170b6d3b11d72a2163bdb"},
|
{file = "gevent-20.5.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:52e5cd607749ed3b8aa0272cacf2c11deec61fca4c3bec57a9fea8c49316627d"},
|
||||||
{file = "gevent-20.4.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:e7d23d5f32c9db6ae49c4b58585618dcafd6ad0babae251c9c8297afebc4744b"},
|
{file = "gevent-20.5.0-cp36-cp36m-win32.whl", hash = "sha256:15eae3cd450dac7dae7f4ac59e01db1378965c9ef565c39c5ae78c5a888f9ac9"},
|
||||||
{file = "gevent-20.4.0-cp36-cp36m-win32.whl", hash = "sha256:0b84a8d6f088b29a74402728681c9f11864b95e49f5587a666e6fbf5c683e597"},
|
{file = "gevent-20.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9b4e940fc6071afebb86ba5f48dbb5f1fc3cb96ebeb8cf145eb5b499e9c6ee33"},
|
||||||
{file = "gevent-20.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b0aea12de542f8fcd6882087bdd5b4d7dc8bb316d28181f6b012dd0b91583285"},
|
{file = "gevent-20.5.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e01d5373528e4ebdde66dc47a608d225fa3c4408ccd828d26c49b7ff75d82bd9"},
|
||||||
{file = "gevent-20.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e0990009e7c1624f9a0f3335df1ab8d45678241c852659ac645b70ed8229097c"},
|
{file = "gevent-20.5.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:31dc5d4ab8172cc00c4ff17cb18edee633babd961f64bf54214244d769bc3a74"},
|
||||||
{file = "gevent-20.4.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c7a62d51c6dca84f91a91b940037523c926a516f0568f47dc1386bd1682cf4e9"},
|
{file = "gevent-20.5.0-cp37-cp37m-win32.whl", hash = "sha256:0acc15ba2ac2a555529ad82d5a28fc85dbb6b2ff947657d67bebfd352e2b5c14"},
|
||||||
{file = "gevent-20.4.0-cp37-cp37m-win32.whl", hash = "sha256:d56f36eb98532d2bccc51cb0964c31e9fbd9b2282074c297dc9b006b047e2966"},
|
{file = "gevent-20.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a7805934e8ce81610b61f806572c3d504cedd698cc8c9460d78d2893ba598c4a"},
|
||||||
{file = "gevent-20.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2fbe0bc43d8c5540153f06eece6235dda14e5f99bdd9183838396313100815d7"},
|
{file = "gevent-20.5.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:5c604179cebcc57f10505d8db177b92a715907815a464b066e7eba322d1c33ac"},
|
||||||
{file = "gevent-20.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4572dc7907a0ac3c39b9f0898dbdf390ae3250baaae5f7395661fb844e2e23be"},
|
{file = "gevent-20.5.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:88c76df4967c5229f853aa67ad1b394d9e4f985b0359c9bc9879416bba3e7c68"},
|
||||||
{file = "gevent-20.4.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:956e82a5d0e90f8d71efe4cecccde602cfb657cd866c58bb953c9c30ca1b3d77"},
|
{file = "gevent-20.5.0-cp38-cp38-win32.whl", hash = "sha256:d07a2afe4215731eb57d5b257a2e7e7e170d8a7ae1f02f6d0682cd3403debea9"},
|
||||||
{file = "gevent-20.4.0-cp38-cp38-win32.whl", hash = "sha256:38c45d8a3b647f56f8a68769a8ac4953be84a84735c7c7a4d7ca62022bd54036"},
|
{file = "gevent-20.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:28b7d83b4327ceb79668eca2049bf4b9ce66d5ace18a88335e3035b573f889fd"},
|
||||||
{file = "gevent-20.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:32813de352918fb652a3db805fd6e08e0a1666a1a9304eef95938c9c426f9573"},
|
{file = "gevent-20.5.0-pp27-pypy_73-win32.whl", hash = "sha256:38db524ea88d81d596b2cbb6948fced26654a15fec40ea4529224e239a6f45e8"},
|
||||||
{file = "gevent-20.4.0-pp27-pypy_73-macosx_10_7_x86_64.whl", hash = "sha256:42cae3be36b7458f411bd589c66aaba27e4e611ec3d3621e37fd732fe383f9b6"},
|
{file = "gevent-20.5.0.tar.gz", hash = "sha256:1dc7f1f6bc1f67d625e4272b01e717eba0b4fa024d2ff7934c8d320674d6f7fa"},
|
||||||
{file = "gevent-20.4.0-pp27-pypy_73-win32.whl", hash = "sha256:cea28f958bc4206ae092043e0775cd7a2bb2536bcbece292732c6484c1076c01"},
|
|
||||||
{file = "gevent-20.4.0.tar.gz", hash = "sha256:c516cc5d70c3faf07f271d50930d144339c69fb80f3cac9b687aa964e518535e"},
|
|
||||||
]
|
]
|
||||||
gevent-eventemitter = [
|
gevent-eventemitter = [
|
||||||
{file = "gevent-eventemitter-2.1.tar.gz", hash = "sha256:00e6e688c6a255f7bdcef1d8c999e0d02d9ab87d3c6ff626e6dc1a09762107f4"},
|
{file = "gevent-eventemitter-2.1.tar.gz", hash = "sha256:00e6e688c6a255f7bdcef1d8c999e0d02d9ab87d3c6ff626e6dc1a09762107f4"},
|
||||||
|
@ -1076,14 +953,6 @@ h11 = [
|
||||||
{file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"},
|
{file = "h11-0.9.0-py2.py3-none-any.whl", hash = "sha256:4bc6d6a1238b7615b266ada57e0618568066f57dd6fa967d1290ec9309b2f2f1"},
|
||||||
{file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"},
|
{file = "h11-0.9.0.tar.gz", hash = "sha256:33d4bca7be0fa039f4e84d50ab00531047e53d6ee8ffbc83501ea602c169cae1"},
|
||||||
]
|
]
|
||||||
h2 = [
|
|
||||||
{file = "h2-3.2.0-py2.py3-none-any.whl", hash = "sha256:61e0f6601fa709f35cdb730863b4e5ec7ad449792add80d1410d4174ed139af5"},
|
|
||||||
{file = "h2-3.2.0.tar.gz", hash = "sha256:875f41ebd6f2c44781259005b157faed1a5031df3ae5aa7bcb4628a6c0782f14"},
|
|
||||||
]
|
|
||||||
hpack = [
|
|
||||||
{file = "hpack-3.0.0-py2.py3-none-any.whl", hash = "sha256:0edd79eda27a53ba5be2dfabf3b15780928a0dff6eb0c60a3d6767720e970c89"},
|
|
||||||
{file = "hpack-3.0.0.tar.gz", hash = "sha256:8eec9c1f4bfae3408a3f30500261f7e6a65912dc138526ea054f9ad98892e9d2"},
|
|
||||||
]
|
|
||||||
httptools = [
|
httptools = [
|
||||||
{file = "httptools-0.0.13.tar.gz", hash = "sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"},
|
{file = "httptools-0.0.13.tar.gz", hash = "sha256:e00cbd7ba01ff748e494248183abc6e153f49181169d8a3d41bb49132ca01dfc"},
|
||||||
]
|
]
|
||||||
|
@ -1091,32 +960,10 @@ humanfriendly = [
|
||||||
{file = "humanfriendly-8.2-py2.py3-none-any.whl", hash = "sha256:e78960b31198511f45fd455534ae7645a6207d33e512d2e842c766d15d9c8080"},
|
{file = "humanfriendly-8.2-py2.py3-none-any.whl", hash = "sha256:e78960b31198511f45fd455534ae7645a6207d33e512d2e842c766d15d9c8080"},
|
||||||
{file = "humanfriendly-8.2.tar.gz", hash = "sha256:bf52ec91244819c780341a3438d5d7b09f431d3f113a475147ac9b7b167a3d12"},
|
{file = "humanfriendly-8.2.tar.gz", hash = "sha256:bf52ec91244819c780341a3438d5d7b09f431d3f113a475147ac9b7b167a3d12"},
|
||||||
]
|
]
|
||||||
hyperframe = [
|
|
||||||
{file = "hyperframe-5.2.0-py2.py3-none-any.whl", hash = "sha256:5187962cb16dcc078f23cb5a4b110098d546c3f41ff2d4038a9896893bbd0b40"},
|
|
||||||
{file = "hyperframe-5.2.0.tar.gz", hash = "sha256:a9f5c17f2cc3c719b917c4f33ed1c61bd1f8dfac4b1bd23b7c80b3400971b41f"},
|
|
||||||
]
|
|
||||||
idna = [
|
idna = [
|
||||||
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
|
{file = "idna-2.9-py2.py3-none-any.whl", hash = "sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"},
|
||||||
{file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"},
|
{file = "idna-2.9.tar.gz", hash = "sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb"},
|
||||||
]
|
]
|
||||||
jsonschema = [
|
|
||||||
{file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
|
|
||||||
{file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
|
|
||||||
]
|
|
||||||
logbook = [
|
|
||||||
{file = "Logbook-1.5.3-cp27-cp27m-win32.whl", hash = "sha256:56ee54c11df3377314cedcd6507638f015b4b88c0238c2e01b5eb44fd3a6ad1b"},
|
|
||||||
{file = "Logbook-1.5.3-cp27-cp27m-win_amd64.whl", hash = "sha256:2dc85f1510533fddb481e97677bb7bca913560862734c0b3b289bfed04f78c92"},
|
|
||||||
{file = "Logbook-1.5.3-cp35-cp35m-win32.whl", hash = "sha256:94e2e11ff3c2304b0d09a36c6208e5ae756eb948b210e5cbd63cd8d27f911542"},
|
|
||||||
{file = "Logbook-1.5.3-cp35-cp35m-win_amd64.whl", hash = "sha256:97fee1bd9605f76335b169430ed65e15e457a844b2121bd1d90a08cf7e30aba0"},
|
|
||||||
{file = "Logbook-1.5.3-cp36-cp36m-win32.whl", hash = "sha256:7c533eb728b3d220b1b5414ba4635292d149d79f74f6973b4aa744c850ca944a"},
|
|
||||||
{file = "Logbook-1.5.3-cp36-cp36m-win_amd64.whl", hash = "sha256:e18f7422214b1cf0240c56f884fd9c9b4ff9d0da2eabca9abccba56df7222f66"},
|
|
||||||
{file = "Logbook-1.5.3-cp37-cp37m-win32.whl", hash = "sha256:8f76a2e7b1f72595f753228732f81ce342caf03babc3fed6bbdcf366f2f20f18"},
|
|
||||||
{file = "Logbook-1.5.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0cf2cdbfb65a03b5987d19109dacad13417809dcf697f66e1a7084fb21744ea9"},
|
|
||||||
{file = "Logbook-1.5.3.tar.gz", hash = "sha256:66f454ada0f56eae43066f604a222b09893f98c1adc18df169710761b8f32fe8"},
|
|
||||||
]
|
|
||||||
matrix-nio = [
|
|
||||||
{file = "matrix-nio-0.6.tar.gz", hash = "sha256:25a4ac9d5e1435035f5c5b6e9a6b453ac66ade25cb455ba6bbe9cc3ae1e0ef50"},
|
|
||||||
]
|
|
||||||
multidict = [
|
multidict = [
|
||||||
{file = "multidict-4.7.5-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3"},
|
{file = "multidict-4.7.5-cp35-cp35m-macosx_10_13_x86_64.whl", hash = "sha256:fc3b4adc2ee8474cb3cd2a155305d5f8eda0a9c91320f83e55748e1fcb68f8e3"},
|
||||||
{file = "multidict-4.7.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35"},
|
{file = "multidict-4.7.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:42f56542166040b4474c0c608ed051732033cd821126493cf25b6c276df7dd35"},
|
||||||
|
@ -1197,38 +1044,6 @@ pycparser = [
|
||||||
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
|
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
|
||||||
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
||||||
]
|
]
|
||||||
pycryptodome = [
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:0e10f352ccbbcb5bb2dc4ecaf106564e65702a717d72ab260f9ac4c19753cfc2"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:9c739b7795ccf2ef1fdad8d44e539a39ad300ee6786e804ea7f0c6a786eb5343"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9977086e0f93adb326379897437373871b80501e1d176fec63c7f46fb300c862"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27m-win32.whl", hash = "sha256:83295a3fb5cf50c48631eb5b440cb5e9832d8c14d81d1d45f4497b67a9987de8"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27m-win_amd64.whl", hash = "sha256:b1e332587b3b195542e77681389c296e1837ca01240399d88803a075447d3557"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:9378c309aec1f8cd8bad361ed0816a440151b97a2a3f6ffdaba1d1a1fb76873a"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4f94368ce2d65873a87ad867eb3bf63f4ba81eb97a9ee66d38c2b71ce5a7439"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:f655addaaaa9974108d4808f4150652589cada96074c87115c52e575bfcd87d5"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:9a94fca11fdc161460bd8659c15b6adef45c1b20da86402256eaf3addfaab324"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:ea83bcd9d6c03248ebd46e71ac313858e0afd5aa2fa81478c0e653242f3eb476"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:07024fc364869eae8d6ac0d316e089956e6aeffe42dbdcf44fe1320d96becf7f"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:426c188c83c10df71f053e04b4003b1437bae5cb37606440e498b00f160d71d0"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp35-cp35m-win32.whl", hash = "sha256:d61b012baa8c2b659e9890011358455c0019a4108536b811602d2f638c40802a"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp35-cp35m-win_amd64.whl", hash = "sha256:1f4752186298caf2e9ff5354f2e694d607ca7342aa313a62005235d46e28cf04"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:767ad0fb5d23efc36a4d5c2fc608ac603f3de028909bcf59abc943e0d0bc5a36"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:2fbc472e0b567318fe2052281d5a8c0ae70099b446679815f655e9fbc18c3a65"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:9230fcb5d948c3fb40049bace4d33c5d254f8232c2c0bba05d2570aea3ba4520"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp36-cp36m-win32.whl", hash = "sha256:8f06556a8f7ea7b1e42eff39726bb0dca1c251205debae64e6eebea3cd7b438a"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp36-cp36m-win_amd64.whl", hash = "sha256:d6e1bc5c94873bec742afe2dfadce0d20445b18e75c47afc0c115b19e5dd38dd"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:3ec3dc2f80f71fd0c955ce48b81bfaf8914c6f63a41a738f28885a1c4892968a"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cff31f5a8977534f255f729d5d2467526f2b10563a30bbdade92223e0bf264bd"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ed5761b37615a1f222c5345bbf45272ae2cf8c7dff88a4f53a1e9f977cbb6d95"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp37-cp37m-win32.whl", hash = "sha256:f011cd0062e54658b7086a76f8cf0f4222812acc66e219e196ea2d0a8849d0ed"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp37-cp37m-win_amd64.whl", hash = "sha256:626c0a1d4d83ec6303f970a17158114f75c3ba1736f7f2983f7b40a265861bd8"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be56bde3312e022d9d1d6afa124556460ad5c844c2fc63642f6af723c098d35"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c818dc1f3eace93ee50c2b6b5c2becf7c418fa5dd1ba6fc0ef7db279ea21d5e4"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:09b6d6bcc01a4eb1a2b4deeff5aa602a108ec5aed8ac75ae554f97d1d7f0a5ad"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp38-cp38-win32.whl", hash = "sha256:7ac729d9091ed5478af2b4a4f44f5335a98febbc008af619e4569a59fe503e40"},
|
|
||||||
{file = "pycryptodome-3.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:c109a26a21f21f695d369ff9b87f5d43e0d6c768d8384e10bc74142bed2e092e"},
|
|
||||||
{file = "pycryptodome-3.9.7.tar.gz", hash = "sha256:f1add21b6d179179b3c177c33d18a2186a09cc0d3af41ff5ed3f377360b869f2"},
|
|
||||||
]
|
|
||||||
pynacl = [
|
pynacl = [
|
||||||
{file = "PyNaCl-1.3.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621"},
|
{file = "PyNaCl-1.3.0-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621"},
|
||||||
{file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39"},
|
{file = "PyNaCl-1.3.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39"},
|
||||||
|
@ -1261,9 +1076,6 @@ pyreadline = [
|
||||||
{file = "pyreadline-2.1.win32.exe", hash = "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e"},
|
{file = "pyreadline-2.1.win32.exe", hash = "sha256:65540c21bfe14405a3a77e4c085ecfce88724743a4ead47c66b84defcf82c32e"},
|
||||||
{file = "pyreadline-2.1.zip", hash = "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1"},
|
{file = "pyreadline-2.1.zip", hash = "sha256:4530592fc2e85b25b1a9f79664433da09237c1a270e4d78ea5aa3a2c7229e2d1"},
|
||||||
]
|
]
|
||||||
pyrsistent = [
|
|
||||||
{file = "pyrsistent-0.16.0.tar.gz", hash = "sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3"},
|
|
||||||
]
|
|
||||||
python-dateutil = [
|
python-dateutil = [
|
||||||
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
|
{file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
|
||||||
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
|
||||||
|
@ -1272,35 +1084,35 @@ python-multipart = [
|
||||||
{file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
|
{file = "python-multipart-0.0.5.tar.gz", hash = "sha256:f7bb5f611fc600d15fa47b3974c8aa16e93724513b49b5f95c81e6624c83fa43"},
|
||||||
]
|
]
|
||||||
python-telegram-bot = [
|
python-telegram-bot = [
|
||||||
{file = "python-telegram-bot-12.6.1.tar.gz", hash = "sha256:935397390910291c8e41d7f2a06a3bb13d1d74d78b59562be9f8a330d4527049"},
|
{file = "python-telegram-bot-12.7.tar.gz", hash = "sha256:218b0583afb8baeefe6f2f1ddd8f1bb1ae30f0af3ce9160a372abd2cdf258eef"},
|
||||||
{file = "python_telegram_bot-12.6.1-py2.py3-none-any.whl", hash = "sha256:c7bdb5788ad2edea5c5c1bc8e50967fad68aa35245c209baadf74fc8ad00ff06"},
|
{file = "python_telegram_bot-12.7-py2.py3-none-any.whl", hash = "sha256:6878cc642114c8c116ceada41639a9df487f42d5478d9f34cae513cc5c260dee"},
|
||||||
]
|
]
|
||||||
pytz = [
|
pytz = [
|
||||||
{file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"},
|
{file = "pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"},
|
||||||
{file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"},
|
{file = "pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"},
|
||||||
]
|
]
|
||||||
regex = [
|
regex = [
|
||||||
{file = "regex-2020.4.4-cp27-cp27m-win32.whl", hash = "sha256:90742c6ff121a9c5b261b9b215cb476eea97df98ea82037ec8ac95d1be7a034f"},
|
{file = "regex-2020.5.7-cp27-cp27m-win32.whl", hash = "sha256:5493a02c1882d2acaaf17be81a3b65408ff541c922bfd002535c5f148aa29f74"},
|
||||||
{file = "regex-2020.4.4-cp27-cp27m-win_amd64.whl", hash = "sha256:24f4f4062eb16c5bbfff6a22312e8eab92c2c99c51a02e39b4eae54ce8255cd1"},
|
{file = "regex-2020.5.7-cp27-cp27m-win_amd64.whl", hash = "sha256:021a0ae4d2baeeb60a3014805a2096cb329bd6d9f30669b7ad0da51a9cb73349"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:08119f707f0ebf2da60d2f24c2f39ca616277bb67ef6c92b72cbf90cbe3a556b"},
|
{file = "regex-2020.5.7-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:4df91094ced6f53e71f695c909d9bad1cca8761d96fd9f23db12245b5521136e"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c9423a150d3a4fc0f3f2aae897a59919acd293f4cb397429b120a5fcd96ea3db"},
|
{file = "regex-2020.5.7-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7ce4a213a96d6c25eeae2f7d60d4dad89ac2b8134ec3e69db9bc522e2c0f9388"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c087bff162158536387c53647411db09b6ee3f9603c334c90943e97b1052a156"},
|
{file = "regex-2020.5.7-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b059e2476b327b9794c792c855aa05531a3f3044737e455d283c7539bd7534d"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:1cbe0fa0b7f673400eb29e9ef41d4f53638f65f9a2143854de6b1ce2899185c3"},
|
{file = "regex-2020.5.7-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:652ab4836cd5531d64a34403c00ada4077bb91112e8bcdae933e2eae232cf4a8"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-win32.whl", hash = "sha256:0ce9537396d8f556bcfc317c65b6a0705320701e5ce511f05fc04421ba05b8a8"},
|
{file = "regex-2020.5.7-cp36-cp36m-win32.whl", hash = "sha256:1e2255ae938a36e9bd7db3b93618796d90c07e5f64dd6a6750c55f51f8b76918"},
|
||||||
{file = "regex-2020.4.4-cp36-cp36m-win_amd64.whl", hash = "sha256:7e1037073b1b7053ee74c3c6c0ada80f3501ec29d5f46e42669378eae6d4405a"},
|
{file = "regex-2020.5.7-cp36-cp36m-win_amd64.whl", hash = "sha256:8127ca2bf9539d6a64d03686fd9e789e8c194fc19af49b69b081f8c7e6ecb1bc"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4385f12aa289d79419fede43f979e372f527892ac44a541b5446617e4406c468"},
|
{file = "regex-2020.5.7-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f7f2f4226db6acd1da228adf433c5c3792858474e49d80668ea82ac87cf74a03"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a58dd45cb865be0ce1d5ecc4cfc85cd8c6867bea66733623e54bd95131f473b6"},
|
{file = "regex-2020.5.7-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:2bc6a17a7fa8afd33c02d51b6f417fc271538990297167f68a98cae1c9e5c945"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:ccccdd84912875e34c5ad2d06e1989d890d43af6c2242c6fcfa51556997af6cd"},
|
{file = "regex-2020.5.7-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:b7c9f65524ff06bf70c945cd8d8d1fd90853e27ccf86026af2afb4d9a63d06b1"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ea4adf02d23b437684cd388d557bf76e3afa72f7fed5bbc013482cc00c816948"},
|
{file = "regex-2020.5.7-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:fa09da4af4e5b15c0e8b4986a083f3fd159302ea115a6cc0649cd163435538b8"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-win32.whl", hash = "sha256:2294f8b70e058a2553cd009df003a20802ef75b3c629506be20687df0908177e"},
|
{file = "regex-2020.5.7-cp37-cp37m-win32.whl", hash = "sha256:669a8d46764a09f198f2e91fc0d5acdac8e6b620376757a04682846ae28879c4"},
|
||||||
{file = "regex-2020.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:e91ba11da11cf770f389e47c3f5c30473e6d85e06d7fd9dcba0017d2867aab4a"},
|
{file = "regex-2020.5.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b5b5b2e95f761a88d4c93691716ce01dc55f288a153face1654f868a8034f494"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5635cd1ed0a12b4c42cce18a8d2fb53ff13ff537f09de5fd791e97de27b6400e"},
|
{file = "regex-2020.5.7-cp38-cp38-manylinux1_i686.whl", hash = "sha256:0ff50843535593ee93acab662663cb2f52af8e31c3f525f630f1dc6156247938"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:23069d9c07e115537f37270d1d5faea3e0bdded8279081c4d4d607a2ad393683"},
|
{file = "regex-2020.5.7-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:1b17bf37c2aefc4cac8436971fe6ee52542ae4225cfc7762017f7e97a63ca998"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c162a21e0da33eb3d31a3ac17a51db5e634fc347f650d271f0305d96601dc15b"},
|
{file = "regex-2020.5.7-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:04d6e948ef34d3eac133bedc0098364a9e635a7914f050edb61272d2ddae3608"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:fb95debbd1a824b2c4376932f2216cc186912e389bdb0e27147778cf6acb3f89"},
|
{file = "regex-2020.5.7-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:5b741ecc3ad3e463d2ba32dce512b412c319993c1bb3d999be49e6092a769fb2"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-win32.whl", hash = "sha256:2a3bf8b48f8e37c3a40bb3f854bf0121c194e69a650b209628d951190b862de3"},
|
{file = "regex-2020.5.7-cp38-cp38-win32.whl", hash = "sha256:099568b372bda492be09c4f291b398475587d49937c659824f891182df728cdf"},
|
||||||
{file = "regex-2020.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bfed051dbff32fd8945eccca70f5e22b55e4148d2a8a45141a3b053d6455ae3"},
|
{file = "regex-2020.5.7-cp38-cp38-win_amd64.whl", hash = "sha256:3ab5e41c4ed7cd4fa426c50add2892eb0f04ae4e73162155cd668257d02259dd"},
|
||||||
{file = "regex-2020.4.4.tar.gz", hash = "sha256:295badf61a51add2d428a46b8580309c520d8b26e769868b922750cf3ce67142"},
|
{file = "regex-2020.5.7.tar.gz", hash = "sha256:73a10404867b835f1b8a64253e4621908f0d71150eb4e97ab2e7e441b53e9451"},
|
||||||
]
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"},
|
{file = "requests-2.23.0-py2.py3-none-any.whl", hash = "sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee"},
|
||||||
|
@ -1311,8 +1123,8 @@ riotwatcher = [
|
||||||
{file = "riotwatcher-2.7.1.tar.gz", hash = "sha256:5349271c7e00637b7619491a6070e66603705db60558ea2a690e7016f6e6d9a4"},
|
{file = "riotwatcher-2.7.1.tar.gz", hash = "sha256:5349271c7e00637b7619491a6070e66603705db60558ea2a690e7016f6e6d9a4"},
|
||||||
]
|
]
|
||||||
royalnet = [
|
royalnet = [
|
||||||
{file = "royalnet-5.7.7-py3-none-any.whl", hash = "sha256:e426c5fa21ee81deccd5ba35a17bd110d9de8382713b09851647fa71f3f9e3fa"},
|
{file = "royalnet-5.8.7-py3-none-any.whl", hash = "sha256:5fee088e02ec375b580af48e03894db2ca2edd10c19f7fcbfdacf0a6e07622e7"},
|
||||||
{file = "royalnet-5.7.7.tar.gz", hash = "sha256:6c7724296df890ea61f9f9f46efa4270e857dbe84a76521675fec7a163321bf5"},
|
{file = "royalnet-5.8.7.tar.gz", hash = "sha256:a72fd52e2ed9fa2a8163859ac93b517ec684348d44f5c0b09146c9880430f67b"},
|
||||||
]
|
]
|
||||||
royalspells = [
|
royalspells = [
|
||||||
{file = "royalspells-3.2.tar.gz", hash = "sha256:2bd4a9a66514532e35c02c3907425af48c7cb292364c4843c795719a82b25dfe"},
|
{file = "royalspells-3.2.tar.gz", hash = "sha256:2bd4a9a66514532e35c02c3907425af48c7cb292364c4843c795719a82b25dfe"},
|
||||||
|
@ -1369,12 +1181,8 @@ tornado = [
|
||||||
{file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"},
|
{file = "tornado-6.0.4.tar.gz", hash = "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc"},
|
||||||
]
|
]
|
||||||
tzlocal = [
|
tzlocal = [
|
||||||
{file = "tzlocal-2.0.0-py2.py3-none-any.whl", hash = "sha256:11c9f16e0a633b4b60e1eede97d8a46340d042e67b670b290ca526576e039048"},
|
{file = "tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"},
|
||||||
{file = "tzlocal-2.0.0.tar.gz", hash = "sha256:949b9dd5ba4be17190a80c0268167d7e6c92c62b30026cf9764caf3e308e5590"},
|
{file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"},
|
||||||
]
|
|
||||||
unpaddedbase64 = [
|
|
||||||
{file = "unpaddedbase64-1.1.0-py2-none-any.whl", hash = "sha256:8917367e4e915b7dce1a72a99db8798c9f3d0d9a74cdd9aafac6d7c65ca495c5"},
|
|
||||||
{file = "unpaddedbase64-1.1.0-py2.py3-none-any.whl", hash = "sha256:81cb4eaaa28cc6a282dd3f2c3855eaa1fbaafa736b5ee64df69889e20540a339"},
|
|
||||||
]
|
]
|
||||||
urllib3 = [
|
urllib3 = [
|
||||||
{file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"},
|
{file = "urllib3-1.25.9-py2.py3-none-any.whl", hash = "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115"},
|
||||||
|
@ -1443,6 +1251,6 @@ yarl = [
|
||||||
{file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"},
|
{file = "yarl-1.4.2.tar.gz", hash = "sha256:58cd9c469eced558cd81aa3f484b2924e8897049e06889e8ff2510435b7ef74b"},
|
||||||
]
|
]
|
||||||
youtube-dl = [
|
youtube-dl = [
|
||||||
{file = "youtube_dl-2020.3.24-py2.py3-none-any.whl", hash = "sha256:c0be39ea9bca72fa02a0d2d043c5e9bd8ea8e0fe79705e891161d6fcd29da59e"},
|
{file = "youtube_dl-2020.5.8-py2.py3-none-any.whl", hash = "sha256:0b5d3280522469968eb62eecb1f966f422b2be22f000a801bf87cb2172d8ea39"},
|
||||||
{file = "youtube_dl-2020.3.24.tar.gz", hash = "sha256:4b03efe439f7cae26eba909821d1df00a9a4eb82741cb2e8b78fe29702bd4633"},
|
{file = "youtube_dl-2020.5.8.tar.gz", hash = "sha256:22da6788b55b7b267c6d59bcdfaf10e67a9ac980976d50d29a670473ad2a05bb"},
|
||||||
]
|
]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "royalpack"
|
name = "royalpack"
|
||||||
version = "5.7.15"
|
version = "5.8.0"
|
||||||
description = "A Royalnet command pack for the Royal Games community"
|
description = "A Royalnet command pack for the Royal Games community"
|
||||||
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
|
authors = ["Stefano Pigozzi <ste.pigozzi@gmail.com>"]
|
||||||
license = "AGPL-3.0+"
|
license = "AGPL-3.0+"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
steam = "^0.9.1"
|
steam = "^0.9.1"
|
||||||
|
|
||||||
[tool.poetry.dependencies.royalnet]
|
[tool.poetry.dependencies.royalnet]
|
||||||
version = "~5.7.7"
|
version = "~5.8.7"
|
||||||
# Maybe... there is a way to make these selectable?
|
# Maybe... there is a way to make these selectable?
|
||||||
extras = [
|
extras = [
|
||||||
"telegram",
|
"telegram",
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
"sentry",
|
"sentry",
|
||||||
"herald",
|
"herald",
|
||||||
"coloredlogs",
|
"coloredlogs",
|
||||||
"matrix"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Development dependencies
|
# Development dependencies
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
|
from typing import *
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import sentry_sdk
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from typing import *
|
|
||||||
from royalnet.commands import *
|
from royalnet.commands import *
|
||||||
from royalnet.utils import *
|
from royalnet.utils import *
|
||||||
from royalnet.serf.telegram.escape import escape as tg_escape
|
from royalnet.serf.telegram.escape import escape as tg_escape
|
||||||
|
from sqlalchemy import or_, and_
|
||||||
|
|
||||||
from ..tables import Steam, Brawlhalla, BrawlhallaDuo
|
from ..tables import Steam, Brawlhalla, BrawlhallaDuo
|
||||||
from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier
|
from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier
|
||||||
from sqlalchemy import or_, and_
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
import telegram
|
import telegram
|
||||||
from royalnet.commands import *
|
from royalnet.commands import *
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from royalnet.commands import *
|
from royalnet.commands import *
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import asyncify
|
import royalnet.utils as ru
|
||||||
|
|
||||||
from ..tables import Cvstats
|
from ..tables import Cvstats
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ class CvstatsCommand(rc.Command):
|
||||||
|
|
||||||
log.debug("Saving to database...")
|
log.debug("Saving to database...")
|
||||||
db_session.add(cvstats)
|
db_session.add(cvstats)
|
||||||
await asyncify(db_session.commit)
|
await ru.asyncify(db_session.commit)
|
||||||
log.debug("Done!")
|
log.debug("Done!")
|
||||||
|
|
||||||
async def _updater(self, period: int):
|
async def _updater(self, period: int):
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
from typing import *
|
||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
import telegram
|
import telegram
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from typing import *
|
import royalnet.commands as rc
|
||||||
from royalnet.commands import *
|
import royalnet.utils as ru
|
||||||
from royalnet.utils import asyncify
|
import royalnet.backpack.tables as rbt
|
||||||
from royalnet.backpack.tables import *
|
|
||||||
from ..tables import *
|
from ..tables import *
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ async def to_imgur(imgur_api_key, photosizes: List[telegram.PhotoSize], caption=
|
||||||
# Select the largest photo
|
# Select the largest photo
|
||||||
largest_photo = sorted(photosizes, key=lambda p: p.width * p.height)[-1]
|
largest_photo = sorted(photosizes, key=lambda p: p.width * p.height)[-1]
|
||||||
# Get the photo url
|
# Get the photo url
|
||||||
photo_file: telegram.File = await asyncify(largest_photo.get_file)
|
photo_file: telegram.File = await ru.asyncify(largest_photo.get_file)
|
||||||
# Forward the url to imgur, as an upload
|
# Forward the url to imgur, as an upload
|
||||||
async with aiohttp.request("post", "https://api.imgur.com/3/upload", data={
|
async with aiohttp.request("post", "https://api.imgur.com/3/upload", data={
|
||||||
"image": photo_file.file_path,
|
"image": photo_file.file_path,
|
||||||
|
@ -25,18 +26,18 @@ async def to_imgur(imgur_api_key, photosizes: List[telegram.PhotoSize], caption=
|
||||||
}) as request:
|
}) as request:
|
||||||
response = await request.json()
|
response = await request.json()
|
||||||
if not response["success"]:
|
if not response["success"]:
|
||||||
raise CommandError("Imgur returned an error in the image upload.")
|
raise rc.CommandError("Imgur returned an error in the image upload.")
|
||||||
return response["data"]["link"]
|
return response["data"]["link"]
|
||||||
|
|
||||||
|
|
||||||
class DiarioCommand(Command):
|
class DiarioCommand(rc.Command):
|
||||||
name: str = "diario"
|
name: str = "diario"
|
||||||
|
|
||||||
description: str = "Aggiungi una citazione al Diario."
|
description: str = "Aggiungi una citazione al Diario."
|
||||||
|
|
||||||
syntax = "[!] \"{testo}\" --[autore], [contesto]"
|
syntax = "[!] \"{testo}\" --[autore], [contesto]"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
message: telegram.Message = data.message
|
message: telegram.Message = data.message
|
||||||
reply: telegram.Message = message.reply_to_message
|
reply: telegram.Message = message.reply_to_message
|
||||||
|
@ -70,11 +71,11 @@ class DiarioCommand(Command):
|
||||||
media_url = None
|
media_url = None
|
||||||
# Ensure there is a text or an image
|
# Ensure there is a text or an image
|
||||||
if not (text or media_url):
|
if not (text or media_url):
|
||||||
raise InvalidInputError("Il messaggio a cui hai risposto non contiene testo o immagini.")
|
raise rc.InvalidInputError("Il messaggio a cui hai risposto non contiene testo o immagini.")
|
||||||
# Find the Royalnet account associated with the sender
|
# Find the Royalnet account associated with the sender
|
||||||
quoted_tg = await asyncify(data.session.query(self.alchemy.get(Telegram))
|
quoted_tg = await ru.asyncify(data.session.query(self.alchemy.get(rbt.Telegram))
|
||||||
.filter_by(tg_id=reply.from_user.id)
|
.filter_by(tg_id=reply.from_user.id)
|
||||||
.one_or_none)
|
.one_or_none)
|
||||||
quoted_account = quoted_tg.user if quoted_tg is not None else None
|
quoted_account = quoted_tg.user if quoted_tg is not None else None
|
||||||
# Find the quoted name to assign
|
# Find the quoted name to assign
|
||||||
quoted_user: telegram.User = reply.from_user
|
quoted_user: telegram.User = reply.from_user
|
||||||
|
@ -121,9 +122,9 @@ class DiarioCommand(Command):
|
||||||
context = None
|
context = None
|
||||||
# Find if there's a Royalnet account associated with the quoted name
|
# Find if there's a Royalnet account associated with the quoted name
|
||||||
if quoted is not None:
|
if quoted is not None:
|
||||||
quoted_alias = await asyncify(
|
quoted_alias = await ru.asyncify(
|
||||||
data.session.query(self.alchemy.get(Alias))
|
data.session.query(self.alchemy.get(rbt.Alias))
|
||||||
.filter_by(alias=quoted.lower()).one_or_none
|
.filter_by(alias=quoted.lower()).one_or_none
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
quoted_alias = None
|
quoted_alias = None
|
||||||
|
@ -136,7 +137,7 @@ class DiarioCommand(Command):
|
||||||
context = None
|
context = None
|
||||||
# Ensure there is a text or an image
|
# Ensure there is a text or an image
|
||||||
if not (text or media_url):
|
if not (text or media_url):
|
||||||
raise InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
raise rc.InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
||||||
# Create the diario quote
|
# Create the diario quote
|
||||||
diario = self.alchemy.get(Diario)(creator=creator,
|
diario = self.alchemy.get(Diario)(creator=creator,
|
||||||
quoted_account=quoted_account,
|
quoted_account=quoted_account,
|
||||||
|
@ -147,7 +148,7 @@ class DiarioCommand(Command):
|
||||||
media_url=media_url,
|
media_url=media_url,
|
||||||
spoiler=spoiler)
|
spoiler=spoiler)
|
||||||
data.session.add(diario)
|
data.session.add(diario)
|
||||||
await asyncify(data.session.commit)
|
await ru.asyncify(data.session.commit)
|
||||||
await data.reply(f"✅ {str(diario)}")
|
await data.reply(f"✅ {str(diario)}")
|
||||||
else:
|
else:
|
||||||
# Find the creator of the quotes
|
# Find the creator of the quotes
|
||||||
|
@ -172,7 +173,7 @@ class DiarioCommand(Command):
|
||||||
timestamp = datetime.datetime.now()
|
timestamp = datetime.datetime.now()
|
||||||
# Ensure there is some text
|
# Ensure there is some text
|
||||||
if not text:
|
if not text:
|
||||||
raise InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
raise rc.InvalidInputError("Manca il testo o l'immagine da inserire nel diario.")
|
||||||
# Or a quoted
|
# Or a quoted
|
||||||
if not quoted:
|
if not quoted:
|
||||||
quoted = None
|
quoted = None
|
||||||
|
@ -180,17 +181,17 @@ class DiarioCommand(Command):
|
||||||
context = None
|
context = None
|
||||||
# Find if there's a Royalnet account associated with the quoted name
|
# Find if there's a Royalnet account associated with the quoted name
|
||||||
if quoted is not None:
|
if quoted is not None:
|
||||||
quoted_alias = await asyncify(
|
quoted_alias = await ru.asyncify(
|
||||||
data.session.query(self.alchemy.get(Alias))
|
data.session.query(self.alchemy.get(rbt.Alias))
|
||||||
.filter_by(alias=quoted.lower())
|
.filter_by(alias=quoted.lower())
|
||||||
.one_or_none
|
.one_or_none
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
quoted_alias = None
|
quoted_alias = None
|
||||||
quoted_account = quoted_alias.user if quoted_alias is not None else None
|
quoted_account = quoted_alias.user if quoted_alias is not None else None
|
||||||
if quoted_alias is not None and quoted_account is None:
|
if quoted_alias is not None and quoted_account is None:
|
||||||
raise UserError("Il nome dell'autore è ambiguo, quindi la riga non è stata aggiunta.\n"
|
raise rc.UserError("Il nome dell'autore è ambiguo, quindi la riga non è stata aggiunta.\n"
|
||||||
"Per piacere, ripeti il comando con un nome più specifico!")
|
"Per piacere, ripeti il comando con un nome più specifico!")
|
||||||
# Create the diario quote
|
# Create the diario quote
|
||||||
diario = self.alchemy.Diario(creator=creator,
|
diario = self.alchemy.Diario(creator=creator,
|
||||||
quoted_account=quoted_account,
|
quoted_account=quoted_account,
|
||||||
|
@ -201,5 +202,5 @@ class DiarioCommand(Command):
|
||||||
media_url=None,
|
media_url=None,
|
||||||
spoiler=spoiler)
|
spoiler=spoiler)
|
||||||
data.session.add(diario)
|
data.session.add(diario)
|
||||||
await asyncify(data.session.commit)
|
await ru.asyncify(data.session.commit)
|
||||||
await data.reply(f"✅ {str(diario)}")
|
await data.reply(f"✅ {str(diario)}")
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from royalnet.commands import *
|
from typing import *
|
||||||
from royalnet.utils import *
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
|
||||||
from ..tables import Diario
|
from ..tables import Diario
|
||||||
|
|
||||||
|
|
||||||
class DiarioquoteCommand(Command):
|
class DiarioquoteCommand(rc.Command):
|
||||||
name: str = "diarioquote"
|
name: str = "diarioquote"
|
||||||
|
|
||||||
description: str = "Cita una riga del diario."
|
description: str = "Cita una riga del diario."
|
||||||
|
@ -12,12 +14,12 @@ class DiarioquoteCommand(Command):
|
||||||
|
|
||||||
syntax = "{id}"
|
syntax = "{id}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
try:
|
try:
|
||||||
entry_id = int(args[0].lstrip("#"))
|
entry_id = int(args[0].lstrip("#"))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise CommandError("L'id che hai specificato non è valido.")
|
raise rc.CommandError("L'id che hai specificato non è valido.")
|
||||||
entry: Diario = await asyncify(data.session.query(self.alchemy.get(Diario)).get, entry_id)
|
entry: Diario = await ru.asyncify(data.session.query(self.alchemy.get(Diario)).get, entry_id)
|
||||||
if entry is None:
|
if entry is None:
|
||||||
raise CommandError("Nessuna riga con quell'id trovata.")
|
raise rc.CommandError("Nessuna riga con quell'id trovata.")
|
||||||
await data.reply(f"ℹ️ {entry}")
|
await data.reply(f"ℹ️ {entry}")
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import *
|
import royalnet.utils as ru
|
||||||
from ..tables import Diario
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func
|
||||||
|
|
||||||
|
from ..tables import Diario
|
||||||
|
|
||||||
class DiarioshuffleCommand(Command):
|
|
||||||
|
class DiarioshuffleCommand(rc.Command):
|
||||||
name: str = "diarioshuffle"
|
name: str = "diarioshuffle"
|
||||||
|
|
||||||
description: str = "Cita una riga casuale del diario."
|
description: str = "Cita una riga casuale del diario."
|
||||||
|
@ -14,9 +15,9 @@ class DiarioshuffleCommand(Command):
|
||||||
|
|
||||||
syntax = ""
|
syntax = ""
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
DiarioT = self.alchemy.get(Diario)
|
DiarioT = self.alchemy.get(Diario)
|
||||||
entry: List[Diario] = await asyncify(
|
entry: List[Diario] = await ru.asyncify(
|
||||||
data.session
|
data.session
|
||||||
.query(DiarioT)
|
.query(DiarioT)
|
||||||
.order_by(func.random())
|
.order_by(func.random())
|
||||||
|
@ -24,5 +25,5 @@ class DiarioshuffleCommand(Command):
|
||||||
.one_or_none
|
.one_or_none
|
||||||
)
|
)
|
||||||
if entry is None:
|
if entry is None:
|
||||||
raise CommandError("Nessuna riga del diario trovata.")
|
raise rc.CommandError("Nessuna riga del diario trovata.")
|
||||||
await data.reply(f"ℹ️ {entry}")
|
await data.reply(f"ℹ️ {entry}")
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
|
from typing import *
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from typing import *
|
import royalnet.commands as rc
|
||||||
from royalnet.commands import *
|
import royalnet.utils as ru
|
||||||
from royalnet.utils import *
|
import royalnet.serf.telegram as rst
|
||||||
from royalnet.serf.telegram.escape import escape as tg_escape
|
|
||||||
from ..tables import Steam, Dota
|
from ..tables import Steam, Dota
|
||||||
from ..types import DotaRank
|
from ..types import DotaRank
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DotaCommand(Command):
|
class DotaCommand(rc.Command):
|
||||||
name: str = "dota"
|
name: str = "dota"
|
||||||
|
|
||||||
aliases = ["dota2", "doto", "doto2", "dotka", "dotka2"]
|
aliases = ["dota2", "doto", "doto2", "dotka", "dotka2"]
|
||||||
|
@ -21,7 +22,7 @@ class DotaCommand(Command):
|
||||||
|
|
||||||
syntax: str = ""
|
syntax: str = ""
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
if self.interface.name == "telegram" and self.config["Dota"]["updater"]:
|
if self.interface.name == "telegram" and self.config["Dota"]["updater"]:
|
||||||
self.loop.create_task(self._updater(7200))
|
self.loop.create_task(self._updater(7200))
|
||||||
|
@ -30,7 +31,7 @@ class DotaCommand(Command):
|
||||||
client = self.serf.client
|
client = self.serf.client
|
||||||
await self.serf.api_call(client.send_message,
|
await self.serf.api_call(client.send_message,
|
||||||
chat_id=self.config["Telegram"]["main_group_id"],
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
text=tg_escape(message),
|
text=rst.escape(message),
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_webpage_preview=True)
|
disable_webpage_preview=True)
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ class DotaCommand(Command):
|
||||||
# Get profile data
|
# Get profile data
|
||||||
async with session.get(f"https://api.opendota.com/api/players/{steam.steamid.as_32}/") as response:
|
async with session.get(f"https://api.opendota.com/api/players/{steam.steamid.as_32}/") as response:
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
raise ExternalError(f"OpenDota / returned {response.status}!")
|
raise rc.ExternalError(f"OpenDota / returned {response.status}!")
|
||||||
p = await response.json()
|
p = await response.json()
|
||||||
# No such user
|
# No such user
|
||||||
if "profile" not in p:
|
if "profile" not in p:
|
||||||
|
@ -94,7 +95,7 @@ class DotaCommand(Command):
|
||||||
# Get win/loss data
|
# Get win/loss data
|
||||||
async with session.get(f"https://api.opendota.com/api/players/{steam.steamid.as_32}/wl") as response:
|
async with session.get(f"https://api.opendota.com/api/players/{steam.steamid.as_32}/wl") as response:
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
raise ExternalError(f"OpenDota /wl returned {response.status}!")
|
raise rc.ExternalError(f"OpenDota /wl returned {response.status}!")
|
||||||
wl = await response.json()
|
wl = await response.json()
|
||||||
# No such user
|
# No such user
|
||||||
if wl["win"] == 0 and wl["lose"] == 0:
|
if wl["win"] == 0 and wl["lose"] == 0:
|
||||||
|
@ -127,12 +128,12 @@ class DotaCommand(Command):
|
||||||
sentry_sdk.capture_exception(e)
|
sentry_sdk.capture_exception(e)
|
||||||
log.error(f"Error while updating {steam.user.username}: {e}")
|
log.error(f"Error while updating {steam.user.username}: {e}")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await asyncify(session.commit)
|
await ru.asyncify(session.commit)
|
||||||
session.close()
|
session.close()
|
||||||
log.info(f"Sleeping for {period}s")
|
log.info(f"Sleeping for {period}s")
|
||||||
await asyncio.sleep(period)
|
await asyncio.sleep(period)
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
author = await data.get_author(error_if_none=True)
|
author = await data.get_author(error_if_none=True)
|
||||||
|
|
||||||
found_something = False
|
found_something = False
|
||||||
|
@ -146,5 +147,5 @@ class DotaCommand(Command):
|
||||||
message += self._display(steam.dota)
|
message += self._display(steam.dota)
|
||||||
message += "\n"
|
message += "\n"
|
||||||
if not found_something:
|
if not found_something:
|
||||||
raise UserError("Nessun account di Dota 2 trovato.")
|
raise rc.UserError("Nessun account di Dota 2 trovato.")
|
||||||
await data.reply(message)
|
await data.reply(message)
|
||||||
|
|
|
@ -165,7 +165,10 @@ class EatCommand(Command):
|
||||||
"mia sul fiume": "💧 Hai mangiato il miglior piatto al mondo, la {food}, esclusivo ai membri Royal Games.\n"
|
"mia sul fiume": "💧 Hai mangiato il miglior piatto al mondo, la {food}, esclusivo ai membri Royal Games.\n"
|
||||||
"[i]Nessuno, tranne il bot, sa di cosa è fatta esattamente, ma una cosa è certa: è "
|
"[i]Nessuno, tranne il bot, sa di cosa è fatta esattamente, ma una cosa è certa: è "
|
||||||
"buonissima![/i]",
|
"buonissima![/i]",
|
||||||
"angelo": "👼 Oh mio dio! E' un {food}!\n[i]Ora hai un digramma ad onda blu.[/i]"
|
"angelo": "👼 Oh mio dio! E' un {food}!\n[i]Ora hai un digramma ad onda blu.[/i]",
|
||||||
|
|
||||||
|
"terraria": "🌳 Hai provato a mangiare {food}, ma non ne sei stato all'Altezza (Coniglio).\n[i]Prova a mangiare qualcos'altro...[/i]",
|
||||||
|
"cooked fish": "🐟 Hai mangiato {food}.\n[i]Ora sei Well Fed per 20 minuti.[/i]"
|
||||||
}
|
}
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
from typing import *
|
||||||
import random
|
import random
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
|
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
from typing import *
|
||||||
import random
|
import random
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class EmojifyCommand(Command):
|
class EmojifyCommand(rc.Command):
|
||||||
name: str = "emojify"
|
name: str = "emojify"
|
||||||
|
|
||||||
description: str = "Converti un messaggio in emoji."
|
description: str = "Converti un messaggio in emoji."
|
||||||
|
@ -94,6 +95,6 @@ class EmojifyCommand(Command):
|
||||||
new_string = new_string.replace(key, selected_emoji)
|
new_string = new_string.replace(key, selected_emoji)
|
||||||
return new_string
|
return new_string
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
string = args.joined(require_at_least=1)
|
string = args.joined(require_at_least=1)
|
||||||
await data.reply(self._emojify(string))
|
await data.reply(self._emojify(string))
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import royalnet
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.backpack.tables import *
|
import royalnet.backpack.tables as rbt
|
||||||
|
|
||||||
|
|
||||||
class EvalCommand(Command):
|
class EvalCommand(rc.Command):
|
||||||
# oh god if there is a security vulnerability
|
# oh god if there is a security vulnerability
|
||||||
name: str = "eval"
|
name: str = "eval"
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ class EvalCommand(Command):
|
||||||
|
|
||||||
syntax: str = "{espressione}"
|
syntax: str = "{espressione}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
user: User = await data.get_author(error_if_none=True)
|
user: rbt.User = await data.get_author(error_if_none=True)
|
||||||
if user.role != "Admin":
|
if "admin" not in user.roles:
|
||||||
raise CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
raise rc.CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
||||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||||
try:
|
try:
|
||||||
result = eval(args.joined(require_at_least=1))
|
result = eval(args.joined(require_at_least=1))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise CommandError(f"Eval fallito: {e}")
|
raise rc.CommandError(f"Eval fallito: {e}")
|
||||||
await data.reply(repr(result))
|
await data.reply(repr(result))
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import royalnet
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.backpack.tables import *
|
import royalnet.backpack.tables as rbt
|
||||||
|
|
||||||
|
|
||||||
class ExecCommand(Command):
|
class ExecCommand(rc.Command):
|
||||||
# oh god if there is a security vulnerability
|
# oh god if there is a security vulnerability
|
||||||
name: str = "exec"
|
name: str = "exec"
|
||||||
|
|
||||||
|
@ -11,13 +11,13 @@ class ExecCommand(Command):
|
||||||
|
|
||||||
syntax: str = "{script}"
|
syntax: str = "{script}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
user: User = await data.get_author(error_if_none=True)
|
user: rbt.User = await data.get_author(error_if_none=True)
|
||||||
if user.role != "Admin":
|
if "admin" not in user.roles:
|
||||||
raise CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
raise rc.CommandError("Non sei autorizzato a eseguire codice arbitrario!\n"
|
||||||
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
"(Sarebbe un po' pericoloso se te lo lasciassi eseguire, non trovi?)")
|
||||||
try:
|
try:
|
||||||
exec(args.joined(require_at_least=1))
|
exec(args.joined(require_at_least=1))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise CommandError(f"Esecuzione fallita: {e}")
|
raise rc.CommandError(f"Esecuzione fallita: {e}")
|
||||||
await data.reply(f"✅ Fatto!")
|
await data.reply(f"✅ Fatto!")
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from .play import PlayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
class FunkwhaleCommand(PlayCommand):
|
class FunkwhaleCommand(PlayCommand):
|
||||||
|
@ -23,5 +25,5 @@ class FunkwhaleCommand(PlayCommand):
|
||||||
f"/api/v1/search?query={search}") as response:
|
f"/api/v1/search?query={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["tracks"]) < 1:
|
if len(j["tracks"]) < 1:
|
||||||
raise UserError("Nessun file audio trovato con il nome richiesto.")
|
raise rc.UserError("Nessun file audio trovato con il nome richiesto.")
|
||||||
return [f'{self.config["Funkwhale"]["instance_url"]}{j["tracks"][0]["listen_url"]}']
|
return [f'{self.config["Funkwhale"]["instance_url"]}{j["tracks"][0]["listen_url"]}']
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from .play import PlayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
class FunkwhalealbumCommand(PlayCommand):
|
class FunkwhalealbumCommand(PlayCommand):
|
||||||
|
@ -23,6 +25,6 @@ class FunkwhalealbumCommand(PlayCommand):
|
||||||
f"/api/v1/search?query={search}") as response:
|
f"/api/v1/search?query={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["albums"]) < 1:
|
if len(j["albums"]) < 1:
|
||||||
raise UserError("Nessun file audio trovato con il nome richiesto.")
|
raise rc.UserError("Nessun file audio trovato con il nome richiesto.")
|
||||||
album = j["albums"][0]
|
album = j["albums"][0]
|
||||||
return [f'{self.config["Funkwhale"]["instance_url"]}{track["listen_url"]}' for track in album["tracks"]]
|
return [f'{self.config["Funkwhale"]["instance_url"]}{track["listen_url"]}' for track in album["tracks"]]
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from .play import PlayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
class FunkwhaleplaylistCommand(PlayCommand):
|
class FunkwhaleplaylistCommand(PlayCommand):
|
||||||
|
@ -23,7 +25,7 @@ class FunkwhaleplaylistCommand(PlayCommand):
|
||||||
f"/api/v1/playlists/?q={search}&ordering=-creation_date&playable=true") as response:
|
f"/api/v1/playlists/?q={search}&ordering=-creation_date&playable=true") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["results"]) < 1:
|
if len(j["results"]) < 1:
|
||||||
raise UserError("Nessuna playlist trovata con il nome richiesto.")
|
raise rc.UserError("Nessuna playlist trovata con il nome richiesto.")
|
||||||
playlist = j["results"][0]
|
playlist = j["results"][0]
|
||||||
playlist_id = playlist["id"]
|
playlist_id = playlist["id"]
|
||||||
async with session.get(self.config["Funkwhale"]["instance_url"] +
|
async with session.get(self.config["Funkwhale"]["instance_url"] +
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from .lazyplay import LazyplayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
class LazyfunkwhaleCommand(LazyplayCommand):
|
class LazyfunkwhaleCommand(LazyplayCommand):
|
||||||
name: str = "lazyfunkwhale"
|
name: str = "lazyfunkwhale"
|
||||||
|
@ -23,5 +25,5 @@ class LazyfunkwhaleCommand(LazyplayCommand):
|
||||||
f"/api/v1/search?query={search}") as response:
|
f"/api/v1/search?query={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["tracks"]) < 1:
|
if len(j["tracks"]) < 1:
|
||||||
raise UserError("Nessun file audio trovato con il nome richiesto.")
|
raise rc.UserError("Nessun file audio trovato con il nome richiesto.")
|
||||||
return [f'{self.config["Funkwhale"]["instance_url"]}{j["tracks"][0]["listen_url"]}']
|
return [f'{self.config["Funkwhale"]["instance_url"]}{j["tracks"][0]["listen_url"]}']
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from .lazyplay import LazyplayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
class LazyfunkwhalealbumCommand(LazyplayCommand):
|
class LazyfunkwhalealbumCommand(LazyplayCommand):
|
||||||
name: str = "lazyfunkwhalealbum"
|
name: str = "lazyfunkwhalealbum"
|
||||||
|
@ -23,6 +25,6 @@ class LazyfunkwhalealbumCommand(LazyplayCommand):
|
||||||
f"/api/v1/search?query={search}") as response:
|
f"/api/v1/search?query={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["albums"]) < 1:
|
if len(j["albums"]) < 1:
|
||||||
raise UserError("Nessun file audio trovato con il nome richiesto.")
|
raise rc.UserError("Nessun file audio trovato con il nome richiesto.")
|
||||||
album = j["albums"][0]
|
album = j["albums"][0]
|
||||||
return [f'{self.config["Funkwhale"]["instance_url"]}{track["listen_url"]}' for track in album["tracks"]]
|
return [f'{self.config["Funkwhale"]["instance_url"]}{track["listen_url"]}' for track in album["tracks"]]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from .lazyplay import LazyplayCommand
|
|
||||||
from royalnet.commands import *
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
import royalnet.commands as rc
|
||||||
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
class LazyfunkwhaleplaylistCommand(LazyplayCommand):
|
class LazyfunkwhaleplaylistCommand(LazyplayCommand):
|
||||||
|
@ -23,7 +23,7 @@ class LazyfunkwhaleplaylistCommand(LazyplayCommand):
|
||||||
f"/api/v1/playlists/?q={search}&ordering=-creation_date&playable=true") as response:
|
f"/api/v1/playlists/?q={search}&ordering=-creation_date&playable=true") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if len(j["results"]) < 1:
|
if len(j["results"]) < 1:
|
||||||
raise UserError("Nessuna playlist trovata con il nome richiesto.")
|
raise rc.UserError("Nessuna playlist trovata con il nome richiesto.")
|
||||||
playlist = j["results"][0]
|
playlist = j["results"][0]
|
||||||
playlist_id = playlist["id"]
|
playlist_id = playlist["id"]
|
||||||
async with session.get(self.config["Funkwhale"]["instance_url"] +
|
async with session.get(self.config["Funkwhale"]["instance_url"] +
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .lazyplay import LazyplayCommand
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from .lazyplay import LazyplayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
class LazypeertubeCommand(LazyplayCommand):
|
class LazypeertubeCommand(LazyplayCommand):
|
||||||
name: str = "lazypeertube"
|
name: str = "lazypeertube"
|
||||||
|
@ -20,5 +22,5 @@ class LazypeertubeCommand(LazyplayCommand):
|
||||||
f"/api/v1/search/videos?search={search}") as response:
|
f"/api/v1/search/videos?search={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if j["total"] < 1:
|
if j["total"] < 1:
|
||||||
raise InvalidInputError("Nessun video trovato.")
|
raise rc.InvalidInputError("Nessun video trovato.")
|
||||||
return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']
|
return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
from typing import *
|
||||||
import discord
|
import discord
|
||||||
import asyncio as aio
|
import asyncio as aio
|
||||||
from typing import *
|
import royalnet.commands as rc
|
||||||
from royalnet.commands import *
|
import royalnet.backpack.tables as rbt
|
||||||
from royalnet.backpack.tables import User, Discord
|
|
||||||
|
|
||||||
|
|
||||||
class LazyplayCommand(Command):
|
class LazyplayCommand(rc.Command):
|
||||||
name: str = "lazyplay"
|
name: str = "lazyplay"
|
||||||
|
|
||||||
aliases = ["lp"]
|
aliases = ["lp"]
|
||||||
|
@ -15,17 +15,17 @@ class LazyplayCommand(Command):
|
||||||
|
|
||||||
syntax = "{url}"
|
syntax = "{url}"
|
||||||
|
|
||||||
async def get_urls(self, args: CommandArgs):
|
async def get_urls(self, args: rc.CommandArgs):
|
||||||
url = args.joined(require_at_least=1)
|
url = args.joined(require_at_least=1)
|
||||||
if not (url.startswith("http://") or url.startswith("https://")):
|
if not (url.startswith("http://") or url.startswith("https://")):
|
||||||
raise InvalidInputError(f"L'URL specificato non inizia con il nome di un protocollo supportato"
|
raise rc.InvalidInputError(f"L'URL specificato non inizia con il nome di un protocollo supportato"
|
||||||
f" ([c]http://[/c] o [c]https://[/c]).")
|
f" ([c]http://[/c] o [c]https://[/c]).")
|
||||||
return [url]
|
return [url]
|
||||||
|
|
||||||
def get_embed_color(self) -> Optional[int]:
|
def get_embed_color(self) -> Optional[int]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
guild: discord.Guild = message.guild
|
guild: discord.Guild = message.guild
|
||||||
|
@ -36,12 +36,12 @@ class LazyplayCommand(Command):
|
||||||
else:
|
else:
|
||||||
guild_id = None
|
guild_id = None
|
||||||
|
|
||||||
user: User = await data.get_author()
|
user: rbt.User = await data.get_author()
|
||||||
user_str = None
|
user_str = None
|
||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
try:
|
try:
|
||||||
user_discord: Discord = user.discord[0]
|
user_discord: rbt.Discord = user.discord[0]
|
||||||
except (AttributeError, IndexError):
|
except (AttributeError, IndexError):
|
||||||
user_str = str(user)
|
user_str = str(user)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .lazyplay import LazyplayCommand
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .lazyplay import LazyplayCommand
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .lazyplay import LazyplayCommand
|
from .lazyplay import LazyplayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import typing
|
from typing import *
|
||||||
import riotwatcher
|
import riotwatcher
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import *
|
import royalnet.utils as ru
|
||||||
from royalnet.serf.telegram import *
|
import royalnet.serf.telegram as rst
|
||||||
|
|
||||||
from ..tables import LeagueOfLegends, FiorygiTransaction
|
from ..tables import LeagueOfLegends, FiorygiTransaction
|
||||||
from ..types import LeagueLeague
|
from ..types import LeagueLeague
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class LeagueoflegendsCommand(Command):
|
class LeagueoflegendsCommand(rc.Command):
|
||||||
name: str = "leagueoflegends"
|
name: str = "leagueoflegends"
|
||||||
|
|
||||||
aliases = ["lol", "league"]
|
aliases = ["lol", "league"]
|
||||||
|
@ -21,7 +22,7 @@ class LeagueoflegendsCommand(Command):
|
||||||
|
|
||||||
syntax = "[nomeevocatore]"
|
syntax = "[nomeevocatore]"
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
self._riotwatcher = riotwatcher.RiotWatcher(api_key=self.config["Lol"]["token"])
|
self._riotwatcher = riotwatcher.RiotWatcher(api_key=self.config["Lol"]["token"])
|
||||||
if self.interface.name == "telegram" and self.config["Lol"]["updater"]:
|
if self.interface.name == "telegram" and self.config["Lol"]["updater"]:
|
||||||
|
@ -31,15 +32,15 @@ class LeagueoflegendsCommand(Command):
|
||||||
client = self.serf.client
|
client = self.serf.client
|
||||||
await self.serf.api_call(client.send_message,
|
await self.serf.api_call(client.send_message,
|
||||||
chat_id=self.config["Telegram"]["main_group_id"],
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
text=escape(message),
|
text=rst.escape(message),
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_webpage_preview=True)
|
disable_webpage_preview=True)
|
||||||
|
|
||||||
async def _notify(self,
|
async def _notify(self,
|
||||||
obj: LeagueOfLegends,
|
obj: LeagueOfLegends,
|
||||||
attribute_name: str,
|
attribute_name: str,
|
||||||
old_value: typing.Any,
|
old_value: Any,
|
||||||
new_value: typing.Any):
|
new_value: Any):
|
||||||
if isinstance(old_value, LeagueLeague):
|
if isinstance(old_value, LeagueLeague):
|
||||||
# This is a rank change!
|
# This is a rank change!
|
||||||
# Don't send messages for every rank change, send messages just if the TIER or RANK changes!
|
# Don't send messages for every rank change, send messages just if the TIER or RANK changes!
|
||||||
|
@ -69,9 +70,9 @@ class LeagueoflegendsCommand(Command):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def _change(obj: LeagueOfLegends,
|
async def _change(obj: LeagueOfLegends,
|
||||||
attribute_name: str,
|
attribute_name: str,
|
||||||
new_value: typing.Any,
|
new_value: Any,
|
||||||
callback: typing.Callable[
|
callback: Callable[
|
||||||
[LeagueOfLegends, str, typing.Any, typing.Any], typing.Awaitable[None]]):
|
[LeagueOfLegends, str, Any, Any], Awaitable[None]]):
|
||||||
old_value = obj.__getattribute__(attribute_name)
|
old_value = obj.__getattribute__(attribute_name)
|
||||||
if old_value != new_value:
|
if old_value != new_value:
|
||||||
await callback(obj, attribute_name, old_value, new_value)
|
await callback(obj, attribute_name, old_value, new_value)
|
||||||
|
@ -80,8 +81,8 @@ class LeagueoflegendsCommand(Command):
|
||||||
async def _update(self, lol: LeagueOfLegends):
|
async def _update(self, lol: LeagueOfLegends):
|
||||||
log.info(f"Updating: {lol}")
|
log.info(f"Updating: {lol}")
|
||||||
log.debug(f"Getting summoner data: {lol}")
|
log.debug(f"Getting summoner data: {lol}")
|
||||||
summoner = await asyncify(self._riotwatcher.summoner.by_id, region=self.config["Lol"]["region"],
|
summoner = await ru.asyncify(self._riotwatcher.summoner.by_id, region=self.config["Lol"]["region"],
|
||||||
encrypted_summoner_id=lol.summoner_id)
|
encrypted_summoner_id=lol.summoner_id)
|
||||||
await self._change(lol, "profile_icon_id", summoner["profileIconId"], self._notify)
|
await self._change(lol, "profile_icon_id", summoner["profileIconId"], self._notify)
|
||||||
await self._change(lol, "summoner_name", summoner["name"], self._notify)
|
await self._change(lol, "summoner_name", summoner["name"], self._notify)
|
||||||
await self._change(lol, "puuid", summoner["puuid"], self._notify)
|
await self._change(lol, "puuid", summoner["puuid"], self._notify)
|
||||||
|
@ -89,8 +90,8 @@ class LeagueoflegendsCommand(Command):
|
||||||
await self._change(lol, "summoner_id", summoner["id"], self._notify)
|
await self._change(lol, "summoner_id", summoner["id"], self._notify)
|
||||||
await self._change(lol, "account_id", summoner["accountId"], self._notify)
|
await self._change(lol, "account_id", summoner["accountId"], self._notify)
|
||||||
log.debug(f"Getting leagues data: {lol}")
|
log.debug(f"Getting leagues data: {lol}")
|
||||||
leagues = await asyncify(self._riotwatcher.league.by_summoner, region=self.config["Lol"]["region"],
|
leagues = await ru.asyncify(self._riotwatcher.league.by_summoner, region=self.config["Lol"]["region"],
|
||||||
encrypted_summoner_id=lol.summoner_id)
|
encrypted_summoner_id=lol.summoner_id)
|
||||||
soloq = LeagueLeague()
|
soloq = LeagueLeague()
|
||||||
flexq = LeagueLeague()
|
flexq = LeagueLeague()
|
||||||
twtrq = LeagueLeague()
|
twtrq = LeagueLeague()
|
||||||
|
@ -109,9 +110,9 @@ class LeagueoflegendsCommand(Command):
|
||||||
await self._change(lol, "rank_twtrq", twtrq, self._notify)
|
await self._change(lol, "rank_twtrq", twtrq, self._notify)
|
||||||
await self._change(lol, "rank_tftq", tftq, self._notify)
|
await self._change(lol, "rank_tftq", tftq, self._notify)
|
||||||
log.debug(f"Getting mastery data: {lol}")
|
log.debug(f"Getting mastery data: {lol}")
|
||||||
mastery = await asyncify(self._riotwatcher.champion_mastery.scores_by_summoner,
|
mastery = await ru.asyncify(self._riotwatcher.champion_mastery.scores_by_summoner,
|
||||||
region=self.config["Lol"]["region"],
|
region=self.config["Lol"]["region"],
|
||||||
encrypted_summoner_id=lol.summoner_id)
|
encrypted_summoner_id=lol.summoner_id)
|
||||||
await self._change(lol, "mastery_score", mastery, self._notify)
|
await self._change(lol, "mastery_score", mastery, self._notify)
|
||||||
|
|
||||||
async def _updater(self, period: int):
|
async def _updater(self, period: int):
|
||||||
|
@ -128,7 +129,7 @@ class LeagueoflegendsCommand(Command):
|
||||||
sentry_sdk.capture_exception(e)
|
sentry_sdk.capture_exception(e)
|
||||||
log.error(f"Error while updating {lol.user.username}: {e}")
|
log.error(f"Error while updating {lol.user.username}: {e}")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await asyncify(session.commit)
|
await ru.asyncify(session.commit)
|
||||||
session.close()
|
session.close()
|
||||||
log.info(f"Sleeping for {period}s")
|
log.info(f"Sleeping for {period}s")
|
||||||
await asyncio.sleep(period)
|
await asyncio.sleep(period)
|
||||||
|
@ -149,7 +150,7 @@ class LeagueoflegendsCommand(Command):
|
||||||
string += f"TFT: {lol.rank_tftq}\n"
|
string += f"TFT: {lol.rank_tftq}\n"
|
||||||
return string
|
return string
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
author = await data.get_author(error_if_none=True)
|
author = await data.get_author(error_if_none=True)
|
||||||
|
|
||||||
name = args.joined()
|
name = args.joined()
|
||||||
|
@ -159,10 +160,10 @@ class LeagueoflegendsCommand(Command):
|
||||||
log.debug(f"Searching for: {name}")
|
log.debug(f"Searching for: {name}")
|
||||||
summoner = self._riotwatcher.summoner.by_name(region=self.config["Lol"]["region"], summoner_name=name)
|
summoner = self._riotwatcher.summoner.by_name(region=self.config["Lol"]["region"], summoner_name=name)
|
||||||
# Ensure the account isn't already connected to something else
|
# Ensure the account isn't already connected to something else
|
||||||
leagueoflegends = await asyncify(
|
leagueoflegends = await ru.asyncify(
|
||||||
data.session.query(self.alchemy.get(LeagueOfLegends)).filter_by(summoner_id=summoner["id"]).one_or_none)
|
data.session.query(self.alchemy.get(LeagueOfLegends)).filter_by(summoner_id=summoner["id"]).one_or_none)
|
||||||
if leagueoflegends:
|
if leagueoflegends:
|
||||||
raise CommandError(f"L'account {leagueoflegends} è già registrato su Royalnet.")
|
raise rc.CommandError(f"L'account {leagueoflegends} è già registrato su Royalnet.")
|
||||||
# Get rank information
|
# Get rank information
|
||||||
log.debug(f"Getting leagues data: {name}")
|
log.debug(f"Getting leagues data: {name}")
|
||||||
leagues = self._riotwatcher.league.by_summoner(region=self.config["Lol"]["region"],
|
leagues = self._riotwatcher.league.by_summoner(region=self.config["Lol"]["region"],
|
||||||
|
@ -209,7 +210,7 @@ class LeagueoflegendsCommand(Command):
|
||||||
else:
|
else:
|
||||||
# Update and display the League of Legends stats for the current account
|
# Update and display the League of Legends stats for the current account
|
||||||
if len(author.leagueoflegends) == 0:
|
if len(author.leagueoflegends) == 0:
|
||||||
raise UserError("Nessun account di League of Legends trovato.")
|
raise rc.UserError("Nessun account di League of Legends trovato.")
|
||||||
message = ""
|
message = ""
|
||||||
for account in author.leagueoflegends:
|
for account in author.leagueoflegends:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import royalnet
|
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
import royalnet.serf.telegram as rt
|
import royalnet.backpack.tables as rbt
|
||||||
from royalnet.backpack.tables import Alias
|
|
||||||
from ..tables import Fiorygi, FiorygiTransaction
|
from ..tables import FiorygiTransaction
|
||||||
|
|
||||||
|
|
||||||
class MagickfiorygiCommand(rc.Command):
|
class MagickfiorygiCommand(rc.Command):
|
||||||
|
@ -24,7 +23,7 @@ class MagickfiorygiCommand(rc.Command):
|
||||||
|
|
||||||
if user_arg is None:
|
if user_arg is None:
|
||||||
raise rc.InvalidInputError("Non hai specificato un destinatario!")
|
raise rc.InvalidInputError("Non hai specificato un destinatario!")
|
||||||
user = await Alias.find_user(self.alchemy, data.session, user_arg)
|
user = await rbt.Alias.find_user(self.alchemy, data.session, user_arg)
|
||||||
if user is None:
|
if user is None:
|
||||||
raise rc.InvalidInputError("L'utente specificato non esiste!")
|
raise rc.InvalidInputError("L'utente specificato non esiste!")
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ from royalnet.serf.telegram import TelegramSerf as TelegramBot
|
||||||
from royalnet.serf.telegram import escape as telegram_escape
|
from royalnet.serf.telegram import escape as telegram_escape
|
||||||
from royalnet.utils import asyncify, sleep_until, sentry_async_wrap
|
from royalnet.utils import asyncify, sleep_until, sentry_async_wrap
|
||||||
from royalnet.backpack.tables import User
|
from royalnet.backpack.tables import User
|
||||||
|
|
||||||
from ..tables import MMEvent, MMResponse, FiorygiTransaction
|
from ..tables import MMEvent, MMResponse, FiorygiTransaction
|
||||||
from ..types import MMChoice, MMInterfaceDataTelegram
|
from ..types import MMChoice, MMInterfaceDataTelegram
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import discord
|
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import discord
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class PauseCommand(Command):
|
class PauseCommand(rc.Command):
|
||||||
name: str = "pause"
|
name: str = "pause"
|
||||||
|
|
||||||
aliases = ["resume"]
|
aliases = ["resume"]
|
||||||
|
|
||||||
description: str = "Metti in pausa o riprendi la riproduzione di un file."
|
description: str = "Metti in pausa o riprendi la riproduzione di un file."
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
guild: discord.Guild = message.guild
|
guild: discord.Guild = message.guild
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from .play import PlayCommand
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
class PeertubeCommand(PlayCommand):
|
class PeertubeCommand(PlayCommand):
|
||||||
name: str = "peertube"
|
name: str = "peertube"
|
||||||
|
@ -20,5 +22,5 @@ class PeertubeCommand(PlayCommand):
|
||||||
f"/api/v1/search/videos?search={search}") as response:
|
f"/api/v1/search/videos?search={search}") as response:
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
if j["total"] < 1:
|
if j["total"] < 1:
|
||||||
raise InvalidInputError("Nessun video trovato.")
|
raise rc.InvalidInputError("Nessun video trovato.")
|
||||||
return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']
|
return [f'{self.config["Peertube"]["instance_url"]}/videos/watch/{j["data"][0]["uuid"]}']
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
|
from typing import *
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import dateparser
|
import dateparser
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.serf.telegram.escape import escape
|
import royalnet.serf.telegram as rst
|
||||||
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PeertubeUpdatesCommand(Command):
|
class PeertubeUpdatesCommand(rc.Command):
|
||||||
name: str = "peertubeupdates"
|
name: str = "peertubeupdates"
|
||||||
|
|
||||||
description: str = "Guarda quando è uscito l'ultimo video su PeerTube."
|
description: str = "Guarda quando è uscito l'ultimo video su PeerTube."
|
||||||
|
@ -21,7 +22,7 @@ class PeertubeUpdatesCommand(Command):
|
||||||
|
|
||||||
_latest_date: datetime.datetime = None
|
_latest_date: datetime.datetime = None
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
self.loop.create_task(self._ready_up())
|
self.loop.create_task(self._ready_up())
|
||||||
|
@ -34,7 +35,7 @@ class PeertubeUpdatesCommand(Command):
|
||||||
"/feeds/videos.json?sort=-publishedAt&filter=local") as response:
|
"/feeds/videos.json?sort=-publishedAt&filter=local") as response:
|
||||||
log.debug("Parsing jsonfeed")
|
log.debug("Parsing jsonfeed")
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
raise ExternalError("Peertube is unavailable")
|
raise rc.ExternalError("Peertube is unavailable")
|
||||||
j = await response.json()
|
j = await response.json()
|
||||||
log.debug("Jsonfeed parsed successfully")
|
log.debug("Jsonfeed parsed successfully")
|
||||||
return j
|
return j
|
||||||
|
@ -43,14 +44,14 @@ class PeertubeUpdatesCommand(Command):
|
||||||
client = self.interface.bot.client
|
client = self.interface.bot.client
|
||||||
await self.interface.bot.safe_api_call(client.send_message,
|
await self.interface.bot.safe_api_call(client.send_message,
|
||||||
chat_id=self.config["Telegram"]["main_group_id"],
|
chat_id=self.config["Telegram"]["main_group_id"],
|
||||||
text=escape(message),
|
text=rst.escape(message),
|
||||||
parse_mode="HTML",
|
parse_mode="HTML",
|
||||||
disable_webpage_preview=True)
|
disable_webpage_preview=True)
|
||||||
|
|
||||||
async def _ready_up(self):
|
async def _ready_up(self):
|
||||||
j = await self._get_json()
|
j = await self._get_json()
|
||||||
if j["version"] != "https://jsonfeed.org/version/1":
|
if j["version"] != "https://jsonfeed.org/version/1":
|
||||||
raise ConfigurationError("url is not a jsonfeed")
|
raise rc.ConfigurationError("url is not a jsonfeed")
|
||||||
videos = j["items"]
|
videos = j["items"]
|
||||||
for video in reversed(videos):
|
for video in reversed(videos):
|
||||||
date_modified = dateparser.parse(video["date_modified"])
|
date_modified = dateparser.parse(video["date_modified"])
|
||||||
|
@ -74,7 +75,7 @@ class PeertubeUpdatesCommand(Command):
|
||||||
f"{video['url']}")
|
f"{video['url']}")
|
||||||
await asyncio.sleep(self.config["Peertube"]["feed_update_timeout"])
|
await asyncio.sleep(self.config["Peertube"]["feed_update_timeout"])
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name != "telegram":
|
if self.interface.name != "telegram":
|
||||||
raise UnsupportedError()
|
raise rc.UnsupportedError()
|
||||||
await data.reply(f"ℹ️ Ultimo video caricato il: [b]{self._latest_date.isoformat()}[/b]")
|
await data.reply(f"ℹ️ Ultimo video caricato il: [b]{self._latest_date.isoformat()}[/b]")
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
from typing import *
|
||||||
import discord
|
import discord
|
||||||
import asyncio as aio
|
import asyncio as aio
|
||||||
from typing import *
|
import royalnet.commands as rc
|
||||||
from royalnet.commands import *
|
import royalnet.backpack.tables as rbt
|
||||||
from royalnet.backpack.tables import User, Discord
|
|
||||||
|
|
||||||
|
|
||||||
class PlayCommand(Command):
|
class PlayCommand(rc.Command):
|
||||||
name: str = "play"
|
name: str = "play"
|
||||||
|
|
||||||
aliases = ["p"]
|
aliases = ["p"]
|
||||||
|
@ -14,17 +14,17 @@ class PlayCommand(Command):
|
||||||
|
|
||||||
syntax = "{url}"
|
syntax = "{url}"
|
||||||
|
|
||||||
async def get_urls(self, args: CommandArgs):
|
async def get_urls(self, args: rc.CommandArgs):
|
||||||
url = args.joined(require_at_least=1)
|
url = args.joined(require_at_least=1)
|
||||||
if not (url.startswith("http://") or url.startswith("https://")):
|
if not (url.startswith("http://") or url.startswith("https://")):
|
||||||
raise InvalidInputError(f"L'URL specificato non inizia con il nome di un protocollo supportato"
|
raise rc.InvalidInputError(f"L'URL specificato non inizia con il nome di un protocollo supportato"
|
||||||
f" ([c]http://[/c] o [c]https://[/c]).")
|
f" ([c]http://[/c] o [c]https://[/c]).")
|
||||||
return [url]
|
return [url]
|
||||||
|
|
||||||
def get_embed_color(self) -> Optional[int]:
|
def get_embed_color(self) -> Optional[int]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
guild: discord.Guild = message.guild
|
guild: discord.Guild = message.guild
|
||||||
|
@ -35,12 +35,12 @@ class PlayCommand(Command):
|
||||||
else:
|
else:
|
||||||
guild_id = None
|
guild_id = None
|
||||||
|
|
||||||
user: User = await data.get_author()
|
user: rbt.User = await data.get_author()
|
||||||
user_str = None
|
user_str = None
|
||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
try:
|
try:
|
||||||
user_discord: Discord = user.discord[0]
|
user_discord: rbt.Discord = user.discord[0]
|
||||||
except (AttributeError, IndexError):
|
except (AttributeError, IndexError):
|
||||||
user_str = str(user)
|
user_str = str(user)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import royalnet
|
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
import discord
|
import discord
|
||||||
from royalnet.backpack.tables import User, Discord
|
import royalnet.backpack.tables as rbt
|
||||||
|
|
||||||
|
|
||||||
class PlaymodeCommand(rc.Command):
|
class PlaymodeCommand(rc.Command):
|
||||||
|
@ -25,12 +24,12 @@ class PlaymodeCommand(rc.Command):
|
||||||
else:
|
else:
|
||||||
guild_id = None
|
guild_id = None
|
||||||
|
|
||||||
user: User = await data.get_author()
|
user: rbt.User = await data.get_author()
|
||||||
user_str = None
|
user_str = None
|
||||||
|
|
||||||
if user is not None:
|
if user is not None:
|
||||||
try:
|
try:
|
||||||
user_discord: Discord = user.discord[0]
|
user_discord: rbt.Discord = user.discord[0]
|
||||||
except (AttributeError, IndexError):
|
except (AttributeError, IndexError):
|
||||||
user_str = str(user)
|
user_str = str(user)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class PmotsCommand(Command):
|
class PmotsCommand(rc.Command):
|
||||||
name: str = "pmots"
|
name: str = "pmots"
|
||||||
|
|
||||||
description: str = "Confondi Proto!"
|
description: str = "Confondi Proto!"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
await data.reply("👣 pmots pmots")
|
await data.reply("👣 pmots pmots")
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
|
from typing import *
|
||||||
import pickle
|
import pickle
|
||||||
import base64
|
import base64
|
||||||
import discord
|
import discord
|
||||||
from typing import *
|
import royalnet.commands as rc
|
||||||
from royalnet.commands import *
|
import royalnet.utils as ru
|
||||||
from royalnet.utils import *
|
|
||||||
|
|
||||||
|
|
||||||
class QueueCommand(Command):
|
class QueueCommand(rc.Command):
|
||||||
name: str = "queue"
|
name: str = "queue"
|
||||||
|
|
||||||
aliases = ["q"]
|
aliases = ["q"]
|
||||||
|
|
||||||
description: str = "Visualizza la coda di riproduzione attuale."
|
description: str = "Visualizza la coda di riproduzione attuale."
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
guild: discord.Guild = message.guild
|
guild: discord.Guild = message.guild
|
||||||
|
@ -54,9 +54,9 @@ class QueueCommand(Command):
|
||||||
# noinspection PyUnboundLocalVariable
|
# noinspection PyUnboundLocalVariable
|
||||||
await message.channel.send(embed=embed)
|
await message.channel.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
reply += numberemojiformat([a["title"] for a in next_up[:5]])
|
reply += ru.numberemojiformat([a["title"] for a in next_up[:5]])
|
||||||
await data.reply(reply)
|
await data.reply(reply)
|
||||||
else:
|
else:
|
||||||
await data.reply("ℹ️ Non ci sono altri file in coda.")
|
await data.reply("ℹ️ Non ci sono altri file in coda.")
|
||||||
else:
|
else:
|
||||||
raise CommandError(f"Non so come visualizzare il contenuto di un [c]{queue_type}[/c].")
|
raise rc.CommandError(f"Non so come visualizzare il contenuto di un [c]{queue_type}[/c].")
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import typing
|
from typing import *
|
||||||
import random
|
import random
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class RageCommand(Command):
|
class RageCommand(rc.Command):
|
||||||
name: str = "rage"
|
name: str = "rage"
|
||||||
|
|
||||||
aliases = ["balurage", "madden"]
|
aliases = ["balurage", "madden"]
|
||||||
|
@ -18,5 +18,5 @@ class RageCommand(Command):
|
||||||
"Fondiamo la RRYG!"
|
"Fondiamo la RRYG!"
|
||||||
]
|
]
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
await data.reply(f"😠 {random.sample(self._MAD, 1)[0]}")
|
await data.reply(f"😠 {random.sample(self._MAD, 1)[0]}")
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import typing
|
from typing import *
|
||||||
import dateparser
|
import dateparser
|
||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle
|
||||||
import telegram
|
import telegram
|
||||||
import discord
|
import discord
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import *
|
import royalnet.utils as ru
|
||||||
from royalnet.serf.telegram import escape as telegram_escape
|
from royalnet.serf.telegram import escape as telegram_escape
|
||||||
from royalnet.serf.discord import escape as discord_escape
|
from royalnet.serf.discord import escape as discord_escape
|
||||||
|
|
||||||
from ..tables import Reminder
|
from ..tables import Reminder
|
||||||
|
|
||||||
|
|
||||||
class ReminderCommand(Command):
|
class ReminderCommand(rc.Command):
|
||||||
name: str = "reminder"
|
name: str = "reminder"
|
||||||
|
|
||||||
aliases = ["calendar"]
|
aliases = ["calendar"]
|
||||||
|
@ -21,7 +22,7 @@ class ReminderCommand(Command):
|
||||||
|
|
||||||
syntax: str = "[ {data} ] {messaggio}"
|
syntax: str = "[ {data} ] {messaggio}"
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
session = interface.alchemy.Session()
|
session = interface.alchemy.Session()
|
||||||
reminders = (
|
reminders = (
|
||||||
|
@ -35,7 +36,7 @@ class ReminderCommand(Command):
|
||||||
interface.loop.create_task(self._remind(reminder))
|
interface.loop.create_task(self._remind(reminder))
|
||||||
|
|
||||||
async def _remind(self, reminder):
|
async def _remind(self, reminder):
|
||||||
await sleep_until(reminder.datetime)
|
await ru.sleep_until(reminder.datetime)
|
||||||
if self.interface.name == "telegram":
|
if self.interface.name == "telegram":
|
||||||
chat_id: int = pickle.loads(reminder.interface_data)
|
chat_id: int = pickle.loads(reminder.interface_data)
|
||||||
client: telegram.Bot = self.serf.client
|
client: telegram.Bot = self.serf.client
|
||||||
|
@ -50,14 +51,14 @@ class ReminderCommand(Command):
|
||||||
channel = client.get_channel(channel_id)
|
channel = client.get_channel(channel_id)
|
||||||
await channel.send(discord_escape(f"❗️ {reminder.message}"))
|
await channel.send(discord_escape(f"❗️ {reminder.message}"))
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
try:
|
try:
|
||||||
date_str, reminder_text = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*")
|
date_str, reminder_text = args.match(r"\[\s*([^]]+)\s*]\s*([^\n]+)\s*")
|
||||||
except InvalidInputError:
|
except rc.InvalidInputError:
|
||||||
date_str, reminder_text = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*")
|
date_str, reminder_text = args.match(r"\s*(.+?)\s*\n\s*([^\n]+)\s*")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
date: typing.Optional[datetime.datetime] = dateparser.parse(date_str, settings={
|
date: Optional[datetime.datetime] = dateparser.parse(date_str, settings={
|
||||||
"PREFER_DATES_FROM": "future"
|
"PREFER_DATES_FROM": "future"
|
||||||
})
|
})
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
|
@ -74,7 +75,7 @@ class ReminderCommand(Command):
|
||||||
elif self.interface.name == "discord":
|
elif self.interface.name == "discord":
|
||||||
interface_data = pickle.dumps(data.message.channel.id)
|
interface_data = pickle.dumps(data.message.channel.id)
|
||||||
else:
|
else:
|
||||||
raise UnsupportedError("This command does not support the current interface.")
|
raise rc.UnsupportedError("This command does not support the current interface.")
|
||||||
creator = await data.get_author()
|
creator = await data.get_author()
|
||||||
reminder = self.interface.alchemy.get(Reminder)(creator=creator,
|
reminder = self.interface.alchemy.get(Reminder)(creator=creator,
|
||||||
interface_name=self.interface.name,
|
interface_name=self.interface.name,
|
||||||
|
@ -83,4 +84,4 @@ class ReminderCommand(Command):
|
||||||
message=reminder_text)
|
message=reminder_text)
|
||||||
self.interface.loop.create_task(self._remind(reminder))
|
self.interface.loop.create_task(self._remind(reminder))
|
||||||
data.session.add(reminder)
|
data.session.add(reminder)
|
||||||
await asyncify(data.session.commit)
|
await ru.asyncify(data.session.commit)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
|
|
||||||
from ..version import semantic
|
from ..version import semantic
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
|
from typing import *
|
||||||
import re
|
import re
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class ShipCommand(Command):
|
class ShipCommand(rc.Command):
|
||||||
name: str = "ship"
|
name: str = "ship"
|
||||||
|
|
||||||
description: str = "Crea una ship tra due nomi."
|
description: str = "Crea una ship tra due nomi."
|
||||||
|
|
||||||
syntax = "{nomeuno} {nomedue}"
|
syntax = "{nomeuno} {nomedue}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
name_one = args[0]
|
name_one = args[0]
|
||||||
name_two = args[1]
|
name_two = args[1]
|
||||||
if name_two == "+":
|
if name_two == "+":
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import discord
|
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import discord
|
||||||
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class SkipCommand(Command):
|
class SkipCommand(rc.Command):
|
||||||
name: str = "skip"
|
name: str = "skip"
|
||||||
|
|
||||||
aliases = ["s"]
|
aliases = ["s"]
|
||||||
|
|
||||||
description: str = "Salta il file attualmente in riproduzione."
|
description: str = "Salta il file attualmente in riproduzione."
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
guild: discord.Guild = message.guild
|
guild: discord.Guild = message.guild
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import typing
|
from typing import *
|
||||||
import random
|
import random
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class SmecdsCommand(Command):
|
class SmecdsCommand(rc.Command):
|
||||||
name: str = "smecds"
|
name: str = "smecds"
|
||||||
|
|
||||||
aliases = ["secondomeecolpadellostagista"]
|
aliases = ["secondomeecolpadellostagista"]
|
||||||
|
@ -61,6 +61,6 @@ class SmecdsCommand(Command):
|
||||||
"dello Slime God", "del salassato", "della salsa", "di Senjougahara", "di Sugar", "della Stampa",
|
"dello Slime God", "del salassato", "della salsa", "di Senjougahara", "di Sugar", "della Stampa",
|
||||||
"della Stampante"]
|
"della Stampante"]
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
ds = random.sample(self._DS_LIST, 1)[0]
|
ds = random.sample(self._DS_LIST, 1)[0]
|
||||||
await data.reply(f"🤔 Secondo me, è colpa {ds}.")
|
await data.reply(f"🤔 Secondo me, è colpa {ds}.")
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,17 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import *
|
import royalnet.utils as ru
|
||||||
from royalnet.backpack.tables import User
|
|
||||||
from sqlalchemy import func
|
|
||||||
import royalspells as rs
|
import royalspells as rs
|
||||||
|
|
||||||
|
|
||||||
class SpellCommand(Command):
|
class SpellCommand(rc.Command):
|
||||||
name: str = "spell"
|
name: str = "spell"
|
||||||
|
|
||||||
description: str = "Genera casualmente una spell!"
|
description: str = "Genera casualmente una spell!"
|
||||||
|
|
||||||
syntax = "{nome_spell}"
|
syntax = "{nome_spell}"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
spell_name = args.joined(require_at_least=1)
|
spell_name = args.joined(require_at_least=1)
|
||||||
spell = rs.Spell(spell_name)
|
spell = rs.Spell(spell_name)
|
||||||
|
|
||||||
|
@ -23,7 +21,7 @@ class SpellCommand(Command):
|
||||||
dmg: rs.DamageComponent = spell.damage_component
|
dmg: rs.DamageComponent = spell.damage_component
|
||||||
constant_str: str = f"{dmg.constant:+d}" if dmg.constant != 0 else ""
|
constant_str: str = f"{dmg.constant:+d}" if dmg.constant != 0 else ""
|
||||||
rows.append(f"Danni: [b]{dmg.dice_number}d{dmg.dice_type}{constant_str}[/b]"
|
rows.append(f"Danni: [b]{dmg.dice_number}d{dmg.dice_type}{constant_str}[/b]"
|
||||||
f" {andformat(dmg.damage_types, final=' e ')}")
|
f" {ru.andformat(dmg.damage_types, final=' e ')}")
|
||||||
rows.append(f"Precisione: [b]{dmg.miss_chance}%[/b]")
|
rows.append(f"Precisione: [b]{dmg.miss_chance}%[/b]")
|
||||||
if dmg.repeat > 1:
|
if dmg.repeat > 1:
|
||||||
rows.append(f"Multiattacco: [b]×{dmg.repeat}[/b]")
|
rows.append(f"Multiattacco: [b]×{dmg.repeat}[/b]")
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
|
||||||
from royalnet.utils import *
|
|
||||||
from royalnet.backpack.tables import Alias
|
|
||||||
from ..tables import Steam
|
|
||||||
import steam
|
import steam
|
||||||
import requests.exceptions
|
import requests.exceptions
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
import royalnet.backpack.tables as rbt
|
||||||
|
|
||||||
|
from ..tables import Steam
|
||||||
|
|
||||||
|
|
||||||
class SteamGame:
|
class SteamGame:
|
||||||
|
@ -45,47 +46,47 @@ class SteamGame:
|
||||||
return f"<{self.__class__.__qualname__} {self.appid} ({self.name})>"
|
return f"<{self.__class__.__qualname__} {self.appid} ({self.name})>"
|
||||||
|
|
||||||
|
|
||||||
class SteammatchCommand(Command):
|
class SteammatchCommand(rc.Command):
|
||||||
name: str = "steammatch"
|
name: str = "steammatch"
|
||||||
|
|
||||||
description: str = "Vedi quali giochi hai in comune con uno o più membri!"
|
description: str = "Vedi quali giochi hai in comune con uno o più membri!"
|
||||||
|
|
||||||
syntax: str = "{royalnet_username}+"
|
syntax: str = "{royalnet_username}+"
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
if "Steam" not in self.config or "web_api_key" not in self.config["Steam"]:
|
if "Steam" not in self.config or "web_api_key" not in self.config["Steam"]:
|
||||||
raise ConfigurationError("[c]Steam.web_api_key[/c] config option is missing!")
|
raise rc.ConfigurationError("[c]Steam.web_api_key[/c] config option is missing!")
|
||||||
self._api = steam.WebAPI(self.config["Steam"]["web_api_key"])
|
self._api = steam.WebAPI(self.config["Steam"]["web_api_key"])
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
users = []
|
users = []
|
||||||
|
|
||||||
author = await data.get_author(error_if_none=True)
|
author = await data.get_author(error_if_none=True)
|
||||||
users.append(author)
|
users.append(author)
|
||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
user = await Alias.find_user(self.alchemy, data.session, arg)
|
user = await rbt.User.find(self.alchemy, data.session, arg)
|
||||||
users.append(user)
|
users.append(user)
|
||||||
|
|
||||||
if len(users) < 2:
|
if len(users) < 2:
|
||||||
raise InvalidInputError("Devi specificare almeno un altro utente!")
|
raise rc.InvalidInputError("Devi specificare almeno un altro utente!")
|
||||||
|
|
||||||
shared_games: Optional[set] = None
|
shared_games: Optional[set] = None
|
||||||
for user in users:
|
for user in users:
|
||||||
user_games = set()
|
user_games = set()
|
||||||
if len(user.steam) == 0:
|
if len(user.steam) == 0:
|
||||||
raise UserError(f"{user} non ha un account Steam registrato!")
|
raise rc.UserError(f"{user} non ha un account Steam registrato!")
|
||||||
for steam_account in user.steam:
|
for steam_account in user.steam:
|
||||||
steam_account: Steam
|
steam_account: Steam
|
||||||
try:
|
try:
|
||||||
response = await asyncify(self._api.IPlayerService.GetOwnedGames,
|
response = await ru.asyncify(self._api.IPlayerService.GetOwnedGames,
|
||||||
steamid=steam_account._steamid,
|
steamid=steam_account._steamid,
|
||||||
include_appinfo=True,
|
include_appinfo=True,
|
||||||
include_played_free_games=True,
|
include_played_free_games=True,
|
||||||
appids_filter=0)
|
appids_filter=0)
|
||||||
except requests.exceptions.HTTPError:
|
except requests.exceptions.HTTPError:
|
||||||
raise ExternalError(f"L'account Steam di {user} è privato!")
|
raise rc.ExternalError(f"L'account Steam di {user} è privato!")
|
||||||
games = response["response"]["games"]
|
games = response["response"]["games"]
|
||||||
for game in games:
|
for game in games:
|
||||||
user_games.add(SteamGame(**game))
|
user_games.add(SteamGame(**game))
|
||||||
|
@ -94,7 +95,7 @@ class SteammatchCommand(Command):
|
||||||
else:
|
else:
|
||||||
shared_games = shared_games.intersection(user_games)
|
shared_games = shared_games.intersection(user_games)
|
||||||
|
|
||||||
message_rows = [f"🎮 Giochi in comune tra {andformat([str(user) for user in users], final=' e ')}:"]
|
message_rows = [f"🎮 Giochi in comune tra {ru.andformat([str(user) for user in users], final=' e ')}:"]
|
||||||
for game in sorted(list(shared_games), key=lambda g: g.name):
|
for game in sorted(list(shared_games), key=lambda g: g.name):
|
||||||
message_rows.append(f"- {game}")
|
message_rows.append(f"- {game}")
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
|
||||||
from royalnet.utils import *
|
|
||||||
from ..tables import Steam, FiorygiTransaction
|
|
||||||
import steam
|
import steam
|
||||||
import datetime
|
import datetime
|
||||||
|
import royalnet.commands as rc
|
||||||
|
import royalnet.utils as ru
|
||||||
|
|
||||||
|
from ..tables import Steam, FiorygiTransaction
|
||||||
|
|
||||||
|
|
||||||
class SteampoweredCommand(Command):
|
class SteampoweredCommand(rc.Command):
|
||||||
name: str = "steampowered"
|
name: str = "steampowered"
|
||||||
|
|
||||||
description: str = "Connetti il tuo account di Steam!"
|
description: str = "Connetti il tuo account di Steam!"
|
||||||
|
|
||||||
syntax: str = "{profile_url}"
|
syntax: str = "{profile_url}"
|
||||||
|
|
||||||
def __init__(self, interface: CommandInterface):
|
def __init__(self, interface: rc.CommandInterface):
|
||||||
super().__init__(interface)
|
super().__init__(interface)
|
||||||
if "Steam" not in self.config or "web_api_key" not in self.config["Steam"]:
|
if "Steam" not in self.config or "web_api_key" not in self.config["Steam"]:
|
||||||
raise ConfigurationError("[c]Steam.web_api_key[/c] config option is missing!")
|
raise rc.ConfigurationError("[c]Steam.web_api_key[/c] config option is missing!")
|
||||||
self._api = steam.WebAPI(self.config["Steam"]["web_api_key"])
|
self._api = steam.WebAPI(self.config["Steam"]["web_api_key"])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -34,9 +35,9 @@ class SteampoweredCommand(Command):
|
||||||
|
|
||||||
async def _call(self, method, *args, **kwargs):
|
async def _call(self, method, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
await asyncify(method, *args, **kwargs)
|
await ru.asyncify(method, *args, **kwargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ExternalError("\n".join(e.args).replace(self.config["Steam"]["web_api_key"], "HIDDEN"))
|
raise rc.ExternalError("\n".join(e.args).replace(self.config["Steam"]["web_api_key"], "HIDDEN"))
|
||||||
|
|
||||||
async def _update(self, account: Steam):
|
async def _update(self, account: Steam):
|
||||||
# noinspection PyProtectedMember
|
# noinspection PyProtectedMember
|
||||||
|
@ -48,13 +49,13 @@ class SteampoweredCommand(Command):
|
||||||
account.primary_clan_id = r["primaryclanid"]
|
account.primary_clan_id = r["primaryclanid"]
|
||||||
account.account_creation_date = datetime.datetime.fromtimestamp(r["timecreated"])
|
account.account_creation_date = datetime.datetime.fromtimestamp(r["timecreated"])
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
author = await data.get_author()
|
author = await data.get_author()
|
||||||
if len(args) > 0:
|
if len(args) > 0:
|
||||||
url = args.joined()
|
url = args.joined()
|
||||||
steamid64 = await self._call(steam.steamid.steam64_from_url, url)
|
steamid64 = await self._call(steam.steamid.steam64_from_url, url)
|
||||||
if steamid64 is None:
|
if steamid64 is None:
|
||||||
raise InvalidInputError("Quel link non è associato ad alcun account Steam.")
|
raise rc.InvalidInputError("Quel link non è associato ad alcun account Steam.")
|
||||||
response = await self._call(self._api.ISteamUser.GetPlayerSummaries_v2, steamids=steamid64)
|
response = await self._call(self._api.ISteamUser.GetPlayerSummaries_v2, steamids=steamid64)
|
||||||
r = response["response"]["players"][0]
|
r = response["response"]["players"][0]
|
||||||
steam_account = self.alchemy.get(Steam)(
|
steam_account = self.alchemy.get(Steam)(
|
||||||
|
@ -74,7 +75,7 @@ class SteampoweredCommand(Command):
|
||||||
else:
|
else:
|
||||||
# Update and display the Steam info for the current account
|
# Update and display the Steam info for the current account
|
||||||
if len(author.steam) == 0:
|
if len(author.steam) == 0:
|
||||||
raise UserError("Nessun account di Steam trovato.")
|
raise rc.UserError("Nessun account di Steam trovato.")
|
||||||
message = ""
|
message = ""
|
||||||
for account in author.steam:
|
for account in author.steam:
|
||||||
await self._update(account)
|
await self._update(account)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
from typing import *
|
||||||
|
import royalnet.commands as rc
|
||||||
import discord
|
import discord
|
||||||
from royalnet.commands import *
|
|
||||||
|
|
||||||
|
|
||||||
class SummonCommand(Command):
|
class SummonCommand(rc.Command):
|
||||||
name: str = "summon"
|
name: str = "summon"
|
||||||
|
|
||||||
aliases = ["cv"]
|
aliases = ["cv"]
|
||||||
|
@ -11,7 +12,7 @@ class SummonCommand(Command):
|
||||||
|
|
||||||
syntax: str = "[nomecanale]"
|
syntax: str = "[nomecanale]"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
channel_name = args.joined()
|
channel_name = args.joined()
|
||||||
if self.interface.name == "discord":
|
if self.interface.name == "discord":
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
|
|
|
@ -6,8 +6,8 @@ import uuid
|
||||||
import html
|
import html
|
||||||
import royalnet.commands as rc
|
import royalnet.commands as rc
|
||||||
import royalnet.utils as ru
|
import royalnet.utils as ru
|
||||||
|
import royalnet.backpack.tables as rbt
|
||||||
from ..tables import TriviaScore
|
from ..tables import TriviaScore
|
||||||
from royalnet.backpack.tables.users import User
|
|
||||||
|
|
||||||
|
|
||||||
class TriviaCommand(rc.Command):
|
class TriviaCommand(rc.Command):
|
||||||
|
@ -126,7 +126,7 @@ class TriviaCommand(rc.Command):
|
||||||
results = f"❗️ Tempo scaduto!\n" \
|
results = f"❗️ Tempo scaduto!\n" \
|
||||||
f"La risposta corretta era [b]{answers[correct_index]}[/b]!\n\n"
|
f"La risposta corretta era [b]{answers[correct_index]}[/b]!\n\n"
|
||||||
for answerer_id in self._answerers[question_id]:
|
for answerer_id in self._answerers[question_id]:
|
||||||
answerer = data.session.query(self.alchemy.get(User)).get(answerer_id)
|
answerer = data.session.query(self.alchemy.get(rbt.users.User)).get(answerer_id)
|
||||||
if answerer.trivia_score is None:
|
if answerer.trivia_score is None:
|
||||||
ts = self.interface.alchemy.get(TriviaScore)(user=answerer)
|
ts = self.interface.alchemy.get(TriviaScore)(user=answerer)
|
||||||
data.session.add(ts)
|
data.session.add(ts)
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
from royalnet.utils import *
|
import royalnet.backpack.tables as rbt
|
||||||
from royalnet.backpack.tables import User, Alias
|
|
||||||
from sqlalchemy import func
|
|
||||||
|
|
||||||
|
|
||||||
class UserinfoCommand(Command):
|
class UserinfoCommand(rc.Command):
|
||||||
name: str = "userinfo"
|
name: str = "userinfo"
|
||||||
|
|
||||||
aliases = ["uinfo", "ui", "useri"]
|
aliases = ["uinfo", "ui", "useri"]
|
||||||
|
@ -14,23 +12,27 @@ class UserinfoCommand(Command):
|
||||||
|
|
||||||
syntax = "[username]"
|
syntax = "[username]"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
username = args.optional(0)
|
username = args.optional(0)
|
||||||
if username is None:
|
if username is None:
|
||||||
user: User = await data.get_author(error_if_none=True)
|
user: rbt.User = await data.get_author(error_if_none=True)
|
||||||
else:
|
else:
|
||||||
found: Optional[User] = await Alias.find_user(self.alchemy, data.session, username)
|
found: Optional[rbt.User] = await rbt.User.find(self.alchemy, data.session, username)
|
||||||
if not found:
|
if not found:
|
||||||
raise InvalidInputError("Utente non trovato.")
|
raise rc.InvalidInputError("Utente non trovato.")
|
||||||
else:
|
else:
|
||||||
user = found
|
user = found
|
||||||
|
|
||||||
r = [
|
r = [
|
||||||
f"ℹ️ [url=https://ryg.steffo.eu/#/user/{user.uid}]{user.username}[/url]",
|
f"ℹ️ [url=https://ryg.steffo.eu/#/user/{user.uid}]{user.username}[/url]",
|
||||||
f"{user.role}",
|
f"{', '.join(user.roles)}",
|
||||||
"",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if user.email:
|
||||||
|
r.append(f"{user.email}")
|
||||||
|
|
||||||
|
r.append("")
|
||||||
|
|
||||||
# Bios are a bit too long
|
# Bios are a bit too long
|
||||||
# if user.bio:
|
# if user.bio:
|
||||||
# r.append(f"{user.bio}")
|
# r.append(f"{user.bio}")
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import typing
|
from typing import *
|
||||||
import discord
|
import discord
|
||||||
from royalnet.commands import *
|
import royalnet.commands as rc
|
||||||
|
|
||||||
|
|
||||||
class VideochannelCommand(Command):
|
class VideochannelCommand(rc.Command):
|
||||||
name: str = "videochannel"
|
name: str = "videochannel"
|
||||||
|
|
||||||
aliases = ["golive", "live", "video"]
|
aliases = ["golive", "live", "video"]
|
||||||
|
@ -12,33 +12,33 @@ class VideochannelCommand(Command):
|
||||||
|
|
||||||
syntax = "[nomecanale]"
|
syntax = "[nomecanale]"
|
||||||
|
|
||||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
async def run(self, args: rc.CommandArgs, data: rc.CommandData) -> None:
|
||||||
if self.interface.name != "discord":
|
if self.interface.name != "discord":
|
||||||
raise UnsupportedError(f"{self} non è supportato su {self.interface.name}.")
|
raise rc.UnsupportedError(f"{self} non è supportato su {self.interface.name}.")
|
||||||
bot: discord.Client = self.serf.client
|
bot: discord.Client = self.serf.client
|
||||||
message: discord.Message = data.message
|
message: discord.Message = data.message
|
||||||
channel_name: str = args.optional(0)
|
channel_name: str = args.optional(0)
|
||||||
if channel_name:
|
if channel_name:
|
||||||
guild: typing.Optional[discord.Guild] = message.guild
|
guild: Optional[discord.Guild] = message.guild
|
||||||
if guild is not None:
|
if guild is not None:
|
||||||
channels: typing.List[discord.abc.GuildChannel] = guild.channels
|
channels: List[discord.abc.GuildChannel] = guild.channels
|
||||||
else:
|
else:
|
||||||
channels = bot.get_all_channels()
|
channels = bot.get_all_channels()
|
||||||
matching_channels: typing.List[discord.VoiceChannel] = []
|
matching_channels: List[discord.VoiceChannel] = []
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
if isinstance(channel, discord.VoiceChannel):
|
if isinstance(channel, discord.VoiceChannel):
|
||||||
if channel.name == channel_name:
|
if channel.name == channel_name:
|
||||||
matching_channels.append(channel)
|
matching_channels.append(channel)
|
||||||
if len(matching_channels) == 0:
|
if len(matching_channels) == 0:
|
||||||
raise InvalidInputError("Non esiste alcun canale vocale con il nome specificato.")
|
raise rc.InvalidInputError("Non esiste alcun canale vocale con il nome specificato.")
|
||||||
elif len(matching_channels) > 1:
|
elif len(matching_channels) > 1:
|
||||||
raise UserError("Esiste più di un canale vocale con il nome specificato.")
|
raise rc.UserError("Esiste più di un canale vocale con il nome specificato.")
|
||||||
channel = matching_channels[0]
|
channel = matching_channels[0]
|
||||||
else:
|
else:
|
||||||
author: discord.Member = message.author
|
author: discord.Member = message.author
|
||||||
voice: typing.Optional[discord.VoiceState] = author.voice
|
voice: Optional[discord.VoiceState] = author.voice
|
||||||
if voice is None:
|
if voice is None:
|
||||||
raise InvalidInputError("Non sei connesso a nessun canale vocale.")
|
raise rc.InvalidInputError("Non sei connesso a nessun canale vocale.")
|
||||||
channel = voice.channel
|
channel = voice.channel
|
||||||
if author.is_on_mobile():
|
if author.is_on_mobile():
|
||||||
await data.reply(f"📹 Per entrare in modalità video, clicca qui:\n"
|
await data.reply(f"📹 Per entrare in modalità video, clicca qui:\n"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from typing import *
|
||||||
from .play import PlayCommand
|
from .play import PlayCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
semantic = "5.7.15"
|
semantic = "5.8.0"
|
||||||
|
|
Loading…
Reference in a new issue