Compare commits

...

7 Commits

@ -4,12 +4,9 @@ url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
python-lsp-server = "*"
rope = "*"
pyflakes = "*"
pycodestyle = "*"
jedi-language-server = "*"
flake8 = "*"
mypy = "*"
pylsp-mypy = "*"
[packages]
irc = "*"
@ -22,3 +19,4 @@ translate = "*"
scaruffi = "==0.0.3"
wolframalpha = "*"
meteofrance-api = "~=1.0.2"
openai = "~=0.25.0"

335
Pipfile.lock generated

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "eace7846cb6748062257f5ae8a5937802e0538a2f1c81e9bba4bbafb088b3ad8"
"sha256": "74c2948feced60416cae440f5c2443aaf845aed3a8ef85c741f5c7799bba0088"
},
"pipfile-spec": 6,
"requires": {},
@ -57,6 +57,13 @@
],
"version": "==8.1.3"
},
"et-xmlfile": {
"hashes": [
"sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c",
"sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"
],
"version": "==1.1.0"
},
"google-api-core": {
"hashes": [
"sha256:10c06f7739fe57781f87523375e8e1a3a4674bf6392cd6131a3222182b971320",
@ -275,6 +282,93 @@
],
"version": "==9.0.0"
},
"numpy": {
"hashes": [
"sha256:01dd17cbb340bf0fc23981e52e1d18a9d4050792e8fb8363cecbf066a84b827d",
"sha256:06005a2ef6014e9956c09ba07654f9837d9e26696a0470e42beedadb78c11b07",
"sha256:09b7847f7e83ca37c6e627682f145856de331049013853f344f37b0c9690e3df",
"sha256:0aaee12d8883552fadfc41e96b4c82ee7d794949e2a7c3b3a7201e968c7ecab9",
"sha256:0cbe9848fad08baf71de1a39e12d1b6310f1d5b2d0ea4de051058e6e1076852d",
"sha256:1b1766d6f397c18153d40015ddfc79ddb715cabadc04d2d228d4e5a8bc4ded1a",
"sha256:33161613d2269025873025b33e879825ec7b1d831317e68f4f2f0f84ed14c719",
"sha256:5039f55555e1eab31124a5768898c9e22c25a65c1e0037f4d7c495a45778c9f2",
"sha256:522e26bbf6377e4d76403826ed689c295b0b238f46c28a7251ab94716da0b280",
"sha256:56e454c7833e94ec9769fa0f86e6ff8e42ee38ce0ce1fa4cbb747ea7e06d56aa",
"sha256:58f545efd1108e647604a1b5aa809591ccd2540f468a880bedb97247e72db387",
"sha256:5e05b1c973a9f858c74367553e236f287e749465f773328c8ef31abe18f691e1",
"sha256:7903ba8ab592b82014713c491f6c5d3a1cde5b4a3bf116404e08f5b52f6daf43",
"sha256:8969bfd28e85c81f3f94eb4a66bc2cf1dbdc5c18efc320af34bffc54d6b1e38f",
"sha256:92c8c1e89a1f5028a4c6d9e3ccbe311b6ba53694811269b992c0b224269e2398",
"sha256:9c88793f78fca17da0145455f0d7826bcb9f37da4764af27ac945488116efe63",
"sha256:a7ac231a08bb37f852849bbb387a20a57574a97cfc7b6cabb488a4fc8be176de",
"sha256:abdde9f795cf292fb9651ed48185503a2ff29be87770c3b8e2a14b0cd7aa16f8",
"sha256:af1da88f6bc3d2338ebbf0e22fe487821ea4d8e89053e25fa59d1d79786e7481",
"sha256:b2a9ab7c279c91974f756c84c365a669a887efa287365a8e2c418f8b3ba73fb0",
"sha256:bf837dc63ba5c06dc8797c398db1e223a466c7ece27a1f7b5232ba3466aafe3d",
"sha256:ca51fcfcc5f9354c45f400059e88bc09215fb71a48d3768fb80e357f3b457e1e",
"sha256:ce571367b6dfe60af04e04a1834ca2dc5f46004ac1cc756fb95319f64c095a96",
"sha256:d208a0f8729f3fb790ed18a003f3a57895b989b40ea4dce4717e9cf4af62c6bb",
"sha256:dbee87b469018961d1ad79b1a5d50c0ae850000b639bcb1b694e9981083243b6",
"sha256:e9f4c4e51567b616be64e05d517c79a8a22f3606499941d97bb76f2ca59f982d",
"sha256:f063b69b090c9d918f9df0a12116029e274daf0181df392839661c4c7ec9018a",
"sha256:f9a909a8bae284d46bbfdefbdd4a262ba19d3bc9921b1e76126b1d21c3c34135"
],
"markers": "python_version < '3.10'",
"version": "==1.23.5"
},
"openai": {
"hashes": [
"sha256:59ac6531e4f7bf8e9a53186e853d9ffb1d5f07973ecb4f7d273163a314814510"
],
"index": "pypi",
"version": "==0.25.0"
},
"openpyxl": {
"hashes": [
"sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355",
"sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"
],
"version": "==3.0.10"
},
"pandas": {
"hashes": [
"sha256:0183cb04a057cc38fde5244909fca9826d5d57c4a5b7390c0cc3fa7acd9fa883",
"sha256:1fc87eac0541a7d24648a001d553406f4256e744d92df1df8ebe41829a915028",
"sha256:220b98d15cee0b2cd839a6358bd1f273d0356bf964c1a1aeb32d47db0215488b",
"sha256:2552bffc808641c6eb471e55aa6899fa002ac94e4eebfa9ec058649122db5824",
"sha256:315e19a3e5c2ab47a67467fc0362cb36c7c60a93b6457f675d7d9615edad2ebe",
"sha256:344021ed3e639e017b452aa8f5f6bf38a8806f5852e217a7594417fb9bbfa00e",
"sha256:375262829c8c700c3e7cbb336810b94367b9c4889818bbd910d0ecb4e45dc261",
"sha256:457d8c3d42314ff47cc2d6c54f8fc0d23954b47977b2caed09cd9635cb75388b",
"sha256:4aed257c7484d01c9a194d9a94758b37d3d751849c05a0050c087a358c41ad1f",
"sha256:530948945e7b6c95e6fa7aa4be2be25764af53fba93fe76d912e35d1c9ee46f5",
"sha256:5ae7e989f12628f41e804847a8cc2943d362440132919a69429d4dea1f164da0",
"sha256:71f510b0efe1629bf2f7c0eadb1ff0b9cf611e87b73cd017e6b7d6adb40e2b3a",
"sha256:73f219fdc1777cf3c45fde7f0708732ec6950dfc598afc50588d0d285fddaefc",
"sha256:8092a368d3eb7116e270525329a3e5c15ae796ccdf7ccb17839a73b4f5084a39",
"sha256:82ae615826da838a8e5d4d630eb70c993ab8636f0eff13cb28aafc4291b632b5",
"sha256:9608000a5a45f663be6af5c70c3cbe634fa19243e720eb380c0d378666bc7702",
"sha256:a40dd1e9f22e01e66ed534d6a965eb99546b41d4d52dbdb66565608fde48203f",
"sha256:b4f5a82afa4f1ff482ab8ded2ae8a453a2cdfde2001567b3ca24a4c5c5ca0db3",
"sha256:c009a92e81ce836212ce7aa98b219db7961a8b95999b97af566b8dc8c33e9519",
"sha256:c218796d59d5abd8780170c937b812c9637e84c32f8271bbf9845970f8c1351f",
"sha256:cc3cd122bea268998b79adebbb8343b735a5511ec14efb70a39e7acbc11ccbdc",
"sha256:d0d8fd58df5d17ddb8c72a5075d87cd80d71b542571b5f78178fb067fa4e9c72",
"sha256:e18bc3764cbb5e118be139b3b611bc3fbc5d3be42a7e827d1096f46087b395eb",
"sha256:e2b83abd292194f350bb04e188f9379d36b8dfac24dd445d5c87575f3beaf789",
"sha256:e7469271497960b6a781eaa930cba8af400dd59b62ec9ca2f4d31a19f2f91090",
"sha256:e9dbacd22555c2d47f262ef96bb4e30880e5956169741400af8b306bbb24a273",
"sha256:f6257b314fc14958f8122779e5a1557517b0f8e500cfb2bd53fa1f75a8ad0af2"
],
"version": "==1.5.2"
},
"pandas-stubs": {
"hashes": [
"sha256:5a2c47a0cf8e12e113d760d5da9c48daa2b977b14a4c368b8bbff27dbfcfd2bb",
"sha256:d6bab9f373ff3c309bf560065d230a38ce4dcd22368be393fad6eb353d102b7c"
],
"version": "==1.5.2.221124"
},
"protobuf": {
"hashes": [
"sha256:2c9c2ed7466ad565f18668aa4731c535511c5d9a40c6da39524bccf43e441719",
@ -379,6 +473,13 @@
"markers": "python_version > '3.0'",
"version": "==3.0.9"
},
"python-dateutil": {
"hashes": [
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
],
"version": "==2.8.2"
},
"pytz": {
"hashes": [
"sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c",
@ -430,6 +531,13 @@
],
"version": "==5.1.0"
},
"tqdm": {
"hashes": [
"sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4",
"sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"
],
"version": "==4.64.1"
},
"translate": {
"hashes": [
"sha256:7e70ffa46f193cc744be7c88b8e1323f10f6b2bb90d24bb5d29fdf1e56618783",
@ -438,6 +546,13 @@
"index": "pypi",
"version": "==3.6.1"
},
"types-pytz": {
"hashes": [
"sha256:bea605ce5d5a5d52a8e1afd7656c9b42476e18a0f888de6be91587355313ddf4",
"sha256:d078196374d1277e9f9984d49373ea043cf2c64d5d5c491fbc86c258557bd46f"
],
"version": "==2022.6.0.1"
},
"typing-extensions": {
"hashes": [
"sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa",
@ -490,13 +605,6 @@
}
},
"develop": {
"appdirs": {
"hashes": [
"sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
"sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
],
"version": "==1.4.4"
},
"docstring-to-markdown": {
"hashes": [
"sha256:12f75b0c7b7572defea2d9e24b57ef7ac38c3e26e91c0e5547cfc02b1c168bf6",
@ -504,6 +612,14 @@
],
"version": "==0.10"
},
"flake8": {
"hashes": [
"sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7",
"sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"
],
"index": "pypi",
"version": "==6.0.0"
},
"jedi": {
"hashes": [
"sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e",
@ -511,6 +627,21 @@
],
"version": "==0.18.2"
},
"jedi-language-server": {
"hashes": [
"sha256:8ae12605f934cf9c3fc60d02ec6d8ee5ef66441ea4f117d87e3f634bf0e6e48e",
"sha256:bfa5a7a1769d015b45747c00c669f48ebcd13d3d362ccd9663e9a6e3db80b2c9"
],
"index": "pypi",
"version": "==0.39.0"
},
"mccabe": {
"hashes": [
"sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325",
"sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"
],
"version": "==0.7.0"
},
"mypy": {
"hashes": [
"sha256:0714258640194d75677e86c786e80ccf294972cc76885d3ebbb560f11db0003d",
@ -554,13 +685,6 @@
],
"version": "==0.4.3"
},
"packaging": {
"hashes": [
"sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb",
"sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"
],
"version": "==21.3"
},
"parso": {
"hashes": [
"sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0",
@ -568,81 +692,67 @@
],
"version": "==0.8.3"
},
"pluggy": {
"hashes": [
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159",
"sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"
],
"version": "==1.0.0"
},
"pycodestyle": {
"hashes": [
"sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053",
"sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"
],
"index": "pypi",
"version": "==2.10.0"
},
"pydantic": {
"hashes": [
"sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42",
"sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624",
"sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e",
"sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559",
"sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709",
"sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9",
"sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d",
"sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52",
"sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda",
"sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912",
"sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c",
"sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525",
"sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe",
"sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41",
"sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b",
"sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283",
"sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965",
"sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c",
"sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410",
"sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5",
"sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116",
"sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98",
"sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f",
"sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644",
"sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13",
"sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd",
"sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254",
"sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6",
"sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488",
"sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5",
"sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c",
"sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1",
"sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a",
"sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2",
"sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d",
"sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"
],
"version": "==1.10.2"
},
"pyflakes": {
"hashes": [
"sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf",
"sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"
],
"index": "pypi",
"version": "==3.0.1"
},
"pylsp-mypy": {
"hashes": [
"sha256:06a6fd68c3e829d2c9f633bd96c15b6671a7e411139110ae9747d9245b31c8bd",
"sha256:3d623ca05f13cf80c8b9fe61f6ac064855bcbef2d1c9b5cf1c9d40ba6158002e"
],
"index": "pypi",
"version": "==0.6.3"
},
"pyparsing": {
"hashes": [
"sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb",
"sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"
],
"markers": "python_version > '3.0'",
"version": "==3.0.9"
},
"python-lsp-jsonrpc": {
"pygls": {
"hashes": [
"sha256:079b143be64b0a378bdb21dff5e28a8c1393fe7e8a654ef068322d754e545fc7",
"sha256:7bec170733db628d3506ea3a5288ff76aa33c70215ed223abdb0d95e957660bd"
"sha256:1b96378452217a02f19d89d9e647a4256d8d445ab3c641a589b4f73bf11898b6",
"sha256:63b859411307ed6f99fb9dd0e71be507a17ae9b3de5c5d07c497f5bddadcc46a"
],
"version": "==1.0.0"
},
"python-lsp-server": {
"hashes": [
"sha256:7ea502b1d392888efb841cbfdabb33e6ec96e44ab4cb81dd38aacefe657b1abf",
"sha256:d75cdff9027c4212e5b9e861e9a0219219c8e2c69508d9f24949951dabd0dc1b"
],
"index": "pypi",
"version": "==1.6.0"
},
"pytoolconfig": {
"hashes": [
"sha256:2512a1f261a40e73cef2e58e786184261b60c802ae7ed01249342b1949ec3aa2",
"sha256:825d97b052e58b609c2684b04efeb543075588d33a4916a6dc2ae39676458c7d"
],
"version": "==1.2.2"
},
"rope": {
"hashes": [
"sha256:9761758c222df9466f08232bc046d182960ffa881c1c53bca9fafff210e8da7c",
"sha256:d0514b3cddb1a9e103a040756fb53674828d73df70282b7d7d783a220b0354d8"
],
"index": "pypi",
"version": "==1.5.1"
},
"toml": {
"hashes": [
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
],
"version": "==0.10.2"
"version": "==0.12.4"
},
"tomli": {
"hashes": [
@ -652,82 +762,19 @@
"markers": "python_version < '3.11'",
"version": "==2.0.1"
},
"typeguard": {
"hashes": [
"sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4",
"sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1"
],
"version": "==2.13.3"
},
"typing-extensions": {
"hashes": [
"sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa",
"sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"
],
"version": "==4.4.0"
},
"ujson": {
"hashes": [
"sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb",
"sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7",
"sha256:1a485117f97312bef45f5d79d2ff97eff4da503b8a04f3691f59d31141686459",
"sha256:1cef44ea4973344baed3d50a5da4a8843de3a6af7dea7fadf0a594e53ce5892f",
"sha256:1dc2f46c31ef22b0aaa28cd71be897bea271e700636658d573df9c43c49ebbd0",
"sha256:21678d7e068707e4d54bdfeb8c250ebc548b51e499aed778b22112ca31a79669",
"sha256:278aa9d7cb56435c96d19f5d702e026bcf69f824e24b41e9b52706abd3565837",
"sha256:2ab011e3556a9a1d9461bd686870c527327765ed02fe53550531d6609a8a33ff",
"sha256:2d90414e3b4b44b39825049185959488e084ea7fcaf6124afd5c00893938b09d",
"sha256:2e506ecf89b6b9d304362ccef770831ec242a52c89dab1b4aabf1ab0eb1d5ed6",
"sha256:33cd9084fefc74cbacf88c92fd260b61211e00bcde38d640c369e5dc34a2b4e1",
"sha256:3b74467564814fbce322427a5664e6bcc7dae6dbc8acbef76300fe43ca4072ab",
"sha256:3f3f4240d99d55eb97cb012e9adf401f5ed9cd827af0341ac44603832202b0d2",
"sha256:3fe1aea596f9539fc20cd9e52f098c842afc090168824fd4ca9744fe13151a03",
"sha256:4a8cb3c8637006c5bd8237ebb5992a76ba06e39988ad5cff2096227443e8fd6a",
"sha256:4ef4ab8352861b99bd7fedb1fc6df3ea7f7d5216c789ba6d859e4ea06f1a4c45",
"sha256:5035bb997d163f346c22abcec75190e7e756a5349e7c708bd3d5fd7066a9a854",
"sha256:593a0f6fb0e186c5ba65465ed6f6215a30d1efa898c25e74de1c8577a1bff6d0",
"sha256:59cdcd934385f36e8bd76aedc234371cc75c848d95bdce804ac8aa8744cfeffa",
"sha256:5a9b1320d8363a42d857fae8065a2174d38217cdd58cd8dc4f48d54e0591271e",
"sha256:5f9681ec4c60d0da590552427d770636d9079038c30b265f507ccde23caa7823",
"sha256:5fd797a4837ba10671954e7c09010cec7aca67e09d193f4920a16beea5f66f65",
"sha256:6019e3480d933d3698f2ecb4b46d64bfadd64e718f04fac36e681f3254b49a93",
"sha256:603607f56a0ee84d9cd2c7e9b1d29b18a70684b94ee34f07b9ffe8dc9c8a9f81",
"sha256:60a4b481978ea2aad8fe8af1ecc271624d01b3cf4b09e9b643dd2fe19c07634c",
"sha256:6b9812638d7aa8ecda2e8e1513fb4da999249603bffab7439a5f8f0bb362b0db",
"sha256:6c7ae6e0778ab9610f5e80e0595957d101ab8de18c32a8c053a19943ef4831d0",
"sha256:6f83be8257b2f2dd6dea5ee62cd28db90584da7a7af1fba77a2102fc7943638a",
"sha256:701e81e047f5c0cffd4ac828efca68b0bd270c616654966a051e9a5f836b385e",
"sha256:703fd69d9cb21d6ec2086789df9be2cf8140a76ff127050c24007ea8940dcd3b",
"sha256:7471d4486f23518cff343f1eec6c68d1b977ed74c3e6cc3e1ac896b9b7d68645",
"sha256:765d46f3d5e7a1d48075035e2d1a9164f683e3fccde834ca04602e6c588835bc",
"sha256:7a09d203983104918c62f2eef9406f24c355511f9217967df23e70fa7f5b54ff",
"sha256:7c20cc83b0df47129ec6ed8a47fa7dcfc309c5bad029464004162738502568bb",
"sha256:7d7cfac2547c93389fa303fc0c0eb6698825564e8389c41c9b60009c746207b6",
"sha256:7d87c817b292efb748f1974f37e8bb8a8772ef92f05f84e507159360814bcc3f",
"sha256:8141f654432cf75144d6103bfac2286b8adf23467201590b173a74535d6be22d",
"sha256:849f2ff40264152f25589cb48ddb4a43d14db811f841ec73989bfc0c8c4853fa",
"sha256:880c84ce59f49776cf120f77e7ca04877c97c6887917078dbc369eb47004d7cf",
"sha256:94874584b733a18b310b0e954d53168e62cd4a0fd9db85b1903f0902a7eb33e8",
"sha256:95603eff711b8f3b9596e1c961dbeb745a792ba1904141612f194e07edd71e5f",
"sha256:9585892091ae86045135d6a6129a644142d6a51b23e1428bb5de6d10bc0ce0c7",
"sha256:977bf5be704a88d46bf5b228df8b44521b1f3119d741062191608b3a6a38f224",
"sha256:9cdc46859024501c20ab74ad542cdf2f08b94b5ce384f2f569483fa3ed926d04",
"sha256:a34a5f034b339f69ef7f6a134c22d04b92e07b6ddc1dd65382e7e4ec65d6437d",
"sha256:a655f7b755cfc5c07f2116b6dcf0ba148c89adef9a6d40c1b0f1fada878c4345",
"sha256:a7d12f2d2df195c8c4e49d2cdbad640353a856c62ca2c624d8b47aa33b65a2a2",
"sha256:abfe83e082c9208891e2158c1b5044a650ecec408b823bf6bf16cd7f8085cafa",
"sha256:b25077a971c7da47bd6846a912a747f6963776d90720c88603b1b55d81790780",
"sha256:bf416a93e1331820c77e3429df26946dbd4fe105e9b487cd2d1b7298b75784a8",
"sha256:c04ae27e076d81a3839047d8eed57c1e17e361640616fd520d752375e3ba8f0c",
"sha256:d5bea13c73f36c4346808df3fa806596163a7962b6d28001ca2a391cab856089",
"sha256:d75bef34e69e7effb7b4849e3f830e3174d2cc6ec7273503fdde111c222dc9b3",
"sha256:d93940664a5ccfd79f72dcb939b0c31a3479889f14f0eb95ec52976f8c0cae7d",
"sha256:d9c89c521dc90c7564358e525f849b93ad1d710553c1491f66b8cce8113bc901",
"sha256:e0b36257dc90194784531c3b922d8d31fb2b4d8e5adfd27aff4eee7174176365",
"sha256:e1135264bcd40965cd35b0869e36952f54825024befdc7a923df9a7d83cfd800",
"sha256:e510d288e613d6927796dfb728e13e4530fc83b9ccac5888a21f7860486eab21",
"sha256:ee9a2c9a4b2421e77f8fe33ed0621dea03c66c710707553020b1e32f3afb6240",
"sha256:f19f11055ba2961eb39bdb1ff15763a53fca4fa0b5b624da3c7a528e83cdd09c",
"sha256:f26544bc10c83a2ff9aa2e093500c1b473f327faae31fb468d591e5823333376",
"sha256:f4875cafc9a6482c04c7df52a725d1c41beb74913c0ff4ec8f189f1954a2afe9",
"sha256:f5179088ef6487c475604b7898731a6ddeeada7702cfb2162155b016703a8475",
"sha256:f63d1ae1ca17bb2c847e298c7bcf084a73d56d434b4c50509fb93a4b4300b0b2",
"sha256:ff4928dc1e9704b567171c16787238201fdbf023665573c12c02146fe1e02eec"
],
"version": "==5.5.0"
}
}
}

@ -68,6 +68,11 @@
"doupsland": {
"commands": ["doupsland"]
},
"gpt3": {
"openai_key": ""
"join_lines": "; ",
"computing_replies": ["Hmm…"]
},
"horoscope": {
"commands": ["horoscope"],
"meditation": "/me looks at the stars",
@ -184,10 +189,6 @@
"param_source": "from",
"param_dest": "to"
},
"unknowncommand": {
"api_key": "",
"max_pods": 1
},
"unknownquestion": {
"pass_to_misc_rate": 50
},
@ -197,6 +198,14 @@
"ambiguous_response": "It is ambiguous.",
"empty_response": "I can't find it."
},
"wolframalpha": {
"commands": ["wolfram"],
"aliases": {
"wolfram": ["wolframalpha", "compute"]
},
"api_key": "",
"max_pods": 1
},
"yell": {
"commands": ["yell"],
"target_word": "to",

@ -146,10 +146,6 @@ class Bot(irc.client.SimpleIRCClient, Logger):
)
for plugin_name in plugin_names:
module = importlib.import_module(f"edmond.plugins.{plugin_name}")
are_dependencies_ok = getattr(module, "DEPENDENCIES_FOUND", True)
if not are_dependencies_ok:
self.log_e(f"Dependencies not found for plugin {plugin_name}.")
continue
# Get plugin class name from its module name.
class_name = (
"".join(map(lambda w: w.capitalize(), plugin_name.split("_")))

@ -177,7 +177,7 @@ class Plugin:
self,
key: str,
value: Any,
ns: str = None,
ns: Optional[str] = None,
skip_save: bool = False,
) -> None:
"""Append a value to a list in the plugin persistent storage."""
@ -253,7 +253,7 @@ class Plugin:
return False
# Is it a question I can answer?
question = message[len(words[0]) :].strip()
question = message[len(words[0]):].strip()
for preamble in self.config.get("questions", []):
aliases = self.config.get("aliases", {}).get(preamble, [])
for q in (preamble, *aliases):
@ -263,7 +263,7 @@ class Plugin:
return False
def __save_question(self, question: str, matched: str, preamble: str):
content = question[len(matched) :].strip()
content = question[len(matched):].strip()
content = content.rstrip("?").rstrip()
self.question = Question(preamble, content)
self.bot.log_i(f"Answering from plugin {self.name}: {self.question}")
@ -300,19 +300,8 @@ class Plugin:
available_commands = self.config.get("commands", [])
aliases = self.config.get("aliases", {})
for ident in available_commands:
# Match commands differently according to no_content. If no_content
# is True, check the parsed command (pc) raw data as a string that
# may contain the available identifier (ai) at its beginning.
# If no_content is False (default), simply compare the parsed
# identifier with available identifiers.
if no_content:
matches = lambda pc, ai: (
pc.raw == ai or pc.raw.startswith(ai + " ")
)
else:
matches = lambda pc, ai: pc.ident == ai
# First case: the command identifier has been used.
if matches(parsed_command, ident):
if self.__command_matches(parsed_command, ident, no_content):
parsed_command.ident = ident
parsed_command.matched = ident
self.__save_command(parsed_command)
@ -320,13 +309,31 @@ class Plugin:
# Second case: an alias of the identifier has been used.
ident_aliases = aliases.get(ident, [])
for alias in ident_aliases:
if matches(parsed_command, alias):
if self.__command_matches(parsed_command, alias, no_content):
parsed_command.ident = ident
parsed_command.matched = alias
self.__save_command(parsed_command)
return True
return False
@staticmethod
def __command_matches(
command: Command,
ident: str,
no_content: bool
) -> bool:
"""Return True if this command matches this command identifier.
Match commands differently according to no_content. If no_content is
True, check the parsed command raw data as a string that
may contain the available identifier at its beginning.
If no_content is False (default), simply compare the parsed
identifier with available identifiers.
"""
if no_content:
return command.raw == ident or command.raw.startswith(ident + " ")
return command.ident == ident
def __parse_command(
self, message: str, no_content: bool = False
) -> Optional[Command]:

@ -0,0 +1,48 @@
import random
import re
from typing import Optional
import openai
from edmond.plugin import Plugin
from edmond.utils import limit_text_length
class Gpt3Plugin(Plugin):
REQUIRED_CONFIGS = ["openai_key", "computing_replies", "join_lines"]
def __init__(self, bot):
super().__init__(bot)
openai.api_key = self.config["openai_key"]
def reply(self, prompt: str, target: str):
computing_reply = random.choice(self.config["computing_replies"])
self.bot.say(target, computing_reply)
completion = self.complete(prompt)
if completion and (reply := self.sanitize(completion)):
self.bot.say(target, reply)
else:
self.bot.signal_failure(target)
def complete(self, prompt: str) -> Optional[str]:
try:
completion = openai.Completion.create(
model="text-davinci-002",
prompt=prompt,
temperature=0.7,
max_tokens=128,
top_p=1,
frequency_penalty=0.5,
presence_penalty=0
)
except openai.error.OpenAIError:
return None
return completion.choices[0].text
def sanitize(self, text: str) -> str:
text = text.strip()
text = re.sub(r"\n+", self.config["join_lines"], text)
text = limit_text_length(text)
return text

@ -1,12 +1,7 @@
import datetime
from typing import cast
# BS is optional and only for scrapping journee-mondiale.com, thus why we do not
# mark the dependencies flag here.
try:
from bs4 import BeautifulSoup
except ImportError:
BeautifulSoup = None
from bs4 import BeautifulSoup
from edmond.plugin import Plugin
from edmond.plugins.plus import PlusPlugin

@ -1,11 +1,6 @@
import time
try:
import meteofrance_api as mf
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
import meteofrance_api as mf
from edmond.plugin import Plugin

@ -1,11 +1,6 @@
import random
try:
from scaruffi.api import ScaruffiApi
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
from scaruffi.api import ScaruffiApi
from edmond.plugin import Plugin

@ -1,9 +1,4 @@
try:
from translate import Translator
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
from translate import Translator
from edmond.plugin import Plugin
@ -11,11 +6,11 @@ from edmond.plugin import Plugin
class TranslatePlugin(Plugin):
"""Translate text using the `translate` package.
The translate package can use a bunch of translation interfaces but the default is
MyMemory which is fine for our purposes. There are two ways to ask for a
translation:
- Without any additional params, the source language is autodetected and the target
language is specified in the config file;
The translate package can use a bunch of translation interfaces but the
default is MyMemory which is fine for our purposes. There are two ways to
ask for a translation:
- Without any additional params, the source language is autodetected and
the target language is specified in the config file;
- With BOTH source and target languages.
"""

@ -1,37 +1,21 @@
try:
import wolframalpha
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
from edmond.plugin import Plugin
from edmond.plugins.gpt3 import Gpt3Plugin
class UnknownCommandPlugin(Plugin):
"""Handle unknown command by sending it to WolframAlpha."""
REQUIRED_CONFIGS = ["api_key", "max_pods"]
MAX_LENGTH = 256
CUT_MARK = "..."
def __init__(self, bot):
super().__init__(bot)
self.priority = -6
self._client = None
self.priority: int = -6
self.gpt3_plugin: Gpt3Plugin
@property
def client(self):
if self._client is None and self.has_api_key():
self._client = wolframalpha.Client(self.config["api_key"])
return self._client
def has_api_key(self):
return self.config["api_key"] != ""
def on_welcome(self, _):
self.gpt3_plugin = self.bot.get_plugin("gpt3")
if self.gpt3_plugin is None or not self.gpt3_plugin:
self.bot.log_w("GPT-3 plugin is not available.")
self.is_ready = False
def on_pubmsg(self, event):
if not self.has_api_key:
return False
message = self.should_read_message(event.arguments[0])
if not message:
return False
@ -40,51 +24,5 @@ class UnknownCommandPlugin(Plugin):
return False
query = " ".join(words[:-1])
self.process_query(query, event.target)
self.gpt3_plugin.reply(query, event.target)
return True
def process_query(self, query, target):
self.bot.log_d(f"Processing '{query}' with WolframAlpha.")
try:
response = self.client.query(query)
except Exception as exc: # unstable lib
self.bot.log_w(f"wolframalpha exception: {exc}")
self.signal_failure(target)
return
if not response["@success"]:
self.bot.log_d("Call to WA succeeded but response is an error.")
self.signal_failure(target)
return
inputs = []
answers = []
num_pods = 0
for pod in response.pods:
for subpod in pod.subpods:
self.bot.log_d(f"WolframAlpha subpod: {subpod}")
if pod["@id"] == "Input":
inputs.append(self.sanitize_text(subpod.plaintext or ""))
else:
answers.append(self.sanitize_text(subpod.plaintext or ""))
num_pods += 1
if num_pods >= self.config["max_pods"]:
break
if num_pods >= self.config["max_pods"]:
break
input_text = ", ".join(inputs)
answer_text = ", ".join(answers)
if input_text:
reply = input_text + " -- " + answer_text
else:
reply = answer_text
if len(reply) > self.MAX_LENGTH - len(self.CUT_MARK):
reply = (
reply[: self.MAX_LENGTH - len(self.CUT_MARK)] + self.CUT_MARK
)
self.bot.say(target, reply)
@staticmethod
def sanitize_text(text):
return text.replace("\n", ", ")

@ -7,26 +7,34 @@ from edmond.utils import proc
class UnknownQuestionPlugin(Plugin):
"""Handle unknown questions.
Reply with some question marks, but there is a configurable rate to pass
processing of the message to the misc_reactions if available.
"""
REQUIRED_CONFIGS = ["pass_to_misc_rate"]
def __init__(self, bot):
super().__init__(bot)
self.priority = -7
self.misc_plugin = None
self.gpt3_plugin = None
def on_welcome(self, event):
def on_welcome(self, _):
self.misc_plugin = self.bot.get_plugin("miscreactions")
self.gpt3_plugin = self.bot.get_plugin("gpt3")
def on_pubmsg(self, event):
message = self.should_read_message(event.arguments[0])
if message is None:
return False
if self.misc_plugin and proc(self.config["pass_to_misc_rate"]):
if self.gpt3_plugin:
return self.gpt3_plugin.reply(message, event.target)
else:
return self.classic_reply(event)
def classic_reply(self, event):
if (
self.misc_plugin
and "pass_to_misc_rate" in self.config
and proc(self.config["pass_to_misc_rate"])
):
self.misc_plugin.react(event)
else:
self.bot.say(event.target, "?" * random.randint(1, 3))
return True

@ -1,15 +1,11 @@
import time
from typing import cast
try:
import wikipedia
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
import wikipedia
from edmond.plugin import Plugin
from edmond.plugins.plus import PlusPlugin
from edmond.utils import limit_text_length
class WikipediaPlugin(Plugin):
@ -52,7 +48,7 @@ class WikipediaPlugin(Plugin):
self.bot.log_d(f"Wikipedia exception: {exc}")
retries -= 1
if page:
reply = WikipediaPlugin.limit_text_length(page.summary)
reply = limit_text_length(page.summary)
self.register_url_for_plus(page.url, event.target)
self.bot.say(event.target, reply)
@ -76,7 +72,7 @@ class WikipediaPlugin(Plugin):
time.sleep(1)
retries -= 1
if page:
reply = WikipediaPlugin.limit_text_length(page.summary)
reply = limit_text_length(page.summary)
self.register_url_for_plus(page.url, event.target)
self.bot.say(event.target, reply)
@ -85,19 +81,3 @@ class WikipediaPlugin(Plugin):
def handler(plus_event):
self.bot.say(plus_event.target, url)
cast(PlusPlugin, plus_plugin).add_handler(target, handler)
@staticmethod
def limit_text_length(text, max_length=200):
"""Limit text size to 200 characters max."""
words = text.split(" ")
cut_text = ""
while words:
next_word = words.pop(0)
if len(cut_text) + len(next_word) + 1 >= max_length:
break
cut_text += next_word + " "
if len(cut_text) < len(text):
cut_text = cut_text[:-1] + ""
else:
cut_text = cut_text.rstrip()
return cut_text

@ -0,0 +1,79 @@
import wolframalpha
from edmond.plugin import Plugin
class WolframAlphaPlugin(Plugin):
"""Handle unknown command by sending it to WolframAlpha."""
REQUIRED_CONFIGS = ["commands", "api_key", "max_pods"]
MAX_LENGTH = 256
CUT_MARK = "..."
def __init__(self, bot):
super().__init__(bot)
self.priority = -6
self._client = None
@property
def client(self):
if self._client is None and self.has_api_key():
self._client = wolframalpha.Client(self.config["api_key"])
return self._client
def on_welcome(self, _):
if not self.config["api_key"]:
self.bot.log_w("API key unavailable.")
self.is_ready = False
def on_pubmsg(self, event):
if not self.should_handle_command(event.arguments[0]):
return False
self.process_query(self.command.content, event.target)
return True
def process_query(self, query, target):
self.bot.log_d(f"Processing '{query}' with WolframAlpha.")
try:
response = self.client.query(query)
except Exception as exc: # unstable lib
self.bot.log_w(f"wolframalpha exception: {exc}")
self.signal_failure(target)
return
if not response["@success"]:
self.bot.log_d("Call to WA succeeded but response is an error.")
self.signal_failure(target)
return
inputs = []
answers = []
num_pods = 0
for pod in response.pods:
for subpod in pod.subpods:
self.bot.log_d(f"WolframAlpha subpod: {subpod}")
if pod["@id"] == "Input":
inputs.append(self.sanitize_text(subpod.plaintext or ""))
else:
answers.append(self.sanitize_text(subpod.plaintext or ""))
num_pods += 1
if num_pods >= self.config["max_pods"]:
break
if num_pods >= self.config["max_pods"]:
break
input_text = ", ".join(inputs)
answer_text = ", ".join(answers)
if input_text:
reply = input_text + " -- " + answer_text
else:
reply = answer_text
if len(reply) > self.MAX_LENGTH - len(self.CUT_MARK):
reply = (
reply[: self.MAX_LENGTH - len(self.CUT_MARK)] + self.CUT_MARK
)
self.bot.say(target, reply)
@staticmethod
def sanitize_text(text):
return text.replace("\n", ", ")

@ -1,12 +1,7 @@
from typing import cast, Optional
try:
from googleapiclient.discovery import build as gapi_discovery_build
from googleapiclient.errors import Error as GoogleApiError
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
from googleapiclient.discovery import build as gapi_discovery_build
from googleapiclient.errors import Error as GoogleApiError
from edmond.plugin import Plugin
from edmond.plugins.playlist_of_the_day import PlaylistOfTheDayPlugin

@ -1,12 +1,7 @@
import re
from typing import cast, Optional
try:
from googleapiclient.errors import Error as GoogleApiError # type: ignore
DEPENDENCIES_FOUND = True
except ImportError:
DEPENDENCIES_FOUND = False
from googleapiclient.errors import Error as GoogleApiError # type: ignore
from edmond.plugin import Plugin
from edmond.plugins.playlist_of_the_day import PlaylistOfTheDayPlugin
@ -24,9 +19,7 @@ class YoutubeParserPlugin(Plugin):
super().__init__(bot)
self.priority = -3
self._youtube_plugin: Optional[YoutubePlugin] = None
self._playlist_of_the_day_plugin: Optional[
PlaylistOfTheDayPlugin
] = None
self._potd_plugin: Optional[PlaylistOfTheDayPlugin] = None
@property
def youtube_plugin(self) -> Optional[YoutubePlugin]:
@ -39,12 +32,12 @@ class YoutubeParserPlugin(Plugin):
@property
def playlist_of_the_day_plugin(self) -> Optional[PlaylistOfTheDayPlugin]:
if self._playlist_of_the_day_plugin is None:
self._playlist_of_the_day_plugin = cast(
if self._potd_plugin is None:
self._potd_plugin = cast(
PlaylistOfTheDayPlugin,
self.bot.get_plugin("playlistoftheday"),
)
return self._playlist_of_the_day_plugin
return self._potd_plugin
def on_welcome(self, _):
if not (self.youtube_plugin and self.youtube_plugin.is_ready):

@ -13,3 +13,19 @@ def http_get(url: str) -> Optional[str]:
def proc(proba_percentage: int) -> bool:
return random.random() < (proba_percentage / 100.0)
def limit_text_length(text, max_length=400):
"""Limit text size to 400 characters max."""
words = text.split(" ")
cut_text = ""
while words:
next_word = words.pop(0)
if len(cut_text) + len(next_word) + 1 >= max_length:
break
cut_text += next_word + " "
if len(cut_text) < len(text):
cut_text = cut_text[:-1] + ""
else:
cut_text = cut_text.rstrip()
return cut_text

Loading…
Cancel
Save