Compare commits

...

5 Commits

Author SHA1 Message Date
abbf94b21a fix: whatever random thing I throw into this commit
To fix bugs ofc
2023-06-17 09:25:54 +07:00
426062c20b deps: add requests
How could I forget that
2023-06-17 09:25:14 +07:00
437c9a5e76 feat: add more exceptions 2023-06-17 09:20:57 +07:00
9cb18a26c4 feat: add re-exports 2023-06-17 09:18:09 +07:00
e8ee174146 docs: add some text 2023-06-17 09:16:50 +07:00
14 changed files with 281 additions and 32 deletions

146
poetry.lock generated
View File

@ -1,5 +1,16 @@
# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand. # This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand.
[[package]]
name = "certifi"
version = "2023.5.7"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"},
{file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"},
]
[[package]] [[package]]
name = "cfgv" name = "cfgv"
version = "3.3.1" version = "3.3.1"
@ -11,6 +22,90 @@ files = [
{file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"},
] ]
[[package]]
name = "charset-normalizer"
version = "3.1.0"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7.0"
files = [
{file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
{file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
{file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
{file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
{file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
{file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
{file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
{file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
{file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
{file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
{file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
{file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
{file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
{file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
{file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
{file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
{file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
{file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
{file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
{file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
{file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
{file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
{file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
]
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
@ -62,6 +157,17 @@ files = [
[package.extras] [package.extras]
license = ["ukkonen"] license = ["ukkonen"]
[[package]]
name = "idna"
version = "3.4"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.5"
files = [
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
]
[[package]] [[package]]
name = "iniconfig" name = "iniconfig"
version = "2.0.0" version = "2.0.0"
@ -215,6 +321,27 @@ files = [
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
] ]
[[package]]
name = "requests"
version = "2.31.0"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.7"
files = [
{file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
{file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
]
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<4"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "67.8.0" version = "67.8.0"
@ -231,6 +358,23 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "urllib3"
version = "2.0.3"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.7"
files = [
{file = "urllib3-2.0.3-py3-none-any.whl", hash = "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1"},
{file = "urllib3-2.0.3.tar.gz", hash = "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[[package]] [[package]]
name = "virtualenv" name = "virtualenv"
version = "20.23.0" version = "20.23.0"
@ -254,4 +398,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.11" python-versions = "^3.11"
content-hash = "d95937232038c908071d8189633a81e1116f76a8cc62cdfeeaa4c556a7ec3f2b" content-hash = "7d2bf3678e910680af7a343064533ccd713d5583786eef1d7d8fa2d930da6128"

View File

@ -9,6 +9,7 @@ readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.11" python = "^3.11"
platformdirs = "^3.5.1" platformdirs = "^3.5.1"
requests = "^2.31.0"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.3.1" pytest = "^7.3.1"

View File

@ -1,5 +1,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from os import PathLike from os import PathLike
from pathlib import Path
class GameABC(ABC): class GameABC(ABC):
@ -10,6 +11,12 @@ class GameABC(ABC):
def __init__(self, path: PathLike = None): def __init__(self, path: PathLike = None):
pass pass
def data_folder(self) -> Path:
"""
Get the game data folder
"""
pass
def is_installed(self) -> bool: def is_installed(self) -> bool:
""" """
Check if the game is installed Check if the game is installed

View File

@ -9,8 +9,28 @@ class PatcherABC(ABC):
@abstractmethod @abstractmethod
def patch_game(self, game: GameABC): def patch_game(self, game: GameABC):
"""
Patch the game
If the game is not installed then it'll raise `GameNotInstalledError`, if the
game version is not supported then it'll raise `VersionNotSupportedError` and
if the patching fails then it'll raise `PatchingFailedError`.
Args:
game (Game): Game instance to patch
"""
pass pass
@abstractmethod @abstractmethod
def unpatch_game(self, game: GameABC): def unpatch_game(self, game: GameABC):
"""
Unpatch the game
This method unpatch the game by restoring backups and removing the patch files.
It'll fail if you removed the backup files, in that case you'll have to repair
the game.
If the game is not installed then it'll raise `GameNotInstalledError` and if the
unpatching fails then it'll raise `UnpatchingFailedError`.
"""
pass pass

View File

@ -8,7 +8,3 @@ telemetry_hosts = [
"log-upload.mihoyo.com", "log-upload.mihoyo.com",
"public-data-api.mihoyo.com", "public-data-api.mihoyo.com",
] ]
# HSR
astra_repo = "https://notabug.org/mkrsym1/astra"
jadeite_repo = "https://codeberg.org/mkrsym1/jadeite/"

View File

@ -11,3 +11,21 @@ class VersionNotSupportedError(PatcherError):
"""Exception raised when the game version is not supported.""" """Exception raised when the game version is not supported."""
pass pass
class PatchingFailedError(PatcherError):
"""Exception raised when the patching failed."""
pass
class PatchUpdateError(PatcherError):
"""Exception raised when the patch update failed."""
pass
class UnpatchingFailedError(PatcherError):
"""Exception raised when the unpatching failed."""
pass

View File

@ -0,0 +1,6 @@
# Re-exports
from vollerei.hsr.patcher import Patcher
from vollerei.hsr.launcher import Game, GameChannel
__all__ = ["Patcher", "Game", "GameChannel"]

View File

@ -11,3 +11,6 @@ md5sums = {
}, },
} }
} }
# Patches
astra_repo = "https://notabug.org/mkrsym1/astra"
jadeite_repo = "https://codeberg.org/mkrsym1/jadeite/"

View File

@ -0,0 +1,5 @@
# Re-exports
from vollerei.hsr.launcher.game import Game, GameChannel
__all__ = ["Game", "GameChannel"]

View File

@ -19,17 +19,28 @@ class Game(GameABC):
def path(self) -> Path | None: def path(self) -> Path | None:
return self._path return self._path
@path.setter
def path(self, path: PathLike):
self._path = Path(path)
def data_folder(self) -> Path: def data_folder(self) -> Path:
return self._path.joinpath("StarRail_Data") return self._path.joinpath("StarRail_Data")
def is_installed(self) -> bool: def is_installed(self) -> bool:
"""
Check if the game is installed.
"""
if self._path is None: if self._path is None:
return False return False
if ( if (
not self._path.joinpath("StarRail.exe").exists() not self._path.joinpath("StarRail.exe").exists()
or not self._path.joinpath("StarRailBase.dll").exists() or not self._path.joinpath("StarRailBase.dll").exists()
or not self._path.joinpath("StarRail_Data").exists()
): ):
return False return False
if self.get_version() == (0, 0, 0):
return False
return True
def get_version(self) -> tuple[int, int, int]: def get_version(self) -> tuple[int, int, int]:
""" """
@ -86,9 +97,23 @@ class Game(GameABC):
return (0, 0, 0) return (0, 0, 0)
def get_version_str(self) -> str: def get_version_str(self) -> str:
"""
Same as get_version, but returns a string instead.
Returns:
str: The version as a string.
"""
return ".".join(str(i) for i in self.get_version()) return ".".join(str(i) for i in self.get_version())
def get_channel(self) -> GameChannel: def get_channel(self) -> GameChannel:
"""
Get the current game channel.
Only works for Star Rail version 1.0.5, other versions will return None
Returns:
GameChannel: The current game channel.
"""
if self.get_version() == (1, 0, 5): if self.get_version() == (1, 0, 5):
for channel, v in md5sums["1.0.5"].values(): for channel, v in md5sums["1.0.5"].values():
for file, md5sum in v.values(): for file, md5sum in v.values():

View File

@ -1,4 +1,3 @@
from pathlib import Path
from enum import Enum from enum import Enum
from shutil import copy2 from shutil import copy2
from distutils.version import StrictVersion from distutils.version import StrictVersion
@ -8,7 +7,7 @@ from vollerei.exceptions.patcher import VersionNotSupportedError
from vollerei.hsr.launcher.game import Game, GameChannel from vollerei.hsr.launcher.game import Game, GameChannel
from vollerei.utils import download_and_extract, Git, Xdelta3 from vollerei.utils import download_and_extract, Git, Xdelta3
from vollerei.paths import tools_data_path from vollerei.paths import tools_data_path
from vollerei.constants import astra_repo, jadeite_repo from vollerei.hsr.constants import astra_repo, jadeite_repo
class PatchType(Enum): class PatchType(Enum):
@ -24,6 +23,10 @@ class PatchType(Enum):
class Patcher(PatcherABC): class Patcher(PatcherABC):
"""
Patch helper for HSR.
"""
def __init__(self, patch_type: PatchType = PatchType.Jadeite): def __init__(self, patch_type: PatchType = PatchType.Jadeite):
self._patch_type: PatchType = patch_type self._patch_type: PatchType = patch_type
self._path = tools_data_path.joinpath("patcher") self._path = tools_data_path.joinpath("patcher")
@ -45,8 +48,9 @@ class Patcher(PatcherABC):
self._git.pull_or_clone(astra_repo, self._astra) self._git.pull_or_clone(astra_repo, self._astra)
def _update_jadeite(self): def _update_jadeite(self):
file = self._git.get_latest_release_dl(jadeite_repo)[0] release_info = self._git.get_latest_release(jadeite_repo)
file_version = Path(file).stem[1:] file = self._git.get_latest_release_dl(release_info)[0]
file_version = release_info["tag_name"][1:] # Remove "v" prefix
current_version = None current_version = None
if self._jadeite.joinpath("version").exists(): if self._jadeite.joinpath("version").exists():
with open(self._jadeite.joinpath("version"), "r") as f: with open(self._jadeite.joinpath("version"), "r") as f:
@ -121,3 +125,6 @@ class Patcher(PatcherABC):
self._patch_astra(game) self._patch_astra(game)
case PatchType.Jadeite: case PatchType.Jadeite:
return self._patch_jadeite() return self._patch_jadeite()
def unpatch_game(self, game: Game):
pass

View File

@ -1,21 +1,23 @@
from pathlib import Path from pathlib import Path
from os import PathLike
from platformdirs import PlatformDirs from platformdirs import PlatformDirs
base_paths = PlatformDirs("vollerei", "tretrauit", roaming=True) base_paths = PlatformDirs("vollerei", "tretrauit", roaming=True)
tools_data_path: Path = None cache_path = base_paths.site_cache_path
tools_cache_path: Path = None data_path = base_paths.site_data_path
launcher_cache_path: Path = None tools_data_path = data_path.joinpath("tools")
utils_cache_path: Path = None tools_cache_path = cache_path.joinpath("tools")
launcher_cache_path = cache_path.joinpath("launcher")
utils_cache_path = cache_path.joinpath("utils")
def init_paths(): def change_base_path(path: PathLike):
global tools_data_path, tools_cache_path, launcher_cache_path, utils_cache_path path = Path(path)
tools_data_path = base_paths.site_data_path.joinpath("tools") global base_paths, tools_data_path, tools_cache_path, launcher_cache_path, utils_cache_path, cache_path, data_path
tools_cache_path = base_paths.site_cache_path.joinpath("tools") cache_path = path.joinpath("cache")
launcher_cache_path = base_paths.site_cache_path.joinpath("launcher") data_path = path.joinpath("data")
utils_cache_path = base_paths.site_cache_path.joinpath("utils") tools_data_path = data_path.joinpath("tools")
tools_data_path.mkdir(parents=True, exist_ok=True) tools_cache_path = cache_path.joinpath("tools")
tools_cache_path.mkdir(parents=True, exist_ok=True) launcher_cache_path = cache_path.joinpath("launcher")
launcher_cache_path.mkdir(parents=True, exist_ok=True) utils_cache_path = cache_path.joinpath("utils")
utils_cache_path.mkdir(parents=True, exist_ok=True)

View File

@ -1,12 +1,13 @@
from io import BytesIO
import subprocess import subprocess
from zipfile import ZipFile
import requests import requests
import json import json
from pathlib import Path from pathlib import Path
from shutil import which, rmtree from shutil import which, rmtree
from urllib.parse import urlparse from urllib.parse import urlparse
from vollerei.constants import utils_cache_path from vollerei.paths import utils_cache_path
from vollerei.utils.git.exceptions import GitCloneError from vollerei.utils.git.exceptions import GitCloneError
from vollerei.utils import download_and_extract
class Git: class Git:
@ -36,7 +37,7 @@ class Git:
""" """
Check if the url is a Gitea server Check if the url is a Gitea server
""" """
rsp = requests.get(f"https://{netloc}/api/v1/meta") rsp = requests.get(f"https://{netloc}/api/v1/version")
try: try:
data: dict = rsp.json() data: dict = rsp.json()
except json.JSONDecodeError: except json.JSONDecodeError:
@ -61,7 +62,15 @@ class Git:
return data[0]["sha"] return data[0]["sha"]
def _download_and_extract_zip(self, url: str, path: Path) -> None: def _download_and_extract_zip(self, url: str, path: Path) -> None:
download_and_extract(url, path) # Copied code so it doesn't depend on vollerei.utils.download_and_extract
rsp = requests.get(url, stream=True)
rsp.raise_for_status()
with BytesIO() as f:
for chunk in rsp.iter_content(chunk_size=32768):
f.write(chunk)
f.seek(0)
with ZipFile(f) as z:
z.extractall(path)
path.joinpath(".git/PLEASE_INSTALL_GIT").touch() path.joinpath(".git/PLEASE_INSTALL_GIT").touch()
def _clone(self, url: str, path: str = None) -> None: def _clone(self, url: str, path: str = None) -> None:
@ -91,8 +100,7 @@ class Git:
else: else:
raise NotImplementedError raise NotImplementedError
def get_latest_release_dl(self, url: str) -> list[str]: def get_latest_release(self, url: str) -> dict:
dl = []
if Path(url).suffix == ".git": if Path(url).suffix == ".git":
url = url[:-4] url = url[:-4]
url_info = urlparse(url) url_info = urlparse(url)
@ -103,11 +111,18 @@ class Git:
) )
rsp.raise_for_status() rsp.raise_for_status()
data = rsp.json() data = rsp.json()
for asset in data["assets"]: return data
dl.append(asset["browser_download_url"])
else: else:
raise NotImplementedError raise NotImplementedError
def get_latest_release_dl(self, data: dict) -> list[str]:
dl = []
if not data.get("assets"):
return dl
for asset in data["assets"]:
dl.append(asset["browser_download_url"])
return dl
def pull_or_clone(self, url: str, path: str = None) -> None: def pull_or_clone(self, url: str, path: str = None) -> None:
""" """
Pulls or clones a git repository Pulls or clones a git repository

View File

@ -4,7 +4,7 @@ import requests
from os import PathLike from os import PathLike
from zipfile import ZipFile from zipfile import ZipFile
from shutil import which from shutil import which
from vollerei.constants import tools_cache_path from vollerei.paths import tools_cache_path
from vollerei.utils.xdelta3.exceptions import ( from vollerei.utils.xdelta3.exceptions import (
Xdelta3NotInstalledError, Xdelta3NotInstalledError,
Xdelta3PatchError, Xdelta3PatchError,