Compare commits
60 Commits
e9d80e5e62
...
main
Author | SHA1 | Date | |
---|---|---|---|
3525ea42e1 | |||
f1db0f62fc | |||
fd5f5a7e7a | |||
fc2fe0a396 | |||
292db8133d | |||
febdfaf355 | |||
9702e1e77a | |||
ff5e7f310a | |||
d7f4540dcd | |||
97a1ab1b2b | |||
43cfb49cd6 | |||
133af80aad | |||
59d1dc4afb | |||
7577e3afee | |||
ad70870d8e | |||
a774d0a0fc | |||
512b3b05d2 | |||
0c4224314b | |||
1a3d2f0b14 | |||
4318b58db0 | |||
a32bb598d2 | |||
dbaa692711 | |||
5557c16d8c | |||
b7bd032e07 | |||
16a419f558 | |||
03fcc5ef52 | |||
5f70ffd69b | |||
460a3e08d2 | |||
51092e52a2 | |||
b067a6ca07 | |||
bcbb74a3e1 | |||
0ed4ca4034 | |||
2d8dc471f5 | |||
1b53d230cb | |||
13eab14f17 | |||
3e98b025c7 | |||
f9a5a8023d | |||
98de64b7aa | |||
353f858bac | |||
e05f023c4e | |||
7818109a9c | |||
49f2630e38 | |||
175b02536c | |||
5cf6b30eb2 | |||
7cf006cd4f | |||
5131c4a3c1 | |||
fbf588a85e | |||
bf8819fb46 | |||
946d826dc4 | |||
83b6bda124 | |||
e68ef52292 | |||
3435e4ce7a | |||
eb5ed5fe9e | |||
e39a19da55 | |||
f6860bb43f | |||
3c5fead8b0 | |||
b6377aef97 | |||
9a39399936 | |||
65bc29cfa1 | |||
b0c6b8e5bb |
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.linting.enabled": true,
|
||||
"python.formatting.provider": "black"
|
||||
}
|
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# Build with: docker build -t baseballbot:<version> .
|
||||
# Run with: docker run -it
|
||||
|
||||
FROM python:3.10-alpine3.16 AS build
|
||||
|
||||
RUN pip install --no-cache-dir discord peewee
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
|
||||
FROM build AS run
|
||||
|
||||
ENV discord_token ""
|
||||
ENV database_path "/tmp/baseball.db"
|
||||
|
||||
CMD ["python", "-u", "/app/main.py"]
|
734
GhostBallBot/Pipfile.lock
generated
734
GhostBallBot/Pipfile.lock
generated
@@ -1,734 +0,0 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "0f1a335d8076579fbcc256d8fdcfedb582793218af78b4ccbdbc5572e32c25dd"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8",
|
||||
"sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142",
|
||||
"sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18",
|
||||
"sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34",
|
||||
"sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a",
|
||||
"sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033",
|
||||
"sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06",
|
||||
"sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4",
|
||||
"sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d",
|
||||
"sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b",
|
||||
"sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc",
|
||||
"sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091",
|
||||
"sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d",
|
||||
"sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85",
|
||||
"sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb",
|
||||
"sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937",
|
||||
"sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf",
|
||||
"sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1",
|
||||
"sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b",
|
||||
"sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d",
|
||||
"sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269",
|
||||
"sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da",
|
||||
"sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346",
|
||||
"sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494",
|
||||
"sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697",
|
||||
"sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4",
|
||||
"sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585",
|
||||
"sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c",
|
||||
"sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da",
|
||||
"sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad",
|
||||
"sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2",
|
||||
"sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6",
|
||||
"sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c",
|
||||
"sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849",
|
||||
"sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa",
|
||||
"sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b",
|
||||
"sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb",
|
||||
"sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7",
|
||||
"sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715",
|
||||
"sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76",
|
||||
"sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d",
|
||||
"sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276",
|
||||
"sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6",
|
||||
"sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37",
|
||||
"sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb",
|
||||
"sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d",
|
||||
"sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c",
|
||||
"sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446",
|
||||
"sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008",
|
||||
"sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342",
|
||||
"sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d",
|
||||
"sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7",
|
||||
"sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061",
|
||||
"sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba",
|
||||
"sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7",
|
||||
"sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290",
|
||||
"sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0",
|
||||
"sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d",
|
||||
"sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8",
|
||||
"sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f",
|
||||
"sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48",
|
||||
"sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502",
|
||||
"sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62",
|
||||
"sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9",
|
||||
"sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403",
|
||||
"sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77",
|
||||
"sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476",
|
||||
"sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e",
|
||||
"sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96",
|
||||
"sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5",
|
||||
"sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784",
|
||||
"sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091",
|
||||
"sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b",
|
||||
"sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97",
|
||||
"sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a",
|
||||
"sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2",
|
||||
"sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9",
|
||||
"sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d",
|
||||
"sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73",
|
||||
"sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017",
|
||||
"sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363",
|
||||
"sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c",
|
||||
"sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d",
|
||||
"sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618",
|
||||
"sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491",
|
||||
"sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b",
|
||||
"sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==3.8.3"
|
||||
},
|
||||
"aiosignal": {
|
||||
"hashes": [
|
||||
"sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a",
|
||||
"sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"astroid": {
|
||||
"hashes": [
|
||||
"sha256:1c00a14f5a3ed0339d38d2e2e5b74ea2591df5861c0936bb292b84ccf3a78d83",
|
||||
"sha256:72702205200b2a638358369d90c222d74ebc376787af8fb2f7f2a86f7b5cc85f"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.2'",
|
||||
"version": "==2.12.12"
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15",
|
||||
"sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6",
|
||||
"sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==22.1.0"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:14ff67aec0a47c424bc99b71005202045dc09270da44a27848d534600ac64fc7",
|
||||
"sha256:197df8509263b0b8614e1df1756b1dd41be6738eed2ba9e9769f3880c2b9d7b6",
|
||||
"sha256:1e464456d24e23d11fced2bc8c47ef66d471f845c7b7a42f3bd77bf3d1789650",
|
||||
"sha256:2039230db3c6c639bd84efe3292ec7b06e9214a2992cd9beb293d639c6402edb",
|
||||
"sha256:21199526696b8f09c3997e2b4db8d0b108d801a348414264d2eb8eb2532e540d",
|
||||
"sha256:2644b5d63633702bc2c5f3754b1b475378fbbfb481f62319388235d0cd104c2d",
|
||||
"sha256:432247333090c8c5366e69627ccb363bc58514ae3e63f7fc75c54b1ea80fa7de",
|
||||
"sha256:444ebfb4e441254e87bad00c661fe32df9969b2bf224373a448d8aca2132b395",
|
||||
"sha256:5b9b29da4f564ba8787c119f37d174f2b69cdfdf9015b7d8c5c16121ddc054ae",
|
||||
"sha256:5cc42ca67989e9c3cf859e84c2bf014f6633db63d1cbdf8fdb666dcd9e77e3fa",
|
||||
"sha256:5d8f74030e67087b219b032aa33a919fae8806d49c867846bfacde57f43972ef",
|
||||
"sha256:72ef3925f30e12a184889aac03d77d031056860ccae8a1e519f6cbb742736383",
|
||||
"sha256:819dc789f4498ecc91438a7de64427c73b45035e2e3680c92e18795a839ebb66",
|
||||
"sha256:915ace4ff03fdfff953962fa672d44be269deb2eaf88499a0f8805221bc68c87",
|
||||
"sha256:9311e99228ae10023300ecac05be5a296f60d2fd10fff31cf5c1fa4ca4b1988d",
|
||||
"sha256:974308c58d057a651d182208a484ce80a26dac0caef2895836a92dd6ebd725e0",
|
||||
"sha256:b8b49776299fece66bffaafe357d929ca9451450f5466e997a7285ab0fe28e3b",
|
||||
"sha256:c957b2b4ea88587b46cf49d1dc17681c1e672864fd7af32fc1e9664d572b3458",
|
||||
"sha256:e41a86c6c650bcecc6633ee3180d80a025db041a8e2398dcc059b3afa8382cd4",
|
||||
"sha256:f513588da599943e0cde4e32cc9879e825d58720d6557062d1098c5ad80080e1",
|
||||
"sha256:fba8a281e570adafb79f7755ac8721b6cf1bbf691186a287e990c7929c7692ff"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==22.10.0"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845",
|
||||
"sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"dateparser": {
|
||||
"hashes": [
|
||||
"sha256:3821bf191f95b2658c4abd91571c09821ce7a2bc179bf6cefd8b4515c3ccf9ef",
|
||||
"sha256:d31659dc806a7d88e2b510b2c74f68b525ae531f145c62a57a99bd616b7f90cf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"dill": {
|
||||
"hashes": [
|
||||
"sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0",
|
||||
"sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.3.6"
|
||||
},
|
||||
"discord": {
|
||||
"hashes": [
|
||||
"sha256:b6df1dd56c19750b3cb9b69de85bf463e712a0db232546ae8109c04bf0a61083",
|
||||
"sha256:ffc714978d338d2b506e4924d66d7d02a649378a46743e2bdf42ef1bd43d1a67"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"discord.py": {
|
||||
"hashes": [
|
||||
"sha256:309146476e986cb8faf038cd5d604d4b3834ef15c2d34df697ce5064bf5cd779",
|
||||
"sha256:aeb186348bf011708b085b2715cf92bbb72c692eb4f59c4c0b488130cc4c4b7e"
|
||||
],
|
||||
"markers": "python_full_version >= '3.8.0'",
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"frozenlist": {
|
||||
"hashes": [
|
||||
"sha256:022178b277cb9277d7d3b3f2762d294f15e85cd2534047e68a118c2bb0058f3e",
|
||||
"sha256:086ca1ac0a40e722d6833d4ce74f5bf1aba2c77cbfdc0cd83722ffea6da52a04",
|
||||
"sha256:0bc75692fb3770cf2b5856a6c2c9de967ca744863c5e89595df64e252e4b3944",
|
||||
"sha256:0dde791b9b97f189874d654c55c24bf7b6782343e14909c84beebd28b7217845",
|
||||
"sha256:12607804084d2244a7bd4685c9d0dca5df17a6a926d4f1967aa7978b1028f89f",
|
||||
"sha256:19127f8dcbc157ccb14c30e6f00392f372ddb64a6ffa7106b26ff2196477ee9f",
|
||||
"sha256:1b51eb355e7f813bcda00276b0114c4172872dc5fb30e3fea059b9367c18fbcb",
|
||||
"sha256:1e1cf7bc8cbbe6ce3881863671bac258b7d6bfc3706c600008925fb799a256e2",
|
||||
"sha256:219a9676e2eae91cb5cc695a78b4cb43d8123e4160441d2b6ce8d2c70c60e2f3",
|
||||
"sha256:2743bb63095ef306041c8f8ea22bd6e4d91adabf41887b1ad7886c4c1eb43d5f",
|
||||
"sha256:2af6f7a4e93f5d08ee3f9152bce41a6015b5cf87546cb63872cc19b45476e98a",
|
||||
"sha256:31b44f1feb3630146cffe56344704b730c33e042ffc78d21f2125a6a91168131",
|
||||
"sha256:31bf9539284f39ff9398deabf5561c2b0da5bb475590b4e13dd8b268d7a3c5c1",
|
||||
"sha256:35c3d79b81908579beb1fb4e7fcd802b7b4921f1b66055af2578ff7734711cfa",
|
||||
"sha256:3a735e4211a04ccfa3f4833547acdf5d2f863bfeb01cfd3edaffbc251f15cec8",
|
||||
"sha256:42719a8bd3792744c9b523674b752091a7962d0d2d117f0b417a3eba97d1164b",
|
||||
"sha256:49459f193324fbd6413e8e03bd65789e5198a9fa3095e03f3620dee2f2dabff2",
|
||||
"sha256:4c0c99e31491a1d92cde8648f2e7ccad0e9abb181f6ac3ddb9fc48b63301808e",
|
||||
"sha256:52137f0aea43e1993264a5180c467a08a3e372ca9d378244c2d86133f948b26b",
|
||||
"sha256:526d5f20e954d103b1d47232e3839f3453c02077b74203e43407b962ab131e7b",
|
||||
"sha256:53b2b45052e7149ee8b96067793db8ecc1ae1111f2f96fe1f88ea5ad5fd92d10",
|
||||
"sha256:572ce381e9fe027ad5e055f143763637dcbac2542cfe27f1d688846baeef5170",
|
||||
"sha256:58fb94a01414cddcdc6839807db77ae8057d02ddafc94a42faee6004e46c9ba8",
|
||||
"sha256:5e77a8bd41e54b05e4fb2708dc6ce28ee70325f8c6f50f3df86a44ecb1d7a19b",
|
||||
"sha256:5f271c93f001748fc26ddea409241312a75e13466b06c94798d1a341cf0e6989",
|
||||
"sha256:5f63c308f82a7954bf8263a6e6de0adc67c48a8b484fab18ff87f349af356efd",
|
||||
"sha256:61d7857950a3139bce035ad0b0945f839532987dfb4c06cfe160254f4d19df03",
|
||||
"sha256:61e8cb51fba9f1f33887e22488bad1e28dd8325b72425f04517a4d285a04c519",
|
||||
"sha256:625d8472c67f2d96f9a4302a947f92a7adbc1e20bedb6aff8dbc8ff039ca6189",
|
||||
"sha256:6e19add867cebfb249b4e7beac382d33215d6d54476bb6be46b01f8cafb4878b",
|
||||
"sha256:717470bfafbb9d9be624da7780c4296aa7935294bd43a075139c3d55659038ca",
|
||||
"sha256:74140933d45271c1a1283f708c35187f94e1256079b3c43f0c2267f9db5845ff",
|
||||
"sha256:74e6b2b456f21fc93ce1aff2b9728049f1464428ee2c9752a4b4f61e98c4db96",
|
||||
"sha256:9494122bf39da6422b0972c4579e248867b6b1b50c9b05df7e04a3f30b9a413d",
|
||||
"sha256:94e680aeedc7fd3b892b6fa8395b7b7cc4b344046c065ed4e7a1e390084e8cb5",
|
||||
"sha256:97d9e00f3ac7c18e685320601f91468ec06c58acc185d18bb8e511f196c8d4b2",
|
||||
"sha256:9c6ef8014b842f01f5d2b55315f1af5cbfde284eb184075c189fd657c2fd8204",
|
||||
"sha256:a027f8f723d07c3f21963caa7d585dcc9b089335565dabe9c814b5f70c52705a",
|
||||
"sha256:a718b427ff781c4f4e975525edb092ee2cdef6a9e7bc49e15063b088961806f8",
|
||||
"sha256:ab386503f53bbbc64d1ad4b6865bf001414930841a870fc97f1546d4d133f141",
|
||||
"sha256:ab6fa8c7871877810e1b4e9392c187a60611fbf0226a9e0b11b7b92f5ac72792",
|
||||
"sha256:b47d64cdd973aede3dd71a9364742c542587db214e63b7529fbb487ed67cddd9",
|
||||
"sha256:b499c6abe62a7a8d023e2c4b2834fce78a6115856ae95522f2f974139814538c",
|
||||
"sha256:bbb1a71b1784e68870800b1bc9f3313918edc63dbb8f29fbd2e767ce5821696c",
|
||||
"sha256:c3b31180b82c519b8926e629bf9f19952c743e089c41380ddca5db556817b221",
|
||||
"sha256:c56c299602c70bc1bb5d1e75f7d8c007ca40c9d7aebaf6e4ba52925d88ef826d",
|
||||
"sha256:c92deb5d9acce226a501b77307b3b60b264ca21862bd7d3e0c1f3594022f01bc",
|
||||
"sha256:cc2f3e368ee5242a2cbe28323a866656006382872c40869b49b265add546703f",
|
||||
"sha256:d82bed73544e91fb081ab93e3725e45dd8515c675c0e9926b4e1f420a93a6ab9",
|
||||
"sha256:da1cdfa96425cbe51f8afa43e392366ed0b36ce398f08b60de6b97e3ed4affef",
|
||||
"sha256:da5ba7b59d954f1f214d352308d1d86994d713b13edd4b24a556bcc43d2ddbc3",
|
||||
"sha256:e0c8c803f2f8db7217898d11657cb6042b9b0553a997c4a0601f48a691480fab",
|
||||
"sha256:ee4c5120ddf7d4dd1eaf079af3af7102b56d919fa13ad55600a4e0ebe532779b",
|
||||
"sha256:eee0c5ecb58296580fc495ac99b003f64f82a74f9576a244d04978a7e97166db",
|
||||
"sha256:f5abc8b4d0c5b556ed8cd41490b606fe99293175a82b98e652c3f2711b452988",
|
||||
"sha256:f810e764617b0748b49a731ffaa525d9bb36ff38332411704c2400125af859a6",
|
||||
"sha256:f89139662cc4e65a4813f4babb9ca9544e42bddb823d2ec434e18dad582543bc",
|
||||
"sha256:fa47319a10e0a076709644a0efbcaab9e91902c8bd8ef74c6adb19d320f69b83",
|
||||
"sha256:fabb953ab913dadc1ff9dcc3a7a7d3dc6a92efab3a0373989b8063347f8705be"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.1"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
|
||||
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7",
|
||||
"sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"
|
||||
],
|
||||
"markers": "python_version < '4.0' and python_full_version >= '3.6.1'",
|
||||
"version": "==5.10.1"
|
||||
},
|
||||
"lazy-object-proxy": {
|
||||
"hashes": [
|
||||
"sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7",
|
||||
"sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a",
|
||||
"sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c",
|
||||
"sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc",
|
||||
"sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f",
|
||||
"sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09",
|
||||
"sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442",
|
||||
"sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e",
|
||||
"sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029",
|
||||
"sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61",
|
||||
"sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb",
|
||||
"sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0",
|
||||
"sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35",
|
||||
"sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42",
|
||||
"sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1",
|
||||
"sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad",
|
||||
"sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443",
|
||||
"sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd",
|
||||
"sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9",
|
||||
"sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148",
|
||||
"sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38",
|
||||
"sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55",
|
||||
"sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36",
|
||||
"sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a",
|
||||
"sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b",
|
||||
"sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44",
|
||||
"sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6",
|
||||
"sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69",
|
||||
"sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4",
|
||||
"sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84",
|
||||
"sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de",
|
||||
"sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28",
|
||||
"sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c",
|
||||
"sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1",
|
||||
"sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8",
|
||||
"sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b",
|
||||
"sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==1.7.1"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
|
||||
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"multidict": {
|
||||
"hashes": [
|
||||
"sha256:0327292e745a880459ef71be14e709aaea2f783f3537588fb4ed09b6c01bca60",
|
||||
"sha256:041b81a5f6b38244b34dc18c7b6aba91f9cdaf854d9a39e5ff0b58e2b5773b9c",
|
||||
"sha256:0556a1d4ea2d949efe5fd76a09b4a82e3a4a30700553a6725535098d8d9fb672",
|
||||
"sha256:05f6949d6169878a03e607a21e3b862eaf8e356590e8bdae4227eedadacf6e51",
|
||||
"sha256:07a017cfa00c9890011628eab2503bee5872f27144936a52eaab449be5eaf032",
|
||||
"sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2",
|
||||
"sha256:19adcfc2a7197cdc3987044e3f415168fc5dc1f720c932eb1ef4f71a2067e08b",
|
||||
"sha256:19d9bad105dfb34eb539c97b132057a4e709919ec4dd883ece5838bcbf262b80",
|
||||
"sha256:225383a6603c086e6cef0f2f05564acb4f4d5f019a4e3e983f572b8530f70c88",
|
||||
"sha256:23b616fdc3c74c9fe01d76ce0d1ce872d2d396d8fa8e4899398ad64fb5aa214a",
|
||||
"sha256:2957489cba47c2539a8eb7ab32ff49101439ccf78eab724c828c1a54ff3ff98d",
|
||||
"sha256:2d36e929d7f6a16d4eb11b250719c39560dd70545356365b494249e2186bc389",
|
||||
"sha256:2e4a0785b84fb59e43c18a015ffc575ba93f7d1dbd272b4cdad9f5134b8a006c",
|
||||
"sha256:3368bf2398b0e0fcbf46d85795adc4c259299fec50c1416d0f77c0a843a3eed9",
|
||||
"sha256:373ba9d1d061c76462d74e7de1c0c8e267e9791ee8cfefcf6b0b2495762c370c",
|
||||
"sha256:4070613ea2227da2bfb2c35a6041e4371b0af6b0be57f424fe2318b42a748516",
|
||||
"sha256:45183c96ddf61bf96d2684d9fbaf6f3564d86b34cb125761f9a0ef9e36c1d55b",
|
||||
"sha256:4571f1beddff25f3e925eea34268422622963cd8dc395bb8778eb28418248e43",
|
||||
"sha256:47e6a7e923e9cada7c139531feac59448f1f47727a79076c0b1ee80274cd8eee",
|
||||
"sha256:47fbeedbf94bed6547d3aa632075d804867a352d86688c04e606971595460227",
|
||||
"sha256:497988d6b6ec6ed6f87030ec03280b696ca47dbf0648045e4e1d28b80346560d",
|
||||
"sha256:4bae31803d708f6f15fd98be6a6ac0b6958fcf68fda3c77a048a4f9073704aae",
|
||||
"sha256:50bd442726e288e884f7be9071016c15a8742eb689a593a0cac49ea093eef0a7",
|
||||
"sha256:514fe2b8d750d6cdb4712346a2c5084a80220821a3e91f3f71eec11cf8d28fd4",
|
||||
"sha256:5774d9218d77befa7b70d836004a768fb9aa4fdb53c97498f4d8d3f67bb9cfa9",
|
||||
"sha256:5fdda29a3c7e76a064f2477c9aab1ba96fd94e02e386f1e665bca1807fc5386f",
|
||||
"sha256:5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013",
|
||||
"sha256:626fe10ac87851f4cffecee161fc6f8f9853f0f6f1035b59337a51d29ff3b4f9",
|
||||
"sha256:6701bf8a5d03a43375909ac91b6980aea74b0f5402fbe9428fc3f6edf5d9677e",
|
||||
"sha256:684133b1e1fe91eda8fa7447f137c9490a064c6b7f392aa857bba83a28cfb693",
|
||||
"sha256:6f3cdef8a247d1eafa649085812f8a310e728bdf3900ff6c434eafb2d443b23a",
|
||||
"sha256:75bdf08716edde767b09e76829db8c1e5ca9d8bb0a8d4bd94ae1eafe3dac5e15",
|
||||
"sha256:7c40b7bbece294ae3a87c1bc2abff0ff9beef41d14188cda94ada7bcea99b0fb",
|
||||
"sha256:8004dca28e15b86d1b1372515f32eb6f814bdf6f00952699bdeb541691091f96",
|
||||
"sha256:8064b7c6f0af936a741ea1efd18690bacfbae4078c0c385d7c3f611d11f0cf87",
|
||||
"sha256:89171b2c769e03a953d5969b2f272efa931426355b6c0cb508022976a17fd376",
|
||||
"sha256:8cbf0132f3de7cc6c6ce00147cc78e6439ea736cee6bca4f068bcf892b0fd658",
|
||||
"sha256:9cc57c68cb9139c7cd6fc39f211b02198e69fb90ce4bc4a094cf5fe0d20fd8b0",
|
||||
"sha256:a007b1638e148c3cfb6bf0bdc4f82776cef0ac487191d093cdc316905e504071",
|
||||
"sha256:a2c34a93e1d2aa35fbf1485e5010337c72c6791407d03aa5f4eed920343dd360",
|
||||
"sha256:a45e1135cb07086833ce969555df39149680e5471c04dfd6a915abd2fc3f6dbc",
|
||||
"sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3",
|
||||
"sha256:aef9cc3d9c7d63d924adac329c33835e0243b5052a6dfcbf7732a921c6e918ba",
|
||||
"sha256:b9d153e7f1f9ba0b23ad1568b3b9e17301e23b042c23870f9ee0522dc5cc79e8",
|
||||
"sha256:bfba7c6d5d7c9099ba21f84662b037a0ffd4a5e6b26ac07d19e423e6fdf965a9",
|
||||
"sha256:c207fff63adcdf5a485969131dc70e4b194327666b7e8a87a97fbc4fd80a53b2",
|
||||
"sha256:d0509e469d48940147e1235d994cd849a8f8195e0bca65f8f5439c56e17872a3",
|
||||
"sha256:d16cce709ebfadc91278a1c005e3c17dd5f71f5098bfae1035149785ea6e9c68",
|
||||
"sha256:d48b8ee1d4068561ce8033d2c344cf5232cb29ee1a0206a7b828c79cbc5982b8",
|
||||
"sha256:de989b195c3d636ba000ee4281cd03bb1234635b124bf4cd89eeee9ca8fcb09d",
|
||||
"sha256:e07c8e79d6e6fd37b42f3250dba122053fddb319e84b55dd3a8d6446e1a7ee49",
|
||||
"sha256:e2c2e459f7050aeb7c1b1276763364884595d47000c1cddb51764c0d8976e608",
|
||||
"sha256:e5b20e9599ba74391ca0cfbd7b328fcc20976823ba19bc573983a25b32e92b57",
|
||||
"sha256:e875b6086e325bab7e680e4316d667fc0e5e174bb5611eb16b3ea121c8951b86",
|
||||
"sha256:f4f052ee022928d34fe1f4d2bc743f32609fb79ed9c49a1710a5ad6b2198db20",
|
||||
"sha256:fcb91630817aa8b9bc4a74023e4198480587269c272c58b3279875ed7235c293",
|
||||
"sha256:fd9fc9c4849a07f3635ccffa895d57abce554b467d611a5009ba4f39b78a8849",
|
||||
"sha256:feba80698173761cddd814fa22e88b0661e98cb810f9f986c54aa34d281e4937",
|
||||
"sha256:feea820722e69451743a3d56ad74948b68bf456984d63c1a92e8347b7b88452d"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==6.0.2"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93",
|
||||
"sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.10.1"
|
||||
},
|
||||
"peewee": {
|
||||
"hashes": [
|
||||
"sha256:cc934286d0c0842203abe66a3c6583d1463371e633b03d6da054d0f74e70706f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.15.3"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788",
|
||||
"sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.5.2"
|
||||
},
|
||||
"pylint": {
|
||||
"hashes": [
|
||||
"sha256:3b120505e5af1d06a5ad76b55d8660d44bf0f2fc3c59c2bdd94e39188ee3a4df",
|
||||
"sha256:c2108037eb074334d9e874dc3c783752cc03d0796c88c9a9af282d0f161a1004"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.15.5"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
|
||||
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==2.8.2"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22",
|
||||
"sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914"
|
||||
],
|
||||
"version": "==2022.5"
|
||||
},
|
||||
"pytz-deprecation-shim": {
|
||||
"hashes": [
|
||||
"sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6",
|
||||
"sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||
"version": "==0.1.0.post0"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:0008650041531d0eadecc96a73d37c2dc4821cf51b0766e374cb4f1ddc4e1c14",
|
||||
"sha256:03299b0bcaa7824eb7c0ebd7ef1e3663302d1b533653bfe9dc7e595d453e2ae9",
|
||||
"sha256:06b1df01cf2aef3a9790858af524ae2588762c8a90e784ba00d003f045306204",
|
||||
"sha256:09b4b6ccc61d4119342b26246ddd5a04accdeebe36bdfe865ad87a0784efd77f",
|
||||
"sha256:0be0c34a39e5d04a62fd5342f0886d0e57592a4f4993b3f9d257c1f688b19737",
|
||||
"sha256:0d96eec8550fd2fd26f8e675f6d8b61b159482ad8ffa26991b894ed5ee19038b",
|
||||
"sha256:0eb0e2845e81bdea92b8281a3969632686502565abf4a0b9e4ab1471c863d8f3",
|
||||
"sha256:13bbf0c9453c6d16e5867bda7f6c0c7cff1decf96c5498318bb87f8136d2abd4",
|
||||
"sha256:17e51ad1e6131c496b58d317bc9abec71f44eb1957d32629d06013a21bc99cac",
|
||||
"sha256:1977bb64264815d3ef016625adc9df90e6d0e27e76260280c63eca993e3f455f",
|
||||
"sha256:1e30762ddddb22f7f14c4f59c34d3addabc789216d813b0f3e2788d7bcf0cf29",
|
||||
"sha256:1e73652057473ad3e6934944af090852a02590c349357b79182c1b681da2c772",
|
||||
"sha256:20e6a27959f162f979165e496add0d7d56d7038237092d1aba20b46de79158f1",
|
||||
"sha256:286ff9ec2709d56ae7517040be0d6c502642517ce9937ab6d89b1e7d0904f863",
|
||||
"sha256:297c42ede2c81f0cb6f34ea60b5cf6dc965d97fa6936c11fc3286019231f0d66",
|
||||
"sha256:320c2f4106962ecea0f33d8d31b985d3c185757c49c1fb735501515f963715ed",
|
||||
"sha256:35ed2f3c918a00b109157428abfc4e8d1ffabc37c8f9abc5939ebd1e95dabc47",
|
||||
"sha256:3d146e5591cb67c5e836229a04723a30af795ef9b70a0bbd913572e14b7b940f",
|
||||
"sha256:42bb37e2b2d25d958c25903f6125a41aaaa1ed49ca62c103331f24b8a459142f",
|
||||
"sha256:42d6007722d46bd2c95cce700181570b56edc0dcbadbfe7855ec26c3f2d7e008",
|
||||
"sha256:43eba5c46208deedec833663201752e865feddc840433285fbadee07b84b464d",
|
||||
"sha256:452519bc4c973e961b1620c815ea6dd8944a12d68e71002be5a7aff0a8361571",
|
||||
"sha256:4b9c16a807b17b17c4fa3a1d8c242467237be67ba92ad24ff51425329e7ae3d0",
|
||||
"sha256:5510932596a0f33399b7fff1bd61c59c977f2b8ee987b36539ba97eb3513584a",
|
||||
"sha256:55820bc631684172b9b56a991d217ec7c2e580d956591dc2144985113980f5a3",
|
||||
"sha256:57484d39447f94967e83e56db1b1108c68918c44ab519b8ecfc34b790ca52bf7",
|
||||
"sha256:58ba41e462653eaf68fc4a84ec4d350b26a98d030be1ab24aba1adcc78ffe447",
|
||||
"sha256:5bc5f921be39ccb65fdda741e04b2555917a4bced24b4df14eddc7569be3b493",
|
||||
"sha256:5dcc4168536c8f68654f014a3db49b6b4a26b226f735708be2054314ed4964f4",
|
||||
"sha256:5f92a7cdc6a0ae2abd184e8dfd6ef2279989d24c85d2c85d0423206284103ede",
|
||||
"sha256:67250b36edfa714ba62dc62d3f238e86db1065fccb538278804790f578253640",
|
||||
"sha256:6df070a986fc064d865c381aecf0aaff914178fdf6874da2f2387e82d93cc5bd",
|
||||
"sha256:729aa8ca624c42f309397c5fc9e21db90bf7e2fdd872461aabdbada33de9063c",
|
||||
"sha256:72bc3a5effa5974be6d965ed8301ac1e869bc18425c8a8fac179fbe7876e3aee",
|
||||
"sha256:74d86e8924835f863c34e646392ef39039405f6ce52956d8af16497af4064a30",
|
||||
"sha256:79e5af1ff258bc0fe0bdd6f69bc4ae33935a898e3cbefbbccf22e88a27fa053b",
|
||||
"sha256:7b103dffb9f6a47ed7ffdf352b78cfe058b1777617371226c1894e1be443afec",
|
||||
"sha256:83f03f0bd88c12e63ca2d024adeee75234d69808b341e88343b0232329e1f1a1",
|
||||
"sha256:86d7a68fa53688e1f612c3246044157117403c7ce19ebab7d02daf45bd63913e",
|
||||
"sha256:878c626cbca3b649e14e972c14539a01191d79e58934e3f3ef4a9e17f90277f8",
|
||||
"sha256:878f5d649ba1db9f52cc4ef491f7dba2d061cdc48dd444c54260eebc0b1729b9",
|
||||
"sha256:87bc01226cd288f0bd9a4f9f07bf6827134dc97a96c22e2d28628e824c8de231",
|
||||
"sha256:8babb2b5751105dc0aef2a2e539f4ba391e738c62038d8cb331c710f6b0f3da7",
|
||||
"sha256:91e0f7e7be77250b808a5f46d90bf0032527d3c032b2131b63dee54753a4d729",
|
||||
"sha256:9557545c10d52c845f270b665b52a6a972884725aa5cf12777374e18f2ea8960",
|
||||
"sha256:9ccb0a4ab926016867260c24c192d9df9586e834f5db83dfa2c8fffb3a6e5056",
|
||||
"sha256:9d828c5987d543d052b53c579a01a52d96b86f937b1777bbfe11ef2728929357",
|
||||
"sha256:9efa41d1527b366c88f265a227b20bcec65bda879962e3fc8a2aee11e81266d7",
|
||||
"sha256:aaf5317c961d93c1a200b9370fb1c6b6836cc7144fef3e5a951326912bf1f5a3",
|
||||
"sha256:ab69b4fe09e296261377d209068d52402fb85ef89dc78a9ac4a29a895f4e24a7",
|
||||
"sha256:ad397bc7d51d69cb07ef89e44243f971a04ce1dca9bf24c992c362406c0c6573",
|
||||
"sha256:ae17fc8103f3b63345709d3e9654a274eee1c6072592aec32b026efd401931d0",
|
||||
"sha256:af4d8cc28e4c7a2f6a9fed544228c567340f8258b6d7ea815b62a72817bbd178",
|
||||
"sha256:b22ff939a8856a44f4822da38ef4868bd3a9ade22bb6d9062b36957c850e404f",
|
||||
"sha256:b549d851f91a4efb3e65498bd4249b1447ab6035a9972f7fc215eb1f59328834",
|
||||
"sha256:be319f4eb400ee567b722e9ea63d5b2bb31464e3cf1b016502e3ee2de4f86f5c",
|
||||
"sha256:c0446b2871335d5a5e9fcf1462f954586b09a845832263db95059dcd01442015",
|
||||
"sha256:c68d2c04f7701a418ec2e5631b7f3552efc32f6bcc1739369c6eeb1af55f62e0",
|
||||
"sha256:c87ac58b9baaf50b6c1b81a18d20eda7e2883aa9a4fb4f1ca70f2e443bfcdc57",
|
||||
"sha256:caa2734ada16a44ae57b229d45091f06e30a9a52ace76d7574546ab23008c635",
|
||||
"sha256:cb34c2d66355fb70ae47b5595aafd7218e59bb9c00ad8cc3abd1406ca5874f07",
|
||||
"sha256:cb3652bbe6720786b9137862205986f3ae54a09dec8499a995ed58292bdf77c2",
|
||||
"sha256:cf668f26604e9f7aee9f8eaae4ca07a948168af90b96be97a4b7fa902a6d2ac1",
|
||||
"sha256:d326ff80ed531bf2507cba93011c30fff2dd51454c85f55df0f59f2030b1687b",
|
||||
"sha256:d6c2441538e4fadd4291c8420853431a229fcbefc1bf521810fbc2629d8ae8c2",
|
||||
"sha256:d6ecfd1970b3380a569d7b3ecc5dd70dba295897418ed9e31ec3c16a5ab099a5",
|
||||
"sha256:e5602a9b5074dcacc113bba4d2f011d2748f50e3201c8139ac5b68cf2a76bd8b",
|
||||
"sha256:ef806f684f17dbd6263d72a54ad4073af42b42effa3eb42b877e750c24c76f86",
|
||||
"sha256:f3356afbb301ec34a500b8ba8b47cba0b44ed4641c306e1dd981a08b416170b5",
|
||||
"sha256:f6f7ee2289176cb1d2c59a24f50900f8b9580259fa9f1a739432242e7d254f93",
|
||||
"sha256:f7e8f1ee28e0a05831c92dc1c0c1c94af5289963b7cf09eca5b5e3ce4f8c91b0",
|
||||
"sha256:f8169ec628880bdbca67082a9196e2106060a4a5cbd486ac51881a4df805a36f",
|
||||
"sha256:fbc88d3ba402b5d041d204ec2449c4078898f89c4a6e6f0ed1c1a510ef1e221d",
|
||||
"sha256:fbd3fe37353c62fd0eb19fb76f78aa693716262bcd5f9c14bb9e5aca4b3f0dc4"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.3.2"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
|
||||
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
||||
"version": "==1.16.0"
|
||||
},
|
||||
"tomli": {
|
||||
"hashes": [
|
||||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
|
||||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
|
||||
],
|
||||
"markers": "python_full_version < '3.11.0a7'",
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"tomlkit": {
|
||||
"hashes": [
|
||||
"sha256:571854ebbb5eac89abcb4a2e47d7ea27b89bf29e09c35395da6f03dd4ae23d1c",
|
||||
"sha256:f2ef9da9cef846ee027947dc99a45d6b68a63b0ebc21944649505bf2e8bc5fe7"
|
||||
],
|
||||
"markers": "python_version >= '3.6' and python_version < '4.0'",
|
||||
"version": "==0.11.5"
|
||||
},
|
||||
"tzdata": {
|
||||
"hashes": [
|
||||
"sha256:323161b22b7802fdc78f20ca5f6073639c64f1a7227c40cd3e19fd1d0ce6650a",
|
||||
"sha256:e15b2b3005e2546108af42a0eb4ccab4d9e225e2dfbf4f77aad50c70a4b1f3ab"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2022.5"
|
||||
},
|
||||
"tzlocal": {
|
||||
"hashes": [
|
||||
"sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745",
|
||||
"sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==4.2"
|
||||
},
|
||||
"wrapt": {
|
||||
"hashes": [
|
||||
"sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3",
|
||||
"sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b",
|
||||
"sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4",
|
||||
"sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2",
|
||||
"sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656",
|
||||
"sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3",
|
||||
"sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff",
|
||||
"sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310",
|
||||
"sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a",
|
||||
"sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57",
|
||||
"sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069",
|
||||
"sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383",
|
||||
"sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe",
|
||||
"sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87",
|
||||
"sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d",
|
||||
"sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b",
|
||||
"sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907",
|
||||
"sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f",
|
||||
"sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0",
|
||||
"sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28",
|
||||
"sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1",
|
||||
"sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853",
|
||||
"sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc",
|
||||
"sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3",
|
||||
"sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3",
|
||||
"sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164",
|
||||
"sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1",
|
||||
"sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c",
|
||||
"sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1",
|
||||
"sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7",
|
||||
"sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1",
|
||||
"sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320",
|
||||
"sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed",
|
||||
"sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1",
|
||||
"sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248",
|
||||
"sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c",
|
||||
"sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456",
|
||||
"sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77",
|
||||
"sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef",
|
||||
"sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1",
|
||||
"sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7",
|
||||
"sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86",
|
||||
"sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4",
|
||||
"sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d",
|
||||
"sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d",
|
||||
"sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8",
|
||||
"sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5",
|
||||
"sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471",
|
||||
"sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00",
|
||||
"sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68",
|
||||
"sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3",
|
||||
"sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d",
|
||||
"sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735",
|
||||
"sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d",
|
||||
"sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569",
|
||||
"sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7",
|
||||
"sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59",
|
||||
"sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5",
|
||||
"sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb",
|
||||
"sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b",
|
||||
"sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f",
|
||||
"sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462",
|
||||
"sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015",
|
||||
"sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"
|
||||
],
|
||||
"markers": "python_version < '3.11'",
|
||||
"version": "==1.14.1"
|
||||
},
|
||||
"yarl": {
|
||||
"hashes": [
|
||||
"sha256:076eede537ab978b605f41db79a56cad2e7efeea2aa6e0fa8f05a26c24a034fb",
|
||||
"sha256:07b21e274de4c637f3e3b7104694e53260b5fc10d51fb3ec5fed1da8e0f754e3",
|
||||
"sha256:0ab5a138211c1c366404d912824bdcf5545ccba5b3ff52c42c4af4cbdc2c5035",
|
||||
"sha256:0c03f456522d1ec815893d85fccb5def01ffaa74c1b16ff30f8aaa03eb21e453",
|
||||
"sha256:12768232751689c1a89b0376a96a32bc7633c08da45ad985d0c49ede691f5c0d",
|
||||
"sha256:19cd801d6f983918a3f3a39f3a45b553c015c5aac92ccd1fac619bd74beece4a",
|
||||
"sha256:1ca7e596c55bd675432b11320b4eacc62310c2145d6801a1f8e9ad160685a231",
|
||||
"sha256:1e4808f996ca39a6463f45182e2af2fae55e2560be586d447ce8016f389f626f",
|
||||
"sha256:205904cffd69ae972a1707a1bd3ea7cded594b1d773a0ce66714edf17833cdae",
|
||||
"sha256:20df6ff4089bc86e4a66e3b1380460f864df3dd9dccaf88d6b3385d24405893b",
|
||||
"sha256:21ac44b763e0eec15746a3d440f5e09ad2ecc8b5f6dcd3ea8cb4773d6d4703e3",
|
||||
"sha256:29e256649f42771829974e742061c3501cc50cf16e63f91ed8d1bf98242e5507",
|
||||
"sha256:2d800b9c2eaf0684c08be5f50e52bfa2aa920e7163c2ea43f4f431e829b4f0fd",
|
||||
"sha256:2d93a049d29df172f48bcb09acf9226318e712ce67374f893b460b42cc1380ae",
|
||||
"sha256:31a9a04ecccd6b03e2b0e12e82131f1488dea5555a13a4d32f064e22a6003cfe",
|
||||
"sha256:3d1a50e461615747dd93c099f297c1994d472b0f4d2db8a64e55b1edf704ec1c",
|
||||
"sha256:449c957ffc6bc2309e1fbe67ab7d2c1efca89d3f4912baeb8ead207bb3cc1cd4",
|
||||
"sha256:4a88510731cd8d4befaba5fbd734a7dd914de5ab8132a5b3dde0bbd6c9476c64",
|
||||
"sha256:4c322cbaa4ed78a8aac89b2174a6df398faf50e5fc12c4c191c40c59d5e28357",
|
||||
"sha256:5395da939ffa959974577eff2cbfc24b004a2fb6c346918f39966a5786874e54",
|
||||
"sha256:5587bba41399854703212b87071c6d8638fa6e61656385875f8c6dff92b2e461",
|
||||
"sha256:56c11efb0a89700987d05597b08a1efcd78d74c52febe530126785e1b1a285f4",
|
||||
"sha256:5999c4662631cb798496535afbd837a102859568adc67d75d2045e31ec3ac497",
|
||||
"sha256:59ddd85a1214862ce7c7c66457f05543b6a275b70a65de366030d56159a979f0",
|
||||
"sha256:6347f1a58e658b97b0a0d1ff7658a03cb79bdbda0331603bed24dd7054a6dea1",
|
||||
"sha256:6628d750041550c5d9da50bb40b5cf28a2e63b9388bac10fedd4f19236ef4957",
|
||||
"sha256:6afb336e23a793cd3b6476c30f030a0d4c7539cd81649683b5e0c1b0ab0bf350",
|
||||
"sha256:6c8148e0b52bf9535c40c48faebb00cb294ee577ca069d21bd5c48d302a83780",
|
||||
"sha256:76577f13333b4fe345c3704811ac7509b31499132ff0181f25ee26619de2c843",
|
||||
"sha256:7c0da7e44d0c9108d8b98469338705e07f4bb7dab96dbd8fa4e91b337db42548",
|
||||
"sha256:7de89c8456525650ffa2bb56a3eee6af891e98f498babd43ae307bd42dca98f6",
|
||||
"sha256:7ec362167e2c9fd178f82f252b6d97669d7245695dc057ee182118042026da40",
|
||||
"sha256:7fce6cbc6c170ede0221cc8c91b285f7f3c8b9fe28283b51885ff621bbe0f8ee",
|
||||
"sha256:85cba594433915d5c9a0d14b24cfba0339f57a2fff203a5d4fd070e593307d0b",
|
||||
"sha256:8b0af1cf36b93cee99a31a545fe91d08223e64390c5ecc5e94c39511832a4bb6",
|
||||
"sha256:9130ddf1ae9978abe63808b6b60a897e41fccb834408cde79522feb37fb72fb0",
|
||||
"sha256:99449cd5366fe4608e7226c6cae80873296dfa0cde45d9b498fefa1de315a09e",
|
||||
"sha256:9de955d98e02fab288c7718662afb33aab64212ecb368c5dc866d9a57bf48880",
|
||||
"sha256:a0fb2cb4204ddb456a8e32381f9a90000429489a25f64e817e6ff94879d432fc",
|
||||
"sha256:a165442348c211b5dea67c0206fc61366212d7082ba8118c8c5c1c853ea4d82e",
|
||||
"sha256:ab2a60d57ca88e1d4ca34a10e9fb4ab2ac5ad315543351de3a612bbb0560bead",
|
||||
"sha256:abc06b97407868ef38f3d172762f4069323de52f2b70d133d096a48d72215d28",
|
||||
"sha256:af887845b8c2e060eb5605ff72b6f2dd2aab7a761379373fd89d314f4752abbf",
|
||||
"sha256:b19255dde4b4f4c32e012038f2c169bb72e7f081552bea4641cab4d88bc409dd",
|
||||
"sha256:b3ded839a5c5608eec8b6f9ae9a62cb22cd037ea97c627f38ae0841a48f09eae",
|
||||
"sha256:c1445a0c562ed561d06d8cbc5c8916c6008a31c60bc3655cdd2de1d3bf5174a0",
|
||||
"sha256:d0272228fabe78ce00a3365ffffd6f643f57a91043e119c289aaba202f4095b0",
|
||||
"sha256:d0b51530877d3ad7a8d47b2fff0c8df3b8f3b8deddf057379ba50b13df2a5eae",
|
||||
"sha256:d0f77539733e0ec2475ddcd4e26777d08996f8cd55d2aef82ec4d3896687abda",
|
||||
"sha256:d2b8f245dad9e331540c350285910b20dd913dc86d4ee410c11d48523c4fd546",
|
||||
"sha256:dd032e8422a52e5a4860e062eb84ac94ea08861d334a4bcaf142a63ce8ad4802",
|
||||
"sha256:de49d77e968de6626ba7ef4472323f9d2e5a56c1d85b7c0e2a190b2173d3b9be",
|
||||
"sha256:de839c3a1826a909fdbfe05f6fe2167c4ab033f1133757b5936efe2f84904c07",
|
||||
"sha256:e80ed5a9939ceb6fda42811542f31c8602be336b1fb977bccb012e83da7e4936",
|
||||
"sha256:ea30a42dc94d42f2ba4d0f7c0ffb4f4f9baa1b23045910c0c32df9c9902cb272",
|
||||
"sha256:ea513a25976d21733bff523e0ca836ef1679630ef4ad22d46987d04b372d57fc",
|
||||
"sha256:ed19b74e81b10b592084a5ad1e70f845f0aacb57577018d31de064e71ffa267a",
|
||||
"sha256:f5af52738e225fcc526ae64071b7e5342abe03f42e0e8918227b38c9aa711e28",
|
||||
"sha256:fae37373155f5ef9b403ab48af5136ae9851151f7aacd9926251ab26b953118b"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.8.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
@@ -1,265 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=no-member
|
||||
|
||||
"""
|
||||
A Context Manager / State Machine that keeps track of
|
||||
a single game instance (there should only be one) in a
|
||||
Discord channel
|
||||
"""
|
||||
|
||||
import uuid
|
||||
import datetime
|
||||
|
||||
# import dateparser
|
||||
|
||||
from database.models import (
|
||||
database,
|
||||
GameModel as Game,
|
||||
GuessModel as Guess,
|
||||
PlayerModel as Player,
|
||||
)
|
||||
|
||||
|
||||
async def check_is_running(method, start_new_game=True):
|
||||
"""
|
||||
Decorator that determines if the game is running or not
|
||||
"""
|
||||
|
||||
async def wrapper(self):
|
||||
|
||||
if self.is_running and start_new_game:
|
||||
return await self.message.channel.send("A game is already running")
|
||||
|
||||
if not self.is_running and not start_new_game:
|
||||
return await self.message.channel.send("There is no game running")
|
||||
|
||||
await method(self)
|
||||
|
||||
return await wrapper
|
||||
|
||||
|
||||
class GameManager:
|
||||
"""
|
||||
The game state class
|
||||
|
||||
This represents a game that exists in a channel
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
# Only one game should run at at time
|
||||
self.is_running = False
|
||||
|
||||
self.commands = {
|
||||
"ghostball": self.start,
|
||||
"resolve": self.stop,
|
||||
"guess": self.guess,
|
||||
"points": self.points,
|
||||
"help": self.help,
|
||||
}
|
||||
|
||||
self.game = Game
|
||||
|
||||
# Discord message
|
||||
self.message = None
|
||||
|
||||
# Discord client instance
|
||||
self.discord = None
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
Allows use of `with Game() as game` for try/except statements
|
||||
(https://peps.python.org/pep-0343/)
|
||||
"""
|
||||
|
||||
database.connect()
|
||||
return self
|
||||
|
||||
def __exit__(self, exception_type, exception_value, exception_traceback):
|
||||
"""
|
||||
Automagically close the database
|
||||
when this class has ended execution
|
||||
"""
|
||||
database.close()
|
||||
|
||||
@check_is_running
|
||||
async def start(self):
|
||||
"""
|
||||
Start command - Starts a new game if there isn't already one running
|
||||
"""
|
||||
self.is_running = True
|
||||
|
||||
# game.pitch_value is unknown at the start of the game
|
||||
self.game = Game.create(game_id=uuid.uuid4(), server_id=self.message.guild.id)
|
||||
|
||||
await self.message.send("Send me your guesses with !guess <number>")
|
||||
|
||||
def __stop_args__(self):
|
||||
pieces = self.message.content.split()
|
||||
|
||||
if len(pieces) == 2:
|
||||
return pieces[1], False, None, None
|
||||
|
||||
if len(pieces) == 4:
|
||||
return pieces[1], True, pieces[2], pieces[3]
|
||||
|
||||
return None, False, None, None
|
||||
|
||||
async def close_game(self):
|
||||
"""Update game state database for closing arguments"""
|
||||
# Determine arguments
|
||||
pitch_value, has_batter, batter_id, batter_guess = self.__stop_args__()
|
||||
if not pitch_value:
|
||||
return await self.message.channel.send(
|
||||
f"Invalid command <@{ str(self.message.author.id) }>!"
|
||||
)
|
||||
|
||||
if has_batter:
|
||||
player_id = batter_id[3:]
|
||||
Guess.create(
|
||||
game_id=self.game.game_id,
|
||||
player_id=player_id,
|
||||
player_name=self.discord.get_user(int(player_id).name),
|
||||
guess=int(batter_guess),
|
||||
).save()
|
||||
|
||||
# Save the pitch value
|
||||
self.game.update(
|
||||
{
|
||||
Game.pitch_value: pitch_value,
|
||||
Game.date_ended: datetime.datetime.now(),
|
||||
}
|
||||
)
|
||||
|
||||
return pitch_value
|
||||
|
||||
@check_is_running(stop, start_new_game=False)
|
||||
async def stop(self):
|
||||
"""
|
||||
Stop command - Stops the game if it is currently running,
|
||||
saves the pitch value, and displays differences
|
||||
"""
|
||||
|
||||
pitch_value = await self.close_game()
|
||||
|
||||
# Start calculating difference
|
||||
|
||||
# Get all guesses for this game as a list of combo Guess + Player models,
|
||||
# excluding invalid results, from lowest to highest
|
||||
# http://docs.peewee-orm.com/en/latest/peewee/query_examples.html#joins-and-subqueries
|
||||
records = (
|
||||
Guess.select(
|
||||
Guess.guess, Player.player_id, Player.player_name, Player.total_points
|
||||
)
|
||||
.join(Player)
|
||||
.where(
|
||||
(Guess.game_id == self.game.game_id)
|
||||
& (Guess.guess > 0)
|
||||
& (Guess.player_id == Player.player_id)
|
||||
)
|
||||
.order_by(Guess.guess)
|
||||
)
|
||||
|
||||
# Minimum of 3 players
|
||||
if len(records) < 2:
|
||||
self.game = None
|
||||
self.is_running = False
|
||||
return await self.message.channel.send(
|
||||
("Play closed!\n" + "However, there were not enough participants.")
|
||||
)
|
||||
|
||||
message = (
|
||||
"Closed this play! Here are the results\n"
|
||||
+ "PLAYER | GUESS | DIFFERENCE | POINTS GAINED | TOTAL POINTS\n"
|
||||
)
|
||||
|
||||
# Determine which guesses are closest and furthest from the pitch_value
|
||||
guess_values = [record.guess for record in records]
|
||||
closest_guess_value = min(
|
||||
guess_values, key=lambda guess: abs(guess - pitch_value)
|
||||
)
|
||||
furthest_guess_value = max(
|
||||
guess_values, key=lambda guess: abs(guess - pitch_value)
|
||||
)
|
||||
|
||||
def get_difference_score():
|
||||
# TODO: Calculate score based on scoring table
|
||||
return 0
|
||||
|
||||
for record in records:
|
||||
difference = abs(record.guess - pitch_value)
|
||||
difference_score = get_difference_score()
|
||||
|
||||
# TODO: Update Guess.difference
|
||||
# TODO: Update Player.total_points
|
||||
|
||||
if record.guess == closest_guess_value:
|
||||
closest_player_id = record.player.player_id
|
||||
|
||||
if record.guess == furthest_guess_value:
|
||||
furthest_player_id = record.player.player_id
|
||||
|
||||
message += f"{record.player.player_name} | {record.guess} | {difference} | {difference_score}"
|
||||
|
||||
message += (
|
||||
f"Congrats <@{closest_player_id}>! You were the closest!\n"
|
||||
+ f"Sorry <@{furthest_player_id}>, you were way off"
|
||||
)
|
||||
|
||||
await self.message.channel.send(message)
|
||||
|
||||
# stop and discard game
|
||||
self.is_running = False
|
||||
self.game = None
|
||||
|
||||
@check_is_running(guess, start_new_game=False)
|
||||
async def guess(self):
|
||||
"""
|
||||
Guess command - Allows the player to add a guess to the current
|
||||
running game
|
||||
"""
|
||||
|
||||
value = int(self.message.content.split()[1])
|
||||
if value < 1 or value > 1000:
|
||||
return await self.message.channel.send(
|
||||
"Invalid value. It must be between 1 and 1000 inclusive"
|
||||
)
|
||||
|
||||
player_guess, created = Guess.get_or_create(
|
||||
game_id=self.game.game_id,
|
||||
player_id=self.message.author.id,
|
||||
player_name=self.message.author.name,
|
||||
)
|
||||
|
||||
player_guess.update({Guess.guess: value})
|
||||
if created:
|
||||
return await self.message.add_reaction(emoji="\N{THUMBS UP SIGN}")
|
||||
|
||||
return await self.message.channel.send(
|
||||
f"<@{ str(self.message.author.id) }> your guess has been updated"
|
||||
)
|
||||
|
||||
async def points(self):
|
||||
"""
|
||||
Points command - returns a table ordered from highest to lowest
|
||||
of the players and their points
|
||||
"""
|
||||
# TODO
|
||||
# value = self.message.content.split()
|
||||
# try:
|
||||
# if len(value) > 1:
|
||||
# timestamp = dateparser.parse(value[1])
|
||||
# except:
|
||||
# return await self.message.channel.send("Invalid timestamp. Try again")
|
||||
|
||||
return await self.message.channel.send("Sorry, not implemented yet")
|
||||
|
||||
async def help(self):
|
||||
"""help command"""
|
||||
# TODO: Add help message
|
||||
help_message = "help"
|
||||
|
||||
recipient = await self.discord.fetch_user(self.message.author.id)
|
||||
await recipient.send(help_message)
|
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
pylint main.py game.py discord_client database > lint.log
|
||||
black main.py game.py discord_client database
|
@@ -6,7 +6,6 @@ name = "pypi"
|
||||
[packages]
|
||||
discord = "*"
|
||||
peewee = "*"
|
||||
dateparser = "*"
|
||||
pylint = "*"
|
||||
black = "*"
|
||||
|
617
Pipfile.lock
generated
Normal file
617
Pipfile.lock
generated
Normal file
@@ -0,0 +1,617 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "b6fb0d9cfe588eab84db4024e6b319681e9e70d00c74282b6722fe283ac3e348"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.10"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"aiohttp": {
|
||||
"hashes": [
|
||||
"sha256:02f9a2c72fc95d59b881cf38a4b2be9381b9527f9d328771e90f72ac76f31ad8",
|
||||
"sha256:059a91e88f2c00fe40aed9031b3606c3f311414f86a90d696dd982e7aec48142",
|
||||
"sha256:05a3c31c6d7cd08c149e50dc7aa2568317f5844acd745621983380597f027a18",
|
||||
"sha256:08c78317e950e0762c2983f4dd58dc5e6c9ff75c8a0efeae299d363d439c8e34",
|
||||
"sha256:09e28f572b21642128ef31f4e8372adb6888846f32fecb288c8b0457597ba61a",
|
||||
"sha256:0d2c6d8c6872df4a6ec37d2ede71eff62395b9e337b4e18efd2177de883a5033",
|
||||
"sha256:16c121ba0b1ec2b44b73e3a8a171c4f999b33929cd2397124a8c7fcfc8cd9e06",
|
||||
"sha256:1d90043c1882067f1bd26196d5d2db9aa6d268def3293ed5fb317e13c9413ea4",
|
||||
"sha256:1e56b9cafcd6531bab5d9b2e890bb4937f4165109fe98e2b98ef0dcfcb06ee9d",
|
||||
"sha256:20acae4f268317bb975671e375493dbdbc67cddb5f6c71eebdb85b34444ac46b",
|
||||
"sha256:21b30885a63c3f4ff5b77a5d6caf008b037cb521a5f33eab445dc566f6d092cc",
|
||||
"sha256:21d69797eb951f155026651f7e9362877334508d39c2fc37bd04ff55b2007091",
|
||||
"sha256:256deb4b29fe5e47893fa32e1de2d73c3afe7407738bd3c63829874661d4822d",
|
||||
"sha256:25892c92bee6d9449ffac82c2fe257f3a6f297792cdb18ad784737d61e7a9a85",
|
||||
"sha256:2ca9af5f8f5812d475c5259393f52d712f6d5f0d7fdad9acdb1107dd9e3cb7eb",
|
||||
"sha256:2d252771fc85e0cf8da0b823157962d70639e63cb9b578b1dec9868dd1f4f937",
|
||||
"sha256:2dea10edfa1a54098703cb7acaa665c07b4e7568472a47f4e64e6319d3821ccf",
|
||||
"sha256:2df5f139233060578d8c2c975128fb231a89ca0a462b35d4b5fcf7c501ebdbe1",
|
||||
"sha256:2feebbb6074cdbd1ac276dbd737b40e890a1361b3cc30b74ac2f5e24aab41f7b",
|
||||
"sha256:309aa21c1d54b8ef0723181d430347d7452daaff93e8e2363db8e75c72c2fb2d",
|
||||
"sha256:3828fb41b7203176b82fe5d699e0d845435f2374750a44b480ea6b930f6be269",
|
||||
"sha256:398701865e7a9565d49189f6c90868efaca21be65c725fc87fc305906be915da",
|
||||
"sha256:43046a319664a04b146f81b40e1545d4c8ac7b7dd04c47e40bf09f65f2437346",
|
||||
"sha256:437399385f2abcd634865705bdc180c8314124b98299d54fe1d4c8990f2f9494",
|
||||
"sha256:45d88b016c849d74ebc6f2b6e8bc17cabf26e7e40c0661ddd8fae4c00f015697",
|
||||
"sha256:47841407cc89a4b80b0c52276f3cc8138bbbfba4b179ee3acbd7d77ae33f7ac4",
|
||||
"sha256:4a4fbc769ea9b6bd97f4ad0b430a6807f92f0e5eb020f1e42ece59f3ecfc4585",
|
||||
"sha256:4ab94426ddb1ecc6a0b601d832d5d9d421820989b8caa929114811369673235c",
|
||||
"sha256:4b0f30372cef3fdc262f33d06e7b411cd59058ce9174ef159ad938c4a34a89da",
|
||||
"sha256:4e3a23ec214e95c9fe85a58470b660efe6534b83e6cbe38b3ed52b053d7cb6ad",
|
||||
"sha256:512bd5ab136b8dc0ffe3fdf2dfb0c4b4f49c8577f6cae55dca862cd37a4564e2",
|
||||
"sha256:527b3b87b24844ea7865284aabfab08eb0faf599b385b03c2aa91fc6edd6e4b6",
|
||||
"sha256:54d107c89a3ebcd13228278d68f1436d3f33f2dd2af5415e3feaeb1156e1a62c",
|
||||
"sha256:5835f258ca9f7c455493a57ee707b76d2d9634d84d5d7f62e77be984ea80b849",
|
||||
"sha256:598adde339d2cf7d67beaccda3f2ce7c57b3b412702f29c946708f69cf8222aa",
|
||||
"sha256:599418aaaf88a6d02a8c515e656f6faf3d10618d3dd95866eb4436520096c84b",
|
||||
"sha256:5bf651afd22d5f0c4be16cf39d0482ea494f5c88f03e75e5fef3a85177fecdeb",
|
||||
"sha256:5c59fcd80b9049b49acd29bd3598cada4afc8d8d69bd4160cd613246912535d7",
|
||||
"sha256:653acc3880459f82a65e27bd6526e47ddf19e643457d36a2250b85b41a564715",
|
||||
"sha256:66bd5f950344fb2b3dbdd421aaa4e84f4411a1a13fca3aeb2bcbe667f80c9f76",
|
||||
"sha256:6f3553510abdbec67c043ca85727396ceed1272eef029b050677046d3387be8d",
|
||||
"sha256:7018ecc5fe97027214556afbc7c502fbd718d0740e87eb1217b17efd05b3d276",
|
||||
"sha256:713d22cd9643ba9025d33c4af43943c7a1eb8547729228de18d3e02e278472b6",
|
||||
"sha256:73a4131962e6d91109bca6536416aa067cf6c4efb871975df734f8d2fd821b37",
|
||||
"sha256:75880ed07be39beff1881d81e4a907cafb802f306efd6d2d15f2b3c69935f6fb",
|
||||
"sha256:75e14eac916f024305db517e00a9252714fce0abcb10ad327fb6dcdc0d060f1d",
|
||||
"sha256:8135fa153a20d82ffb64f70a1b5c2738684afa197839b34cc3e3c72fa88d302c",
|
||||
"sha256:84b14f36e85295fe69c6b9789b51a0903b774046d5f7df538176516c3e422446",
|
||||
"sha256:86fc24e58ecb32aee09f864cb11bb91bc4c1086615001647dbfc4dc8c32f4008",
|
||||
"sha256:87f44875f2804bc0511a69ce44a9595d5944837a62caecc8490bbdb0e18b1342",
|
||||
"sha256:88c70ed9da9963d5496d38320160e8eb7e5f1886f9290475a881db12f351ab5d",
|
||||
"sha256:88e5be56c231981428f4f506c68b6a46fa25c4123a2e86d156c58a8369d31ab7",
|
||||
"sha256:89d2e02167fa95172c017732ed7725bc8523c598757f08d13c5acca308e1a061",
|
||||
"sha256:8d6aaa4e7155afaf994d7924eb290abbe81a6905b303d8cb61310a2aba1c68ba",
|
||||
"sha256:92a2964319d359f494f16011e23434f6f8ef0434acd3cf154a6b7bec511e2fb7",
|
||||
"sha256:96372fc29471646b9b106ee918c8eeb4cca423fcbf9a34daa1b93767a88a2290",
|
||||
"sha256:978b046ca728073070e9abc074b6299ebf3501e8dee5e26efacb13cec2b2dea0",
|
||||
"sha256:9c7149272fb5834fc186328e2c1fa01dda3e1fa940ce18fded6d412e8f2cf76d",
|
||||
"sha256:a0239da9fbafd9ff82fd67c16704a7d1bccf0d107a300e790587ad05547681c8",
|
||||
"sha256:ad5383a67514e8e76906a06741febd9126fc7c7ff0f599d6fcce3e82b80d026f",
|
||||
"sha256:ad61a9639792fd790523ba072c0555cd6be5a0baf03a49a5dd8cfcf20d56df48",
|
||||
"sha256:b29bfd650ed8e148f9c515474a6ef0ba1090b7a8faeee26b74a8ff3b33617502",
|
||||
"sha256:b97decbb3372d4b69e4d4c8117f44632551c692bb1361b356a02b97b69e18a62",
|
||||
"sha256:ba71c9b4dcbb16212f334126cc3d8beb6af377f6703d9dc2d9fb3874fd667ee9",
|
||||
"sha256:c37c5cce780349d4d51739ae682dec63573847a2a8dcb44381b174c3d9c8d403",
|
||||
"sha256:c971bf3786b5fad82ce5ad570dc6ee420f5b12527157929e830f51c55dc8af77",
|
||||
"sha256:d1fde0f44029e02d02d3993ad55ce93ead9bb9b15c6b7ccd580f90bd7e3de476",
|
||||
"sha256:d24b8bb40d5c61ef2d9b6a8f4528c2f17f1c5d2d31fed62ec860f6006142e83e",
|
||||
"sha256:d5ba88df9aa5e2f806650fcbeedbe4f6e8736e92fc0e73b0400538fd25a4dd96",
|
||||
"sha256:d6f76310355e9fae637c3162936e9504b4767d5c52ca268331e2756e54fd4ca5",
|
||||
"sha256:d737fc67b9a970f3234754974531dc9afeea11c70791dcb7db53b0cf81b79784",
|
||||
"sha256:da22885266bbfb3f78218dc40205fed2671909fbd0720aedba39b4515c038091",
|
||||
"sha256:da37dcfbf4b7f45d80ee386a5f81122501ec75672f475da34784196690762f4b",
|
||||
"sha256:db19d60d846283ee275d0416e2a23493f4e6b6028825b51290ac05afc87a6f97",
|
||||
"sha256:db4c979b0b3e0fa7e9e69ecd11b2b3174c6963cebadeecfb7ad24532ffcdd11a",
|
||||
"sha256:e164e0a98e92d06da343d17d4e9c4da4654f4a4588a20d6c73548a29f176abe2",
|
||||
"sha256:e168a7560b7c61342ae0412997b069753f27ac4862ec7867eff74f0fe4ea2ad9",
|
||||
"sha256:e381581b37db1db7597b62a2e6b8b57c3deec95d93b6d6407c5b61ddc98aca6d",
|
||||
"sha256:e65bc19919c910127c06759a63747ebe14f386cda573d95bcc62b427ca1afc73",
|
||||
"sha256:e7b8813be97cab8cb52b1375f41f8e6804f6507fe4660152e8ca5c48f0436017",
|
||||
"sha256:e8a78079d9a39ca9ca99a8b0ac2fdc0c4d25fc80c8a8a82e5c8211509c523363",
|
||||
"sha256:ebf909ea0a3fc9596e40d55d8000702a85e27fd578ff41a5500f68f20fd32e6c",
|
||||
"sha256:ec40170327d4a404b0d91855d41bfe1fe4b699222b2b93e3d833a27330a87a6d",
|
||||
"sha256:f178d2aadf0166be4df834c4953da2d7eef24719e8aec9a65289483eeea9d618",
|
||||
"sha256:f88df3a83cf9df566f171adba39d5bd52814ac0b94778d2448652fc77f9eb491",
|
||||
"sha256:f973157ffeab5459eefe7b97a804987876dd0a55570b8fa56b4e1954bf11329b",
|
||||
"sha256:ff25f48fc8e623d95eca0670b8cc1469a83783c924a602e0fbd47363bb54aaca"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==3.8.3"
|
||||
},
|
||||
"aiosignal": {
|
||||
"hashes": [
|
||||
"sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc",
|
||||
"sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.1"
|
||||
},
|
||||
"astroid": {
|
||||
"hashes": [
|
||||
"sha256:10e0ad5f7b79c435179d0d0f0df69998c4eef4597534aae44910db060baeb907",
|
||||
"sha256:1493fe8bd3dfd73dc35bd53c9d5b6e49ead98497c47b2307662556a5692d29d7"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.2'",
|
||||
"version": "==2.12.13"
|
||||
},
|
||||
"async-timeout": {
|
||||
"hashes": [
|
||||
"sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15",
|
||||
"sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"attrs": {
|
||||
"hashes": [
|
||||
"sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6",
|
||||
"sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==22.1.0"
|
||||
},
|
||||
"black": {
|
||||
"hashes": [
|
||||
"sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320",
|
||||
"sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351",
|
||||
"sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350",
|
||||
"sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f",
|
||||
"sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf",
|
||||
"sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148",
|
||||
"sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4",
|
||||
"sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d",
|
||||
"sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc",
|
||||
"sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d",
|
||||
"sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2",
|
||||
"sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==22.12.0"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845",
|
||||
"sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2.1.1"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e",
|
||||
"sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==8.1.3"
|
||||
},
|
||||
"dill": {
|
||||
"hashes": [
|
||||
"sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0",
|
||||
"sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.3.6"
|
||||
},
|
||||
"discord": {
|
||||
"hashes": [
|
||||
"sha256:3f479fcab569c621528c0190092d6383b4da13ec9631711ce3c14f33aedff4ff",
|
||||
"sha256:44515e6d02e61528b2a81e511e03b3f60ce0b3737ba9efc69c2defce2f1ebc1d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"discord.py": {
|
||||
"hashes": [
|
||||
"sha256:027ccdd22b5bb66a9e19cbd8daa1bc74b49271a16a074d57e52f288fcfa208e8",
|
||||
"sha256:a2cfa9f09e3013aaaa43600cc8dfaf67c532dd34afcb71e550f5a0dc9133a5e0"
|
||||
],
|
||||
"markers": "python_full_version >= '3.8.0'",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"frozenlist": {
|
||||
"hashes": [
|
||||
"sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c",
|
||||
"sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f",
|
||||
"sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a",
|
||||
"sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784",
|
||||
"sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27",
|
||||
"sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d",
|
||||
"sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3",
|
||||
"sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678",
|
||||
"sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a",
|
||||
"sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483",
|
||||
"sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8",
|
||||
"sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf",
|
||||
"sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99",
|
||||
"sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c",
|
||||
"sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48",
|
||||
"sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5",
|
||||
"sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56",
|
||||
"sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e",
|
||||
"sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1",
|
||||
"sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401",
|
||||
"sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4",
|
||||
"sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e",
|
||||
"sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649",
|
||||
"sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a",
|
||||
"sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d",
|
||||
"sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0",
|
||||
"sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6",
|
||||
"sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d",
|
||||
"sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b",
|
||||
"sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6",
|
||||
"sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf",
|
||||
"sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef",
|
||||
"sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7",
|
||||
"sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842",
|
||||
"sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba",
|
||||
"sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420",
|
||||
"sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b",
|
||||
"sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d",
|
||||
"sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332",
|
||||
"sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936",
|
||||
"sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816",
|
||||
"sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91",
|
||||
"sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420",
|
||||
"sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448",
|
||||
"sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411",
|
||||
"sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4",
|
||||
"sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32",
|
||||
"sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b",
|
||||
"sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0",
|
||||
"sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530",
|
||||
"sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669",
|
||||
"sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7",
|
||||
"sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1",
|
||||
"sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5",
|
||||
"sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce",
|
||||
"sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4",
|
||||
"sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e",
|
||||
"sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2",
|
||||
"sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d",
|
||||
"sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9",
|
||||
"sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642",
|
||||
"sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0",
|
||||
"sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703",
|
||||
"sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb",
|
||||
"sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1",
|
||||
"sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13",
|
||||
"sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab",
|
||||
"sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38",
|
||||
"sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb",
|
||||
"sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb",
|
||||
"sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81",
|
||||
"sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8",
|
||||
"sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd",
|
||||
"sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.3.3"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4",
|
||||
"sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"isort": {
|
||||
"hashes": [
|
||||
"sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7",
|
||||
"sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"
|
||||
],
|
||||
"markers": "python_version < '4.0' and python_full_version >= '3.6.1'",
|
||||
"version": "==5.10.1"
|
||||
},
|
||||
"lazy-object-proxy": {
|
||||
"hashes": [
|
||||
"sha256:0c1c7c0433154bb7c54185714c6929acc0ba04ee1b167314a779b9025517eada",
|
||||
"sha256:14010b49a2f56ec4943b6cf925f597b534ee2fe1f0738c84b3bce0c1a11ff10d",
|
||||
"sha256:4e2d9f764f1befd8bdc97673261b8bb888764dfdbd7a4d8f55e4fbcabb8c3fb7",
|
||||
"sha256:4fd031589121ad46e293629b39604031d354043bb5cdf83da4e93c2d7f3389fe",
|
||||
"sha256:5b51d6f3bfeb289dfd4e95de2ecd464cd51982fe6f00e2be1d0bf94864d58acd",
|
||||
"sha256:6850e4aeca6d0df35bb06e05c8b934ff7c533734eb51d0ceb2d63696f1e6030c",
|
||||
"sha256:6f593f26c470a379cf7f5bc6db6b5f1722353e7bf937b8d0d0b3fba911998858",
|
||||
"sha256:71d9ae8a82203511a6f60ca5a1b9f8ad201cac0fc75038b2dc5fa519589c9288",
|
||||
"sha256:7e1561626c49cb394268edd00501b289053a652ed762c58e1081224c8d881cec",
|
||||
"sha256:8f6ce2118a90efa7f62dd38c7dbfffd42f468b180287b748626293bf12ed468f",
|
||||
"sha256:ae032743794fba4d171b5b67310d69176287b5bf82a21f588282406a79498891",
|
||||
"sha256:afcaa24e48bb23b3be31e329deb3f1858f1f1df86aea3d70cb5c8578bfe5261c",
|
||||
"sha256:b70d6e7a332eb0217e7872a73926ad4fdc14f846e85ad6749ad111084e76df25",
|
||||
"sha256:c219a00245af0f6fa4e95901ed28044544f50152840c5b6a3e7b2568db34d156",
|
||||
"sha256:ce58b2b3734c73e68f0e30e4e725264d4d6be95818ec0a0be4bb6bf9a7e79aa8",
|
||||
"sha256:d176f392dbbdaacccf15919c77f526edf11a34aece58b55ab58539807b85436f",
|
||||
"sha256:e20bfa6db17a39c706d24f82df8352488d2943a3b7ce7d4c22579cb89ca8896e",
|
||||
"sha256:eac3a9a5ef13b332c059772fd40b4b1c3d45a3a2b05e33a361dee48e54a4dad0",
|
||||
"sha256:eb329f8d8145379bf5dbe722182410fe8863d186e51bf034d2075eb8d85ee25b"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.8.0"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
|
||||
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==0.7.0"
|
||||
},
|
||||
"multidict": {
|
||||
"hashes": [
|
||||
"sha256:018c8e3be7f161a12b3e41741b6721f9baeb2210f4ab25a6359b7d76c1017dce",
|
||||
"sha256:01b456046a05ff7cceefb0e1d2a9d32f05efcb1c7e0d152446304e11557639ce",
|
||||
"sha256:114a4ab3e5cfbc56c4b6697686ecb92376c7e8c56893ef20547921552f8bdf57",
|
||||
"sha256:12e0d396faa6dc55ff5379eee54d1df3b508243ff15bfc8295a6ec7a4483a335",
|
||||
"sha256:190626ced82d4cc567a09e7346340d380154a493bac6905e0095d8158cdf1e38",
|
||||
"sha256:1f5d5129a937af4e3c4a1d6c139f4051b7d17d43276cefdd8d442a7031f7eef2",
|
||||
"sha256:21e1ce0b187c4e93112304dcde2aa18922fdbe8fb4f13d8aa72a5657bce0563a",
|
||||
"sha256:24e8d513bfcaadc1f8b0ebece3ff50961951c54b07d5a775008a882966102418",
|
||||
"sha256:2523a29006c034687eccd3ee70093a697129a3ffe8732535d3b2df6a4ecc279d",
|
||||
"sha256:26fbbe17f8a7211b623502d2bf41022a51da3025142401417c765bf9a56fed4c",
|
||||
"sha256:2b66d61966b12e6bba500e5cbb2c721a35e119c30ee02495c5629bd0e91eea30",
|
||||
"sha256:2cf5d19e12eff855aa198259c0b02fd3f5d07e1291fbd20279c37b3b0e6c9852",
|
||||
"sha256:2cfda34b7cb99eacada2072e0f69c0ad3285cb6f8e480b11f2b6d6c1c6f92718",
|
||||
"sha256:3541882266247c7cd3dba78d6ef28dbe704774df60c9e4231edaa4493522e614",
|
||||
"sha256:36df958b15639e40472adaa4f0c2c7828fe680f894a6b48c4ce229f59a6a798b",
|
||||
"sha256:38d394814b39be1c36ac709006d39d50d72a884f9551acd9c8cc1ffae3fc8c4e",
|
||||
"sha256:4159fc1ec9ede8ab93382e0d6ba9b1b3d23c72da39a834db7a116986605c7ab4",
|
||||
"sha256:445c0851a1cbc1f2ec3b40bc22f9c4a235edb3c9a0906122a9df6ea8d51f886c",
|
||||
"sha256:47defc0218682281a52fb1f6346ebb8b68b17538163a89ea24dfe4da37a8a9a3",
|
||||
"sha256:4cc5c8cd205a9810d16a5cd428cd81bac554ad1477cb87f4ad722b10992e794d",
|
||||
"sha256:4ccf55f28066b4f08666764a957c2b7c241c7547b0921d69c7ceab5f74fe1a45",
|
||||
"sha256:4fb3fe591956d8841882c463f934c9f7485cfd5f763a08c0d467b513dc18ef89",
|
||||
"sha256:526f8397fc124674b8f39748680a0ff673bd6a715fecb4866716d36e380f015f",
|
||||
"sha256:578bfcb16f4b8675ef71b960c00f174b0426e0eeb796bab6737389d8288eb827",
|
||||
"sha256:5b51969503709415a35754954c2763f536a70b8bf7360322b2edb0c0a44391f6",
|
||||
"sha256:5e58ec0375803526d395f6f7e730ecc45d06e15f68f7b9cdbf644a2918324e51",
|
||||
"sha256:62db44727d0befea68e8ad2881bb87a9cfb6b87d45dd78609009627167f37b69",
|
||||
"sha256:67090b17a0a5be5704fd109f231ee73cefb1b3802d41288d6378b5df46ae89ba",
|
||||
"sha256:6cd14e61f0da2a2cfb9fe05bfced2a1ed7063ce46a7a8cd473be4973de9a7f91",
|
||||
"sha256:70740c2bc9ab1c99f7cdcb104f27d16c63860c56d51c5bf0ef82fc1d892a2131",
|
||||
"sha256:73009ea04205966d47e16d98686ac5c438af23a1bb30b48a2c5da3423ec9ce37",
|
||||
"sha256:791458a1f7d1b4ab3bd9e93e0dcd1d59ef7ee9aa051dcd1ea030e62e49b923fd",
|
||||
"sha256:7f9511e48bde6b995825e8d35e434fc96296cf07a25f4aae24ff9162be7eaa46",
|
||||
"sha256:81c3d597591b0940e04949e4e4f79359b2d2e542a686ba0da5e25de33fec13e0",
|
||||
"sha256:8230a39bae6c2e8a09e4da6bace5064693b00590a4a213e38f9a9366da10e7dd",
|
||||
"sha256:8b92a9f3ab904397a33b193000dc4de7318ea175c4c460a1e154c415f9008e3d",
|
||||
"sha256:94cbe5535ef150546b8321aebea22862a3284da51e7b55f6f95b7d73e96d90ee",
|
||||
"sha256:960ce1b790952916e682093788696ef7e33ac6a97482f9b983abdc293091b531",
|
||||
"sha256:99341ca1f1db9e7f47914cb2461305665a662383765ced6f843712564766956d",
|
||||
"sha256:9aac6881454a750554ed4b280a839dcf9e2133a9d12ab4d417d673fb102289b7",
|
||||
"sha256:9d359b0a962e052b713647ac1f13eabf2263167b149ed1e27d5c579f5c8c7d2c",
|
||||
"sha256:9dbab2a7e9c073bc9538824a01f5ed689194db7f55f2b8102766873e906a6c1a",
|
||||
"sha256:a27b029caa3b555a4f3da54bc1e718eb55fcf1a11fda8bf0132147b476cf4c08",
|
||||
"sha256:a8b817d4ed68fd568ec5e45dd75ddf30cc72a47a6b41b74d5bb211374c296f5e",
|
||||
"sha256:ad7d66422b9cc51125509229693d27e18c08f2dea3ac9de408d821932b1b3759",
|
||||
"sha256:b46e79a9f4db53897d17bc64a39d1c7c2be3e3d4f8dba6d6730a2b13ddf0f986",
|
||||
"sha256:baa96a3418e27d723064854143b2f414a422c84cc87285a71558722049bebc5a",
|
||||
"sha256:beeca903e4270b4afcd114f371a9602240dc143f9e944edfea00f8d4ad56c40d",
|
||||
"sha256:c2a1168e5aa7c72499fb03c850e0f03f624fa4a5c8d2e215c518d0a73872eb64",
|
||||
"sha256:c5790cc603456b6dcf8a9a4765f666895a6afddc88b3d3ba7b53dea2b6e23116",
|
||||
"sha256:cb4a08f0aaaa869f189ffea0e17b86ad0237b51116d494da15ef7991ee6ad2d7",
|
||||
"sha256:cd5771e8ea325f85cbb361ddbdeb9ae424a68e5dfb6eea786afdcd22e68a7d5d",
|
||||
"sha256:ce8e51774eb03844588d3c279adb94efcd0edeccd2f97516623292445bcc01f9",
|
||||
"sha256:d09daf5c6ce7fc6ed444c9339bbde5ea84e2534d1ca1cd37b60f365c77f00dea",
|
||||
"sha256:d0e798b072cf2aab9daceb43d97c9c527a0c7593e67a7846ad4cc6051de1e303",
|
||||
"sha256:d325d61cac602976a5d47b19eaa7d04e3daf4efce2164c630219885087234102",
|
||||
"sha256:d408172519049e36fb6d29672f060dc8461fc7174eba9883c7026041ef9bfb38",
|
||||
"sha256:d52442e7c951e4c9ee591d6047706e66923d248d83958bbf99b8b19515fffaef",
|
||||
"sha256:dc4cfef5d899f5f1a15f3d2ac49f71107a01a5a2745b4dd53fa0cede1419385a",
|
||||
"sha256:df7b4cee3ff31b3335aba602f8d70dbc641e5b7164b1e9565570c9d3c536a438",
|
||||
"sha256:e068dfeadbce63072b2d8096486713d04db4946aad0a0f849bd4fc300799d0d3",
|
||||
"sha256:e07c24018986fb00d6e7eafca8fcd6e05095649e17fcf0e33a592caaa62a78b9",
|
||||
"sha256:e0bce9f7c30e7e3a9e683f670314c0144e8d34be6b7019e40604763bd278d84f",
|
||||
"sha256:e1925f78a543b94c3d46274c66a366fee8a263747060220ed0188e5f3eeea1c0",
|
||||
"sha256:e322c94596054352f5a02771eec71563c018b15699b961aba14d6dd943367022",
|
||||
"sha256:e4a095e18847c12ec20e55326ab8782d9c2d599400a3a2f174fab4796875d0e2",
|
||||
"sha256:e5a811aab1b4aea0b4be669363c19847a8c547510f0e18fb632956369fdbdf67",
|
||||
"sha256:eddf604a3de2ace3d9a4e4d491be7562a1ac095a0a1c95a9ec5781ef0273ef11",
|
||||
"sha256:ee9b1cae9a6c5d023e5a150f6f6b9dbb3c3bbc7887d6ee07d4c0ecb49a473734",
|
||||
"sha256:f1650ea41c408755da5eed52ac6ccbc8938ccc3e698d81e6f6a1be02ff2a0945",
|
||||
"sha256:f2c0957b3e8c66c10d27272709a5299ab3670a0f187c9428f3b90d267119aedb",
|
||||
"sha256:f76109387e1ec8d8e2137c94c437b89fe002f29e0881aae8ae45529bdff92000",
|
||||
"sha256:f8a728511c977df6f3d8af388fcb157e49f11db4a6637dd60131b8b6e40b0253",
|
||||
"sha256:fb6c3dc3d65014d2c782f5acf0b3ba14e639c6c33d3ed8932ead76b9080b3544"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==6.0.3"
|
||||
},
|
||||
"mypy-extensions": {
|
||||
"hashes": [
|
||||
"sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
|
||||
"sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
|
||||
],
|
||||
"version": "==0.4.3"
|
||||
},
|
||||
"pathspec": {
|
||||
"hashes": [
|
||||
"sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6",
|
||||
"sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.10.3"
|
||||
},
|
||||
"peewee": {
|
||||
"hashes": [
|
||||
"sha256:2581520c8dfbacd9d580c2719ae259f0637a9e46eda47dfc0ce01864c6366205"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.15.4"
|
||||
},
|
||||
"platformdirs": {
|
||||
"hashes": [
|
||||
"sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca",
|
||||
"sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.6.0"
|
||||
},
|
||||
"pylint": {
|
||||
"hashes": [
|
||||
"sha256:ea82cd6a1e11062dc86d555d07c021b0fb65afe39becbe6fe692efd6c4a67443",
|
||||
"sha256:ec4a87c33da054ab86a6c79afa6771dc8765cb5631620053e727fcf3ef8cbed7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.15.8"
|
||||
},
|
||||
"tomli": {
|
||||
"hashes": [
|
||||
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
|
||||
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
|
||||
],
|
||||
"markers": "python_full_version < '3.11.0a7'",
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"tomlkit": {
|
||||
"hashes": [
|
||||
"sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b",
|
||||
"sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==0.11.6"
|
||||
},
|
||||
"wrapt": {
|
||||
"hashes": [
|
||||
"sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3",
|
||||
"sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b",
|
||||
"sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4",
|
||||
"sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2",
|
||||
"sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656",
|
||||
"sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3",
|
||||
"sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff",
|
||||
"sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310",
|
||||
"sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a",
|
||||
"sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57",
|
||||
"sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069",
|
||||
"sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383",
|
||||
"sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe",
|
||||
"sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87",
|
||||
"sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d",
|
||||
"sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b",
|
||||
"sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907",
|
||||
"sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f",
|
||||
"sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0",
|
||||
"sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28",
|
||||
"sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1",
|
||||
"sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853",
|
||||
"sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc",
|
||||
"sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3",
|
||||
"sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3",
|
||||
"sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164",
|
||||
"sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1",
|
||||
"sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c",
|
||||
"sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1",
|
||||
"sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7",
|
||||
"sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1",
|
||||
"sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320",
|
||||
"sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed",
|
||||
"sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1",
|
||||
"sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248",
|
||||
"sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c",
|
||||
"sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456",
|
||||
"sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77",
|
||||
"sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef",
|
||||
"sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1",
|
||||
"sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7",
|
||||
"sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86",
|
||||
"sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4",
|
||||
"sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d",
|
||||
"sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d",
|
||||
"sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8",
|
||||
"sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5",
|
||||
"sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471",
|
||||
"sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00",
|
||||
"sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68",
|
||||
"sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3",
|
||||
"sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d",
|
||||
"sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735",
|
||||
"sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d",
|
||||
"sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569",
|
||||
"sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7",
|
||||
"sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59",
|
||||
"sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5",
|
||||
"sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb",
|
||||
"sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b",
|
||||
"sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f",
|
||||
"sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462",
|
||||
"sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015",
|
||||
"sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"
|
||||
],
|
||||
"markers": "python_version < '3.11'",
|
||||
"version": "==1.14.1"
|
||||
},
|
||||
"yarl": {
|
||||
"hashes": [
|
||||
"sha256:009a028127e0a1755c38b03244c0bea9d5565630db9c4cf9572496e947137a87",
|
||||
"sha256:0414fd91ce0b763d4eadb4456795b307a71524dbacd015c657bb2a39db2eab89",
|
||||
"sha256:0978f29222e649c351b173da2b9b4665ad1feb8d1daa9d971eb90df08702668a",
|
||||
"sha256:0ef8fb25e52663a1c85d608f6dd72e19bd390e2ecaf29c17fb08f730226e3a08",
|
||||
"sha256:10b08293cda921157f1e7c2790999d903b3fd28cd5c208cf8826b3b508026996",
|
||||
"sha256:1684a9bd9077e922300ecd48003ddae7a7474e0412bea38d4631443a91d61077",
|
||||
"sha256:1b372aad2b5f81db66ee7ec085cbad72c4da660d994e8e590c997e9b01e44901",
|
||||
"sha256:1e21fb44e1eff06dd6ef971d4bdc611807d6bd3691223d9c01a18cec3677939e",
|
||||
"sha256:2305517e332a862ef75be8fad3606ea10108662bc6fe08509d5ca99503ac2aee",
|
||||
"sha256:24ad1d10c9db1953291f56b5fe76203977f1ed05f82d09ec97acb623a7976574",
|
||||
"sha256:272b4f1599f1b621bf2aabe4e5b54f39a933971f4e7c9aa311d6d7dc06965165",
|
||||
"sha256:2a1fca9588f360036242f379bfea2b8b44cae2721859b1c56d033adfd5893634",
|
||||
"sha256:2b4fa2606adf392051d990c3b3877d768771adc3faf2e117b9de7eb977741229",
|
||||
"sha256:3150078118f62371375e1e69b13b48288e44f6691c1069340081c3fd12c94d5b",
|
||||
"sha256:326dd1d3caf910cd26a26ccbfb84c03b608ba32499b5d6eeb09252c920bcbe4f",
|
||||
"sha256:34c09b43bd538bf6c4b891ecce94b6fa4f1f10663a8d4ca589a079a5018f6ed7",
|
||||
"sha256:388a45dc77198b2460eac0aca1efd6a7c09e976ee768b0d5109173e521a19daf",
|
||||
"sha256:3adeef150d528ded2a8e734ebf9ae2e658f4c49bf413f5f157a470e17a4a2e89",
|
||||
"sha256:3edac5d74bb3209c418805bda77f973117836e1de7c000e9755e572c1f7850d0",
|
||||
"sha256:3f6b4aca43b602ba0f1459de647af954769919c4714706be36af670a5f44c9c1",
|
||||
"sha256:3fc056e35fa6fba63248d93ff6e672c096f95f7836938241ebc8260e062832fe",
|
||||
"sha256:418857f837347e8aaef682679f41e36c24250097f9e2f315d39bae3a99a34cbf",
|
||||
"sha256:42430ff511571940d51e75cf42f1e4dbdded477e71c1b7a17f4da76c1da8ea76",
|
||||
"sha256:44ceac0450e648de86da8e42674f9b7077d763ea80c8ceb9d1c3e41f0f0a9951",
|
||||
"sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863",
|
||||
"sha256:48dd18adcf98ea9cd721a25313aef49d70d413a999d7d89df44f469edfb38a06",
|
||||
"sha256:49d43402c6e3013ad0978602bf6bf5328535c48d192304b91b97a3c6790b1562",
|
||||
"sha256:4d04acba75c72e6eb90745447d69f84e6c9056390f7a9724605ca9c56b4afcc6",
|
||||
"sha256:57a7c87927a468e5a1dc60c17caf9597161d66457a34273ab1760219953f7f4c",
|
||||
"sha256:58a3c13d1c3005dbbac5c9f0d3210b60220a65a999b1833aa46bd6677c69b08e",
|
||||
"sha256:5df5e3d04101c1e5c3b1d69710b0574171cc02fddc4b23d1b2813e75f35a30b1",
|
||||
"sha256:63243b21c6e28ec2375f932a10ce7eda65139b5b854c0f6b82ed945ba526bff3",
|
||||
"sha256:64dd68a92cab699a233641f5929a40f02a4ede8c009068ca8aa1fe87b8c20ae3",
|
||||
"sha256:6604711362f2dbf7160df21c416f81fac0de6dbcf0b5445a2ef25478ecc4c778",
|
||||
"sha256:6c4fcfa71e2c6a3cb568cf81aadc12768b9995323186a10827beccf5fa23d4f8",
|
||||
"sha256:6d88056a04860a98341a0cf53e950e3ac9f4e51d1b6f61a53b0609df342cc8b2",
|
||||
"sha256:705227dccbe96ab02c7cb2c43e1228e2826e7ead880bb19ec94ef279e9555b5b",
|
||||
"sha256:728be34f70a190566d20aa13dc1f01dc44b6aa74580e10a3fb159691bc76909d",
|
||||
"sha256:74dece2bfc60f0f70907c34b857ee98f2c6dd0f75185db133770cd67300d505f",
|
||||
"sha256:75c16b2a900b3536dfc7014905a128a2bea8fb01f9ee26d2d7d8db0a08e7cb2c",
|
||||
"sha256:77e913b846a6b9c5f767b14dc1e759e5aff05502fe73079f6f4176359d832581",
|
||||
"sha256:7a66c506ec67eb3159eea5096acd05f5e788ceec7b96087d30c7d2865a243918",
|
||||
"sha256:8c46d3d89902c393a1d1e243ac847e0442d0196bbd81aecc94fcebbc2fd5857c",
|
||||
"sha256:93202666046d9edadfe9f2e7bf5e0782ea0d497b6d63da322e541665d65a044e",
|
||||
"sha256:97209cc91189b48e7cfe777237c04af8e7cc51eb369004e061809bcdf4e55220",
|
||||
"sha256:a48f4f7fea9a51098b02209d90297ac324241bf37ff6be6d2b0149ab2bd51b37",
|
||||
"sha256:a783cd344113cb88c5ff7ca32f1f16532a6f2142185147822187913eb989f739",
|
||||
"sha256:ae0eec05ab49e91a78700761777f284c2df119376e391db42c38ab46fd662b77",
|
||||
"sha256:ae4d7ff1049f36accde9e1ef7301912a751e5bae0a9d142459646114c70ecba6",
|
||||
"sha256:b05df9ea7496df11b710081bd90ecc3a3db6adb4fee36f6a411e7bc91a18aa42",
|
||||
"sha256:baf211dcad448a87a0d9047dc8282d7de59473ade7d7fdf22150b1d23859f946",
|
||||
"sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5",
|
||||
"sha256:bcd7bb1e5c45274af9a1dd7494d3c52b2be5e6bd8d7e49c612705fd45420b12d",
|
||||
"sha256:bf071f797aec5b96abfc735ab97da9fd8f8768b43ce2abd85356a3127909d146",
|
||||
"sha256:c15163b6125db87c8f53c98baa5e785782078fbd2dbeaa04c6141935eb6dab7a",
|
||||
"sha256:cb6d48d80a41f68de41212f3dfd1a9d9898d7841c8f7ce6696cf2fd9cb57ef83",
|
||||
"sha256:ceff9722e0df2e0a9e8a79c610842004fa54e5b309fe6d218e47cd52f791d7ef",
|
||||
"sha256:cfa2bbca929aa742b5084fd4663dd4b87c191c844326fcb21c3afd2d11497f80",
|
||||
"sha256:d617c241c8c3ad5c4e78a08429fa49e4b04bedfc507b34b4d8dceb83b4af3588",
|
||||
"sha256:d881d152ae0007809c2c02e22aa534e702f12071e6b285e90945aa3c376463c5",
|
||||
"sha256:da65c3f263729e47351261351b8679c6429151ef9649bba08ef2528ff2c423b2",
|
||||
"sha256:de986979bbd87272fe557e0a8fcb66fd40ae2ddfe28a8b1ce4eae22681728fef",
|
||||
"sha256:df60a94d332158b444301c7f569659c926168e4d4aad2cfbf4bce0e8fb8be826",
|
||||
"sha256:dfef7350ee369197106805e193d420b75467b6cceac646ea5ed3049fcc950a05",
|
||||
"sha256:e59399dda559688461762800d7fb34d9e8a6a7444fd76ec33220a926c8be1516",
|
||||
"sha256:e6f3515aafe0209dd17fb9bdd3b4e892963370b3de781f53e1746a521fb39fc0",
|
||||
"sha256:e7fd20d6576c10306dea2d6a5765f46f0ac5d6f53436217913e952d19237efc4",
|
||||
"sha256:ebb78745273e51b9832ef90c0898501006670d6e059f2cdb0e999494eb1450c2",
|
||||
"sha256:efff27bd8cbe1f9bd127e7894942ccc20c857aa8b5a0327874f30201e5ce83d0",
|
||||
"sha256:f37db05c6051eff17bc832914fe46869f8849de5b92dc4a3466cd63095d23dfd",
|
||||
"sha256:f8ca8ad414c85bbc50f49c0a106f951613dfa5f948ab69c10ce9b128d368baf8",
|
||||
"sha256:fb742dcdd5eec9f26b61224c23baea46c9055cf16f62475e11b9b15dfd5c117b",
|
||||
"sha256:fc77086ce244453e074e445104f0ecb27530d6fd3a46698e33f6c38951d5a0f1",
|
||||
"sha256:ff205b58dc2929191f68162633d5e10e8044398d7a45265f90a0f1d51f85f72c"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==1.8.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
@@ -9,6 +9,7 @@
|
||||
"""
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import datetime
|
||||
|
||||
from peewee import (
|
||||
@@ -22,7 +23,7 @@ from peewee import (
|
||||
)
|
||||
|
||||
# User can provide path to database, or it will be put next to main.py
|
||||
DATABASE = os.environ.get("database_path", os.getcwd() + "/ghostball.db")
|
||||
DATABASE = os.environ.get("database_path", os.getcwd() + "/baseball.db")
|
||||
database = SqliteDatabase(DATABASE, pragmas={"foreign_keys": 1})
|
||||
|
||||
|
||||
@@ -55,7 +56,7 @@ class PlayerModel(BaseModel):
|
||||
class GameModel(BaseModel):
|
||||
"""Games that are ran"""
|
||||
|
||||
game_id = UUIDField(primary_key=True)
|
||||
game_id = UUIDField(primary_key=True, default=uuid.uuid4)
|
||||
server_id = IntegerField()
|
||||
|
||||
pitch_value = IntegerField(null=True)
|
||||
@@ -66,10 +67,10 @@ class GameModel(BaseModel):
|
||||
class GuessModel(BaseModel):
|
||||
"""Guesses for a particular game"""
|
||||
|
||||
guess_id = UUIDField(primary_key=True)
|
||||
guess_id = UUIDField(primary_key=True, default=uuid.uuid4)
|
||||
|
||||
player = ForeignKeyField(PlayerModel, backref="guesses")
|
||||
game_id = ForeignKeyField(GameModel, backref="guesses")
|
||||
game = ForeignKeyField(GameModel, backref="guesses")
|
||||
|
||||
guess = IntegerField(default=0)
|
||||
difference = IntegerField(null=True)
|
||||
@@ -80,4 +81,4 @@ def create_models():
|
||||
"""Create database tables"""
|
||||
|
||||
with database:
|
||||
database.create_tables([GameModel, GuessModel, PlayerModel()])
|
||||
database.create_tables([GameModel, GuessModel, PlayerModel])
|
@@ -5,7 +5,7 @@
|
||||
# pylint: disable=wrong-import-position
|
||||
|
||||
"""
|
||||
A discord bot that hosts Ghostball/Braveball.
|
||||
A discord bot that hosts Baseball/Braveball.
|
||||
|
||||
A discord game where players guess the pitch speed
|
||||
from a fantasy baseball pitcher, and whoever is
|
||||
@@ -18,10 +18,10 @@ import discord
|
||||
|
||||
# Import game functions
|
||||
sys.path.append("..")
|
||||
import game
|
||||
from game.manager import GameManager
|
||||
|
||||
|
||||
class GhostBallClient(discord.Client):
|
||||
class BaseBallClient(discord.Client):
|
||||
"""
|
||||
Implementation of a Discord client that will monitor
|
||||
a channel for messages, and if it recieves a message
|
||||
@@ -31,7 +31,7 @@ class GhostBallClient(discord.Client):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
with game.GameManager() as self.game:
|
||||
with GameManager() as self.game:
|
||||
self.game.discord = self
|
||||
|
||||
async def on_ready(self):
|
||||
@@ -56,4 +56,4 @@ class GhostBallClient(discord.Client):
|
||||
for command, function in self.game.commands:
|
||||
if firstword == command:
|
||||
self.game.message = message
|
||||
await function(self.game)
|
||||
await function()
|
55
game/base.py
Normal file
55
game/base.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring
|
||||
|
||||
import logging
|
||||
|
||||
from database.models import database, GameModel as Game
|
||||
|
||||
|
||||
class BaseGameManager:
|
||||
"""Base Game Manager for each Game Manager class to inherit"""
|
||||
|
||||
def __init__(self):
|
||||
# Only one game should run at at time
|
||||
self.is_running = False
|
||||
|
||||
self.commands = []
|
||||
|
||||
self.game = Game
|
||||
|
||||
# Discord message
|
||||
self.message = None
|
||||
|
||||
# Discord client instance
|
||||
self.discord = None
|
||||
|
||||
logger = logging.getLogger()
|
||||
console = logging.StreamHandler()
|
||||
|
||||
format_str = '%(asctime)s\t%(levelname)s -- %(processName)s %(filename)s:%(lineno)s -- %(message)s'
|
||||
console.setFormatter(logging.Formatter(format_str))
|
||||
|
||||
logger.addHandler(console)
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
self.logger = logger
|
||||
|
||||
def __enter__(self):
|
||||
"""
|
||||
Allows use of `with Game() as game` for try/except statements
|
||||
(https://peps.python.org/pep-0343/)
|
||||
"""
|
||||
|
||||
database.connect()
|
||||
return self
|
||||
|
||||
def __exit__(self, exception_type, exception_value, exception_traceback):
|
||||
"""
|
||||
Automagically close the database
|
||||
when this class has ended execution
|
||||
"""
|
||||
database.close()
|
30
game/clear.py
Normal file
30
game/clear.py
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring,too-few-public-methods
|
||||
|
||||
from database.models import PlayerModel as Player
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class ClearManager(BaseGameManager):
|
||||
"""Commands that run when a player clears the session leaderboard"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("clear", self.clear))
|
||||
|
||||
async def clear(self):
|
||||
"""Clear command - Clears the session scoreboard"""
|
||||
|
||||
players = Player.select(Player.player_id, Player.total_points)
|
||||
|
||||
for player in players:
|
||||
player.total_points = 0
|
||||
|
||||
Player.bulk_update(players, fields=[Player.total_points])
|
||||
|
||||
clear_message = "The score has been cleared!"
|
||||
|
||||
await self.message.channel.send(clear_message)
|
89
game/end_game.py
Normal file
89
game/end_game.py
Normal file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring
|
||||
|
||||
import datetime
|
||||
|
||||
from database.models import GameModel as Game, GuessModel as Guess
|
||||
from game.base import BaseGameManager
|
||||
from game.process_guess import ProcessGuess
|
||||
|
||||
|
||||
class EndGameManager(BaseGameManager):
|
||||
"""Commands that run at the end of a play"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("resolve", self.stop))
|
||||
|
||||
async def update_pitch_value(self):
|
||||
"""Update game state database for closing arguments"""
|
||||
pitch_value = self.message.content.split()[1]
|
||||
if not pitch_value:
|
||||
return await self.message.channel.send(
|
||||
f"Invalid command <@{ str(self.message.author.id) }>!"
|
||||
)
|
||||
|
||||
# Save the pitch value
|
||||
Game.update(
|
||||
{
|
||||
Game.pitch_value: pitch_value,
|
||||
Game.date_ended: datetime.datetime.now(),
|
||||
}
|
||||
).where(Game.game_id == self.game.game_id).execute()
|
||||
|
||||
return int(pitch_value)
|
||||
|
||||
async def stop(self):
|
||||
"""
|
||||
Stop command - Stops the game if it is currently running,
|
||||
saves the pitch value, and displays differences
|
||||
"""
|
||||
|
||||
if not self.is_running:
|
||||
return await self.message.channel.send("There is no game running")
|
||||
|
||||
# How many valid guesses got placed?
|
||||
guess_count = (
|
||||
Guess.select()
|
||||
.join(Game)
|
||||
.where((Guess.game.game_id == self.game.game_id) & (Guess.guess > 0))
|
||||
.count()
|
||||
)
|
||||
|
||||
# Discard the game if there weren't enough players
|
||||
if guess_count < 2:
|
||||
self.game = None
|
||||
self.is_running = False
|
||||
return await self.message.channel.send(
|
||||
("Play closed!\n" + "However, there were not enough participants.")
|
||||
)
|
||||
|
||||
message = (
|
||||
"Closed this play! Here are the results\n"
|
||||
+ "__PLAYER | GUESS | DIFFERENCE | POINTS GAINED | TOTAL POINTS__\n"
|
||||
)
|
||||
|
||||
pitch_value = await self.update_pitch_value()
|
||||
guess_processor = ProcessGuess(
|
||||
game=self, pitch_value=pitch_value, message=message
|
||||
)
|
||||
|
||||
(
|
||||
message,
|
||||
closest_player_id,
|
||||
furthest_player_id,
|
||||
) = guess_processor.process_guesses()
|
||||
|
||||
message += (
|
||||
f"\nCongrats <@{closest_player_id}>! You were the closest!\n"
|
||||
+ f"Sorry <@{furthest_player_id}>, you were way off"
|
||||
)
|
||||
|
||||
await self.message.channel.send(message)
|
||||
|
||||
# stop and discard game
|
||||
self.is_running = False
|
||||
self.game = None
|
52
game/guess.py
Normal file
52
game/guess.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring,too-few-public-methods
|
||||
|
||||
from database.models import PlayerModel as Player, GuessModel as Guess
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class GuessManager(BaseGameManager):
|
||||
"""Commands that run when a player makes a guess"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("guess", self.guess))
|
||||
|
||||
async def guess(self):
|
||||
"""
|
||||
Guess command - Allows the player to add a guess to the current
|
||||
running game
|
||||
"""
|
||||
|
||||
if not self.is_running:
|
||||
return await self.message.channel.send("There is no game running")
|
||||
|
||||
value = int(self.message.content.split()[1])
|
||||
if value < 1 or value > 1000:
|
||||
return await self.message.channel.send(
|
||||
"Invalid value. It must be between 1 and 1000 inclusive"
|
||||
)
|
||||
|
||||
# Create player if they don't exist
|
||||
player, _ = Player.get_or_create(
|
||||
player_id=self.message.author.id, player_name=self.message.author.name
|
||||
)
|
||||
|
||||
# Create the guess (or allow us to say update successful)
|
||||
_, created = Guess.get_or_create(
|
||||
game_id=self.game.game_id, player_id=player.player_id
|
||||
)
|
||||
|
||||
Guess.update({"guess": value}).where(
|
||||
(Guess.game == self.game.game_id) & (Guess.player == self.message.author.id)
|
||||
).execute()
|
||||
|
||||
if created:
|
||||
return await self.message.add_reaction("\N{THUMBS UP SIGN}")
|
||||
|
||||
return await self.message.channel.send(
|
||||
f"<@{ str(self.message.author.id) }> your guess has been updated"
|
||||
)
|
34
game/help.py
Normal file
34
game/help.py
Normal file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring,too-few-public-methods
|
||||
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class HelpManager(BaseGameManager):
|
||||
"""Commands that run when a player asks for help"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("help", self.help))
|
||||
|
||||
async def help(self):
|
||||
"""help command - Sends a DM to the requesting user with available commands"""
|
||||
|
||||
help_message = (
|
||||
"Braveball commands\n"
|
||||
+ "ping - Will respond 'pong' if the bot is alive\n"
|
||||
+ "!braveball - Start new game\n"
|
||||
+ "!guess - While a game is running, add a guess"
|
||||
+ " (or update an existing one) from 1-1000\n"
|
||||
+ "!resolve <value> - 1-1000 to resolve the game\n"
|
||||
+ "!clear - Clear the session scoreboard\n"
|
||||
+ "!points - Shows a table of the most recent players, and their scores\n"
|
||||
+ "!reset - Removes all players and total points\n"
|
||||
+ "!help - Shows this message"
|
||||
)
|
||||
|
||||
recipient = await self.discord.fetch_user(self.message.author.id)
|
||||
await recipient.send(help_message)
|
27
game/manager.py
Normal file
27
game/manager.py
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=no-member
|
||||
|
||||
"""
|
||||
A Context Manager / State Machine that keeps track of
|
||||
a single game instance (there should only be one) in a
|
||||
Discord channel
|
||||
"""
|
||||
|
||||
from game.new_game import NewGameManager
|
||||
from game.end_game import EndGameManager
|
||||
from game.guess import GuessManager
|
||||
from game.points import PointsManager
|
||||
from game.reset import ResetManager
|
||||
from game.help import HelpManager
|
||||
from game.clear import ClearManager
|
||||
|
||||
|
||||
class GameManager(
|
||||
NewGameManager, EndGameManager, GuessManager, PointsManager, ResetManager, HelpManager, ClearManager
|
||||
):
|
||||
"""
|
||||
Represents what this bot is able to do on a channel (or DMs)
|
||||
"""
|
31
game/new_game.py
Normal file
31
game/new_game.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring,too-few-public-methods
|
||||
|
||||
from database.models import GameModel as Game
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class NewGameManager(BaseGameManager):
|
||||
"""Commands that run at the start of a new game"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("bb", self.start))
|
||||
|
||||
async def start(self):
|
||||
"""
|
||||
Start command - Starts a new game if there isn't already one running
|
||||
"""
|
||||
|
||||
if self.is_running:
|
||||
return await self.message.channel.send("A game is already running")
|
||||
|
||||
self.is_running = True
|
||||
|
||||
# game.pitch_value is unknown at the start of the game
|
||||
self.game = Game.create(server_id=self.message.channel.id)
|
||||
|
||||
await self.message.channel.send("Send me your guesses with !guess <number>")
|
44
game/points.py
Normal file
44
game/points.py
Normal file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=not-an-iterable,missing-module-docstring,too-few-public-methods
|
||||
|
||||
from database.models import PlayerModel as Player
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class PointsManager(BaseGameManager):
|
||||
"""Commands that run when a player wants to view the session leaderboard"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("points", self.points))
|
||||
|
||||
async def points(self):
|
||||
"""
|
||||
Points command - returns a table ordered from highest to lowest
|
||||
of the players and their points
|
||||
"""
|
||||
message = (
|
||||
"\nPlayers, who played recently, with their points highest to lowest\n\n"
|
||||
)
|
||||
message += "Player | Total Points | Last Played\n"
|
||||
|
||||
players = Player.select(
|
||||
Player.player_name, Player.total_points, Player.last_update
|
||||
).order_by(Player.total_points.desc())
|
||||
|
||||
for player in players:
|
||||
message += (
|
||||
" | ".join(
|
||||
[
|
||||
player.player_name,
|
||||
str(player.total_points),
|
||||
str(player.last_update)[:-10],
|
||||
]
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
|
||||
return await self.message.channel.send(message)
|
182
game/process_guess.py
Normal file
182
game/process_guess.py
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=unnecessary-lambda,line-too-long,missing-module-docstring
|
||||
|
||||
import math
|
||||
|
||||
from database.models import (
|
||||
GuessModel as Guess,
|
||||
PlayerModel as Player,
|
||||
)
|
||||
|
||||
|
||||
class ProcessGuess:
|
||||
"""
|
||||
A helper class for the GameManager that handles the
|
||||
logic for all of the players at the end of a game
|
||||
"""
|
||||
|
||||
def __init__(self, game, pitch_value, message):
|
||||
self.game_manager = game
|
||||
self.message = message
|
||||
self.pitch_value = pitch_value
|
||||
|
||||
self.difference = 0
|
||||
self.difference_score = 0
|
||||
self.guesses = [Guess]
|
||||
self.guess = Guess
|
||||
|
||||
def get_guesses(self):
|
||||
"""
|
||||
Get all guesses for this game as a list of combo Guess + Player models,
|
||||
excluding invalid results, from lowest to highest value
|
||||
http://docs.peewee-orm.com/en/latest/peewee/query_examples.html#joins-and-subqueries
|
||||
"""
|
||||
self.guesses = (
|
||||
Guess.select(
|
||||
Guess.guess,
|
||||
Player.player_id,
|
||||
Player.player_name,
|
||||
Player.total_points,
|
||||
Guess.difference
|
||||
)
|
||||
.join(Player)
|
||||
.where(
|
||||
(Guess.game == self.game_manager.game.game_id)
|
||||
& (Guess.guess > 0)
|
||||
& (Guess.player.player_id == Player.player_id)
|
||||
)
|
||||
.order_by(Guess.difference)
|
||||
)
|
||||
return self.guesses
|
||||
|
||||
def update_difference_value(self):
|
||||
"""Store the difference between the player's guessed value and the pitch_value"""
|
||||
Guess.update({"difference": self.difference}).where(
|
||||
(Guess.game == self.game_manager.game.game_id)
|
||||
& (Guess.player == self.guess.player.player_id)
|
||||
& (Guess.guess_id == self.guess.guess_id)
|
||||
).execute()
|
||||
|
||||
def update_player_total_points(self):
|
||||
"""Update player's total score with how many points they won this round"""
|
||||
Player.update(
|
||||
{
|
||||
"total_points": math.floor(
|
||||
self.guess.player.total_points + self.difference_score
|
||||
)
|
||||
}
|
||||
).where(Player.player_id == self.guess.player.player_id).execute()
|
||||
|
||||
def get_difference(self, guess=None):
|
||||
"""Difference calculation, includes "loop over" effect"""
|
||||
self.game_manager.logger.debug("get_difference")
|
||||
|
||||
self.game_manager.logger.debug(guess if guess else "")
|
||||
|
||||
if not guess:
|
||||
guess = self.guess.guess
|
||||
|
||||
self.game_manager.logger.debug(f"guess: {guess}")
|
||||
|
||||
difference = abs(guess - self.pitch_value)
|
||||
|
||||
self.game_manager.logger.debug(f"Difference:{difference}")
|
||||
|
||||
if difference > 500:
|
||||
difference = 1000 - difference
|
||||
|
||||
self.game_manager.logger.debug("Diff loop over 500")
|
||||
self.game_manager.logger.debug(f"{difference}")
|
||||
|
||||
self.difference = difference
|
||||
return self.difference
|
||||
|
||||
def get_difference_score(self):
|
||||
"""
|
||||
Calculate points for the player based on how close
|
||||
they are (within range of 0-500) to the pitch_value
|
||||
"""
|
||||
|
||||
self.game_manager.logger.debug("> get_difference_score")
|
||||
self.game_manager.logger.debug(self.difference)
|
||||
|
||||
if self.difference == 0:
|
||||
self.difference_score = 15
|
||||
self.game_manager.logger.debug("0 Diff")
|
||||
elif self.difference > 0 and self.difference < 21:
|
||||
self.difference_score = 8
|
||||
self.game_manager.logger.debug("0 to 20 diff")
|
||||
elif self.difference > 20 and self.difference < 51:
|
||||
self.difference_score = 5
|
||||
self.game_manager.logger.debug("21 to 50 Diff")
|
||||
elif self.difference > 50 and self.difference < 101:
|
||||
self.difference_score = 3
|
||||
self.game_manager.logger.debug("51 to 100 Diff")
|
||||
elif self.difference > 100 and self.difference < 151:
|
||||
self.difference_score = 2
|
||||
self.game_manager.logger.debug("101 to 150 Diff")
|
||||
elif self.difference > 150 and self.difference < 201:
|
||||
self.difference_score = 1
|
||||
self.game_manager.logger.debug("151 to 200 Diff")
|
||||
elif self.difference > 200 and self.difference < 495:
|
||||
self.difference_score = 0
|
||||
self.game_manager.logger.debug("Diff too big")
|
||||
else:
|
||||
self.difference_score = -5
|
||||
self.game_manager.logger.debug("Big succ")
|
||||
|
||||
return self.difference_score
|
||||
|
||||
def get_winner_loser(self):
|
||||
"""Determine which guesses are closest and furthest from the pitch_value"""
|
||||
|
||||
self.game_manager.logger.debug("> get_winner_loser")
|
||||
|
||||
guess_values = [record.guess for record in self.get_guesses()]
|
||||
self.game_manager.logger.debug(", ".join([str(guess) for guess in guess_values]))
|
||||
|
||||
# Closest to the pitch_value
|
||||
winner = min(guess_values, key=lambda guess: self.get_difference(guess))
|
||||
self.game_manager.logger.debug(f"winner: {winner}")
|
||||
|
||||
# Furthest from the pitch_value
|
||||
loser = max(guess_values, key=lambda guess: self.get_difference(guess))
|
||||
self.game_manager.logger.debug(f"loser: {loser}")
|
||||
|
||||
return winner, loser
|
||||
|
||||
def process_guesses(self):
|
||||
"""
|
||||
Iterates through the guesses for this game, and appends to the message string
|
||||
the results of how well that player performed this round.
|
||||
|
||||
Uses the pitch_value to determine the difference from their guess to the correct score
|
||||
"""
|
||||
winner, loser = self.get_winner_loser()
|
||||
|
||||
for guess in self.get_guesses():
|
||||
self.guess = guess
|
||||
|
||||
self.game_manager.logger.debug(f"Current guess: {guess}")
|
||||
|
||||
|
||||
difference = self.get_difference()
|
||||
difference_score = self.get_difference_score()
|
||||
self.update_difference_value()
|
||||
self.update_player_total_points()
|
||||
|
||||
self.message += f"{guess.player.player_name} | {guess.guess} | {difference} | {difference_score} | {(guess.player.total_points + difference_score)}\n"
|
||||
|
||||
self.game_manager.logger.debug(f"new total: {(guess.player.total_points + difference_score)}")
|
||||
|
||||
if guess.guess == winner:
|
||||
closest_player_id = guess.player.player_id
|
||||
|
||||
if guess.guess == loser:
|
||||
furthest_player_id = guess.player.player_id
|
||||
|
||||
self.game_manager.logger.debug(self.message)
|
||||
return self.message, closest_player_id, furthest_player_id
|
22
game/reset.py
Normal file
22
game/reset.py
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2022 - c0de <c0de@c0de.dev>
|
||||
# Licensed under the MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
# pylint: disable=missing-module-docstring,too-few-public-methods
|
||||
|
||||
from database.models import PlayerModel as Player
|
||||
from game.base import BaseGameManager
|
||||
|
||||
|
||||
class ResetManager(BaseGameManager):
|
||||
"""Commands that run when a player asks for help"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.commands.append(("reset", self.reset))
|
||||
|
||||
async def reset(self):
|
||||
"""Reset command purges all players (removes total points)"""
|
||||
Player.delete().where(True).execute()
|
||||
|
||||
return await self.message.channel.send("ok")
|
4
lint.sh
Executable file
4
lint.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
pylint main.py game discord_client database > lint.log
|
||||
black main.py game discord_client database
|
@@ -6,15 +6,16 @@
|
||||
|
||||
import os
|
||||
|
||||
from discord_client.client import GhostBallClient
|
||||
from discord import Intents
|
||||
from discord_client.client import BaseBallClient
|
||||
from database.models import DATABASE, database, create_models
|
||||
|
||||
if __name__ == "__main__":
|
||||
client = GhostBallClient(intents=None)
|
||||
client.run(os.environ.get("discord_token"))
|
||||
|
||||
# Set up the database if we haven't already
|
||||
if not os.path.exists(DATABASE):
|
||||
database.connect()
|
||||
create_models()
|
||||
database.close()
|
||||
|
||||
client = BaseBallClient(intents=Intents.all())
|
||||
client.run(os.environ.get("discord_token"))
|
89
readme.md
89
readme.md
@@ -1,34 +1,85 @@
|
||||
# Discord Ghost Ball Bot
|
||||
# Discord Baseball Bot
|
||||
|
||||
A bot that will listen on a discord channel, accpeting commands.
|
||||
The main commands are `!start`, `!guess [int]` and `!resolve [int]`.
|
||||
A bot that will listen on a discord channel, accpeting commands.
|
||||
|
||||
The integer will be between 1 and 1000, and the person with the closest guess will win points.
|
||||
|
||||
The point scale is:
|
||||
|
||||
* 0-25 - 100 pts
|
||||
* 26-50 - 75 pts
|
||||
* 51-75 - 50 pts
|
||||
* 76-100 - 25 pts
|
||||
|
||||
There should also be a running total for each player that can be checked with a command.
|
||||
The main commands are `!braveball`, `!guess [int]` and `!resolve [int]`
|
||||
Use the `!help` command for more information
|
||||
|
||||
## Requirements
|
||||
|
||||
You will need a discord bot already set up and supply an auth token.
|
||||
1. You will need a discord bot and an auth token
|
||||
1. You will need access to a server that runs Docker
|
||||
* For development, docker is optional. See Development section of Usage below
|
||||
|
||||
Python requirements can be installed with `pipenv install` (install pipenv with `pip3 install pipenv`)
|
||||
## Points
|
||||
|
||||
Points are determined by the difference, which comes from this formula:
|
||||
|
||||
```python
|
||||
difference = abs(guess - pitch_value)
|
||||
|
||||
if difference > 500:
|
||||
difference = 1000 - difference
|
||||
```
|
||||
|
||||
The point scale is a range based on the difference
|
||||
|
||||
| minimum | maximum | points |
|
||||
|-----------------|-----------------|--------|
|
||||
| (no difference) | (no difference) | 15 |
|
||||
| 1 | 20 | 8 |
|
||||
| 21 | 50 | 5 |
|
||||
| 51 | 100 | 3 |
|
||||
| 101 | 150 | 2 |
|
||||
| 151 | 200 | 1 |
|
||||
| 200 | 494 | 0 |
|
||||
| 495 | 500 | -5 |
|
||||
|
||||
Points are added to a running total for each player at the end of each round.
|
||||
|
||||
## Usage
|
||||
|
||||
All of the new bot code is in the [GhostBallBot](./GhostBallBot/) folder. This documentation is for the new code.
|
||||
If you are using docker:
|
||||
|
||||
The original code is in [src](./src/). Feel free to try to get this working.
|
||||
1. You need to determine which version of the bot to use
|
||||
* If you are using a raspberry pi, you want `archarm64`
|
||||
* Otherwise, you most likely want `archx64`
|
||||
|
||||
### Production with docker
|
||||
|
||||
This docker command is the minimum required to run the bot:
|
||||
|
||||
`docker run -d -e discord_token="<discord token> c0defox/baseballbot:<version>"`
|
||||
|
||||
_Note: The above will not persist the database through restarts_
|
||||
|
||||
If you want to keep the database, use the following command:
|
||||
|
||||
`docker run -d -v database:/database -e database_path="/database/baseball.db" -e discord_token="<discord token>" c0defox/baseballbot:<version>`
|
||||
|
||||
### Development with docker
|
||||
|
||||
1. Modify the source code
|
||||
1. Run `docker build -t baseballbot:<tag> .`
|
||||
1. Run the same docker commands you would in production
|
||||
|
||||
_note: You will probably want to purge your builds after a while, as they will eventually take up space_
|
||||
|
||||
### Development without docker
|
||||
|
||||
Python requirements can be installed with `pipenv install` (install pipenv with `pip3 install pipenv`)
|
||||
|
||||
1. Install the python requirements
|
||||
1. Add discord token to run.sh
|
||||
1. Execute run.sh
|
||||
1. Bot should then connect to discord and start responding to commands defined in game.py
|
||||
1. Modify the source code
|
||||
1. Start run.sh in the terminal (restart as you make code changes)
|
||||
|
||||
If you modify the source code, you should also run `lint.sh`. This will warn you of linting problems that you can choose to fix, as well as format all of the code to the same standard automatically (usually this will resolve linting warnings)
|
||||
|
||||
## Roadmap
|
||||
|
||||
Things that would be nice to add:
|
||||
|
||||
* (yaml) Config file for tweaking various internals
|
||||
* Admin commands: table clear, record deletion, record update
|
||||
* Audit log of admin commands, and previous values for anything changed
|
||||
|
@@ -1,4 +1,3 @@
|
||||
export discord_token=''
|
||||
export database_path='/tmp/ghostball.db'
|
||||
|
||||
python3 main.py
|
@@ -1,51 +0,0 @@
|
||||
# Names of Configurations
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
DATABASE_USERNAME = 'ghost_user'
|
||||
DATABASE_PASSWORD = 'root'
|
||||
DATABASE_HOST = '192.168.0.11'
|
||||
DATABASE_PORT = '5432'
|
||||
DATABASE_NAME = 'ghostball'
|
||||
SEASON_1_SPREADSHEET_ID = 's1_spreadsheet_id'
|
||||
SEASON_2_SPREADSHEET_ID = 's2_spreadsheet_id'
|
||||
PLAYER_SPREADSHEET = 'player_spreadsheet'
|
||||
|
||||
'''
|
||||
Main source for configurations fetched from a startup configuration file. Includes the ability to fetch all, or fetch
|
||||
one configuration once the file is loaded.
|
||||
|
||||
You'll find the names of these configs above as constants that can be used throughout the rest of this repository
|
||||
'''
|
||||
class Configs():
|
||||
configs = {}
|
||||
|
||||
def __init__(self, config_file_path):
|
||||
self.config_file_path = config_file_path
|
||||
self.__load_configs__()
|
||||
|
||||
'''
|
||||
Fetches a single configuration by the name of that configuration.
|
||||
Returns None if that configuration does not exist
|
||||
'''
|
||||
def get_config_by_name(self, name):
|
||||
try:
|
||||
return Configs.configs[name]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
'''
|
||||
Fetches all configurations and returns them as a dictionary of config_key -> config_value
|
||||
'''
|
||||
def get_all_configs(self):
|
||||
return Configs.configs
|
||||
|
||||
'''
|
||||
Performs the initial load of configurations from a startup configuration file
|
||||
'''
|
||||
def __load_configs__(self):
|
||||
Configs.configs = {}
|
||||
config_file = open(self.config_file_path, 'r')
|
||||
for line in config_file:
|
||||
split_line = line.split('=')
|
||||
Configs.configs[split_line[0]] = split_line[1].strip('\n')
|
@@ -1,28 +0,0 @@
|
||||
from sqlalchemy import Column, String, Integer, ForeignKey, Date
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Play(Base):
|
||||
__tablename__ = 'play'
|
||||
|
||||
play_id = Column(String, nullable=False, primary_key=True)
|
||||
pitch_value = Column(Integer, nullable=True)
|
||||
creation_date = Column(Date, nullable=False)
|
||||
server_id = Column(String, nullable=False)
|
||||
|
||||
guesses = relationship(lambda : Guess)
|
||||
|
||||
class Guess(Base):
|
||||
__FAKE_VALUE__ = -5000
|
||||
|
||||
__tablename__ = 'guess'
|
||||
member_id = Column(String, nullable=False, primary_key=True)
|
||||
play_id = Column(UUID, ForeignKey(Play.play_id), nullable=False, primary_key=True)
|
||||
guessed_number = Column(Integer, nullable=False)
|
||||
member_name = Column(String, nullable=False)
|
||||
difference = Column(Integer)
|
||||
|
||||
play = relationship("Play", back_populates="guesses")
|
@@ -1,123 +0,0 @@
|
||||
from copy import deepcopy
|
||||
|
||||
from src.main.database_module.database_classes.db_classes import Guess
|
||||
from src.main.db_session import DatabaseSession
|
||||
|
||||
|
||||
MEMBER_ID = 'member_id'
|
||||
PLAY_ID = 'play_id'
|
||||
GUESSED_NUMBER = 'guessed_number'
|
||||
DIFFERENCE = 'difference'
|
||||
MEMBER_NAME = 'member_name'
|
||||
|
||||
class GuessDAO():
|
||||
db_string = None
|
||||
session = None
|
||||
Session = None
|
||||
engine = None
|
||||
|
||||
_database_session = None
|
||||
|
||||
def __init__(self):
|
||||
self._database_session = DatabaseSession()
|
||||
|
||||
def insert(self, guess_info, allow_update=False):
|
||||
session = self._database_session.get_or_create_session()
|
||||
|
||||
guess = Guess(
|
||||
member_id=guess_info[MEMBER_ID],
|
||||
play_id = guess_info[PLAY_ID],
|
||||
guessed_number = guess_info[GUESSED_NUMBER],
|
||||
member_name = guess_info[MEMBER_NAME]
|
||||
)
|
||||
|
||||
existing_guess = self.__convert_all__(session\
|
||||
.query(Guess)\
|
||||
.filter(Guess.member_id == guess_info[MEMBER_ID], Guess.play_id == guess_info[PLAY_ID]))
|
||||
|
||||
if len(existing_guess) == 0:
|
||||
session.add(guess)
|
||||
session.commit()
|
||||
return True
|
||||
elif allow_update:
|
||||
session\
|
||||
.query(Guess)\
|
||||
.filter(Guess.member_id == guess_info[MEMBER_ID], Guess.play_id == guess_info[PLAY_ID], Guess.member_name == guess_info[MEMBER_NAME])\
|
||||
.update({Guess.guessed_number: guess_info[GUESSED_NUMBER]})
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
'''
|
||||
Converts the database object into a Dictionary, so that the database object is not passed out of the
|
||||
datastore layer.
|
||||
'''
|
||||
def __convert_all__(self, games):
|
||||
converted_games = []
|
||||
for game in games:
|
||||
game_dict = {}
|
||||
for column in game.__dict__:
|
||||
game_dict[column] = str(getattr(game, column))
|
||||
|
||||
converted_games.append(deepcopy(game_dict))
|
||||
|
||||
return converted_games
|
||||
|
||||
def set_differences(self, pitch_value, play_id):
|
||||
session = self._database_session.get_or_create_session()
|
||||
games_to_update = self.__convert_all__(session.query(Guess).filter(Guess.play_id == play_id))
|
||||
|
||||
for game in games_to_update:
|
||||
difference = self.calculate_difference(pitch_value, game[GUESSED_NUMBER])
|
||||
session.query(Guess).filter(Guess.member_id == game[MEMBER_ID], Guess.play_id == game[PLAY_ID]).update({Guess.difference: difference})
|
||||
|
||||
session.commit()
|
||||
|
||||
def calculate_difference(self, pitch_value, guess_value):
|
||||
pitched_number = int(pitch_value)
|
||||
possible_value = abs(int(guess_value) - pitched_number)
|
||||
|
||||
if possible_value > 500:
|
||||
return 1000 - possible_value
|
||||
else:
|
||||
return possible_value
|
||||
|
||||
def fetch_closest(self, num_to_fetch):
|
||||
session = self._database_session.get_or_create_session()
|
||||
|
||||
return self.__convert_all__(
|
||||
session\
|
||||
.query(Guess)\
|
||||
.order_by(Guess.difference)\
|
||||
.limit(num_to_fetch)
|
||||
)
|
||||
|
||||
def refresh(self):
|
||||
self._database_session.__create_new_session__() # I know, I know. It's fine.
|
||||
|
||||
def get_all_guesses_for_plays(self, play_ids):
|
||||
session = self._database_session.get_or_create_session()
|
||||
return self.__convert_all__(
|
||||
session
|
||||
.query(Guess)
|
||||
.filter(Guess.play_id.in_(play_ids))
|
||||
)
|
||||
|
||||
def get_closest_on_play(self, play):
|
||||
session = self._database_session.get_or_create_session()
|
||||
|
||||
# TODO: Make this a MAX query for ties
|
||||
converted_guesses = self.__convert_all__(
|
||||
session
|
||||
.query(Guess)
|
||||
.filter(Guess.play_id == play)
|
||||
.order_by(Guess.difference)
|
||||
.limit(1)
|
||||
)
|
||||
|
||||
if len(converted_guesses) > 1:
|
||||
raise AssertionError("More than one best guess! Can't continue!")
|
||||
elif len(converted_guesses) == 0:
|
||||
return None
|
||||
else:
|
||||
return converted_guesses[0]
|
@@ -1,96 +0,0 @@
|
||||
from copy import deepcopy
|
||||
from sqlalchemy.sql.expression import and_
|
||||
|
||||
from src.main.db_session import DatabaseSession
|
||||
from src.main.database_module.database_classes.db_classes import Play
|
||||
|
||||
import datetime
|
||||
|
||||
PLAY_ID = 'play_id'
|
||||
PITCH_VALUE = 'pitch_value'
|
||||
CREATION_DATE = 'creation_date'
|
||||
SERVER_ID = 'server_id'
|
||||
|
||||
class PlayDAO():
|
||||
db_string = None
|
||||
session = None
|
||||
Session = None
|
||||
engine = None
|
||||
_database_session = None
|
||||
|
||||
def __init__(self):
|
||||
self._database_session = DatabaseSession()
|
||||
|
||||
def insert(self, play_info):
|
||||
session = self._database_session.get_or_create_session()
|
||||
|
||||
play = Play(
|
||||
play_id = play_info[PLAY_ID],
|
||||
pitch_value = play_info[PITCH_VALUE] if PITCH_VALUE in play_info else None,
|
||||
creation_date = play_info[CREATION_DATE],
|
||||
server_id = play_info[SERVER_ID]
|
||||
)
|
||||
|
||||
session.add(play)
|
||||
session.commit()
|
||||
|
||||
def get_play_by_id(self, input_id):
|
||||
session = self._database_session.get_or_create_session()
|
||||
return self.__convert_all__(session.query(Play).filter(Play.play_id == input_id))
|
||||
|
||||
def get_all_plays_after(self, timestamp, input_server_id):
|
||||
session = self._database_session.get_or_create_session()
|
||||
return self.__convert_all__(session.query(Play).filter(and_(Play.server_id == str(input_server_id), Play.creation_date > timestamp)))
|
||||
|
||||
def get_all_plays_on_server(self, input_server_id, earliest_timestamp):
|
||||
session = self._database_session.get_or_create_session()
|
||||
converted_datetime = datetime.datetime.fromtimestamp(earliest_timestamp / 1000.0)
|
||||
|
||||
return self.__convert_all__(session.query(Play).filter(and_(Play.server_id == str(input_server_id), Play.creation_date > converted_datetime)))
|
||||
|
||||
'''
|
||||
Checks to see if there is a play that is currently active or not
|
||||
'''
|
||||
def is_active_play(self, server_id):
|
||||
return self.get_active_play(server_id) != None
|
||||
|
||||
def get_active_play(self, input_server_id):
|
||||
session = self._database_session.get_or_create_session()
|
||||
plays = self.__convert_all__(session.query(Play).filter(and_(Play.pitch_value == None, Play.server_id == str(input_server_id))))
|
||||
|
||||
if len(plays) > 1:
|
||||
raise AssertionError("More than one active play! Can't continue!")
|
||||
elif len(plays) == 0:
|
||||
return None
|
||||
else:
|
||||
return plays[0]
|
||||
|
||||
def resolve_play(self, input_pitch, input_server_id):
|
||||
session = self._database_session.get_or_create_session()
|
||||
active_id = self.get_active_play(input_server_id)
|
||||
|
||||
session\
|
||||
.query(Play)\
|
||||
.filter(and_(Play.pitch_value == None, Play.server_id == str(input_server_id)))\
|
||||
.update({Play.pitch_value: input_pitch})
|
||||
session.commit()
|
||||
|
||||
return active_id
|
||||
|
||||
def refresh(self):
|
||||
self._database_session.__create_new_session__() # I know, I know. It's fine.
|
||||
|
||||
'''
|
||||
Converts the database object into a Dictionary, so that the database object is not passed out of the
|
||||
datastore layer.
|
||||
'''
|
||||
def __convert_all__(self, plays):
|
||||
converted_plays = []
|
||||
for play in plays:
|
||||
play_dict = {}
|
||||
for column in play.__dict__:
|
||||
play_dict[column] = str(getattr(play, column))
|
||||
|
||||
converted_plays.append(deepcopy(play_dict))
|
||||
|
||||
return converted_plays
|
@@ -1,49 +0,0 @@
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
import sys
|
||||
import sqlite3
|
||||
sys.path.append('../../../../../../src')
|
||||
|
||||
from src.main.configs import Configs, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_HOST, DATABASE_NAME
|
||||
|
||||
'''
|
||||
Stores a database session for use throughout the application. Must be initialized at startup before any database calls
|
||||
are made and AFTER the Configurations are setup.
|
||||
|
||||
This shouldn't need to be touched after startup. To use, see the sqlalchemy docs...or just start by calling Session()
|
||||
and then use it to handle the necessary CRUD operations.
|
||||
|
||||
You should NOT instantiate this in any method except the main application runner
|
||||
'''
|
||||
class DatabaseSession():
|
||||
_session = None
|
||||
|
||||
def __init__(self):
|
||||
self.__create_new_session__()
|
||||
|
||||
def __create_new_session__(self):
|
||||
if self._session is not None:
|
||||
self._session.close()
|
||||
|
||||
config_map = Configs.configs
|
||||
db_string = self._pgsql_conn_string_(config_map)
|
||||
Session = sessionmaker(create_engine(db_string))
|
||||
self._session = Session()
|
||||
|
||||
return self._session
|
||||
|
||||
def get_or_create_session(self):
|
||||
try:
|
||||
self._session.connection()
|
||||
return self._session
|
||||
except: # The linter can scream all it wants, this makes sense. If it's this broke, we want a new one anyway.
|
||||
return self.__create_new_session__()
|
||||
|
||||
# Look, this kinda sucks. But it's for fun and friends and I'm doing it quick and dirty.
|
||||
def _pgsql_conn_string_(self, config_map):
|
||||
return 'postgresql://%s:%s@%s/%s' % \
|
||||
(config_map[DATABASE_USERNAME], config_map[DATABASE_PASSWORD], config_map[DATABASE_HOST], config_map[DATABASE_NAME])
|
||||
|
||||
def _sqlite_conn_string(self, config_map):
|
||||
return "sqlite:///ghostball.db"
|
@@ -1,220 +0,0 @@
|
||||
import sys
|
||||
|
||||
import discord
|
||||
from discord.utils import get
|
||||
|
||||
import uuid
|
||||
import datetime
|
||||
import dateparser
|
||||
|
||||
from src.main.configs import Configs
|
||||
from src.main.database_module.guess_dao import GuessDAO, GUESSED_NUMBER, MEMBER_ID, MEMBER_NAME, DIFFERENCE
|
||||
from src.main.services.points_service import PointsService
|
||||
from src.main.database_module.play_dao import PlayDAO, PLAY_ID, CREATION_DATE, SERVER_ID
|
||||
from src.main.db_session import DatabaseSession
|
||||
from src.main.discord_module.leaderboard_config import LeaderboardConfig
|
||||
|
||||
play_dao = None
|
||||
guess_dao = None
|
||||
points_service = PointsService()
|
||||
bot = discord.Client()
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print('Logged in as')
|
||||
print(bot.user.name)
|
||||
print(bot.user.id)
|
||||
print('------')
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
if message.author == bot.user:
|
||||
return
|
||||
|
||||
content = message.content
|
||||
server_id = message.guild.id
|
||||
|
||||
'''
|
||||
Sets up the next set of guesses.
|
||||
'''
|
||||
if content.startswith('!ghostball'):
|
||||
if play_dao.is_active_play(server_id):
|
||||
await message.channel.send("There's already an active play. Could you close that one first, please?")
|
||||
else:
|
||||
generated_play_id = uuid.uuid4()
|
||||
play_object = {PLAY_ID: generated_play_id, CREATION_DATE: datetime.datetime.now(), SERVER_ID: server_id}
|
||||
play_dao.insert(play_object)
|
||||
|
||||
await message.channel.send("@flappy ball, pitch is in! Send me your guesses with a !guess command.")
|
||||
|
||||
if content.startswith("!guess"):
|
||||
guess_value = None
|
||||
try:
|
||||
guess_value = __parse_guess__(content)
|
||||
except ValueError:
|
||||
await message.channel.send("That number is not between 1 and 1000. We're still in MLN so don't try to cheat.")
|
||||
return
|
||||
|
||||
if guess_value is None:
|
||||
await message.channel.send("I don't know what you did but I'm pretty sure you're tyring to break the bot so please stop.")
|
||||
return
|
||||
|
||||
if not play_dao.is_active_play(server_id):
|
||||
await message.channel.send("Hey, there's no active play! Start one up first with !ghostball.")
|
||||
else:
|
||||
play = play_dao.get_active_play(server_id)
|
||||
guess_object = {PLAY_ID: play['play_id'],
|
||||
MEMBER_ID: str(message.author.id),
|
||||
GUESSED_NUMBER: guess_value,
|
||||
MEMBER_NAME: str(message.author.name)}
|
||||
|
||||
if guess_dao.insert(guess_object, allow_update=True):
|
||||
await message.add_reaction(emoji="\N{THUMBS UP SIGN}")
|
||||
|
||||
# Closes off the active play to be ready for the next set
|
||||
if content.startswith('!resolve'):
|
||||
# try:
|
||||
pitch_number, batter_id, batter_guess, has_batter = __parse_resolve_play__(content)
|
||||
if args is None:
|
||||
await message.channel.send("Hey " + "<@" + str(message.author.id) + ">, I'm not sure what you meant. "
|
||||
"You need real, numeric, values for this command to work. "
|
||||
"Use !resolve <pitch number> <optional batter> <optional swing number>"
|
||||
" and try again.")
|
||||
|
||||
# Check if we have an active play
|
||||
if not play_dao.is_active_play(server_id):
|
||||
await message.channel.send("You confused me. There's no active play so I have nothing to close!")
|
||||
else:
|
||||
if has_batter:
|
||||
referenced_member_id = batter_id[3:-1]
|
||||
play = play_dao.get_active_play(server_id)
|
||||
guess_object = {PLAY_ID: play['play_id'],
|
||||
MEMBER_ID: str(referenced_member_id),
|
||||
GUESSED_NUMBER: batter_guess,
|
||||
MEMBER_NAME: bot.get_user(int(referenced_member_id)).name}
|
||||
|
||||
guess_dao.insert(guess_object, True)
|
||||
|
||||
play = play_dao.resolve_play(pitch_number, server_id)
|
||||
guess_dao.set_differences(pitch_number, play['play_id'])
|
||||
guesses = points_service.fetch_sorted_guesses_by_play(guess_dao, play['play_id'])
|
||||
|
||||
response_message = "Closed this play! Here are the results:\n"
|
||||
response_message += "PLAYER --- DIFFERENCE --- POINTS GAINED\n"
|
||||
for guess in guesses:
|
||||
response_message += guess[1] + " --- " + str(guess[2]) + " --- " + str(guess[3]) + "\n"
|
||||
|
||||
if len(guesses) < 2:
|
||||
response_message += "Not enough people participated to give best and worst awards. Stop being lazy."
|
||||
|
||||
else:
|
||||
response_message += "\nCongrats to <@" + str(guesses[0][0]) + "> for being the closest! \n"
|
||||
response_message += "And tell <@" + str(guesses[-1][0]) + "> they suck."
|
||||
|
||||
await message.channel.send(response_message)
|
||||
|
||||
if content.startswith("!points"):
|
||||
try:
|
||||
timestamp = __parse_points_message__(content)
|
||||
except:
|
||||
await message.channel.send("You gave me a timestamp that was so bad, the best date handling library in the"
|
||||
" world of software couldn't figure out what you meant. That's...impressive. Now"
|
||||
" fix your shit and try again.")
|
||||
return
|
||||
|
||||
points_by_user = points_service.fetch_points(timestamp, server_id, play_dao, guess_dao)
|
||||
response = "Here are the top guessers by points as per your request..."
|
||||
for user in points_by_user:
|
||||
if str(user[2]) != '0':
|
||||
response += "\n" + str(user[1]) + " : " + str(user[2])
|
||||
|
||||
await message.channel.send(response)
|
||||
|
||||
# Refresh Postgres connection
|
||||
if content.startswith('!restart'):
|
||||
play_dao.refresh()
|
||||
guess_dao.refresh()
|
||||
|
||||
if content.startswith('!help'):
|
||||
help_message = __get_help_message__()
|
||||
recipient = await bot.fetch_user(message.author.id)
|
||||
await recipient.send(help_message)
|
||||
|
||||
|
||||
def __get_help_message__():
|
||||
# Start message with person who asked for help
|
||||
help_message = "Hey! I can be instructed to do any number of things! Use the following commands: \n" \
|
||||
"!guess <NUMBER> --- This will add your guess to the currently active play. " \
|
||||
"I will give you a thumbs up if everything worked!\n" \
|
||||
"!ghostball --- Starts a new play. I'll let you know if this didn't work for some reason!\n" \
|
||||
"!help --- You just asked for this. If you ask for it again, I'll repeat myself.\n" \
|
||||
"!resolve <PITCH_NUMBER> <OPTIONAL --- BATTER by @-mention> <OPTIONAL - ACTUAL SWING NUMBER> --- " \
|
||||
"Uses the pitch number and real swing number to figure out who was closest and ends the active play." \
|
||||
"If you include the batter and their swing number, they will get credit for how well they did!\n" \
|
||||
"!points <OPTIONAL --- TIMESTAMP> Fetches all plays since your requested time, or the beginning of the unvierse " \
|
||||
"if none given. Will currently always dump all players - top X coming soon...\n" \
|
||||
"!restart --- If the bot looks broken, this will take a shot at fixing it. It won't answer your commands " \
|
||||
"for about 3 seconds after you do this! BE CAREFUL! ONLY USE IN AN EMERGENCY!\n" \
|
||||
"<PING KALI IF YOU'RE CONFUSED, ANGRY, OR WANT TO GEEK OUT ABOUT BRAVELY DEFAULT!>\n"
|
||||
|
||||
return help_message
|
||||
|
||||
|
||||
def __parse_leaderboard_message__(message_content):
|
||||
return LeaderboardConfig(message_content)
|
||||
|
||||
|
||||
def __parse_points_message__(message_content):
|
||||
pieces = message_content.split(' ')
|
||||
|
||||
if len(pieces) > 1:
|
||||
try:
|
||||
timestamp = dateparser.parse(pieces[1])
|
||||
except:
|
||||
raise RuntimeError("Unable to parse timestamp!")
|
||||
else:
|
||||
timestamp = dateparser.parse("1970-01-01")
|
||||
|
||||
return timestamp
|
||||
|
||||
|
||||
def __parse_guess__(message_content):
|
||||
pieces = message_content.split(' ')
|
||||
try:
|
||||
guess_value = pieces[1]
|
||||
guess_as_int = int(guess_value)
|
||||
if guess_as_int > 1000 or guess_as_int < 1:
|
||||
raise ValueError("Number not between 1 and 1000 inclusive")
|
||||
else:
|
||||
return guess_value
|
||||
except TypeError:
|
||||
return None
|
||||
|
||||
|
||||
def __parse_resolve_play__(message_content):
|
||||
pieces = message_content.split()
|
||||
try:
|
||||
if len(pieces) == 2:
|
||||
return pieces[1], None, None, False
|
||||
elif len(pieces) == 4:
|
||||
return pieces[1], pieces[2], pieces[3], True
|
||||
else:
|
||||
print("Illegal resolution command")
|
||||
return None, None
|
||||
except TypeError:
|
||||
return None, None
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv
|
||||
token = args[1]
|
||||
file_path = args[2]
|
||||
|
||||
configs = Configs(file_path)
|
||||
databaseSession = DatabaseSession()
|
||||
|
||||
play_dao = PlayDAO()
|
||||
guess_dao = GuessDAO()
|
||||
bot.run(token)
|
@@ -1,15 +0,0 @@
|
||||
class LeaderboardConfig():
|
||||
closest = True
|
||||
def __init__(self, message_content):
|
||||
pieces = message_content.split(' ')
|
||||
if len(pieces) == 1:
|
||||
return
|
||||
|
||||
if pieces[1] == 'average':
|
||||
self.closest = False
|
||||
|
||||
def should_sort_by_pure_closest(self):
|
||||
return self.closest
|
||||
|
||||
def should_sort_by_best_average(self):
|
||||
return not self.closest
|
@@ -1,48 +0,0 @@
|
||||
|
||||
|
||||
class PointsService():
|
||||
_point_table = [(5,25),(25, 75), (75, 50), (150, 25)]
|
||||
|
||||
def fetch_points(self, timestamp, server_id, play_dao, guess_dao):
|
||||
plays = play_dao.get_all_plays_after(timestamp, server_id)
|
||||
all_guesses = guess_dao.get_all_guesses_for_plays(x['play_id'] for x in plays)
|
||||
|
||||
# Build a dictionary of each member and their total points
|
||||
totals_by_player = {}
|
||||
for guess in all_guesses:
|
||||
if guess['member_id'] in totals_by_player:
|
||||
totals_by_player[guess['member_id']]['points'] += self.__get_points_for_diff__(guess['difference'])
|
||||
else:
|
||||
totals_by_player[guess['member_id']] = {}
|
||||
totals_by_player[guess['member_id']]['points'] = self.__get_points_for_diff__(guess['difference'])
|
||||
totals_by_player[guess['member_id']]['member_name'] = guess['member_name']
|
||||
|
||||
# And now pull those numbers out into a list and sort them
|
||||
sorted_players = []
|
||||
for player in totals_by_player:
|
||||
sorted_players.append([player,
|
||||
totals_by_player[player]['member_name'],
|
||||
totals_by_player[player]['points']])
|
||||
|
||||
sorted_players.sort(key=lambda x: x[2], reverse=True)
|
||||
return sorted_players
|
||||
|
||||
def fetch_sorted_guesses_by_play(self, guess_dao, play_id):
|
||||
all_guesses = guess_dao.get_all_guesses_for_plays([play_id])
|
||||
player_list = []
|
||||
for guess in all_guesses:
|
||||
player_list.append([guess['member_id'], guess['member_name'], int(guess['difference']), self.__get_points_for_diff__(guess['difference'])])
|
||||
|
||||
player_list.sort(key=lambda x: x[2])
|
||||
return player_list
|
||||
|
||||
# Iterates through the point table, which we assume is sorted, and gets the points
|
||||
def __get_points_for_diff__(self, diff):
|
||||
if diff == 'None':
|
||||
return 0
|
||||
|
||||
for i in range(0, len(self._point_table)):
|
||||
if int(diff) < self._point_table[i][0]:
|
||||
return self._point_table[i][1]
|
||||
|
||||
return 0
|
Reference in New Issue
Block a user