diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000..4c56386 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,12 @@ +version = 1 + +[[analyzers]] +name = "python" +enabled = true + + [analyzers.meta] + runtime_version = "3.x.x" + +[[analyzers]] +name = "secrets" +enabled = true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 34377bf..3137606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.0](https://github.com/janaSunrise/HypixelIO/releases/tag/v1.2.0) - 09-03-2021 + +## Added +- Skyblock models +- Skyblock endpoints +- Added HTML documentation +- More utility functions and support to make it easier and reliable. +- Asynchronous support for discord bot devs and other people to keep it non-blocking. + +## Fixed +- Rewrote most of the code base. +- Rewrite of the inline documentation. +- Pass API Key as `API-Key` header so it's secure and follows the standards. +- Refactored the methods to get better support and converted into multiple methods so its cleaner. +- Fixed the tests and the errors / exceptions raised when issues arrive. +- Make the rest of the codebase usable by the endpoint user, if needed. Not compulsary. + ## [1.1.1](https://github.com/janaSunrise/HypixelIO/releases/tag/v1.1.1) - 29-12-2020 ## Added @@ -46,9 +63,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added attributes like `__author__` and `__version__` - Added Manifest - Added support for Comparisons like - - `obj1 == obj2` - - `obj1 > obj2` - - `obj1 >= obj2` + - `obj1 == obj2` + - `obj1 > obj2` + - `obj1 >= obj2` ## [0.0.5](https://github.com/janaSunrise/HypixelIO/releases/tag/v0.0.5) - 04-11-2020 @@ -57,10 +74,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added timeout for the cache and fetch - Allow users to specify the caching according to needs, and various functions to make experience better - Functions allowed: - - Clearing Cache - - Uninstall cache, If enabled - - removing expired cache - - Get the existsing cache, and check it. + - Clearing Cache + - Uninstall cache, If enabled + - removing expired cache + - Get the existsing cache, and check it. ## [0.0.4](https://github.com/janaSunrise/HypixelIO/releases/tag/v0.0.4) - 31-10-2020 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..4a325a3 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at warriordefenderz@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/Pipfile b/Pipfile index f9b21f2..3cc5238 100644 --- a/Pipfile +++ b/Pipfile @@ -12,11 +12,14 @@ flake8-import-order = "~=0.18.1" pre-commit = "~=2.8.2" pytest-benchmark = "*" bandit = "*" +insegel = "*" +recommonmark = "*" [packages] hypixelio = {editable = true, path = "."} -requests = "==2.25.0" +requests = "==2.25.1" requests-cache = "==0.5.2" +aiohttp = "*" [scripts] lint = "pre-commit run --all-files" diff --git a/Pipfile.lock b/Pipfile.lock index 31b8c86..f9d434c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3d6dafeab318cdc7aa7209bbf5ed20b0f2b9ed4aa495762c1e00e62290519d7f" + "sha256": "0f40dfe4f03d0920e25dbd83485ef48715db051589b37a2c77f1fef862b89d99" }, "pipfile-spec": 6, "requires": {}, @@ -14,6 +14,65 @@ ] }, "default": { + "aiohttp": { + "hashes": [ + "sha256:02f46fc0e3c5ac58b80d4d56eb0a7c7d97fcef69ace9326289fb9f1955e65cfe", + "sha256:0563c1b3826945eecd62186f3f5c7d31abb7391fedc893b7e2b26303b5a9f3fe", + "sha256:114b281e4d68302a324dd33abb04778e8557d88947875cbf4e842c2c01a030c5", + "sha256:14762875b22d0055f05d12abc7f7d61d5fd4fe4642ce1a249abdf8c700bf1fd8", + "sha256:15492a6368d985b76a2a5fdd2166cddfea5d24e69eefed4630cbaae5c81d89bd", + "sha256:17c073de315745a1510393a96e680d20af8e67e324f70b42accbd4cb3315c9fb", + "sha256:209b4a8ee987eccc91e2bd3ac36adee0e53a5970b8ac52c273f7f8fd4872c94c", + "sha256:230a8f7e24298dea47659251abc0fd8b3c4e38a664c59d4b89cca7f6c09c9e87", + "sha256:2e19413bf84934d651344783c9f5e22dee452e251cfd220ebadbed2d9931dbf0", + "sha256:393f389841e8f2dfc86f774ad22f00923fdee66d238af89b70ea314c4aefd290", + "sha256:3cf75f7cdc2397ed4442594b935a11ed5569961333d49b7539ea741be2cc79d5", + "sha256:3d78619672183be860b96ed96f533046ec97ca067fd46ac1f6a09cd9b7484287", + "sha256:40eced07f07a9e60e825554a31f923e8d3997cfc7fb31dbc1328c70826e04cde", + "sha256:493d3299ebe5f5a7c66b9819eacdcfbbaaf1a8e84911ddffcdc48888497afecf", + "sha256:4b302b45040890cea949ad092479e01ba25911a15e648429c7c5aae9650c67a8", + "sha256:515dfef7f869a0feb2afee66b957cc7bbe9ad0cdee45aec7fdc623f4ecd4fb16", + "sha256:547da6cacac20666422d4882cfcd51298d45f7ccb60a04ec27424d2f36ba3eaf", + "sha256:5df68496d19f849921f05f14f31bd6ef53ad4b00245da3195048c69934521809", + "sha256:64322071e046020e8797117b3658b9c2f80e3267daec409b350b6a7a05041213", + "sha256:7615dab56bb07bff74bc865307aeb89a8bfd9941d2ef9d817b9436da3a0ea54f", + "sha256:79ebfc238612123a713a457d92afb4096e2148be17df6c50fb9bf7a81c2f8013", + "sha256:7b18b97cf8ee5452fa5f4e3af95d01d84d86d32c5e2bfa260cf041749d66360b", + "sha256:932bb1ea39a54e9ea27fc9232163059a0b8855256f4052e776357ad9add6f1c9", + "sha256:a00bb73540af068ca7390e636c01cbc4f644961896fa9363154ff43fd37af2f5", + "sha256:a5ca29ee66f8343ed336816c553e82d6cade48a3ad702b9ffa6125d187e2dedb", + "sha256:af9aa9ef5ba1fd5b8c948bb11f44891968ab30356d65fd0cc6707d989cd521df", + "sha256:bb437315738aa441251214dad17428cafda9cdc9729499f1d6001748e1d432f4", + "sha256:bdb230b4943891321e06fc7def63c7aace16095be7d9cf3b1e01be2f10fba439", + "sha256:c6e9dcb4cb338d91a73f178d866d051efe7c62a7166653a91e7d9fb18274058f", + "sha256:cffe3ab27871bc3ea47df5d8f7013945712c46a3cc5a95b6bee15887f1675c22", + "sha256:d012ad7911653a906425d8473a1465caa9f8dea7fcf07b6d870397b774ea7c0f", + "sha256:d9e13b33afd39ddeb377eff2c1c4f00544e191e1d1dee5b6c51ddee8ea6f0cf5", + "sha256:e4b2b334e68b18ac9817d828ba44d8fcb391f6acb398bcc5062b14b2cbeac970", + "sha256:e54962802d4b8b18b6207d4a927032826af39395a3bd9196a5af43fc4e60b009", + "sha256:f705e12750171c0ab4ef2a3c76b9a4024a62c4103e3a55dd6f99265b9bc6fcfc", + "sha256:f881853d2643a29e643609da57b96d5f9c9b93f62429dcc1cbb413c7d07f0e1a", + "sha256:fe60131d21b31fd1a14bd43e6bb88256f69dfc3188b3a89d736d6c71ed43ec95" + ], + "index": "pypi", + "version": "==3.7.4.post0" + }, + "async-timeout": { + "hashes": [ + "sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f", + "sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3" + ], + "markers": "python_full_version >= '3.5.3'", + "version": "==3.0.1" + }, + "attrs": { + "hashes": [ + "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6", + "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==20.3.0" + }, "certifi": { "hashes": [ "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", @@ -23,10 +82,11 @@ }, "chardet": { "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" ], - "version": "==3.0.4" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" }, "hypixelio": { "editable": true, @@ -40,13 +100,56 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.10" }, + "multidict": { + "hashes": [ + "sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a", + "sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93", + "sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632", + "sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656", + "sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79", + "sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7", + "sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d", + "sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5", + "sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224", + "sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26", + "sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea", + "sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348", + "sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6", + "sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76", + "sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1", + "sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f", + "sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952", + "sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a", + "sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37", + "sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9", + "sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359", + "sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8", + "sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da", + "sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3", + "sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d", + "sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf", + "sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841", + "sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d", + "sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93", + "sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f", + "sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647", + "sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635", + "sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456", + "sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda", + "sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5", + "sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281", + "sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80" + ], + "markers": "python_version >= '3.6'", + "version": "==5.1.0" + }, "requests": { "hashes": [ - "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8", - "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998" + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" ], "index": "pypi", - "version": "==2.25.0" + "version": "==2.25.1" }, "requests-cache": { "hashes": [ @@ -56,16 +159,74 @@ "index": "pypi", "version": "==0.5.2" }, + "typing-extensions": { + "hashes": [ + "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918", + "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c", + "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f" + ], + "version": "==3.7.4.3" + }, "urllib3": { "hashes": [ - "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08", - "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473" + "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", + "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.2" + "version": "==1.26.3" + }, + "yarl": { + "hashes": [ + "sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e", + "sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434", + "sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366", + "sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3", + "sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec", + "sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959", + "sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e", + "sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c", + "sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6", + "sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a", + "sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6", + "sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424", + "sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e", + "sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f", + "sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50", + "sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2", + "sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc", + "sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4", + "sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970", + "sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10", + "sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0", + "sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406", + "sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896", + "sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643", + "sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721", + "sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478", + "sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724", + "sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e", + "sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8", + "sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96", + "sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25", + "sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76", + "sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2", + "sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2", + "sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c", + "sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a", + "sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71" + ], + "markers": "python_version >= '3.6'", + "version": "==1.6.3" } }, "develop": { + "alabaster": { + "hashes": [ + "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", + "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" + ], + "version": "==0.7.12" + }, "appdirs": { "hashes": [ "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", @@ -83,10 +244,19 @@ }, "autopep8": { "hashes": [ - "sha256:d21d3901cb0da6ebd1e83fc9b0dfbde8b46afc2ede4fe32fbda0c7c6118ca094" + "sha256:9e136c472c475f4ee4978b51a88a494bfcd4e3ed17950a44a988d9e434837bea", + "sha256:cae4bc0fb616408191af41d062d7ec7ef8679c7f27b068875ca3a9e2878d5443" ], "index": "pypi", - "version": "==1.5.4" + "version": "==1.5.5" + }, + "babel": { + "hashes": [ + "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5", + "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.9.0" }, "bandit": { "hashes": [ @@ -96,6 +266,13 @@ "index": "pypi", "version": "==1.7.0" }, + "certifi": { + "hashes": [ + "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c", + "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830" + ], + "version": "==2020.12.5" + }, "cfgv": { "hashes": [ "sha256:32e43d604bbe7896fe7c248a9c2276447dbef840feb28fe20494f62af110211d", @@ -104,6 +281,29 @@ "markers": "python_full_version >= '3.6.1'", "version": "==3.2.0" }, + "chardet": { + "hashes": [ + "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa", + "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==4.0.0" + }, + "commonmark": { + "hashes": [ + "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60", + "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9" + ], + "version": "==0.9.1" + }, + "datarum": { + "hashes": [ + "sha256:4c4f1aca4da9d38126b91d3488be950b29eced61757b83a30c06587d38ba4566", + "sha256:61f3c7db876e756794c0bff5b32dea1bf1734292224be2c41792a8aa943b3d5a" + ], + "markers": "python_version >= '3'", + "version": "==0.3.0" + }, "distlib": { "hashes": [ "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb", @@ -111,6 +311,14 @@ ], "version": "==0.3.1" }, + "docutils": { + "hashes": [ + "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", + "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.16" + }, "filelock": { "hashes": [ "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59", @@ -160,19 +368,35 @@ }, "gitpython": { "hashes": [ - "sha256:6eea89b655917b500437e9668e4a12eabdcf00229a0df1762aabd692ef9b746b", - "sha256:befa4d101f91bad1b632df4308ec64555db684c360bd7d2130b4807d49ce86b8" + "sha256:3283ae2fba31c913d857e12e5ba5f9a7772bbc064ae2bb09efafa71b0dd4939b", + "sha256:be27633e7509e58391f10207cd32b2a6cf5b908f92d9cd30da2e514e1137af61" ], "markers": "python_version >= '3.4'", - "version": "==3.1.11" + "version": "==3.1.14" }, "identify": { "hashes": [ - "sha256:943cd299ac7f5715fcb3f684e2fc1594c1e0f22a90d15398e5888143bd4144b5", - "sha256:cc86e6a9a390879dcc2976cef169dd9cc48843ed70b7380f321d1b118163c60e" + "sha256:2179e7359471ab55729f201b3fdf7dc2778e221f868410fedcb0987b791ba552", + "sha256:2a5fdf2f5319cc357eda2550bea713a404392495961022cf2462624ce62f0f46" + ], + "markers": "python_full_version >= '3.6.1'", + "version": "==2.1.0" + }, + "idna": { + "hashes": [ + "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", + "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.5.10" + "version": "==2.10" + }, + "imagesize": { + "hashes": [ + "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1", + "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.2.0" }, "iniconfig": { "hashes": [ @@ -181,6 +405,80 @@ ], "version": "==1.1.1" }, + "insegel": { + "hashes": [ + "sha256:9a8218d042d34a05e3a7c19c258fcf296bc6681f1ac00d128a9df7a3359e4c7b", + "sha256:b5c79142dd3b326278a355de81ba7b7db6f0bc141d9c3986665404973617269f" + ], + "index": "pypi", + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419", + "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==2.11.3" + }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", + "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f", + "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014", + "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85", + "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850", + "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1", + "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5", + "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c", + "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be", + "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.1.1" + }, "mccabe": { "hashes": [ "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", @@ -197,11 +495,17 @@ }, "packaging": { "hashes": [ - "sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858", - "sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093" + "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5", + "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.8" + "version": "==20.9" + }, + "parse": { + "hashes": [ + "sha256:9ff82852bcb65d139813e2a5197627a94966245c897796760a3a2a8eb66f020b" + ], + "version": "==1.19.0" }, "pbr": { "hashes": [ @@ -257,6 +561,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.2.0" }, + "pygments": { + "hashes": [ + "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94", + "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8" + ], + "markers": "python_version >= '3.5'", + "version": "==2.8.1" + }, "pyparsing": { "hashes": [ "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", @@ -267,11 +579,11 @@ }, "pytest": { "hashes": [ - "sha256:1969f797a1a0dbd8ccf0fecc80262312729afea9c17f1d70ebf85c5e76c6f7c8", - "sha256:66e419b1899bc27346cb2c993e12c5e5e8daba9073c1fbce33b9807abc95c306" + "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9", + "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839" ], "markers": "python_version >= '3.6'", - "version": "==6.2.1" + "version": "==6.2.2" }, "pytest-benchmark": { "hashes": [ @@ -281,23 +593,63 @@ "index": "pypi", "version": "==3.2.3" }, + "pytz": { + "hashes": [ + "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da", + "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798" + ], + "version": "==2021.1" + }, "pyyaml": { "hashes": [ - "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", - "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", - "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", - "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e", - "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", - "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", - "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", - "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", - "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", - "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a", - "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", - "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", - "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" - ], - "version": "==5.3.1" + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==5.4.1" + }, + "recommonmark": { + "hashes": [ + "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f", + "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67" + ], + "index": "pypi", + "version": "==0.7.1" + }, + "requests": { + "hashes": [ + "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804", + "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e" + ], + "index": "pypi", + "version": "==2.25.1" }, "six": { "hashes": [ @@ -309,11 +661,74 @@ }, "smmap": { "hashes": [ - "sha256:54c44c197c819d5ef1991799a7e30b662d1e520f2ac75c9efbeb54a742214cf4", - "sha256:9c98bbd1f9786d22f14b3d4126894d56befb835ec90cef151af566c7e19b5d24" + "sha256:7bfcf367828031dc893530a29cb35eb8c8f2d7c8f2d0989354d75d24c8573714", + "sha256:84c2751ef3072d4f6b2785ec7ee40244c6f45eb934d9e543e2c51f1bd3d54c50" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==3.0.4" + "version": "==3.0.5" + }, + "snowballstemmer": { + "hashes": [ + "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2", + "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914" + ], + "version": "==2.1.0" + }, + "sphinx": { + "hashes": [ + "sha256:672cfcc24b6b69235c97c750cb190a44ecd72696b4452acaf75c2d9cc78ca5ff", + "sha256:ef64a814576f46ec7de06adf11b433a0d6049be007fefe7fd0d183d28b581fac" + ], + "markers": "python_version >= '3.5'", + "version": "==3.5.2" + }, + "sphinxcontrib-applehelp": { + "hashes": [ + "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", + "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.2" + }, + "sphinxcontrib-devhelp": { + "hashes": [ + "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", + "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.2" + }, + "sphinxcontrib-htmlhelp": { + "hashes": [ + "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f", + "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.3" + }, + "sphinxcontrib-jsmath": { + "hashes": [ + "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", + "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.1" + }, + "sphinxcontrib-qthelp": { + "hashes": [ + "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", + "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" + ], + "markers": "python_version >= '3.5'", + "version": "==1.0.3" + }, + "sphinxcontrib-serializinghtml": { + "hashes": [ + "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc", + "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a" + ], + "markers": "python_version >= '3.5'", + "version": "==1.1.4" }, "stevedore": { "hashes": [ @@ -331,13 +746,21 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, + "urllib3": { + "hashes": [ + "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80", + "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "version": "==1.26.3" + }, "virtualenv": { "hashes": [ - "sha256:54b05fc737ea9c9ee9f8340f579e5da5b09fb64fd010ab5757eb90268616907c", - "sha256:b7a8ec323ee02fb2312f098b6b4c9de99559b462775bc8fe3627a73706603c1b" + "sha256:147b43894e51dd6bba882cf9c282447f780e2251cd35172403745fc381a0a80d", + "sha256:2be72df684b74df0ea47679a7df93fd0e04e72520022c57b479d8f881485dbe3" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==20.2.2" + "version": "==20.4.2" } } } diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index a3e43d7..9c1d44e 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index 031644d..4ec3560 100644 Binary files a/docs/build/doctrees/index.doctree and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo index b925e47..b4dec54 100644 --- a/docs/build/html/.buildinfo +++ b/docs/build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 08ce7dab3522c112c4eb0d66614d476e +config: 09c479514b628a657b6e934d223a2ad8 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_sources/index.rst.txt b/docs/build/html/_sources/index.rst.txt index 23987fd..1b51305 100644 --- a/docs/build/html/_sources/index.rst.txt +++ b/docs/build/html/_sources/index.rst.txt @@ -1,20 +1,32 @@ -.. HypixelIO documentation master file, created by - sphinx-quickstart on Fri Nov 13 13:33:46 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to HypixelIO's documentation! +Welcome to HypixelIO! ===================================== -.. toctree:: - :maxdepth: 2 - :caption: Contents: +HypixelIO is a modern hypixel API wrapper library that suits all your needs. It supports both sync +and async programming, with easy to use features in mind. + +**Features** + +- Modern way of handling requests +- Both async and sync support. +- Simple rate handling, and caching. +- Speed optimized +- Easy to use with a modern and simple design + +Getting started +----------------- +Is this your first time using the library? This is the place to get started! +- **Examples:** Many examples are available in the :resource:`repository `. -Indices and tables -================== -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +Modules and manuals +------------------- + +These pages have info, documentation and help, all you need to learn and use this library! + +.. toctree:: + :maxdepth: 1 + + api + hypixelio.ext.asyncio reference diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css index 24a49f0..be19270 100644 --- a/docs/build/html/_static/basic.css +++ b/docs/build/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js index 7d88f80..61ac9d2 100644 --- a/docs/build/html/_static/doctools.js +++ b/docs/build/html/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -29,9 +29,14 @@ if (!window.console || !console.firebug) { /** * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL */ jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); }; /** diff --git a/docs/build/html/_static/documentation_options.js b/docs/build/html/_static/documentation_options.js index 2fa8c97..b283bb6 100644 --- a/docs/build/html/_static/documentation_options.js +++ b/docs/build/html/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '', + VERSION: '1.1.1', LANGUAGE: 'None', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/build/html/_static/language_data.js b/docs/build/html/_static/language_data.js index d2b4ee9..863704b 100644 --- a/docs/build/html/_static/language_data.js +++ b/docs/build/html/_static/language_data.js @@ -5,7 +5,7 @@ * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -13,7 +13,8 @@ var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; -/* Non-minified version JS is _stemmer.js if file is provided */ +/* Non-minified version is copied as a separate JS file, is available */ + /** * Porter Stemmer */ @@ -199,7 +200,6 @@ var Stemmer = function() { - var splitChars = (function() { var result = {}; var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648, diff --git a/docs/build/html/_static/pygments.css b/docs/build/html/_static/pygments.css index 1b94522..18cc04d 100644 --- a/docs/build/html/_static/pygments.css +++ b/docs/build/html/_static/pygments.css @@ -1,82 +1,74 @@ -pre { line-height: 125%; margin: 0; } -td.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; } -span.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; } -td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } -.highlight { background: #f8f8f8; } -.highlight .c { color: #8f5902; font-style: italic } /* Comment */ -.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ -.highlight .g { color: #000000 } /* Generic */ -.highlight .k { color: #004461; font-weight: bold } /* Keyword */ -.highlight .l { color: #000000 } /* Literal */ -.highlight .n { color: #000000 } /* Name */ -.highlight .o { color: #582800 } /* Operator */ -.highlight .x { color: #000000 } /* Other */ -.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ -.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #8f5902 } /* Comment.Preproc */ -.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #a40000 } /* Generic.Deleted */ -.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight { background: #f0f0f0; } +.highlight .c { color: #60a0b0; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #745334 } /* Generic.Prompt */ -.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ -.highlight .kc { color: #004461; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #004461; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #004461; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #004461; font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { color: #004461; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #004461; font-weight: bold } /* Keyword.Type */ -.highlight .ld { color: #000000 } /* Literal.Date */ -.highlight .m { color: #990000 } /* Literal.Number */ -.highlight .s { color: #4e9a06 } /* Literal.String */ -.highlight .na { color: #c4a000 } /* Name.Attribute */ -.highlight .nb { color: #004461 } /* Name.Builtin */ -.highlight .nc { color: #000000 } /* Name.Class */ -.highlight .no { color: #000000 } /* Name.Constant */ -.highlight .nd { color: #888888 } /* Name.Decorator */ -.highlight .ni { color: #ce5c00 } /* Name.Entity */ -.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #000000 } /* Name.Function */ -.highlight .nl { color: #f57900 } /* Name.Label */ -.highlight .nn { color: #000000 } /* Name.Namespace */ -.highlight .nx { color: #000000 } /* Name.Other */ -.highlight .py { color: #000000 } /* Name.Property */ -.highlight .nt { color: #004461; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #000000 } /* Name.Variable */ -.highlight .ow { color: #004461; font-weight: bold } /* Operator.Word */ -.highlight .w { color: #f8f8f8; text-decoration: underline } /* Text.Whitespace */ -.highlight .mb { color: #990000 } /* Literal.Number.Bin */ -.highlight .mf { color: #990000 } /* Literal.Number.Float */ -.highlight .mh { color: #990000 } /* Literal.Number.Hex */ -.highlight .mi { color: #990000 } /* Literal.Number.Integer */ -.highlight .mo { color: #990000 } /* Literal.Number.Oct */ -.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ -.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ -.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ -.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ -.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ -.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ -.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ -.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ -.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ -.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ -.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ -.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ -.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #000000 } /* Name.Function.Magic */ -.highlight .vc { color: #000000 } /* Name.Variable.Class */ -.highlight .vg { color: #000000 } /* Name.Variable.Global */ -.highlight .vi { color: #000000 } /* Name.Variable.Instance */ -.highlight .vm { color: #000000 } /* Name.Variable.Magic */ -.highlight .il { color: #990000 } /* Literal.Number.Integer.Long */ \ No newline at end of file +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #40a070 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #40a070 } /* Literal.Number.Bin */ +.highlight .mf { color: #40a070 } /* Literal.Number.Float */ +.highlight .mh { color: #40a070 } /* Literal.Number.Hex */ +.highlight .mi { color: #40a070 } /* Literal.Number.Integer */ +.highlight .mo { color: #40a070 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #40a070 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/docs/build/html/_static/searchtools.js b/docs/build/html/_static/searchtools.js index 261ecaa..1a90152 100644 --- a/docs/build/html/_static/searchtools.js +++ b/docs/build/html/_static/searchtools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for the full-text search. * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -248,7 +248,7 @@ var Search = { // results left, load the summary and display it if (results.length) { var item = results.pop(); - var listItem = $('
  • '); + var listItem = $('
  • '); var requestUrl = ""; var linkUrl = ""; if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') { @@ -273,9 +273,9 @@ var Search = { if (item[3]) { listItem.append($(' (' + item[3] + ')')); Search.output.append(listItem); - listItem.slideDown(5, function() { + setTimeout(function() { displayNextItem(); - }); + }, 5); } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { $.ajax({url: requestUrl, dataType: "text", @@ -285,16 +285,16 @@ var Search = { listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); } Search.output.append(listItem); - listItem.slideDown(5, function() { + setTimeout(function() { displayNextItem(); - }); + }, 5); }}); } else { // no source available, just display title Search.output.append(listItem); - listItem.slideDown(5, function() { + setTimeout(function() { displayNextItem(); - }); + }, 5); } } // search finished, update title and status message @@ -379,6 +379,13 @@ var Search = { return results; }, + /** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions + */ + escapeRegExp : function(string) { + return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + }, + /** * search for full-text terms in the index */ @@ -402,13 +409,14 @@ var Search = { ]; // add support for partial matches if (word.length > 2) { + var word_regex = this.escapeRegExp(word); for (var w in terms) { - if (w.match(word) && !terms[word]) { + if (w.match(word_regex) && !terms[word]) { _o.push({files: terms[w], score: Scorer.partialTerm}) } } for (var w in titleterms) { - if (w.match(word) && !titleterms[word]) { + if (w.match(word_regex) && !titleterms[word]) { _o.push({files: titleterms[w], score: Scorer.partialTitle}) } } diff --git a/docs/build/html/_static/underscore.js b/docs/build/html/_static/underscore.js index 5b55f32..166240e 100644 --- a/docs/build/html/_static/underscore.js +++ b/docs/build/html/_static/underscore.js @@ -1,31 +1,6 @@ -// Underscore.js 1.3.1 -// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Underscore is freely distributable under the MIT license. -// Portions of Underscore are inspired or borrowed from Prototype, -// Oliver Steele's Functional, and John Resig's Micro-Templating. -// For all details and documentation: -// http://documentcloud.github.com/underscore -(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== -c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, -h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= -b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a== -null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= -function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= -e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= -function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, -c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}}; -b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, -1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; -b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; -b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), -function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ -u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= -function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= -true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n=n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){ +// Underscore.js 1.12.0 +// https://underscorejs.org +// (c) 2009-2020 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +var n="1.12.0",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,g=isFinite,d=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u=0&&t<=m}}function $(n){return function(r){return null==r?void 0:r[n]}}var G=$("byteLength"),H=J(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:K(!1),Y=$("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e":">",'"':""","'":"'","`":"`"},Kn=Ln(Cn),Jn=Ln(_n(Cn)),$n=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=0;function Zn(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var nr=j((function(n,r){var t=nr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a1)er(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var cr=nr(fr,2);function lr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o0?0:u-1;o>=0&&o0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),C))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a=3;return r(n,Fn(t,u,4),e,o)}}var wr=_r(1),Ar=_r(-1);function xr(n,r,t){var e=[];return r=qn(r,t),mr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Sr(n,r,t){r=qn(r,t);for(var e=!tr(n)&&nn(n),u=(e||n).length,o=0;o=0}var Er=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),jr(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Br(n,r){return jr(n,Rn(r))}function Nr(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=tr(n)?n:jn(n)).length;ao&&(o=e);else r=qn(r,t),mr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Ir(n,r,t){if(null==r||t)return tr(n)||(n=jn(n)),n[Wn(n.length-1)];var e=tr(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i1&&(e=Fn(e,r[1])),r=an(n)):(e=Pr,r=er(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u1&&(t=r[1])):(r=jr(er(r,!1,!1),String),e=function(n,t){return!Mr(r,t)}),qr(n,e,t)}));function Wr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function zr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:Wr(n,n.length-r)}function Lr(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=er(r,!0,!0),xr(n,(function(n){return!Mr(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);ir?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o=function(r,t){e=null,t&&(u=n.apply(r,t))},i=j((function(i){if(e&&clearTimeout(e),t){var a=!e;e=setTimeout(o,r),a&&(u=n.apply(this,i))}else e=or(o,r,this,i);return u}));return i.cancel=function(){clearTimeout(e),e=null},i},wrap:function(n,r){return nr(r,n)},negate:ar,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:fr,once:cr,findKey:lr,findIndex:pr,findLastIndex:vr,sortedIndex:hr,indexOf:gr,lastIndexOf:dr,find:br,detect:br,findWhere:function(n,r){return br(n,Dn(r))},each:mr,forEach:mr,map:jr,collect:jr,reduce:wr,foldl:wr,inject:wr,reduceRight:Ar,foldr:Ar,filter:xr,select:xr,reject:function(n,r,t){return xr(n,ar(qn(r)),t)},every:Sr,all:Sr,some:Or,any:Or,contains:Mr,includes:Mr,include:Mr,invoke:Er,pluck:Br,where:function(n,r){return xr(n,Dn(r))},max:Nr,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=tr(n)?n:jn(n)).length;ae||void 0===t)return 1;if(t - - - - - - Index — HypixelIO documentation - - - - - - - - - - - + + + + - - - + HypixelIO :: Index -
    -
    -
    + + + + + + + + + + + + + + + + +
    +
    +
    + + -
    - +
    +
    +

    HypixelIO Documentation

    +
    +
    + +
    + +
    +
    +

    Index

    +
    +
    +

    Index

    + _ + | A + | C + | F + | G + | M + | P + | U
    +

    _

    + + +
    +

    A

    + + + +
    -
    - -
    -
    - -
    + +
    + + + + + + + +
    +
    - + + \ No newline at end of file diff --git a/docs/build/html/index.html b/docs/build/html/index.html index 6126523..7a4f6c2 100644 --- a/docs/build/html/index.html +++ b/docs/build/html/index.html @@ -1,111 +1,162 @@ - - - - - - - Welcome to HypixelIO’s documentation! — HypixelIO documentation - - - - - - - - - - - + + + + - - - + HypixelIO :: Welcome to HypixelIO! -
    -
    -
    + + + + + + + + + + + + + + + + +
    +
    +
    + + -
    - -
    -

    Welcome to HypixelIO’s documentation!¶

    +
    +
    +

    HypixelIO Documentation

    +
    +
    + +
    + +
    +
    +

    Welcome to HypixelIO!

    +
    +
    + +
    +

    Welcome to HypixelIO!¶

    +

    HypixelIO is a modern hypixel API wrapper library that suits all your needs. It supports both sync +and async programming, with easy to use features in mind.

    +

    Features

    +
      +
    • Modern way of handling requests

    • +
    • Both async and sync support.

    • +
    • Simple rate handling, and caching.

    • +
    • Speed optimized

    • +
    • Easy to use with a modern and simple design

    • +
    +
    +

    Getting started¶

    +

    Is this your first time using the library? This is the place to get started!

    + +
    +
    +

    Modules and manuals¶

    +

    These pages have info, documentation and help, all you need to learn and use this library!

    -
    -

    Indices and tables¶

    -
    -
    -
    - -
    -
    - + - +
    - - + \ No newline at end of file diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index efdf7d6..3b9759a 100644 Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/search.html b/docs/build/html/search.html index c85d70e..0cf940d 100644 --- a/docs/build/html/search.html +++ b/docs/build/html/search.html @@ -1,110 +1,144 @@ - - - - - - - Search — HypixelIO documentation - - - - - - - - - - - - + + - - + + + HypixelIO :: Search - + + + + + + + + + + + + + + + + + +
    +
    +
    + + + + +
    +
    +

    HypixelIO Documentation

    +
    +
    - - +
    -
    -
    -
    +
    +
    +

    Search

    +
    +
    + -
    - -

    Search

    -
    - -

    - Please activate JavaScript to enable the search - functionality. -

    -
    -

    - Searching for multiple words only shows matches that contain - all words. -

    -
    - - - -
    - +
    -
    - +
    - -
    -
    -
    - - +
    - - + \ No newline at end of file diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index 9818cf7..2812fb2 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["index.rst"],objects:{},objnames:{},objtypes:{},terms:{index:0,modul:0,page:0,search:0},titles:["Welcome to HypixelIO\u2019s documentation!"],titleterms:{document:0,hypixelio:0,indic:0,tabl:0,welcom:0}}) \ No newline at end of file +Search.setIndex({docnames:["api","ext/asyncio/api","index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["api.rst","ext/asyncio/api.rst","index.rst"],objects:{"hypixelio.Client":{find_guild:[0,1,1,""],get_boosters:[0,1,1,""],get_friends:[0,1,1,""],get_games_info:[0,1,1,""],get_guild:[0,1,1,""],get_key_info:[0,1,1,""],get_leaderboards:[0,1,1,""],get_player:[0,1,1,""],get_player_recent_games:[0,1,1,""],get_player_status:[0,1,1,""],get_skyblock_active_auctions:[0,1,1,""],get_skyblock_bazaar:[0,1,1,""],get_skyblock_profile:[0,1,1,""],get_skyblock_user_auctions:[0,1,1,""],get_watchdog_info:[0,1,1,""]},"hypixelio.Converters":{url:[0,2,1,""],username_to_uuid:[0,1,1,""],uuid_to_username:[0,1,1,""]},"hypixelio.Utils":{get_avatar:[0,1,1,""],get_body:[0,1,1,""],get_head:[0,1,1,""],get_name_history:[0,1,1,""],mojang_url:[0,2,1,""],url:[0,2,1,""]},"hypixelio.ext.asyncio":{AsyncClient:[1,0,1,""],AsyncConverters:[1,0,1,""],Utils:[1,0,1,""]},"hypixelio.ext.asyncio.AsyncClient":{close:[1,1,1,""],find_guild:[1,1,1,""],get_boosters:[1,1,1,""],get_friends:[1,1,1,""],get_games_info:[1,1,1,""],get_guild:[1,1,1,""],get_key_info:[1,1,1,""],get_leaderboards:[1,1,1,""],get_player:[1,1,1,""],get_player_recent_games:[1,1,1,""],get_player_status:[1,1,1,""],get_skyblock_active_auctions:[1,1,1,""],get_skyblock_bazaar:[1,1,1,""],get_skyblock_profile:[1,1,1,""],get_skyblock_user_auctions:[1,1,1,""],get_watchdog_info:[1,1,1,""]},"hypixelio.ext.asyncio.AsyncConverters":{url:[1,2,1,""],username_to_uuid:[1,1,1,""],uuid_to_username:[1,1,1,""]},"hypixelio.ext.asyncio.Utils":{get_avatar:[1,1,1,""],get_body:[1,1,1,""],get_head:[1,1,1,""],get_name_history:[1,1,1,""],mojang_url:[1,2,1,""],url:[1,2,1,""]},hypixelio:{Client:[0,0,1,""],Converters:[0,0,1,""],Utils:[0,0,1,""],__version__:[0,3,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","data","Python data"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute","3":"py:data"},terms:{"000":[0,1],"0b1":0,"123":[0,1],"2020":[],"440":0,"456":[0,1],"568":[0,1],"789":[0,1],"908":[0,1],"class":[0,1],"default":[0,1],"function":[0,1],"import":[0,1],"int":[0,1],"new":[0,1],"public":[],"return":[0,1],"true":[0,1],Added:[],And:0,For:0,The:[0,1],Their:[0,1],There:0,These:2,Use:[],__author__:[],__repr__:[],__str__:[],__version__:0,about:[0,1],accept:[],access:[0,1],accord:[],account:[0,1],activ:[0,1],active_auct:[0,1],add:[],added:[],adher:[],again:[],aiohttp:1,all:[0,1,2],allow:[],along:[0,1],api:2,api_error:[],api_kei:[0,1],argument:[],async:[1,2],asynccli:1,asyncconvert:1,asyncio:[1,2],attribut:[0,1],auction:[0,1],authent:[0,1],avail:[0,2],avatar:[0,1],backend:0,balanc:[0,1],ban:[0,1],base:0,basic:[],bazaar:[0,1],being:[0,1],better:[0,1],bodi:[0,1],bool:[0,1],booster:[0,1],both:2,bug:[],build:[],cach:[0,2],cache_cfg:0,cache_config:0,cache_nam:0,cachebackend:0,certain:[0,1],chang:[0,1],changed_at:[0,1],changelog:[],check:0,classmethod:[0,1],clean:[],clear:[],client:[],close:1,code:[],coin:[0,1],com:[],command:[0,1],comparison:[],configur:0,connect:0,constant:[],contain:[0,1],convers:[0,1],convert:[],coroutin:[],creat:0,dai:[0,1],data:[0,1],dataclass:[],depend:[],depict:[0,1],design:2,dict:[0,1],dictionari:[0,1],differ:[],direct:[],docstr:[],document:2,due:[],dure:[],each:[0,1],easi:2,either:[0,1],enabl:0,end:[0,1],error:[],exampl:[0,1,2],except:[],exists:[],experi:[],expir:[0,1],expire_aft:0,explain:[],ext:[1,2],fals:[0,1],featur:2,fetch:[],few:[0,1],file:0,find:[0,1],find_guild:[0,1],findguild:[0,1],first:[1,2],fix:[],format:[],friend:[0,1],from:[0,1],game:[0,1],gamecount:[],gener:[0,1],get:[0,1],get_avatar:[0,1],get_bodi:[0,1],get_boost:[0,1],get_friend:[0,1],get_games_info:[0,1],get_guild:[0,1],get_head:[0,1],get_key_info:[0,1],get_leaderboard:[0,1],get_name_histori:[0,1],get_play:[0,1],get_player_recent_gam:[0,1],get_player_statu:[0,1],get_skyblock_active_auct:[0,1],get_skyblock_auct:[],get_skyblock_bazaar:[0,1],get_skyblock_profil:[0,1],get_skyblock_user_auct:[0,1],get_watchdog_info:[0,1],github:[],global:[0,1],guild:[0,1],guild_nam:[0,1],handl:[0,1,2],has:[0,1],have:[0,1,2],head:[0,1],help:2,here:[0,1],high:[],his:[0,1],histori:[0,1],host:0,how:[0,1],html:[],http:[],hypixel:[0,1,2],hypixelio:[0,1],imag:[0,1],improv:[],index:[],info:[1,2],inform:[0,1],inherit:[],instanc:[],integr:[],intern:[],invalid:[],issu:[],item:[0,1],its:[0,1],itself:[],janasunris:[],keep:[0,1],keepachangelog:[],kei:[0,1],last:[0,1],leaderboard:[0,1],leak:1,learn:2,librari:[0,2],like:[],link:[],list:[0,1],load:[0,1],look:[],lookup:[0,1],lot:[],main:[],make:[],mani:2,manifest:[],memori:1,method:[0,1],mind:[0,1,2],minecraft:[0,1],model:[0,1],modern:2,modul:[],modular:[],mojang_url:[0,1],mojangapierror:[],more:[],move:[],multipl:[0,1],multithread:[],name:[0,1],name_histori:[0,1],need:[0,1,2],none:[0,1],notabl:[],note:[0,1],obj1:[],obj2:[],object:[0,1],off:0,opt:0,optim:2,option:[0,1],org:[],other:[],out:[],over:[],overrid:[],packag:[],page:[0,1,2],paramet:[0,1],pass:[0,1],pep:0,perform:[],place:2,plai:[0,1],player:[0,1],player_statu:[0,1],player_uuid:[0,1],playerstatu:[0,1],port:0,prevent:1,process:[],product:[0,1],profil:[0,1],program:2,project:[],rais:[],rank:[0,1],rate:2,recent:[0,1],recent_gam:[0,1],recentgam:[0,1],record:[0,1],redi:0,refactor:[],refer:2,relat:[],releas:[],remov:[],render:[0,1],repo:[],repositori:2,repres:[0,1],represent:0,request:[0,1,2],requir:[0,1],resourc:2,respect:[0,1],rewrot:[],search:[],secur:[],self:[],semant:[],semver:[],session:1,setup:[],sever:[],simpl:2,singl:[0,1],skin:[0,1],skyblock:[0,1],skyblock_bazaar:[0,1],skyblockactiveauct:[0,1],skyblockbazaar:[0,1],skyblockprofil:[0,1],skyblockuserauct:[0,1],small:[],some:[],someth:[],sourc:[0,1],space:[],spec:[],specif:[0,1],specifi:[0,1],speed:2,split:[],sqlite:0,stat:[0,1],statu:[0,1],store:[],str:[0,1],string:[0,1],style:[],suit:2,support:2,sync:2,synchron:[],tag:[],task:[],than:[],thei:[0,1],them:[],thi:[0,1,2],thing:[0,1],time:2,timeout:[],toggl:[0,1],took:[],tupl:[],txt:[],type:[0,1],typo:[],uninstal:[],union:[0,1],uniqu:[],url:[0,1],usag:[0,1],use:[0,1,2],used:[],useless:[],user:[0,1],user_auct:[0,1],usernam:[0,1],username_to_uuid:[0,1],using:[0,1,2],util:[],uuid:[0,1],uuid_to_usernam:[0,1],valid:[],valu:[0,1],variabl:[],variou:[],version:[],wai:[0,2],want:0,watchdog:[0,1],well:[],when:[0,1],which:[0,1],whitespac:[],whole:[0,1],work:[0,1],wouldn:[0,1],wrapper:[0,1,2],you:[0,1,2],your:[0,1,2]},titles:["API Reference","API Reference","Welcome to HypixelIO!"],titleterms:{api:[0,1],changelog:[],client:[0,1],convert:[0,1],document:[],get:2,hypixelio:2,indic:[],info:0,manual:2,meta:[],modul:2,refer:[0,1],relat:0,start:2,tabl:[],util:[0,1],version:0,welcom:2}}) \ No newline at end of file diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 0000000..ac2f740 --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,44 @@ +.. currentmodule:: hypixelio + +API Reference +============= + +Version Related Info +--------------------- + +There is a single way to check the version for this library. + +.. data:: __version__ + + A string representation of the version. e.g. ``'0.1.0b1'``. This is based + off of :pep:`440`. + +Clients +------- + +Client +~~~~~~ + +.. autoclass:: Client + :members: + :undoc-members: + +Converters +---------- + +Converter +~~~~~~~~~ + +.. autoclass:: Converters + :members: + :undoc-members: + +Utility +------- + +Utils +~~~~~ + +.. autoclass:: Utils + :members: + :undoc-members: diff --git a/docs/source/conf.py b/docs/source/conf.py index b19a691..b601c7c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,3 +1,5 @@ +import re + # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full @@ -18,9 +20,16 @@ # -- Project information ----------------------------------------------------- project = 'HypixelIO' -copyright = '2020, Sunrit Jana' +copyright = '2021, Sunrit Jana' author = 'Sunrit Jana' +version = '' + +# -- Version config -- +with open('../../hypixelio/__init__.py') as f: + version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) +release = version + # -- General configuration --------------------------------------------------- @@ -28,15 +37,32 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'recommonmark' + "recommonmark", + "sphinx.ext.intersphinx", + "sphinx.ext.autodoc", + "sphinx.ext.mathjax", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", ] +napoleon_google_docstring = False +napoleon_use_param = False +napoleon_use_ivar = True + +extlinks = { + 'issue': ('https://github.com/janaSunrise/HypixelIO/issues/%s', 'GH-'), +} + source_suffix = { '.rst': 'restructuredtext', '.txt': 'markdown', '.md': 'markdown', } +html_theme_options = { + 'wending_last_updated': False, +} + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -51,7 +77,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'insegel' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, diff --git a/docs/source/ext/asyncio/api.rst b/docs/source/ext/asyncio/api.rst new file mode 100644 index 0000000..a3757a9 --- /dev/null +++ b/docs/source/ext/asyncio/api.rst @@ -0,0 +1,34 @@ +.. currentmodule:: hypixelio + +API Reference +============= + +Clients +------- + +Client +~~~~~~ + +.. autoclass:: hypixelio.ext.asyncio.AsyncClient + :members: + :undoc-members: + +Converters +---------- + +Converter +~~~~~~~~~ + +.. autoclass:: hypixelio.ext.asyncio.AsyncConverters + :members: + :undoc-members: + +Utility +------- + +Utils +~~~~~ + +.. autoclass:: hypixelio.ext.asyncio.Utils + :members: + :undoc-members: diff --git a/docs/source/index.rst b/docs/source/index.rst index 23987fd..1b51305 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,20 +1,32 @@ -.. HypixelIO documentation master file, created by - sphinx-quickstart on Fri Nov 13 13:33:46 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to HypixelIO's documentation! +Welcome to HypixelIO! ===================================== -.. toctree:: - :maxdepth: 2 - :caption: Contents: +HypixelIO is a modern hypixel API wrapper library that suits all your needs. It supports both sync +and async programming, with easy to use features in mind. + +**Features** + +- Modern way of handling requests +- Both async and sync support. +- Simple rate handling, and caching. +- Speed optimized +- Easy to use with a modern and simple design + +Getting started +----------------- +Is this your first time using the library? This is the place to get started! +- **Examples:** Many examples are available in the :resource:`repository `. -Indices and tables -================== -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +Modules and manuals +------------------- + +These pages have info, documentation and help, all you need to learn and use this library! + +.. toctree:: + :maxdepth: 1 + + api + hypixelio.ext.asyncio reference diff --git a/examples/get-watchdog-stats.py b/examples/get-watchdog-stats.py index ccce085..ff57752 100644 --- a/examples/get-watchdog-stats.py +++ b/examples/get-watchdog-stats.py @@ -12,7 +12,7 @@ # Extract the Data last_minute_ban = watchdog.LAST_MINUTE_BAN total_bans = watchdog.TOTAL_BANS -rolling_daily = watchdog.WATCHDOG_ROLLING_DAILY +rolling_daily = watchdog.ROLLING_DAILY # Display the data print( diff --git a/hypixelio/__init__.py b/hypixelio/__init__.py index cbfe6e1..7998f91 100644 --- a/hypixelio/__init__.py +++ b/hypixelio/__init__.py @@ -1,9 +1,20 @@ +import typing as t + from hypixelio.lib import Client, Converters, Utils from hypixelio.models.caching import CacheBackend, Caching from hypixelio.utils import constants __author__ = "Sunrit Jana" __email__ = "warriordefenderz@gmail.com" -__version__ = "1.1.1" -__licence__ = "GPL-3.0 License" -__copyright__ = "Copyright 2020 Sunrit Jana" +__version__ = "1.2.0" +__license__ = "GPL-3.0 License" +__copyright__ = "Copyright 2021 Sunrit Jana" + +__all__: t.Tuple[str, ...] = ( + "Caching", + "CacheBackend", + "Client", + "Converters", + "Utils", + "constants" +) diff --git a/hypixelio/endpoints.py b/hypixelio/endpoints.py new file mode 100644 index 0000000..ccc9e93 --- /dev/null +++ b/hypixelio/endpoints.py @@ -0,0 +1,32 @@ +"""List of all the various endpoint paths.""" + +API_PATH = { + "HYPIXEL": { + "api_key": "/key", + "boosters": "/boosters", + "player": "/player", + "friends": "/friends", + "watchdog": "/watchdogstats", + "guild": "/guild", + "game_info": "/gameCounts", + "leaderboards": "/leaderboards", + "find_guild": "/findGuild", + "status": "/status", + "recent_games": "/recentgames", + "skyblock_auctions": "/skyblock/auction", + "skyblock_active_auctions": "/skyblock/auctions", + "skyblock_bazaar": "/skyblock/bazaar", + "skyblock_profile": "/skyblock/profile" + }, + "MOJANG": { + "username_to_uuid": "/users/profiles/minecraft/{}", + "uuid_to_username": "/user/profiles/{}/names", + "name_history": "/user/profiles/{}/names", + }, + "CRAFATAR": { + "avatar": "/avatars/{}", + "head": "/renders/head/{}", + "body": "/renders/body/{}", + "skins": "/skins/{}" + } +} diff --git a/hypixelio/exceptions/exceptions.py b/hypixelio/exceptions/exceptions.py index 1a165cf..b1a7dbf 100644 --- a/hypixelio/exceptions/exceptions.py +++ b/hypixelio/exceptions/exceptions.py @@ -6,16 +6,18 @@ import typing as t +class InvalidArgumentError(Exception): + """Raised when there is Invalid argument, or Any argument is not specified.""" + + class HypixelAPIError(Exception): - """ - Raised When the Hypixel API is facing some problems. - """ + """Raised When the Hypixel API is facing some problems.""" def __init__(self, reason: str = "undefined") -> None: """ - Constructor for the HypixelAPIError Exception. - - Args: - reason (str, optional): The reason for the Error. Defaults to "undefined". + Parameters + ---------- + reason: str + The reason for the Error. Defaults to "undefined". """ self.err = f"The Hypixel API had a problem [{reason}]" super().__init__(self.err) @@ -25,15 +27,13 @@ def __str__(self) -> str: class CrafatarAPIError(Exception): - """ - Raised When the Hypixel API is facing some problems. - """ + """Raised When the Crafatar API is facing some problems.""" def __init__(self, reason: str = "undefined") -> None: """ - Constructor for the HypixelAPIError Exception. - - Args: - reason (str, optional): The reason for the Error. Defaults to "undefined". + Parameters + ---------- + reason: str + The reason for the Error. Defaults to "undefined". """ self.err = f"The CrafatarAPI had a problem [{reason}]" super().__init__(self.err) @@ -43,15 +43,13 @@ def __str__(self) -> str: class RateLimitError(Exception): - """ - Raised When the Hypixel API Rate limit is hit. - """ + """Raised When the Hypixel API Rate limit is hit.""" def __init__(self, reason: str = "undefined") -> None: """ - Constructor for the RateLimitError exception. - - Args: - reason (str, optional): The reason for the Error. Defaults to "undefined". + Parameters + ---------- + reason: str + The reason for the Error. Defaults to "undefined". """ self.err = f"You just hit the Rate Limit for the Hypixel API [{reason}]" super().__init__(self.err) @@ -61,16 +59,15 @@ def __str__(self) -> str: class PlayerNotFoundError(Exception): - """ - Raised When the Specified Player is not found. - """ + """Raised When the Specified Player is not found.""" def __init__(self, reason: str, user: t.Optional[str]) -> None: """ - The constructor for the PlayerNotFoundError exception. - - Args: - reason (str): The reason for the error. - user (t.Optional[str]): The user searched for, but not found. + Parameters + ---------- + reason: str + The reason for the error. + user: t.Optional[str] + The user searched for, but not found. """ self.err = "Invalid Player Name!" super().__init__(self.err) @@ -83,15 +80,13 @@ def __str__(self) -> str: class GuildNotFoundError(Exception): - """ - Raised When the Specified Guild is not found. - """ + """Raised When the Specified Guild is not found.""" def __init__(self, reason: str = "undefined") -> None: """ - The constructor for the GuildNotFoundError exception. - - Args: - reason (str, optional): The reason for the Error. Defaults to "undefined". + Parameters + ---------- + reason: str + The reason for the Error. Defaults to "undefined". """ self.err = f"Invalid Guild Name or UUID! [{reason}]" super().__init__(self.err) @@ -100,21 +95,14 @@ def __str__(self) -> str: return self.err -class InvalidArgumentError(Exception): - """Raised when there is Invalid argument, or Any argument is not specified.""" - pass - - class MojangAPIError(Exception): - """ - Raised When the Mojang API is facing some problems. - """ + """Raised when the Mojang API is facing some problems.""" def __init__(self, reason: str = "undefined") -> None: """ - The constructor for the MojanAPIError Exception. - - Args: - reason (str, optional): The reason for the Error. Defaults to "undefined". + Parameters + ---------- + reason: str + The reason for the Error. Defaults to "undefined". """ self.err = f"The Mojang API had a problem [{reason}]" super().__init__(self.err) diff --git a/hypixelio/ext/__init__.py b/hypixelio/ext/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hypixelio/ext/asyncio/__init__.py b/hypixelio/ext/asyncio/__init__.py new file mode 100644 index 0000000..8fda3b2 --- /dev/null +++ b/hypixelio/ext/asyncio/__init__.py @@ -0,0 +1,3 @@ +from .client import AsyncClient +from .converters import AsyncConverters +from .utils import Utils diff --git a/hypixelio/ext/asyncio/client.py b/hypixelio/ext/asyncio/client.py new file mode 100644 index 0000000..fc0d66d --- /dev/null +++ b/hypixelio/ext/asyncio/client.py @@ -0,0 +1,427 @@ +import random +import typing as t + +import aiohttp + +from hypixelio.endpoints import API_PATH +from hypixelio.exceptions import ( + GuildNotFoundError, + HypixelAPIError, + InvalidArgumentError, + PlayerNotFoundError, + RateLimitError, +) +from hypixelio.lib.converters import Converters +from hypixelio.models import ( + boosters, + find_guild, + friends, + games, + guild, + key, + leaderboard, + player, + player_status, + recent_games, + skyblock, + watchdog +) +from hypixelio.utils.constants import ( + HYPIXEL_API, + TIMEOUT, +) +from hypixelio.utils.helpers import ( + form_url +) + + +class AsyncClient: + """The client for this wrapper, that handles the requests, authentication, loading and usages of the end user. + + Examples + -------- + Import the async client first. + + >>> from hypixelio.ext.asyncio import AsyncClient + + If you have a single API key, Here's how to authenticate + + >>> client = AsyncClient(api_key="123-456-789") + + Or, If you have multiple API keys (Better option for load balancing) + + >>> client = AsyncClient(api_key=["123-456", "789-000", "568-908"]) + + Notes + ----- + Keep in mind that, your keys wouldn't work if you're banned from hypixel, or if they're expired. + """ + def __init__(self, api_key: t.Union[str, list]) -> None: + """ + Parameters + ---------- + api_key: `t.Union[str, list]` + The API Key generated in Hypixel using `/api new` command. + """ + self.url = API_PATH["HYPIXEL"] + + self.session = aiohttp.ClientSession() + + if not isinstance(api_key, list): + self.api_key = [api_key] + + async def close(self) -> None: + """Close the AIOHTTP sessions to prevent memory leaks.""" + await self.session.close() + + async def _fetch(self, url: str, data: dict = None) -> t.Tuple[dict, bool]: + """ + Get the JSON Response from the Root Hypixel API URL, and also add the ability to include the GET request + parameters with the API KEY Parameter by default. + + Parameters + ---------- + url: `str` + The URL to be accessed from the Root Domain. + data: `t.Optional[dict]` + The GET Request's Key-Value Pair. Example: {"uuid": "abc"} is converted to `?uuid=abc`. Defaults to None. + + Returns + ------- + `t.Tuple[dict, bool]` + The JSON Response from the Fetch Done to the API and the SUCCESS Value from the Response. + """ + if not data: + data = {} + + headers = {"API-Key": random.choice(self.api_key)} + + url = form_url(HYPIXEL_API, url, data) + + async with self.session.get(url, timeout=TIMEOUT, headers=headers) as response: + if response.status == 429: + raise RateLimitError("Out of Requests!") + + try: + json = await response.json() + except Exception as exception: + raise HypixelAPIError(f"{exception}") + else: + if not json["success"]: + reason = "The Key given is invalid, or something else has problem." + if json["cause"] is not None: + reason += f" Reason given: {json['cause']}" + + raise HypixelAPIError(reason=reason) + + return json + + @staticmethod + def _filter_name_uuid(name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + if not name and not uuid: + raise InvalidArgumentError("Please provide a named argument of the player's username or player's UUID.") + + if name: + uuid = Converters.username_to_uuid(name) + + return uuid + + async def get_key_info(self, api_key: t.Optional[str] = None) -> key.Key: + """ + Get the Info about an API Key generated in Hypixel. + + Parameters + ---------- + api_key: `t.Optional[str]` + The API Key generated in Hypixel using `/api new` command. Defaults to None. + + Returns + ------- + `key.Key` + Key object for the API Key. + """ + if not api_key: + api_key = random.choice(self.api_key) + + json = await self._fetch(self.url["api_key"], {"key": api_key}) + return key.Key(json["record"]) + + async def get_boosters(self) -> boosters.Boosters: + """ + Get the List of Hypixel Coin Boosters and Their Info. + + Returns + ------- + `boosters.Boosters` + The Booster class object which depicts the booster data model. + """ + json = await self._fetch(self.url["boosters"]) + + return boosters.Boosters(json["boosters"], json) + + async def get_player(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> player.Player: + """ + Get the Info about a Hypixel Player using either his Username or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `player.Player` + The Player Class Object, Which depicts the Player Data Model + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["player"], {"uuid": uuid}) + + if not json["player"]: + raise PlayerNotFoundError("Null Value is returned", name) + + return player.Player(json["player"]) + + async def get_friends(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> friends.Friends: + """ + Get the List of Friends of a Hypixel Player and their Info. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username of a hypixel player.. Defaults to None. + uuid: `t.Optional[str]` + The UUID of a Certain Hypixel Player. Defaults to None. + + Returns + ------- + `friends.Friends` + Returns the Friend Data Model, Which has the List of Friends, each with a list of attributes. + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["friends"], {"uuid": uuid}) + + return friends.Friends(json["records"]) + + async def get_watchdog_info(self) -> watchdog.Watchdog: + """ + Get the List of Stats About the Watchdog for the last few days. + + Returns + ------- + `watchdog.Watchdog` + The Watchdog data model with certain important attributes for you to get data about the things by watchdog. + """ + json = await self._fetch(self.url["watchdog"]) + + return watchdog.Watchdog(json) + + async def get_guild(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> guild.Guild: + """ + Get the info about a Hypixel Guild, Either using Name or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Name of the Guild. Defaults to None. + uuid: `t.Optional[str]` + The ID Of the guild. Defaults to None. + + Returns + ------- + `guild.Guild` + The Guild Object with certain Attributes for you to access, and use it. + """ + if uuid: + json = await self._fetch(self.url["guild"], {"id": uuid}) + elif name: + json = await self._fetch(self.url["guild"], {"name": name}) + else: + raise InvalidArgumentError("Please provide a Named argument of the guild's Name or guild's ID.") + + if not json["guild"]: + raise GuildNotFoundError("Return Value is null") + return guild.Guild(json["guild"]) + + async def get_games_info(self) -> games.Games: + """ + Get the List of Hypixel Games and Their Info. + + Returns + ------- + `games.Games` + The Games Data model, Containing the information, and attributes for all the games. + """ + json = await self._fetch(self.url["game_info"]) + + return games.Games(json["games"], json["playerCount"]) + + async def get_leaderboards(self) -> leaderboard.Leaderboard: + """ + Get the Leaderboard for all the games, along with the data in it. + + Returns + ------- + `leaderboard.Leaderboard` + The Leaderboard data model, containing all the ranking for the games in Hypixel. + """ + json = await self._fetch(self.url["leaderboards"]) + + return leaderboard.Leaderboard(json["leaderboards"]) + + async def find_guild( + self, guild_name: t.Optional[str] = None, player_uuid: t.Optional[str] = None + ) -> find_guild.FindGuild: + """ + Finds the Guild By the Guild's Name or using a Player's UUID + + Parameters + ---------- + guild_name: `t.Optional[str]` + The name of the Guild. Defaults to None. + player_uuid: `t.Optional[str]` + The UUID of the Player to find his guild. Defaults to None. + + Returns + ------- + `find_guild.FindGuild` + The ID of the guild being find. + """ + if guild_name: + json = await self._fetch(self.url["find_guild"], {"byName": guild_name}) + elif player_uuid: + json = await self._fetch(self.url["find_guild"], {"byUuid": player_uuid}) + else: + raise InvalidArgumentError("Please provide a Named argument of the guild's Name or guild's ID.") + + return find_guild.FindGuild(json) + + async def get_player_status( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> player_status.PlayerStatus: + """ + Get the Status info about a Hypixel Player using either his Username or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `player_status.PlayerStatus` + The Player Status Object, which depicts the Player's status + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["status"], {"uuid": uuid}) + + return player_status.PlayerStatus(json) + + async def get_player_recent_games( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> recent_games.RecentGames: + """ + Get the recent games played by a Hypixel Player using either his Username or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `recent_games.RecentGames` + The recent games model for the respective player specified. + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["recent_games"], {"uuid": uuid}) + + return recent_games.RecentGames(json) + + async def get_skyblock_profile( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> skyblock.SkyblockProfile: + """ + Get the skyblock information and profile about a specific user as passed in the requirements. + + Parameters + ---------- + name: `str` + The player's name in Hypixel + uuid: `str` + The player's global UUID + + Returns + ------- + `skyblock.SkyblockProfile` + The skyblock profile model for the user. + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["skyblock_profile"], {"profile": uuid}) + + if not json["profile"]: + raise PlayerNotFoundError("The skyblock player being searched does not exist!", uuid) + + return skyblock.SkyblockProfile(json) + + async def get_skyblock_user_auctions( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> skyblock.SkyblockUserAuction: + """ + Get the skyblock auction info about a specific user as passed in the requirements. + + Parameters + ---------- + name: `str` + The player's name in Hypixel + uuid: `str` + The player's global UUID + + Returns + ------- + `skyblock.SkyblockUserAuction` + The skyblock auction model for the user. + """ + uuid = self._filter_name_uuid(name, uuid) + json = await self._fetch(self.url["skyblock_auctions"], {"profile": uuid}) + + if not json["auctions"]: + raise PlayerNotFoundError("The skyblock player being searched does not exist!", uuid) + + return skyblock.SkyblockUserAuction(json) + + async def get_skyblock_active_auctions( + self, page: int = 0 + ) -> skyblock.SkyblockActiveAuction: + """ + Get the list of active auctions in skyblock and use the data. + + Parameters + ---------- + page: int + The skyblock auction page to lookup. + + Returns + ------- + skyblock.SkyblockActiveAuction + The active auction model. + """ + json = await self._fetch(self.url["skyblock_active_auctions"], {"page": page}) + return skyblock.SkyblockActiveAuction(json) + + async def get_skyblock_bazaar(self) -> skyblock.SkyblockBazaar: + """ + Get the skyblock bazaar items + + Returns + ------- + skyblock.SkyblockBazaar + The bazaar model object representing each product. + """ + json = await self._fetch(self.url["skyblock_bazaar"]) + return skyblock.SkyblockBazaar(json) diff --git a/hypixelio/ext/asyncio/converters.py b/hypixelio/ext/asyncio/converters.py new file mode 100644 index 0000000..7381eee --- /dev/null +++ b/hypixelio/ext/asyncio/converters.py @@ -0,0 +1,91 @@ +import typing as t + +import aiohttp + +from hypixelio.endpoints import API_PATH +from hypixelio.exceptions.exceptions import ( + MojangAPIError, + PlayerNotFoundError +) +from hypixelio.utils.constants import ( + MOJANG_API, + TIMEOUT +) + + +class AsyncConverters: + url = API_PATH["MOJANG"] + + @classmethod + async def _fetch(cls, url: str) -> t.Optional[dict]: + """ + This is the internal function for fetching the JSON from the Mojang API. + + Parameters + ---------- + url: `str` + The Mojang URL, whose JSON is supposed to be fetched. + + Returns + ------- + `t.Optional[dict]` + The JSON response from the Mojang API, Which is returned. + """ + session = aiohttp.ClientSession() + + async with session.get(f"{MOJANG_API}{url}", timeout=TIMEOUT) as response: + if response.status == 204: + raise PlayerNotFoundError("204 value returned during conversion to UUID.", None) + + if response.status == 400: + raise PlayerNotFoundError("Badly formed UUID error.", None) + + try: + json = await response.json() + except Exception: + raise MojangAPIError("There seems to be some problem with the content type or the API is down.") + else: + if "error" in json: + raise MojangAPIError(f"An error occurred! {json['errorMessage']}") + + return json + + await session.close() + + @classmethod + async def username_to_uuid(cls, username: str) -> str: + """ + This is a method, to convert username in minecraft, for its respective UUID. + + Parameters + ---------- + username: `str` + This is the minecraft user, which is passed to this function for the UUID Conversion. + + Returns + ------- + `str` + returns the converted UUID for the respective username. + """ + json = await AsyncConverters._fetch(AsyncConverters.url["username_to_uuid"].format(username)) + + return json["id"] + + @classmethod + async def uuid_to_username(cls, uuid: str) -> str: + """ + This is the function that converts the UUID for your profile, to the Username for your Minecraft account. + + Parameters + ---------- + uuid: `str` + This is the minecraft UUID, which is passed to this function for the UUID to username Conversion. + + Returns + ------- + `str` + The username for the respective minecraft UUID is returned. + """ + json = await AsyncConverters._fetch(AsyncConverters.url["uuid_to_username"].format(uuid)) + + return json[-1]["name"] diff --git a/hypixelio/ext/asyncio/utils.py b/hypixelio/ext/asyncio/utils.py new file mode 100644 index 0000000..f69422b --- /dev/null +++ b/hypixelio/ext/asyncio/utils.py @@ -0,0 +1,174 @@ +import typing as t + +import aiohttp + +from hypixelio.endpoints import API_PATH +from hypixelio.exceptions.exceptions import ( + CrafatarAPIError, + InvalidArgumentError, +) +from hypixelio.ext.asyncio.converters import ( + AsyncConverters as Converters +) +from hypixelio.utils.constants import ( + TIMEOUT +) + + +class Utils: + mojang_url = API_PATH["MOJANG"] + url = API_PATH["CRAFATAR"] + + @classmethod + async def _crafatar_fetch(cls, url: str) -> t.Any: + """ + This is the function for fetching the JSON from the Crafatar API. + + Parameters + ---------- + url: `str` + The Crafatar URL, whose JSON is supposed to be fetched. + + Returns + ------- + `t.Optional[dict]` + The JSON response from the Crafatar API, which is returned. + """ + session = aiohttp.ClientSession() + + async with session.get(f"https://crafatar.com/{url}", timeout=TIMEOUT) as response: + if response.status == 422: + raise InvalidArgumentError("Invalid data passed for conversion!") + + try: + return await response.text() + except Exception: + raise CrafatarAPIError("There seems to be some problem with the content type or the API IS down.") + + await session.close() + + @staticmethod + def _filter_name_uuid(name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + if not name and not uuid: + raise InvalidArgumentError("Please provide a named argument of the player's username or player's UUID.") + + if name: + uuid = Converters.username_to_uuid(name) + + return uuid + + @classmethod + def _form_crafatar_url(cls, route: str) -> str: + """ + This function forms the crafatar API URL for fetching USER skins. + + Parameters + ---------- + route: `str` + The URL path to visit. + + Returns + ------- + `str` + The well formed API URL for fetching. + """ + return f"https://crafatar.com{route}" + + @classmethod + async def get_name_history( + cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None, changed_at: bool = False + ) -> t.Union[list, dict]: + """ + This get the name history with records of a player. + + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + changed_at: `bool` + Toggle to true, if you need when the player changed name. Defaults to False. + + Returns + ------- + `t.Union[list, dict]` + The list or dictionary with the name history and records. + """ + uuid = cls._filter_name_uuid(name, uuid) + json = await Converters._fetch(Utils.mojang_url["name_history"].format(uuid)) + + if changed_at: + return json + + usernames = [] + for data in json: + usernames.append(data["name"]) + + return usernames + + @classmethod + async def get_avatar(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + """ + Get the avatar of the specified player + + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the avatar. + """ + uuid = cls._filter_name_uuid(name, uuid) + await Utils._crafatar_fetch(Utils.url["avatar"].format(uuid)) + + return Utils._form_crafatar_url(Utils.url["avatar"].format(uuid)) + + @classmethod + async def get_head(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + """ + Get the head skin of the specified player + + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the head. + """ + uuid = cls._filter_name_uuid(name, uuid) + await Utils._crafatar_fetch(Utils.url["head"].format(uuid)) + + return Utils._form_crafatar_url(Utils.url["head"].format(uuid)) + + @classmethod + async def get_body(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + """ + Get the whole body's skin of the specified player + + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the whole body. + """ + uuid = cls._filter_name_uuid(name, uuid) + await Utils._crafatar_fetch(Utils.url["body"].format(uuid)) + + return Utils._form_crafatar_url(Utils.url["body"].format(uuid)) diff --git a/hypixelio/lib/client.py b/hypixelio/lib/client.py index d6ba986..815f250 100644 --- a/hypixelio/lib/client.py +++ b/hypixelio/lib/client.py @@ -4,6 +4,7 @@ import requests import requests_cache +from hypixelio.endpoints import API_PATH from hypixelio.exceptions import ( GuildNotFoundError, HypixelAPIError, @@ -11,6 +12,7 @@ PlayerNotFoundError, RateLimitError, ) +from hypixelio.lib.converters import Converters from hypixelio.models import ( boosters, caching, @@ -21,6 +23,9 @@ key, leaderboard, player, + player_status, + recent_games, + skyblock, watchdog ) from hypixelio.utils.constants import ( @@ -33,23 +38,52 @@ class Client: - """ - This Client Contains the Authentication, and Request system for the Hypixel API. + """The client for this wrapper, that handles the requests, authentication, loading and usages of the end user. + + Examples + -------- + If you have a single API key, Here's how to authenticate + + >>> client = hypixelio.Client(api_key="123-456-789") + + Or, If you have multiple API keys (Better option for load balancing) + + >>> client = hypixelio.Client(api_key=["123-456", "789-000", "568-908"]) + + If you want to enable caching, Here's how to do it + >>> client = hypixelio.Client(cache=True) + + And configuring cache + >>> from hypixelio.models.caching import Caching, CacheBackend + >>> cache_cfg = Caching(cache_name="my-cache", backend=CacheBackend.sqlite, expire_after=10) + >>> client = hypixelio.Client(cache=True, cache_config=cache_cfg) + + Notes + ----- + Keep in mind that, your keys wouldn't work if you're banned from hypixel, or if they're expired. + And if you opt for redis, it connects with the default port and host available. For sqlite it + creates a `.db` file. """ def __init__(self, api_key: t.Union[str, list], cache: bool = False, cache_config: caching.Caching = None) -> None: """ - The constructor for the `Client` class. - - Args: - api_key (t.Union[str, list]): The API Key generated in Hypixel using `/api new` command. - cache (bool, optional): [description]. Whether to enable caching - cache_config (caching.Caching, optional): The configuration for the saving, and reusing of the cache. - Defaults to None. + Parameters + ---------- + api_key: `t.Union[str, list]` + The API Key generated in Hypixel using `/api new` command. + cache: `t.Optional[bool]` + Whether to enable caching + cache_config: `t.Optional[caching.Caching]` + The configuration for the saving, and reusing of the cache. Defaults to None. """ + self.url = API_PATH["HYPIXEL"] + if not isinstance(api_key, list): self.api_key = [api_key] if cache: + if cache_config is None: + cache_config = caching.Caching(expire_after=30, old_data_on_error=True) + requests_cache.install_cache( cache_name=cache_config.cache_name, backend=cache_config.backend, @@ -59,240 +93,199 @@ def __init__(self, api_key: t.Union[str, list], cache: bool = False, cache_confi def _fetch(self, url: str, data: dict = None) -> t.Tuple[dict, bool]: """ - Get the JSON Response from the Root Hypixel API URL, - and Also add the ability to include the GET request parameters - with the API KEY Parameter by default. - - Args: - url (str): The URL to be accessed from the Root Domain. - data (dict, optional): The GET Request's Key-Value Pair. Example: {"uuid": "abc"} is converted to `?uuid=abc`. Defaults to None. - - Raises: - RateLimitError: Raised, When a certain user, or API Key is being ratelimited from the API. - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - t.Tuple[dict, bool]: The JSON Response from the Fetch Done to the API and the SUCCESS Value from the Response. + Get the JSON Response from the Root Hypixel API URL, and also add the ability to include the GET request + parameters with the API KEY Parameter by default. + + Parameters + ---------- + url: `str` + The URL to be accessed from the Root Domain. + data: `t.Optional[dict]` + The GET Request's Key-Value Pair. Example: {"uuid": "abc"} is converted to `?uuid=abc`. Defaults to None. + + Returns + ------- + `t.Tuple[dict, bool]` + The JSON Response from the Fetch Done to the API and the SUCCESS Value from the Response. """ if not data: data = {} - if "key" not in data: - data["key"] = random.choice(self.api_key) + headers = {"API-Key": random.choice(self.api_key)} url = form_url(HYPIXEL_API, url, data) - with requests.get(url, timeout=TIMEOUT) as response: - + with requests.get(url, timeout=TIMEOUT, headers=headers) as response: if response.status_code == 429: raise RateLimitError("Out of Requests!") try: json = response.json() - return json, json["success"] except Exception as exception: - raise HypixelAPIError(f"Invalid Content type Received instead of JSON. {exception}") + raise HypixelAPIError(f"{exception}") + else: + if not json["success"]: + reason = "The Key given is invalid, or something else has problem." + if json["cause"] is not None: + reason += f" Reason given: {json['cause']}" + + raise HypixelAPIError(reason=reason) + + return json + + @staticmethod + def _filter_name_uuid(name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + if not name and not uuid: + raise InvalidArgumentError("Please provide a named argument of the player's username or player's UUID.") + + if name: + uuid = Converters.username_to_uuid(name) + + return uuid def get_key_info(self, api_key: t.Optional[str] = None) -> key.Key: """ Get the Info about an API Key generated in Hypixel. - Args: - api_key (t.Optional[str], optional): The API Key generated in Hypixel using `/api new` command. Defaults to - None. - - Raises: - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. + Parameters + ---------- + api_key: `t.Optional[str]` + The API Key generated in Hypixel using `/api new` command. Defaults to None. - Returns: - key.Key: Key object for the API Key. + Returns + ------- + `key.Key` + Key object for the API Key. """ if not api_key: api_key = random.choice(self.api_key) - json, success = self._fetch("/key", {"key": api_key}) - - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") - - return key.Key( - json["record"] - ) + json = self._fetch(self.url["api_key"], {"key": api_key}) + return key.Key(json["record"]) def get_boosters(self) -> boosters.Boosters: """ Get the List of Hypixel Coin Boosters and Their Info. - Raises: - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - boosters.Boosters: The Booster Class Object, Which depicts the Booster Data Model. + Returns + ------- + `boosters.Boosters` + The Booster class object which depicts the booster data model. """ - json, success = self._fetch("/boosters") - - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") + json = self._fetch(self.url["boosters"]) - return boosters.Boosters( - json["boosters"] - ) + return boosters.Boosters(json["boosters"], json) def get_player(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> player.Player: """ Get the Info about a Hypixel Player using either his Username or UUID. - Args: - name (t.Optional[str], optional): The Optional string value for the Username. Defaults to None. - uuid (t.Optional[str], optional): The Optional string Value to the UUID. Defaults to None. - - Raises: - InvalidArgumentError: Returned when either UUID or Username are not provided. - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - PlayerNotFoundError: Raised, When a ceratin Player is not found. - - Returns: - player.Player: The Player Class Object, Which depicts the Player Data Model + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `player.Player` + The Player Class Object, Which depicts the Player Data Model """ - if name: - json, success = self._fetch("/player", {"name": name}) - elif uuid: - json, success = self._fetch("/player", {"uuid": uuid}) - else: - raise InvalidArgumentError("Please provide a named argument of the player's username or player's UUID.") - - if not success: - raise HypixelAPIError( - f"The Key given is invalid, or something else has problem. Reason given: {json['cause']}" - ) + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["player"], {"uuid": uuid}) if not json["player"]: raise PlayerNotFoundError("Null Value is returned", name) - return player.Player( - json["player"] - ) + return player.Player(json["player"]) - def get_friends(self, uuid: t.Optional[str] = None) -> friends.Friends: + def get_friends(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> friends.Friends: """ Get the List of Friends of a Hypixel Player and their Info. - Args: - uuid (t.Optional[str], optional): The UUID of a Certain Hypixel Player. Defaults to None. - - Raises: - InvalidArgumentError: Returned when the UUID is not provided. - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - friends.Friends: Returns the Friend Data Model, Which has the List of Friends, Each with a List of - Attributes. + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username of a hypixel player.. Defaults to None. + uuid: `t.Optional[str]` + The UUID of a Certain Hypixel Player. Defaults to None. + + Returns + ------- + `friends.Friends` + Returns the Friend Data Model, Which has the List of Friends, each with a list of attributes. """ - if uuid: - json, success = self._fetch("/friends", {"uuid": uuid}) - else: - raise InvalidArgumentError("Please provide a Named argument of the player's UUID") + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["friends"], {"uuid": uuid}) - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") - - return friends.Friends( - json["records"] - ) + return friends.Friends(json["records"]) def get_watchdog_info(self) -> watchdog.Watchdog: """ Get the List of Stats About the Watchdog for the last few days. - Raises: - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - watchdog.Watchdog: The Watchdog data model with certain important attributes for you to get data about the - things by watchdog. + Returns + ------- + `watchdog.Watchdog` + The Watchdog data model with certain important attributes for you to get data about the things by watchdog. """ - json, success = self._fetch("/watchdogstats") + json = self._fetch(self.url["watchdog"]) - if not success: - raise HypixelAPIError( - f"The Key given is invalid, or something else has problem. Cause: {json['cause']}" - ) - - return watchdog.Watchdog( - json - ) + return watchdog.Watchdog(json) def get_guild(self, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> guild.Guild: """ - Get the Info about a Hypixel Guild, Either using Name or UUID. - - Args: - name (t.Optional[str], optional): The Name of the Guild. Defaults to None. - uuid (t.Optional[str], optional): The ID Of the guild. Defaults to None. - - Raises: - InvalidArgumentError: Returned when the UUID is not provided. - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - GuildNotFoundError: Raised, When a certain Guild is not found. - - Returns: - guild.Guild: The Guild Object with certain Attributes for you to access, and use it. + Get the info about a Hypixel Guild, Either using Name or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Name of the Guild. Defaults to None. + uuid: `t.Optional[str]` + The ID Of the guild. Defaults to None. + + Returns + ------- + `guild.Guild` + The Guild Object with certain Attributes for you to access, and use it. """ if uuid: - json, success = self._fetch("/guild", {"id": uuid}) + json = self._fetch(self.url["guild"], {"id": uuid}) elif name: - json, success = self._fetch("/guild", {"name": name}) + json = self._fetch(self.url["guild"], {"name": name}) else: raise InvalidArgumentError("Please provide a Named argument of the guild's Name or guild's ID.") - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") - if not json["guild"]: raise GuildNotFoundError("Return Value is null") - - return guild.Guild( - json["guild"] - ) + return guild.Guild(json["guild"]) def get_games_info(self) -> games.Games: """ Get the List of Hypixel Games and Their Info. - Raises: - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - games.Games: The Games Data model, Containing the information, and attributes for all the games. + Returns + ------- + `games.Games` + The Games Data model, Containing the information, and attributes for all the games. """ - json, success = self._fetch("/gameCounts") + json = self._fetch(self.url["game_info"]) - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") - - return games.Games( - json["games"], - json["playerCount"] - ) + return games.Games(json["games"], json["playerCount"]) def get_leaderboards(self) -> leaderboard.Leaderboard: """ Get the Leaderboard for all the games, along with the data in it. - Raises: - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - leaderboard.Leaderboard: The Leaderboard data model, containing all the ranking for the games in Hypixel. + Returns + ------- + `leaderboard.Leaderboard` + The Leaderboard data model, containing all the ranking for the games in Hypixel. """ - json, success = self._fetch("/leaderboards") + json = self._fetch(self.url["leaderboards"]) - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") - - return leaderboard.Leaderboard( - json["leaderboards"] - ) + return leaderboard.Leaderboard(json["leaderboards"]) def find_guild( self, guild_name: t.Optional[str] = None, player_uuid: t.Optional[str] = None @@ -300,28 +293,152 @@ def find_guild( """ Finds the Guild By the Guild's Name or using a Player's UUID - - Args: - guild_name (t.Optional[str], optional): The name of the Guild. Defaults to None. - player_uuid (t.Optional[str], optional): The UUID of the Player to find his guild. Defaults to None. - - Raises: - InvalidArgumentError: Returned when the named argument is not provided. - HypixelAPIError: Raised when the Hypixel API is facing some issues, or errors. - - Returns: - find_guild.FindGuild: The ID of the guild being find. + Parameters + ---------- + guild_name: `t.Optional[str]` + The name of the Guild. Defaults to None. + player_uuid: `t.Optional[str]` + The UUID of the Player to find his guild. Defaults to None. + + Returns + ------- + `find_guild.FindGuild` + The ID of the guild being find. """ if guild_name: - json, success = self._fetch("/findGuild", {"byName": guild_name}) + json = self._fetch(self.url["find_guild"], {"byName": guild_name}) elif player_uuid: - json, success = self._fetch("/findGuild", {"byUuid": player_uuid}) + json = self._fetch(self.url["find_guild"], {"byUuid": player_uuid}) else: raise InvalidArgumentError("Please provide a Named argument of the guild's Name or guild's ID.") - if not success: - raise HypixelAPIError("The Key given is invalid, or something else has problem.") + return find_guild.FindGuild(json) + + def get_player_status( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> player_status.PlayerStatus: + """ + Get the Status info about a Hypixel Player using either his Username or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `player_status.PlayerStatus` + The Player Status Object, which depicts the Player's status + """ + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["status"], {"uuid": uuid}) + + return player_status.PlayerStatus(json) + + def get_player_recent_games( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> recent_games.RecentGames: + """ + Get the recent games played by a Hypixel Player using either his Username or UUID. + + Parameters + ---------- + name: `t.Optional[str]` + The Optional string value for the Username. Defaults to None. + uuid: `t.Optional[str]` + The Optional string Value to the UUID. Defaults to None. + + Returns + ------- + `recent_games.RecentGames` + The recent games model for the respective player specified. + """ + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["recent_games"], {"uuid": uuid}) + + return recent_games.RecentGames(json) + + def get_skyblock_profile( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> skyblock.SkyblockProfile: + """ + Get the skyblock information and profile about a specific user as passed in the requirements. + + Parameters + ---------- + name: `str` + The player's name in Hypixel + uuid: `str` + The player's global UUID + + Returns + ------- + `skyblock.SkyblockProfile` + The skyblock profile model for the user. + """ + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["skyblock_profile"], {"profile": uuid}) + + if not json["profile"]: + raise PlayerNotFoundError("The skyblock player being searched does not exist!", uuid) + + return skyblock.SkyblockProfile(json) + + def get_skyblock_user_auctions( + self, name: t.Optional[str] = None, uuid: t.Optional[str] = None + ) -> skyblock.SkyblockUserAuction: + """ + Get the skyblock auction info about a specific user as passed in the requirements. + + Parameters + ---------- + name: `str` + The player's name in Hypixel + uuid: `str` + The player's global UUID + + Returns + ------- + `skyblock.SkyblockUserAuction` + The skyblock auction model for the user. + """ + uuid = self._filter_name_uuid(name, uuid) + json = self._fetch(self.url["skyblock_auctions"], {"profile": uuid}) + + if not json["auctions"]: + raise PlayerNotFoundError("The skyblock player being searched does not exist!", uuid) + + return skyblock.SkyblockUserAuction(json) + + def get_skyblock_active_auctions( + self, page: int = 0 + ) -> skyblock.SkyblockActiveAuction: + """ + Get the list of active auctions in skyblock and use the data. + + Parameters + ---------- + page: int + The skyblock auction page to lookup. - return find_guild.FindGuild( - json - ) + Returns + ------- + skyblock.SkyblockActiveAuction + The active auction model. + """ + json = self._fetch(self.url["skyblock_active_auctions"], {"page": page}) + return skyblock.SkyblockActiveAuction(json) + + def get_skyblock_bazaar(self) -> skyblock.SkyblockBazaar: + """ + Get the skyblock bazaar items + + Returns + ------- + skyblock.SkyblockBazaar + The bazaar model object representing each product. + """ + json = self._fetch(self.url["skyblock_bazaar"]) + return skyblock.SkyblockBazaar(json) diff --git a/hypixelio/lib/converters.py b/hypixelio/lib/converters.py index cac6a61..bc042db 100644 --- a/hypixelio/lib/converters.py +++ b/hypixelio/lib/converters.py @@ -2,9 +2,10 @@ import requests +from hypixelio.endpoints import API_PATH from hypixelio.exceptions.exceptions import ( - InvalidArgumentError, - MojangAPIError + MojangAPIError, + PlayerNotFoundError ) from hypixelio.utils.constants import ( MOJANG_API, @@ -13,50 +14,56 @@ class Converters: + url = API_PATH["MOJANG"] + @classmethod def _fetch(cls, url: str) -> t.Optional[dict]: """ - This is the function for fetching the JSON from the Mojang API. - - Args: - url (str): The Mojang URL, whose JSON is supposed to be fetched. + This is the internal function for fetching the JSON from the Mojang API. - Raises: - InvalidArgumentError: Raised When there is an invalid URL, or Response, whose code is not 200. - MojangAPIError: Raised when the Mojang API is facing some problems, or there is some issues with the status. + Parameters + ---------- + url: `str` + The Mojang URL, whose JSON is supposed to be fetched. - Returns: - t.Optional[dict]: The JSON response from the Mojang API, Which is returned. + Returns + ------- + `t.Optional[dict]` + The JSON response from the Mojang API, Which is returned. """ with requests.get(f"{MOJANG_API}{url}", timeout=TIMEOUT) as response: - if response.status_code != 200: - raise InvalidArgumentError("Invalid data passed for conversion!") + if response.status_code == 204: + raise PlayerNotFoundError("204 value returned during conversion to UUID.", None) + + if response.status_code == 400: + raise PlayerNotFoundError("Badly formed UUID error.", None) try: json = response.json() - return json except Exception: - raise MojangAPIError("There seems to be some problem with the content type or the API IS down.") + raise MojangAPIError("There seems to be some problem with the content type or the API is down.") + else: + if "error" in json: + raise MojangAPIError(f"An error occurred! {json['errorMessage']}") + + return json @classmethod def username_to_uuid(cls, username: str) -> str: """ This is a method, to convert username in minecraft, for its respective UUID. - Args: - username (str): This is the minecraft user, which is passed to this function for the UUID Conversion. - - Raises: - MojangAPIError: Raised when there seems to be some problem with the Mojang API, which is contacted, - for this conversion. + Parameters + ---------- + username: `str` + This is the minecraft user, which is passed to this function for the UUID Conversion. - Returns: - str: returns the converted UUID for the respective username. + Returns + ------- + `str` + returns the converted UUID for the respective username. """ - json = Converters._fetch(f"/users/profiles/minecraft/{username}") - - if "error" in json: - raise MojangAPIError(f"An error occurred! {json['errorMessage']}") + json = Converters._fetch(Converters.url["username_to_uuid"].format(username)) return json["id"] @@ -65,19 +72,16 @@ def uuid_to_username(cls, uuid: str) -> str: """ This is the function that converts the UUID for your profile, to the Username for your Minecraft account. - Args: - uuid (str): This is the minecraft UUID, which is passed to this function for the UUID to username Conversion. + Parameters + ---------- + uuid: `str` + This is the minecraft UUID, which is passed to this function for the UUID to username Conversion. - Raises: - MojangAPIError: Raised when there seems to be some problem with the Mojang API, which is contacted, - for this conversion. - - Returns: - str: The username for the respective minecraft UUID is returned. + Returns + ------- + `str` + The username for the respective minecraft UUID is returned. """ - json = Converters._fetch(f"/user/profiles/{uuid}/names") - - if "error" in json: - raise MojangAPIError(f"An error occurred! {json['errorMessage']}") + json = Converters._fetch(Converters.url["uuid_to_username"].format(uuid)) return json[-1]["name"] diff --git a/hypixelio/lib/utils.py b/hypixelio/lib/utils.py index bb611bf..0aa1b38 100644 --- a/hypixelio/lib/utils.py +++ b/hypixelio/lib/utils.py @@ -3,60 +3,37 @@ import requests from requests.models import Response +from hypixelio.endpoints import API_PATH from hypixelio.exceptions.exceptions import ( CrafatarAPIError, InvalidArgumentError, - MojangAPIError, ) from hypixelio.lib.converters import ( Converters ) from hypixelio.utils.constants import ( - MOJANG_API, TIMEOUT ) class Utils: - @classmethod - def _fetch(cls, url: str) -> t.Optional[dict]: - """ - This is the function for fetching the JSON from the Mojang API. - - Args: - url (str): The Mojang URL, whose JSON is supposed to be fetched. - - Raises: - InvalidArgumentError: Raised When there is an invalid URL, or Response, whose code is not 200. - MojangAPIError: Raised when the Mojang API is facing some problems, or there is some issues with the status. - - Returns: - t.Optional[dict]: The JSON response from the Mojang API, Which is returned. - """ - with requests.get(f"{MOJANG_API}{url}", timeout=TIMEOUT) as response: - if response.status_code != 200: - raise InvalidArgumentError("Invalid data passed for conversion!") - - try: - json = response.json() - return json - except Exception: - raise MojangAPIError("There seems to be some problem with the content type or the API IS down.") + mojang_url = API_PATH["MOJANG"] + url = API_PATH["CRAFATAR"] @classmethod def _crafatar_fetch(cls, url: str) -> Response: """ This is the function for fetching the JSON from the Crafatar API. - Args: - url (str): The Crafatar URL, whose JSON is supposed to be fetched. - - Raises: - InvalidArgumentError: Raised When there is an invalid URL, or Response, whose code is not 200. - CrafatarAPIError: Raised when the Crafatar API is facing some problems, or there is some issues with the status. + Parameters + ---------- + url: `str` + The Crafatar URL, whose JSON is supposed to be fetched. - Returns: - t.Optional[dict]: The JSON response from the Crafatar API, Which is returned. + Returns + ------- + `t.Optional[dict]` + The JSON response from the Crafatar API, which is returned. """ with requests.get(f"https://crafatar.com/{url}", timeout=TIMEOUT) as response: if response.status_code == 422: @@ -67,18 +44,32 @@ def _crafatar_fetch(cls, url: str) -> Response: except Exception: raise CrafatarAPIError("There seems to be some problem with the content type or the API IS down.") + @staticmethod + def _filter_name_uuid(name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: + if not name and not uuid: + raise InvalidArgumentError("Please provide a named argument of the player's username or player's UUID.") + + if name: + uuid = Converters.username_to_uuid(name) + + return uuid + @classmethod def _form_crafatar_url(cls, route: str) -> str: """ This function forms the crafatar API URL for fetching USER skins. - Args: - route (str): The URL path to visit. + Parameters + ---------- + route: `str` + The URL path to visit. - Returns: - str: The well formed API URL for fetching. + Returns + ------- + `str` + The well formed API URL for fetching. """ - return f"https://crafatar.com/{route}" + return f"https://crafatar.com{route}" @classmethod def get_name_history( @@ -87,111 +78,94 @@ def get_name_history( """ This get the name history with records of a player. - Args: - name (t.Optional[str], optional): The username of the player. Defaults to None. - uuid (t.Optional[str], optional): The UUID of the player. Defaults to None. - changed_at (bool, optional): Toggle to true, if you need when the player changed name. Defaults to False. - - Raises: - InvalidArgumentError: Raised if neither UUID or username isn't passed. - - Returns: - t.Union[list, dict]: The list or dictionary with the name history and records. + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + changed_at: `bool` + Toggle to true, if you need when the player changed name. Defaults to False. + + Returns + ------- + `t.Union[list, dict]` + The list or dictionary with the name history and records. """ - if name: - uuid = Converters.username_to_uuid(name) - json = Utils._fetch(f"/user/profiles/{uuid}/names") - elif uuid: - json = Utils._fetch(f"/user/profiles/{uuid}/names") - else: - raise InvalidArgumentError("Please provide a Named argument of the User's name or UUID.") + uuid = cls._filter_name_uuid(name, uuid) + json = Converters._fetch(Utils.mojang_url["name_history"].format(uuid)) if changed_at: return json - else: - usernames = [] - for data in json: - usernames.append(data["name"]) - return usernames + usernames = [] + for data in json: + usernames.append(data["name"]) + + return usernames @classmethod def get_avatar(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: """ Get the avatar of the specified player - Args: - name (t.Optional[str], optional): The username of the player. Defaults to None. - uuid (t.Optional[str], optional): The UUID of the player. Defaults to None. - - Raises: - InvalidArgumentError: Raised if neither UUID or username isn't passed. - - Returns: - str: The URL containing the image of the avatar. + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the avatar. """ - url = "/avatars/{}" + uuid = cls._filter_name_uuid(name, uuid) + Utils._crafatar_fetch(Utils.url["avatar"].format(uuid)) - if name: - uuid = Converters.username_to_uuid(name) - Utils._crafatar_fetch(url.format(uuid)) - elif uuid: - Utils._crafatar_fetch(url.format(uuid)) - else: - raise InvalidArgumentError("Please provide a Named argument of the User's name or UUID.") - - return Utils._form_crafatar_url(url.format(uuid)) + return Utils._form_crafatar_url(Utils.url["avatar"].format(uuid)) @classmethod def get_head(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: """ Get the head skin of the specified player - Args: - name (t.Optional[str], optional): The username of the player. Defaults to None. - uuid (t.Optional[str], optional): The UUID of the player. Defaults to None. - - Raises: - InvalidArgumentError: Raised if neither UUID or username isn't passed. - - Returns: - str: The URL containing the image of the head. + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the head. """ - url = "/renders/head/{}" + uuid = cls._filter_name_uuid(name, uuid) + Utils._crafatar_fetch(Utils.url["head"].format(uuid)) - if name: - uuid = Converters.username_to_uuid(name) - Utils._crafatar_fetch(url.format(uuid)) - elif uuid: - Utils._crafatar_fetch(url.format(uuid)) - else: - raise InvalidArgumentError("Please provide a Named argument of the User's name or UUID.") - - return Utils._form_crafatar_url(url.format(uuid)) + return Utils._form_crafatar_url(Utils.url["head"].format(uuid)) @classmethod def get_body(cls, name: t.Optional[str] = None, uuid: t.Optional[str] = None) -> str: """ Get the whole body's skin of the specified player - Args: - name (t.Optional[str], optional): The username of the player. Defaults to None. - uuid (t.Optional[str], optional): The UUID of the player. Defaults to None. - - Raises: - InvalidArgumentError: Raised if neither UUID or username isn't passed. - - Returns: - str: The URL containing the image of the whole body. + Parameters + ---------- + name: `t.Optional[str]` + The username of the player. Defaults to None. + uuid: `t.Optional[str]` + The UUID of the player. Defaults to None. + + Returns + ------- + `str` + The URL containing the image of the whole body. """ - url = "/renders/body/{}" - - if name: - uuid = Converters.username_to_uuid(name) - Utils._crafatar_fetch(url.format(uuid)) - elif uuid: - Utils._crafatar_fetch(url.format(uuid)) - else: - raise InvalidArgumentError("Please provide a Named argument of the User's name or UUID.") + uuid = cls._filter_name_uuid(name, uuid) + Utils._crafatar_fetch(Utils.url["body"].format(uuid)) - return Utils._form_crafatar_url(url.format(uuid)) + return Utils._form_crafatar_url(Utils.url["body"].format(uuid)) diff --git a/hypixelio/models/boosters/booster_info.py b/hypixelio/models/boosters/booster_info.py index b0c8310..e207829 100644 --- a/hypixelio/models/boosters/booster_info.py +++ b/hypixelio/models/boosters/booster_info.py @@ -1,19 +1,11 @@ -"""This module is dedicated to definition of the Player class.""" - - class BoosterInfo: - """ - This is the Custom Hypixel API Booster's Info Model. - """ - def __init__( - self, - info: dict - ) -> None: + """The Hypixel API Booster's Info Model.""" + def __init__(self, info: dict) -> None: """ - The constructor for the Hypixel Booster model. - - Args: - info (dict): This contains the Returned JSON Response for the Booster's List Element API Request. + Parameters + ---------- + info: dict + This contains the Returned JSON Response for the Booster's List Element API Request. """ self.ID = info["_id"] self.PURCHASER_UUID = info["purchaserUuid"] @@ -25,7 +17,7 @@ def __init__( self.GAME_TYPE_CODE = info["gameType"] self.DATE_ACTIVATED = info["dateActivated"] - self.STACKED = True if "stacked" in info else False + self.STACKED = "stacked" in info def __eq__(self, other: "BoosterInfo") -> bool: return self.ID == other.ID and self.PURCHASER_UUID == other.PURCHASER_UUID diff --git a/hypixelio/models/boosters/boosters.py b/hypixelio/models/boosters/boosters.py index aea2f60..72cfdf8 100644 --- a/hypixelio/models/boosters/boosters.py +++ b/hypixelio/models/boosters/boosters.py @@ -1,25 +1,19 @@ -"""This module is dedicated to definition of the Boosters class.""" - import typing as t from .booster_info import BoosterInfo class Boosters: - """ - This is the Custom Hypixel API Boosters Model. - """ - def __init__( - self, - boosters: list, - ) -> None: + """The the Custom Hypixel API Boosters Model.""" + def __init__(self, boosters: list, json: dict) -> None: """ - The constructor for the Booster List model. - - Args: - boosters (list): The list of the Coin Boosters in the Hypixel server. + Parameters + ---------- + boosters: list + The list of the Coin Boosters in the Hypixel server. """ self.BOOSTERS = [BoosterInfo(booster) for booster in boosters] + self.STATE = json["boosterState"] def __len__(self) -> int: return len(self.BOOSTERS) diff --git a/hypixelio/models/caching/backend.py b/hypixelio/models/caching/backend.py index 532d74e..90656c6 100644 --- a/hypixelio/models/caching/backend.py +++ b/hypixelio/models/caching/backend.py @@ -3,10 +3,7 @@ @dataclass class CacheBackend: - """ - The Backend Adapters avilable for the caching. - """ + """The Backend adapters available for the caching.""" sqlite: str = "sqlite" - mongodb: str = "mongodb" redis: str = "redis" memory: str = "memory" diff --git a/hypixelio/models/caching/caching.py b/hypixelio/models/caching/caching.py index e825cf4..7157a41 100644 --- a/hypixelio/models/caching/caching.py +++ b/hypixelio/models/caching/caching.py @@ -6,9 +6,7 @@ class Caching: - """ - This is the Custom Caching model, for the Hypixel Requests to be made. - """ + """The Caching model for the Hypixel requests to be made and cached to save the request calls..""" def __init__( self, cache_name: str = "cache", @@ -17,26 +15,29 @@ def __init__( old_data_on_error: bool = False ) -> None: """ - The Constructor for the Caching Model. - - Args: - cache_name (str, optional): The name of the Cache, Which will be stored. Defaults to "cache". - backend (str, optional): The format of storage of the Cache. Defaults to CacheBackend.memory. - expire_after (int, optional): When will the cahe expire, In seconds. Defaults to None. - old_data_on_error (bool, optional): Whether to use old data, If an error occurs.. Defaults to False. + Parameters + ---------- + cache_name: str + The name of the Cache, Which will be stored. Defaults to "cache". + backend: str + The format of storage of the Cache. Defaults to CacheBackend.memory. + expire_after: int + When will the cache expire, In seconds. Defaults to None. + old_data_on_error: bool + Whether to use old data, If an error occurs. Defaults to False. """ self.cache_name = cache_name self.backend = backend self.expire_after = expire_after self.old_data_on_error = old_data_on_error - def remove_expired_responses(self) -> None: - """ - Remove the expired responses stored in the cache. - """ + @staticmethod + def remove_expired_responses() -> None: + """Remove the expired responses stored in the cache.""" core.remove_expired_responses() - def get_cache(self) -> core.CachedSession: + @staticmethod + def get_cache() -> core.CachedSession: """ Get the cache, which is currently stored and being used. @@ -45,16 +46,14 @@ def get_cache(self) -> core.CachedSession: """ return core.get_cache() - def clear_cache(self) -> None: - """ - Clear the cache stored in the storage specified. - """ + @staticmethod + def clear_cache() -> None: + """Clear the cache stored in the storage specified.""" core.clear() - def uninstall_cache(self) -> None: - """ - Remove caching from your code, if added or integrated. - """ + @staticmethod + def uninstall_cache() -> None: + """Remove caching from your code, if added or integrated.""" core.uninstall_cache() def __str__(self) -> str: diff --git a/hypixelio/models/find_guild.py b/hypixelio/models/find_guild.py index 09d47a1..407491c 100644 --- a/hypixelio/models/find_guild.py +++ b/hypixelio/models/find_guild.py @@ -1,19 +1,11 @@ -"""This module is dedicated to definition of the Find Guild class.""" - - class FindGuild: - """ - This is the Custom Hypixel Find Guild Model. - """ - def __init__( - self, - data: dict - ) -> None: + """This is the Custom Hypixel model for looking up guilds.""" + def __init__(self, data: dict) -> None: """ - The constructor for the Hypixel Find Guild Model. - - Args: - data (dict): The JSON data received from the Hypixel API. + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. """ self.ID = data["guild"] diff --git a/hypixelio/models/friends/friend_data.py b/hypixelio/models/friends/friend_data.py index 028cb67..e361570 100644 --- a/hypixelio/models/friends/friend_data.py +++ b/hypixelio/models/friends/friend_data.py @@ -1,19 +1,13 @@ -"""This module is dedicated to definition of the Friend's Data class.""" - - class FriendData: """ This is the Custom Hypixel API Friend's Data Model. """ - def __init__( - self, - friend: dict, - ) -> None: + def __init__(self, friend: dict) -> None: """ - The constructor for the Friend Data Hypixel Model. - - Args: - friend (dict): This contains the Returned JSON Response for the Friend's list element API Request. + Parameters + ---------- + friend: dict + This contains the JSON Response for the Friend's list element API Request. """ self.REQUEST_ID = friend['_id'] diff --git a/hypixelio/models/friends/friends.py b/hypixelio/models/friends/friends.py index 9d834b0..4435899 100644 --- a/hypixelio/models/friends/friends.py +++ b/hypixelio/models/friends/friends.py @@ -1,23 +1,16 @@ -"""This module is dedicated to definition of the Friends class.""" - import typing as t from .friend_data import FriendData class Friends: - """ - This is the Custom Hypixel API Friends Model. - """ - def __init__( - self, - friends: list - ) -> None: + """The the Custom Hypixel API Friends Model.""" + def __init__(self, friends: list) -> None: """ - The contains for the Friends List model. - - Args: - friends (list): This contains the Returned JSON Response List for the List of the friends of an user. + Parameters + ---------- + friends: list + This contains the Returned JSON Response List for the List of the friends of an user. """ self.FRIENDS = [FriendData(friend) for friend in friends] diff --git a/hypixelio/models/games/game_count.py b/hypixelio/models/games/game_count.py index c0469f3..d305166 100644 --- a/hypixelio/models/games/game_count.py +++ b/hypixelio/models/games/game_count.py @@ -1,19 +1,13 @@ -"""This module is dedicated to definition of the Game Mode Count class.""" - - class GameCount: """ This is the definition of the Custom Hypixel API Game Mode Count Model. """ - def __init__( - self, - game: dict - ) -> None: + def __init__(self, game: dict) -> None: """ - The constructor for the GameCount model. - - Args: - game (dict): The Game JSON data response received from the Hypixel API. + Parameters + ---------- + game: dict + The Game JSON data response received from the Hypixel API. """ self.PLAYERS = game["players"] self.MODES = game.get("modes") diff --git a/hypixelio/models/games/games.py b/hypixelio/models/games/games.py index 76f08dc..1a0a3d3 100644 --- a/hypixelio/models/games/games.py +++ b/hypixelio/models/games/games.py @@ -7,17 +7,14 @@ class Games: """ This is the definition of the Custom Hypixel Game count Model. """ - def __init__( - self, - games: dict, - player_count: int, - ) -> None: + def __init__(self, games: dict, player_count: int) -> None: """ - The constructor of the Games model. - - Args: - games (dict): The Games JSON list data response received from the Hypixel API. - player_count (int): The player count in the whole Hypixel Server. + Parameters + ---------- + games: dict + The Games JSON list data response received from the Hypixel API. + player_count: int + The player count in the whole Hypixel Server. """ self.PLAYER_COUNT = player_count @@ -50,4 +47,5 @@ def __init__( self.QUEUE = GameCount(games["QUEUE"]) def __repr__(self) -> str: - return f'<{self.__class__.__name__} lobby={self.MAIN_LOBBY} idle={self.IDLE} queue={self.QUEUE}>' + return f'<{self.__class__.__name__} lobby={self.MAIN_LOBBY} idle={self.IDLE} queue={self.QUEUE} ' \ + f'players={self.PLAYER_COUNT}>' diff --git a/hypixelio/models/guild.py b/hypixelio/models/guild.py index 214c8c3..4afe8d7 100644 --- a/hypixelio/models/guild.py +++ b/hypixelio/models/guild.py @@ -1,19 +1,11 @@ -"""This module is dedicated to definition of the Guild class.""" - - class Guild: - """ - This is the Custom Hypixel Guild Model. - """ - def __init__( - self, - data: dict - ) -> None: + """The the Custom Hypixel Guild Model.""" + def __init__(self, data: dict) -> None: """ - The constructor for the Hypixel Guild Model. - - Args: - data (dict): The JSON data received from the Hypixel API. + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. """ self.HYPIXEL_ID = data["_id"] self.NAME = data["name"] diff --git a/hypixelio/models/key.py b/hypixelio/models/key.py index 131bedc..c618cb4 100644 --- a/hypixelio/models/key.py +++ b/hypixelio/models/key.py @@ -1,19 +1,11 @@ -"""This module is dedicated to definition of the Key class.""" - - class Key: - """ - This is the Custom Hypixel API Key Model. - """ - def __init__( - self, - data: dict - ) -> None: + """This is the Custom Hypixel API Key Model.""" + def __init__(self, data: dict) -> None: """ - The constructor for the Hypixel Key Model. - - Args: - data (dict): The JSON data received from the Hypixel API. + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. """ self.KEY = data["key"] self.OWNER_UUID = data["owner"] diff --git a/hypixelio/models/leaderboard/leaderboard.py b/hypixelio/models/leaderboard/leaderboard.py index 3c1ca80..3af7739 100644 --- a/hypixelio/models/leaderboard/leaderboard.py +++ b/hypixelio/models/leaderboard/leaderboard.py @@ -4,18 +4,13 @@ class Leaderboard: - """ - This is the definition of the Custom Hypixel API Leaderboard Model. - """ - def __init__( - self, - board: dict, - ) -> None: + """This is the definition of the Custom Hypixel API Leaderboard Model.""" + def __init__(self, board: dict) -> None: """ - The constructor for the Leaderboard Model in Hypixel. - - Args: - board (dict): The Leaderboard JSON data response received from the Hypixel API. + Parameters + ---------- + board: dict + The Leaderboard JSON data response received from the Hypixel API. """ self.ARENA = [data(arena) for arena in board['ARENA']] self.MCGO = [data(arena) for arena in board['MCGO']] diff --git a/hypixelio/models/leaderboard/leaderboard_data.py b/hypixelio/models/leaderboard/leaderboard_data.py index 12134ea..1147888 100644 --- a/hypixelio/models/leaderboard/leaderboard_data.py +++ b/hypixelio/models/leaderboard/leaderboard_data.py @@ -2,18 +2,13 @@ class LeaderboardData: - """ - This is the definition of the Custom Hypixel API Leaderboard Data Model. - """ - def __init__( - self, - data: dict, - ) -> None: + """This is the Custom Hypixel API Leaderboard Data Model.""" + def __init__(self, data: dict) -> None: """ - The Constructor for the Leaderboard Data Model for each Game. - - Args: - data (dict): The Leaderboard JSON data per game response received from the Hypixel API. + Parameters + ---------- + data: dict + The Leaderboard JSON data per game response received from the Hypixel API. """ self.PATH = data['path'] self.PREFIX = data['prefix'] diff --git a/hypixelio/models/player.py b/hypixelio/models/player.py index b00d831..841f2c4 100644 --- a/hypixelio/models/player.py +++ b/hypixelio/models/player.py @@ -1,19 +1,11 @@ -"""This module is dedicated to definition of the Player class.""" - - class Player: - """ - This is the Custom Hypixel Player Model. - """ - def __init__( - self, - data: dict - ) -> None: + """The the Custom Hypixel Player Model.""" + def __init__(self, data: dict) -> None: """ - The constructor for the Hypixel Player Model. - - Args: - data (dict): The JSON data received from the Hypixel API. + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. """ self.HYPIXEL_ID = data["_id"] self.UUID = data["uuid"] diff --git a/hypixelio/models/player_status.py b/hypixelio/models/player_status.py new file mode 100644 index 0000000..7ca0eb6 --- /dev/null +++ b/hypixelio/models/player_status.py @@ -0,0 +1,22 @@ +class PlayerStatus: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. + """ + self.UUID = data["uuid"] + self.SESSION_INFO = data["session"] + + def __str__(self) -> str: + return self.UUID + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} uuid="{self.UUID}" online="{self.SESSION_INFO["online"]}">' + + def __hash__(self) -> int: + return hash(self.UUID) + + def __eq__(self, other: "PlayerStatus") -> bool: + return self.UUID == other.UUID diff --git a/hypixelio/models/recent_games/__init__.py b/hypixelio/models/recent_games/__init__.py new file mode 100644 index 0000000..2d86988 --- /dev/null +++ b/hypixelio/models/recent_games/__init__.py @@ -0,0 +1 @@ +from .recent_games import RecentGames diff --git a/hypixelio/models/recent_games/recent_game_info.py b/hypixelio/models/recent_games/recent_game_info.py new file mode 100644 index 0000000..3761c83 --- /dev/null +++ b/hypixelio/models/recent_games/recent_game_info.py @@ -0,0 +1,22 @@ +class RecentGameInfo: + def __init__(self, game: dict) -> None: + """ + Parameters + ---------- + game: dict + The game's JSON data received from the Hypixel API. + """ + self.DATE = game["date"] + self.END_DATETIME = game["ended"] + self.GAME_TYPE = game["gameType"] + self.MODE = game.get("mode") + self.MAP = game["map"] + + def __hash__(self) -> int: + return hash((self.DATE, self.MAP)) + + def __str__(self) -> str: + return self.GAME_TYPE + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} game_type="{self.GAME_TYPE}" mode="{self.MODE}" map="{self.MAP}">' diff --git a/hypixelio/models/recent_games/recent_games.py b/hypixelio/models/recent_games/recent_games.py new file mode 100644 index 0000000..ff5eba1 --- /dev/null +++ b/hypixelio/models/recent_games/recent_games.py @@ -0,0 +1,39 @@ +import typing as t + +from .recent_game_info import RecentGameInfo + + +class RecentGames: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. + """ + self.UUID = data["uuid"] + self.GAMES = [RecentGameInfo(game) for game in data["games"]] + + def __len__(self) -> int: + return len(self.GAMES) + + def __getitem__(self, key: int) -> RecentGameInfo: + return self.GAMES[key] + + def __setitem__(self, key: int, value: RecentGameInfo) -> None: + self.GAMES[key] = value + + def __iter__(self) -> t.Iterator: + return iter(self.GAMES) + + def __str__(self) -> str: + return self.UUID + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} uuid="{self.UUID}">' + + def __hash__(self) -> int: + return hash(self.UUID) + + def __eq__(self, other: "RecentGames") -> bool: + return self.UUID == other.UUID diff --git a/hypixelio/models/skyblock/__init__.py b/hypixelio/models/skyblock/__init__.py new file mode 100644 index 0000000..c506898 --- /dev/null +++ b/hypixelio/models/skyblock/__init__.py @@ -0,0 +1,4 @@ +from .active_auctions import SkyblockActiveAuction +from .bazaar import SkyblockBazaar +from .profile import SkyblockProfile +from .user_auction import SkyblockUserAuction diff --git a/hypixelio/models/skyblock/active_auctions/__init__.py b/hypixelio/models/skyblock/active_auctions/__init__.py new file mode 100644 index 0000000..2d08c29 --- /dev/null +++ b/hypixelio/models/skyblock/active_auctions/__init__.py @@ -0,0 +1 @@ +from .active_auctions import SkyblockActiveAuction diff --git a/hypixelio/models/skyblock/active_auctions/active_auctions.py b/hypixelio/models/skyblock/active_auctions/active_auctions.py new file mode 100644 index 0000000..8b79e00 --- /dev/null +++ b/hypixelio/models/skyblock/active_auctions/active_auctions.py @@ -0,0 +1,29 @@ +import typing as t + +from hypixelio.models.skyblock.auction import SkyblockAuction + + +class SkyblockActiveAuction: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The data from the Hypixel API endpoint. + """ + self.PAGE_NUMBER = data["page"] + self.TOTAL_PAGES = data["totalPages"] + self.TOTAL_AUCTION = data["totalAuctions"] + self.AUCTIONS = [SkyblockAuction(auction) for auction in data["auctions"]] + + def __len__(self) -> int: + return len(self.AUCTIONS) + + def __getitem__(self, key: int) -> SkyblockAuction: + return self.AUCTIONS[key] + + def __setitem__(self, key: int, value: SkyblockAuction) -> None: + self.AUCTIONS[key] = value + + def __iter__(self) -> t.Iterator: + return iter(self.AUCTIONS) diff --git a/hypixelio/models/skyblock/auction.py b/hypixelio/models/skyblock/auction.py new file mode 100644 index 0000000..fe4b982 --- /dev/null +++ b/hypixelio/models/skyblock/auction.py @@ -0,0 +1,34 @@ +class SkyblockAuction: + def __init__(self, auction_data: dict) -> None: + """ + Parameters + ---------- + auction_data: dict + The auction JSON model to be parsed. + """ + self.ID = auction_data.get("_id") + self.UUID = auction_data["uuid"] + self.AUCTIONEER = auction_data["auctioneer"] + + self.ITEM_NAME = auction_data["item_name"] + self.ITEM_LORE = auction_data["item_lore"] + + self.CATEGORY = auction_data["category"] + self.TIER = auction_data["tier"] + self.STARTING_BID = auction_data["starting_bid"] + + self.CLAIMED_BIDDERS = auction_data.get("claimed_bidders") + self.BIDS = auction_data.get("bids") + self.HIGEST_BID = auction_data.get("highest_bid_amount") + + def __str__(self) -> str: + return self.ID + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id="{self.ID}" uuid="{self.UUID}">' + + def __hash__(self) -> int: + return hash(self.ID) + + def __eq__(self, other: "SkyblockAuction") -> bool: + return self.ID == other.ID diff --git a/hypixelio/models/skyblock/bazaar/__init__.py b/hypixelio/models/skyblock/bazaar/__init__.py new file mode 100644 index 0000000..da3cfa3 --- /dev/null +++ b/hypixelio/models/skyblock/bazaar/__init__.py @@ -0,0 +1 @@ +from .skyblock_bazaar import SkyblockBazaar diff --git a/hypixelio/models/skyblock/bazaar/bazaar_item.py b/hypixelio/models/skyblock/bazaar/bazaar_item.py new file mode 100644 index 0000000..6f8b6a4 --- /dev/null +++ b/hypixelio/models/skyblock/bazaar/bazaar_item.py @@ -0,0 +1,32 @@ +class SkyblockBazaarItem: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The product data from the Hypixel bazaar API endpoint. + """ + self.PRODUCT_ID = data["productId"] + + self.SELL_PRICE = data["sellPrice"] + self.SELL_VOLUME = data["sellVolume"] + self.SELL_MOVING_WEEK = data["sellMovingWeek"] + self.SELL_ORDERS = data["sellOrders"] + + self.BUY_PRICE = data["buyPrice"] + self.BUY_VOLUME = data["buyVolume"] + self.BUY_MOVING_WEEK = data["buyMovingWeek"] + self.BUY_ORDERS = data["buyOrders"] + + def __str__(self) -> str: + return self.PRODUCT_ID + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id="{self.PRODUCT_ID}" sell_price="{self.SELL_PRICE}" ' \ + f'buy_price="{self.BUY_PRICE}">' + + def __hash__(self) -> int: + return hash(self.PRODUCT_ID) + + def __eq__(self, other: "SkyblockBazaarItem") -> bool: + return self.PRODUCT_ID == other.PRODUCT_ID diff --git a/hypixelio/models/skyblock/bazaar/skyblock_bazaar.py b/hypixelio/models/skyblock/bazaar/skyblock_bazaar.py new file mode 100644 index 0000000..637a483 --- /dev/null +++ b/hypixelio/models/skyblock/bazaar/skyblock_bazaar.py @@ -0,0 +1,16 @@ +from .bazaar_item import SkyblockBazaarItem + + +class SkyblockBazaar: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The data from the Hypixel API endpoint. + """ + self.__PRODUCTS = data["products"] + + for key, value in self.__PRODUCTS.items(): + bazaar_item_object = SkyblockBazaarItem(value["quick_status"]) + setattr(self, key, bazaar_item_object) diff --git a/hypixelio/models/skyblock/profile/__init__.py b/hypixelio/models/skyblock/profile/__init__.py new file mode 100644 index 0000000..5a8f131 --- /dev/null +++ b/hypixelio/models/skyblock/profile/__init__.py @@ -0,0 +1 @@ +from .profile import SkyblockProfile diff --git a/hypixelio/models/skyblock/profile/profile.py b/hypixelio/models/skyblock/profile/profile.py new file mode 100644 index 0000000..1dad9ae --- /dev/null +++ b/hypixelio/models/skyblock/profile/profile.py @@ -0,0 +1,44 @@ +import typing as t + +from .profile_member import SkyblockProfileMember + + +class SkyblockProfile: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. + """ + self.__PROFILE_JSON = data["profile"] + + self.PROFILE_ID = self.__PROFILE_JSON["profile_id"] + self.MEMBERS = [ + SkyblockProfileMember(self.__PROFILE_JSON["members"][member]) for member in self.__PROFILE_JSON["members"] + ] + self.COMMUNITY_UPGRADES = self.__PROFILE_JSON["community_upgrades"] + + def __str__(self) -> str: + return self.PROFILE_ID + + def __repr__(self) -> str: + return f'<{self.__class__.__name__} id="{self.PROFILE_ID}" member_count="{len(self.MEMBERS)}">' + + def __hash__(self) -> int: + return hash(self.PROFILE_ID) + + def __eq__(self, other: "SkyblockProfile") -> bool: + return self.PROFILE_ID == other.PROFILE_ID + + def __len__(self) -> int: + return len(self.MEMBERS) + + def __getitem__(self, key: int) -> SkyblockProfileMember: + return self.MEMBERS[key] + + def __setitem__(self, key: int, value: SkyblockProfileMember) -> None: + self.MEMBERS[key] = value + + def __iter__(self) -> t.Iterator: + return iter(self.MEMBERS) diff --git a/hypixelio/models/skyblock/profile/profile_member.py b/hypixelio/models/skyblock/profile/profile_member.py new file mode 100644 index 0000000..e6823b7 --- /dev/null +++ b/hypixelio/models/skyblock/profile/profile_member.py @@ -0,0 +1,42 @@ +class SkyblockProfileMember: + def __init__(self, member_data: dict) -> None: + """ + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. + """ + self.COIN_PURSE = member_data["coin_purse"] + self.DEATH_COUNT = member_data["death_count"] + self.FAIRY_SOULS_COLLECTED = member_data.get("fairy_souls_collected") + self.FISHING_TREASURE_COUNT = member_data.get("fishing_treasure_caught") + + self.STATS = member_data["stats"] + self.OBJECTIVES = member_data["objectives"] + + self.CRAFTED_GENERATORS = member_data.get("crafted_generators") + self.VISITED_ZONES = member_data.get("visited_zones") + self.ACHIEVEMENT_SPAWNED_ISLAND_TYPES = member_data.get("achievement_spawned_island_types") + + self.SLAYER_QUEST = member_data.get("slayer_quest") + self.SLAYER_BOSSES = member_data.get("slayer_bosses") + + self.PETS = member_data["pets"] + self.GRIFFIN = member_data["griffin"] + + self.UNLOCKED_COLLECTION_TIERS = member_data.get("unlocked_coll_tiers") + + self.SKILLS = { + "alchemy": member_data.get("experience_skill_alchemy"), + "farming": member_data.get("experience_skill_farming"), + "taming": member_data.get("experience_skill_taming"), + "enchanting": member_data.get("experience_skill_enchanting"), + "fishing": member_data.get("experience_skill_fishing"), + "foraging": member_data.get("experience_skill_foraging"), + "carpentry": member_data.get("experience_skill_carpentry"), + "runecrafting": member_data.get("experience_skill_runecrafting"), + "combat": member_data.get("experience_skill_combat"), + "mining": member_data.get("experience_skill_mining") + } + + self.COLLECTION = member_data.get("collection") diff --git a/hypixelio/models/skyblock/user_auction/__init__.py b/hypixelio/models/skyblock/user_auction/__init__.py new file mode 100644 index 0000000..51ecbfb --- /dev/null +++ b/hypixelio/models/skyblock/user_auction/__init__.py @@ -0,0 +1 @@ +from .user_auction import SkyblockUserAuction diff --git a/hypixelio/models/skyblock/user_auction/user_auction.py b/hypixelio/models/skyblock/user_auction/user_auction.py new file mode 100644 index 0000000..5965bb5 --- /dev/null +++ b/hypixelio/models/skyblock/user_auction/user_auction.py @@ -0,0 +1,26 @@ +import typing as t + +from hypixelio.models.skyblock.auction import SkyblockAuction + + +class SkyblockUserAuction: + def __init__(self, data: dict) -> None: + """ + Parameters + ---------- + data: dict + The data from the Hypixel API endpoint. + """ + self.AUCTIONS = [SkyblockAuction(auction) for auction in data["auctions"]] + + def __len__(self) -> int: + return len(self.AUCTIONS) + + def __getitem__(self, key: int) -> SkyblockAuction: + return self.AUCTIONS[key] + + def __setitem__(self, key: int, value: SkyblockAuction) -> None: + self.AUCTIONS[key] = value + + def __iter__(self) -> t.Iterator: + return iter(self.AUCTIONS) diff --git a/hypixelio/models/watchdog.py b/hypixelio/models/watchdog.py index 693c084..123f7b2 100644 --- a/hypixelio/models/watchdog.py +++ b/hypixelio/models/watchdog.py @@ -1,33 +1,25 @@ -"""This module is dedicated to definition of the Key class.""" - - class Watchdog: - """ - This is the definition of the Custom Hypixel API Key Model. - """ - def __init__( - self, - data: dict - ) -> None: + """This is the definition of the Custom Hypixel API Key Model.""" + def __init__(self, data: dict) -> None: """ - The constructor for the Hypixel Watchdog Model. - - Args: - data (dict): The JSON data received from the Hypixel API. + Parameters + ---------- + data: dict + The JSON data received from the Hypixel API. """ self.LAST_MINUTE_BAN = data["watchdog_lastMinute"] self.STAFF_ROLLING_DAILY = data["staff_rollingDaily"] self.TOTAL_BANS = data["watchdog_total"] - self.WATCHDOG_ROLLING_DAILY = data["watchdog_rollingDaily"] + self.ROLLING_DAILY = data["watchdog_rollingDaily"] self.STAFF_TOTAL_BANS = data["staff_total"] def __str__(self) -> str: return self.LAST_MINUTE_BAN def __repr__(self) -> str: - return f'<{self.__class__.__name__} last_minute_ban={self.LAST_MINUTE_BAN} rolling_daily={self.WATCHDOG_ROLLING_DAILY}>' + return f'<{self.__class__.__name__} last_minute_ban={self.LAST_MINUTE_BAN} rolling_daily={self.ROLLING_DAILY}>' def __hash__(self) -> int: return hash(self.LAST_MINUTE_BAN) diff --git a/hypixelio/utils/constants.py b/hypixelio/utils/constants.py index b13eaf8..f1e4ceb 100644 --- a/hypixelio/utils/constants.py +++ b/hypixelio/utils/constants.py @@ -3,7 +3,6 @@ used all over the code, hence reusing the same things, Instead of redefining, and accessing from a single place. """ - HYPIXEL_API = "https://api.hypixel.net" MOJANG_API = "https://api.mojang.com" diff --git a/hypixelio/utils/helpers.py b/hypixelio/utils/helpers.py index e9dd526..e049592 100644 --- a/hypixelio/utils/helpers.py +++ b/hypixelio/utils/helpers.py @@ -1,7 +1,7 @@ """ This module is dedicated to the storage of the Helper functions, -Which is imported in the main file: `Client.py` to include in the functions -to Reduce the lines of code, and simplify it. +Which is imported in the main file: `client.py` to include in the functions +to reduce the lines of code, and simplify it. """ @@ -9,23 +9,28 @@ def form_url(main_url: str, url: str, data: dict = None) -> str: """ Form and return the URL for the Hypixel API with GET Params. - Args: - main_url (str): The Main URL With the root domain. - url (str): The Route in the Main URL to acess the JSON From. - data (dict, optional): he GET Request Key Value pair, Added to end of the Final route specified in the main_url + url.. Defaults to None. + Parameters + ---------- + main_url: str + The Main URL With the root domain. + url: str + The Route in the Main URL to access the JSON From. + data: t.Optional[dict] + The GET Request Key Value pair, Added to end of the Final route specified in the main_urlv+ url.. Defaults + to None. - Returns: - str: The Final URL with the Get request parameters, and the URL Route. + Returns + ------- + str: + The Final URL with the GET request parameters, and the URL Route. """ if not data: data = {} url = main_url + url if url.startswith('/') else url - url += "?" + "&".join( - [ - f"{dict_key}={dict_value}" for dict_key, dict_value in data.items() - ] - ) + url += "?" + "&".join([ + f"{dict_key}={dict_value}" for dict_key, dict_value in data.items() + ]) return url diff --git a/setup.py b/setup.py index e19a00a..692d81b 100644 --- a/setup.py +++ b/setup.py @@ -3,10 +3,12 @@ import setuptools +# -- Constants -- BASE_DIR = Path(__file__).resolve().parent - README = Path(BASE_DIR / "README.md").read_text() +URL = "https://github.com/janaSunrise/HypixelIO" +# -- Version config -- VERSION = re.search( r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', Path(BASE_DIR / "hypixelio/__init__.py").read_text(), @@ -14,7 +16,7 @@ ).group(1) if not VERSION: - raise RuntimeError('version is not set') + raise RuntimeError("VERSION is not set!") setuptools.setup( name="HypixelIO", @@ -23,16 +25,16 @@ author="Sunrit Jana", author_email="warriordefenderz@gmail.com", - description="A modern efficient and faster way of interacting with the Hypixel API!", + description="A modern, efficient and faster way of interacting with the Hypixel API!", long_description=README, long_description_content_type="text/markdown", license="GPL v3", - url="https://github.com/janaSunrise/HypixelIO", + url=URL, project_urls={ - "Documentation": "https://github.com/janaSunrise/HypixelIO", - "Issue tracker": "https://github.com/janaSunrise/HypixelIO/issues", + "Documentation": URL, + "Issue tracker": f"{URL}/issues", }, packages=setuptools.find_packages( @@ -40,8 +42,9 @@ ), install_requires=[ - 'requests==2.25.0', - 'requests-cache==0.5.2' + "requests==2.25.1", + "requests-cache==0.5.2", + "aiohttp==3.7.4.post0" ], classifiers=[