From d133d25e564929abc26b766269f5b0ba3526963a Mon Sep 17 00:00:00 2001 From: "nz.zishiri@gmail.com" Date: Mon, 22 Jan 2024 00:22:27 +0200 Subject: [PATCH 1/2] minor refactor --- app/api/mal.py | 2 +- app/routes/utils.py | 25 +++++++------------------ 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/app/api/mal.py b/app/api/mal.py index 0358c56..8d7976e 100644 --- a/app/api/mal.py +++ b/app/api/mal.py @@ -132,7 +132,7 @@ def get_anime_details(token: str, anime_id: str, **kwargs): raise Exception("Auth Token Must Be Provided") if anime_id is None: - raise Exception("A Valid Query Must Be Provided") + raise Exception("A Valid Anime ID Must Be Provided") headers = kwargs_to_dict(Authorization=f'Bearer {token}') query_params = to_query_string(kwargs) diff --git a/app/routes/utils.py b/app/routes/utils.py index 27d631f..71e0a96 100644 --- a/app/routes/utils.py +++ b/app/routes/utils.py @@ -7,11 +7,6 @@ # Enable CORS def respond_with(data): - """ - Respond with CORS headers - :param data: - :return: - """ resp = jsonify(data) resp.headers['Access-Control-Allow-Origin'] = "*" resp.headers['Access-Control-Allow-Headers'] = '*' @@ -30,19 +25,16 @@ def mal_to_meta(anime_item: dict): # Format id to mal addon format formatted_content_id = f"{MAL_ID_PREFIX}{content_id}" - # Get values of title, mean score, synopsis title = anime_item.get('title', None) mean_score = anime_item.get('mean', None) synopsis = anime_item.get('synopsis', None) - # Check for poster key in anime_item poster = None - if poster_objects := anime_item.get('main_picture', None): + if poster_objects := anime_item.get('main_picture', {}): if poster := poster_objects.get('large', None): poster = poster_objects.get('medium') - # Check for genres and format them if they exist - if genres := anime_item.get('genres', None): + if genres := anime_item.get('genres', {}): genres = [genre['name'] for genre in genres] # Check for release info and format it if it exists @@ -50,19 +42,16 @@ def mal_to_meta(anime_item: dict): start_date = start_date[:4] # Get the year only start_date += '-' - # Format start date if end_date of airing was not returned if end_date := anime_item.get('end_date', None): start_date += end_date # Check for background key in anime_item background = None - if picture_objects := anime_item.get('pictures', None): - # Get a random a picture from the list of picture objects - index = random.randint(0, len(picture_objects) - 1) - - # Get the randomly chosen picture object's largest size if it exists else use medium - if background := picture_objects[index].get('large', None) is None: - background = picture_objects[index]['medium'] + picture_objects = anime_item.get('pictures', []) + if len(picture_objects) > 0: + random_background_index = random.randint(0, len(picture_objects) - 1) + if background := picture_objects[random_background_index].get('large', None) is None: + background = picture_objects[random_background_index]['medium'] # Check for media type and filter out non series and movie types if media_type := anime_item.get('media_type', None): From 6b527707f3c8e4155f8795468a8677c25f3eb27c Mon Sep 17 00:00:00 2001 From: "nz.zishiri@gmail.com" Date: Tue, 23 Jan 2024 01:25:56 +0200 Subject: [PATCH 2/2] Token aliasing using user's MAL ID --- Pipfile.lock | 202 +++++++++++++++++++++++------------------ app/api/mal.py | 15 +++ app/db/db.py | 1 + app/routes/auth.py | 18 +++- app/routes/catalog.py | 20 ++-- app/routes/manifest.py | 14 ++- app/routes/meta.py | 13 +-- app/routes/stream.py | 6 +- app/routes/utils.py | 11 ++- config.py | 1 + 10 files changed, 187 insertions(+), 114 deletions(-) diff --git a/Pipfile.lock b/Pipfile.lock index 2888076..34d54b6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d117d3e280d357ea63b88f419977d3448b224698c17aba1d98202e3b005b5b16" + "sha256": "6ad68d90637f340883fac401ffd191554eb2203bede36727d0dfbf4843dc4920" }, "pipfile-spec": 6, "requires": { @@ -26,11 +26,11 @@ }, "blinker": { "hashes": [ - "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213", - "sha256:c3d739772abb7bc2860abf5f2ec284223d9ad5c76da018234f6f50d6f31ab1f0" + "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", + "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182" ], - "markers": "python_version >= '3.7'", - "version": "==1.6.2" + "markers": "python_version >= '3.8'", + "version": "==1.7.0" }, "cachecontrol": { "hashes": [ @@ -40,6 +40,14 @@ "index": "pypi", "version": "==0.12.6" }, + "cachelib": { + "hashes": [ + "sha256:42d49f2fad9310dd946d7be73d46776bcd4d5fde4f49ad210cfdd447fbdfc346", + "sha256:593faeee62a7c037d50fc835617a01b887503f972fb52b188ae7e50e9cb69740" + ], + "markers": "python_version >= '3.7'", + "version": "==0.10.2" + }, "cachy": { "hashes": [ "sha256:186581f4ceb42a0bbe040c407da73c14092379b1e4c0e327fdb72ae4a9b269b1", @@ -207,6 +215,14 @@ "index": "pypi", "version": "==2.3.2" }, + "flask-session": { + "hashes": [ + "sha256:b1ed06cf4c5a211305579a132e81307d242cec6fe2714a276405730ffd22a034", + "sha256:dd77b6c5916021a540a8c188731c529596ad9ea382c07a24f9654355fa40c9ad" + ], + "index": "pypi", + "version": "==0.6.0" + }, "greenlet": { "hashes": [ "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3", @@ -539,11 +555,11 @@ }, "pip": { "hashes": [ - "sha256:0e7c86f486935893c708287b30bd050a36ac827ec7fe5e43fe7cb198dd835fba", - "sha256:3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18" + "sha256:5052d7889c1f9d05224cd41741acb7c5d6fa735ab34e339624a614eaaa7e7d76", + "sha256:7fd9972f96db22c8077a1ee2691b172c8089b17a5652a44494a9ecb0d78f9149" ], "markers": "python_version >= '3.7'", - "version": "==23.1.2" + "version": "==23.3.2" }, "pipenv": { "hashes": [ @@ -614,83 +630,91 @@ "srv" ], "hashes": [ - "sha256:01807a3d0b758cbf65e7b3af84a24d2ee58c9d6c0af8b0af99b581bcaa75a931", - "sha256:02060ced24a26e1c73b6f491b728fe99e73f38ba3a1e4b882dc7b873d419ab3e", - "sha256:028addb304bc525d4a10c5c6e59ef5f140e528ae285c10e1d43f19905631e32f", - "sha256:02f535bc8f8d75d45ec6cd944804d466a73a46afc368d6c36e232b887edd0475", - "sha256:0669823de06c3a77fddf738f6250688b7fdae2b44edbe3c103b7fbfdfc848392", - "sha256:071c256fbb35c6942970b8b6eb6b89bac302db49a2d6d35e68c35b442a0ce710", - "sha256:093c5343c5863e87023318050507511fa7458b0376caabcc41abff0e36aaabc8", - "sha256:15cf004b6329da48078d7d9d1c79c802df6631b94e5a1ed9a112d713cc0f66e9", - "sha256:18acb807de39eb9b8ff7122094920f1da79c1781dc96cfef73dd97da51448f7b", - "sha256:196c2c9ffccdf0ad4efdfae29347c4e2ae52c3415e958736cda84e4062553e96", - "sha256:1a1bb096579ffa59143a8d8fc9d4692db3e04305cf5a0e48e0724ae47a836255", - "sha256:1c6bd8470c89b2cd6312fa685dbf4c64371a04a7e4a3a55e2007626f8f997103", - "sha256:1eea8af506b8b33573c76942a5c2390f2cddb4e195b1cdfc373ca919e9b95904", - "sha256:2128592140426044d59a89f30b7aba1e185faf2553b3d161dcca0aa970ba40c7", - "sha256:23bfd793be088470a1c7bca5c907ae3180e6a4cf731e96a194c89413c042cf4c", - "sha256:242d1a30162ead28e69df37748021039c4b292bbfd7c5449294a26c8365d342d", - "sha256:2578f077b9448b7a420b3e9b0efdfb7ecdb2a3c27e00c181610809717c900cd9", - "sha256:274eb75231aca12d54d421852fc230e8655e4b33b30e9eb7fd34269955e125dd", - "sha256:29956f61ab885c28b190ff817de7ad0c75a470699632b44848b102640fbf9e73", - "sha256:2caac57d2a0160dce877e706e94e8a15b87feb71c257ecb8b5a039f7e98ba99b", - "sha256:2f74b606c11c570ec2a6c384fc194d96f00eaa829c7c08cbec455f7b02d28774", - "sha256:34ea6ffb77f0cf8d01c4c1df60dc68141859ada1507c326380ef81e23b58c9cc", - "sha256:38ece8d2892de19fa437bc4f60b0d8c5353b185e8cc1c543212a488c93c74834", - "sha256:3e6efcf768209dc4d966fabbbe4dcd2dd2d60ec4d8342668da02664f0c73a9e8", - "sha256:40ad38ad6f6dbd8a9dbd05195a15fe7749a0692dc895274a4f806d9831fceb3c", - "sha256:4481f2796d53cd0c74d988a23a11266e6cae03be3878f42ed2c221b192d14f8d", - "sha256:44893b6788da1d67696ff2f27e42e315d40965a4fa23786dcc26c932c5b02149", - "sha256:45838fa9abf3bce35a24fffcd289de23f3d6edc4cc9beac28037df3e1009f892", - "sha256:48908eaca3dccc2af8b4eae73ee00d2e1e7ffe91ce630c8906981c075161ad8c", - "sha256:4a0cfab6b6c1826e8dfe4453c08aa70343a693dede7c09dca564a9b1f2393374", - "sha256:4a28ad09abccc9f71632398febfea12d3f28cec7e44fe6f2b16665807e62c298", - "sha256:4b092e2a11f37a41e1767a221ff2719397ae2e033f978de236ce10c4b1916227", - "sha256:4b43ae6e1c4b972761065f77f3eff4b914154bc5bd74d632305875c5309eafd1", - "sha256:4b65f4e66efe43dcc5fb3a285f899e798742b8365bafdd832054675d34d640d5", - "sha256:4eba5abcee347bdaa7f1a3f18fd97758f0b75a6dc5704885e793aeb51e8e5e32", - "sha256:50294bae0f20ec4f8d3f5eefd133956f582942c156d08f6b88f2a1b1efe04c53", - "sha256:5e13ba36f18489600db28da13da73e8e190bd48899ad268cb482fe726d31a922", - "sha256:67aa85bbab597615efd83f521c8da34dd9a19b7456cc919c227378c793073183", - "sha256:6a2564ed1a07258a73f7adfb0663aa69022f1edc431d11aae4a32a29e7755d3c", - "sha256:6aa18b255af46641d167378f8b8f06becb6eb1670f622aefa34e502362267fa9", - "sha256:6acedf0778b79b6ea111a28fb23760b5f6b7b1c3e1f1e3595cf87ce709bce344", - "sha256:78be52dc21f578a17e2c1cf1a222d4e64e91e0b1dba7e18f5ff7be7c0bf8053f", - "sha256:7e0fbf05bb74a3f610f970a178bfb4e048f6b82fc22dda5e14e0ddfc4d66c9b7", - "sha256:7eb221dcb9e27415d2bd6e2d3001d1da0f351e2aa1564f6f3987f2206c066600", - "sha256:801094c80d117b0d476f0afbe16cdfe438cc4069c5b0f2578564cb4b3c83f80f", - "sha256:88ceab5cd84f7d86f018fa66377d6f90fcf3643d56283f2f4124ccef58390a0e", - "sha256:8b6603315f9a15e5ed80143a5a744c695a8503e27a76fb5828f7269225f39ddd", - "sha256:8d8a8aef8724058d416536902e680f2b06499e58c54220becdfcd3ff8e5dccfd", - "sha256:8edb59aa5c10a3fb8d3a0c2cac8ba58c0d8f4e56f9003378ac1fff503a8d3f42", - "sha256:8fd68b540fb70954deeb2b6a1fb2f34d6342bcf221e003e6063e3b28e87b2778", - "sha256:900c773d4f9d68747bb19ef40c35c701f4a919a6b96efa2d4e1cb50074a9738e", - "sha256:93d8d5ee37cd9634747a1363496fd3949451bdaeb9539278985cb6fd08d929cf", - "sha256:95a5036b7046f617207f38936c188eeb56dbe740cba0fa1215df2e1b9ee38c74", - "sha256:9f3e8fc3433a86ab0b3d960f8fb48fe7135876df04987dd04b3bf35d9b49ae92", - "sha256:a1b5d286fee4b9b5a0312faede02f2ce2f56ac695685af1d25f428abdac9a22c", - "sha256:a2875f0bdb605e56630f46e12082f26ac2c680a5473f5f154b7131841727948c", - "sha256:a2e496753e91bc82dfbe1f3bab21e0907866dab3c810e255ebaf991cd5c5455d", - "sha256:a4315509a4e155e6bd4b199bd435ff2bb31f558915726e0c50a725ae7b99727f", - "sha256:a5551491ace0f05ae0bbe5a496c4daf216d9fc98e182940f471c228235b1626e", - "sha256:a8d482e2ae01a5ac17183afe8c808cb6919889bdf22f0d3663105ccf0ea89adf", - "sha256:b0ddb34591f5e19296ef5b643e23ec5179a7c1d2b73c17701f50dcfa493e0252", - "sha256:b100895d6b57d6a7e8de5fd15578aaa46170b56d978baf56182c10e8ba725fbf", - "sha256:b213fae58d6ba14ac71a481691981e582ff5813630f3a82aaf92fb79399ba0ec", - "sha256:b3eed06a24157a891eac5f73ec2400d22cccc95cde78a3f0e2b90c5ab17f1cf1", - "sha256:b641683de9bf05b4b52a629bf8ddd5fa0fb061ca54bc2412ce89ce2de2beda36", - "sha256:bf4e83af0bd3cf4c98eaf1ed2d028afd520bdffd6f7570f6cc5a44e9363fbb9a", - "sha256:c96a080cae86c1c27758fdd3fbee0298a006b05272de4dff9dea21ca34952c72", - "sha256:cc5c56169effa5bf9fae5e9a66efc211b3f252869d99d6c400792eced7f213b9", - "sha256:d0a8f16a97758ca9af1baa927521b24175dba7e95ce745d5bf64a5c75fe61df8", - "sha256:d368def4564681f681f4fe1ae906239bb4dc7dd403c49d15d3a6fe2688950f13", - "sha256:e5f19bb887d83959ba1c359fba16cdedb0f868ba85ae375c3e4e0fdf5697a524", - "sha256:ebe1954aa85e622674ea01828419f129527c95c40a392e0f7761e242d85a772f", - "sha256:f38bbab4d13d180ed00c2f107e36503bd2e2cc4c6d4ae2734c0a85c2edaf2d2e", - "sha256:ff281a66925790a05e3c7e0de1350a0992b66a4e51724317ac35026ac856ae28" - ], - "index": "pypi", - "version": "==4.4.0" + "sha256:00c199e1c593e2c8b033136d7a08f0c376452bac8a896c923fcd6f419e07bdd2", + "sha256:010bc9aa90fd06e5cc52c8fac2c2fd4ef1b5f990d9638548dde178005770a5e8", + "sha256:026a24a36394dc8930cbcb1d19d5eb35205ef3c838a7e619e04bd170713972e7", + "sha256:061598cbc6abe2f382ab64c9caa83faa2f4c51256f732cdd890bcc6e63bfb67e", + "sha256:13552ca505366df74e3e2f0a4f27c363928f3dff0eef9f281eb81af7f29bc3c5", + "sha256:13d613c866f9f07d51180f9a7da54ef491d130f169e999c27e7633abe8619ec9", + "sha256:144a31391a39a390efce0c5ebcaf4bf112114af4384c90163f402cec5ede476b", + "sha256:1461199b07903fc1424709efafe379205bf5f738144b1a50a08b0396357b5abf", + "sha256:154b361dcb358ad377d5d40df41ee35f1cc14c8691b50511547c12404f89b5cb", + "sha256:1c5654bb8bb2bdb10e7a0bc3c193dd8b49a960b9eebc4381ff5a2043f4c3c441", + "sha256:1de3c6faf948f3edd4e738abdb4b76572b4f4fdfc1fed4dad02427e70c5a6219", + "sha256:1ed23b0e2dac6f84f44c8494fbceefe6eb5c35db5c1099f56ab78fc0d94ab3af", + "sha256:1f2b856518bfcfa316c8dae3d7b412aecacf2e8ba30b149f5eb3b63128d703b9", + "sha256:2346450a075625c4d6166b40a013b605a38b6b6168ce2232b192a37fb200d588", + "sha256:262356ea5fcb13d35fb2ab6009d3927bafb9504ef02339338634fffd8a9f1ae4", + "sha256:27b81ecf18031998ad7db53b960d1347f8f29e8b7cb5ea7b4394726468e4295e", + "sha256:2940aa20e9cc328e8ddeacea8b9a6f5ddafe0b087fedad928912e787c65b4909", + "sha256:2d4ccac3053b84a09251da8f5350bb684cbbf8c8c01eda6b5418417d0a8ab198", + "sha256:2dd2f6960ee3c9360bed7fb3c678be0ca2d00f877068556785ec2eb6b73d2414", + "sha256:3071ec998cc3d7b4944377e5f1217c2c44b811fae16f9a495c7a1ce9b42fb038", + "sha256:3094c7d2f820eecabadae76bfec02669567bbdd1730eabce10a5764778564f7b", + "sha256:30b2c9caf3e55c2e323565d1f3b7e7881ab87db16997dc0cbca7c52885ed2347", + "sha256:3177f783ae7e08aaf7b2802e0df4e4b13903520e8380915e6337cdc7a6ff01d8", + "sha256:31dab1f3e1d0cdd57e8df01b645f52d43cc1b653ed3afd535d2891f4fc4f9712", + "sha256:33bb16a07d3cc4e0aea37b242097cd5f7a156312012455c2fa8ca396953b11c4", + "sha256:349093675a2d3759e4fb42b596afffa2b2518c890492563d7905fac503b20daa", + "sha256:39d77d8bbb392fa443831e6d4ae534237b1f4eee6aa186f0cdb4e334ba89536e", + "sha256:3a7f02a58a0c2912734105e05dedbee4f7507e6f1bd132ebad520be0b11d46fd", + "sha256:3b287e814a01deddb59b88549c1e0c87cefacd798d4afc0c8bd6042d1c3d48aa", + "sha256:3c74f4725485f0a7a3862cfd374cc1b740cebe4c133e0c1425984bcdcce0f4bb", + "sha256:3cadf7f4c8e94d8a77874b54a63c80af01f4d48c4b669c8b6867f86a07ba994f", + "sha256:3d18a9b9b858ee140c15c5bfcb3e66e47e2a70a03272c2e72adda2482f76a6ad", + "sha256:3f0e6a6c807fa887a0c51cc24fe7ea51bb9e496fe88f00d7930063372c3664c3", + "sha256:4344c30025210b9fa80ec257b0e0aab5aa1d5cca91daa70d82ab97b482cc038e", + "sha256:4497d49d785482cc1a44a0ddf8830b036a468c088e72a05217f5b60a9e025012", + "sha256:547dc5d7f834b1deefda51aedb11a7af9c51c45e689e44e14aa85d44147c7657", + "sha256:5556e306713e2522e460287615d26c0af0fe5ed9d4f431dad35c6624c5d277e9", + "sha256:55dac73316e7e8c2616ba2e6f62b750918e9e0ae0b2053699d66ca27a7790105", + "sha256:56816e43c92c2fa8c11dc2a686f0ca248bea7902f4a067fa6cbc77853b0f041e", + "sha256:5bd94c503271e79917b27c6e77f7c5474da6930b3fb9e70a12e68c2dff386b9a", + "sha256:5ec31adc2e988fd7db3ab509954791bbc5a452a03c85e45b804b4bfc31fa221d", + "sha256:69247f7a2835fc0984bbf0892e6022e9a36aec70e187fcfe6cae6a373eb8c4de", + "sha256:6a0ae7a48a6ef82ceb98a366948874834b86c84e288dbd55600c1abfc3ac1d88", + "sha256:6a1810c2cbde714decf40f811d1edc0dae45506eb37298fd9d4247b8801509fe", + "sha256:6dcc95f4bb9ed793714b43f4f23a7b0c57e4ef47414162297d6f650213512c19", + "sha256:76013fef1c9cd1cd00d55efde516c154aa169f2bf059b197c263a255ba8a9ddf", + "sha256:77e0df59b1a4994ad30c6d746992ae887f9756a43fc25dec2db515d94cf0222d", + "sha256:7bb0e9049e81def6829d09558ad12d16d0454c26cabe6efc3658e544460688d9", + "sha256:88beb444fb438385e53dc9110852910ec2a22f0eab7dd489e827038fdc19ed8d", + "sha256:8b47ebd89e69fbf33d1c2df79759d7162fc80c7652dacfec136dae1c9b3afac7", + "sha256:8d219b4508f71d762368caec1fc180960569766049bbc4d38174f05e8ef2fe5b", + "sha256:8ec75f35f62571a43e31e7bd11749d974c1b5cd5ea4a8388725d579263c0fdf6", + "sha256:9167e735379ec43d8eafa3fd675bfbb12e2c0464f98960586e9447d2cf2c7a83", + "sha256:9a710c184ba845afb05a6f876edac8f27783ba70e52d5eaf939f121fc13b2f59", + "sha256:9aafd036f6f2e5ad109aec92f8dbfcbe76cff16bad683eb6dd18013739c0b3ae", + "sha256:9c79d597fb3a7c93d7c26924db7497eba06d58f88f58e586aa69b2ad89fee0f8", + "sha256:a2831e05ce0a4df10c4ac5399ef50b9a621f90894c2a4d2945dc5658765514ed", + "sha256:a5e641f931c5cd95b376fd3c59db52770e17bec2bf86ef16cc83b3906c054845", + "sha256:b10d8cda9fc2fcdcfa4a000aa10413a2bf8b575852cd07cb8a595ed09689ca98", + "sha256:b435b13bb8e36be11b75f7384a34eefe487fe87a6267172964628e2b14ecf0a7", + "sha256:b7b1a83ce514700276a46af3d9e481ec381f05b64939effc9065afe18456a6b9", + "sha256:b8729dbf25eb32ad0dc0b9bd5e6a0d0b7e5c2dc8ec06ad171088e1896b522a74", + "sha256:bbed8cccebe1169d45cedf00461b2842652d476d2897fd1c42cf41b635d88746", + "sha256:c258dbacfff1224f13576147df16ce3c02024a0d792fd0323ac01bed5d3c545d", + "sha256:c30a9e06041fbd7a7590693ec5e407aa8737ad91912a1e70176aff92e5c99d20", + "sha256:c91ea3915425bd4111cb1b74511cdc56d1d16a683a48bf2a5a96b6a6c0f297f7", + "sha256:d0355cff58a4ed6d5e5f6b9c3693f52de0784aa0c17119394e2a8e376ce489d4", + "sha256:d483793a384c550c2d12cb794ede294d303b42beff75f3b3081f57196660edaf", + "sha256:d4c2be9760b112b1caf649b4977b81b69893d75aa86caf4f0f398447be871f3c", + "sha256:d8e62d06e90f60ea2a3d463ae51401475568b995bafaffd81767d208d84d7bb1", + "sha256:da08ea09eefa6b960c2dd9a68ec47949235485c623621eb1d6c02b46765322ac", + "sha256:dd1fa413f8b9ba30140de198e4f408ffbba6396864c7554e0867aa7363eb58b2", + "sha256:e2aced6fb2f5261b47d267cb40060b73b6527e64afe54f6497844c9affed5fd0", + "sha256:e438417ce1dc5b758742e12661d800482200b042d03512a8f31f6aaa9137ad40", + "sha256:e470fa4bace5f50076c32f4b3cc182b31303b4fefb9b87f990144515d572820b", + "sha256:eaf2f65190c506def2581219572b9c70b8250615dc918b3b7c218361a51ec42e", + "sha256:ef102a67ede70e1721fe27f75073b5314911dbb9bc27cde0a1c402a11531e7bd", + "sha256:ef801027629c5b511cf2ba13b9be29bfee36ae834b2d95d9877818479cdc99ea", + "sha256:f7acc03a4f1154ba2643edeb13658d08598fe6e490c3dd96a241b94f09801626", + "sha256:f9756f1d25454ba6a3c2f1ef8b7ddec23e5cdeae3dc3c3377243ae37a383db00", + "sha256:ff62ba8ff70f01ab4fe0ae36b2cb0b5d1f42e73dfc81ddf0758cd9f77331ad25", + "sha256:ff925f1cca42e933376d09ddc254598f8c5fcd36efc5cac0118bb36c36217c41" + ], + "index": "pypi", + "version": "==4.6.1" }, "pyparsing": { "hashes": [ @@ -734,11 +758,11 @@ }, "setuptools": { "hashes": [ - "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f", - "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235" + "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", + "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" ], - "markers": "python_version >= '3.7'", - "version": "==68.0.0" + "markers": "python_version >= '3.8'", + "version": "==69.0.3" }, "shellingham": { "hashes": [ diff --git a/app/api/mal.py b/app/api/mal.py index 8d7976e..da22ef9 100644 --- a/app/api/mal.py +++ b/app/api/mal.py @@ -67,6 +67,21 @@ def get_token(self, authorization_code: str): 'refresh_token': resp_json['refresh_token'] } + @staticmethod + def get_user_details(token: str): + """ + Get the user's details from MyAnimeList + :param token: The user's access token + :return: JSON response + """ + if token is None: + raise Exception("Auth Token Must Be Provided") + + headers = kwargs_to_dict(Authorization=f'Bearer {token}') + resp = requests.get(f'{BASE_URL}/users/@me', headers=headers) + resp.raise_for_status() + return resp.json() + # noinspection DuplicatedCode @staticmethod def get_anime_list(token: str, query: str, **kwargs): diff --git a/app/db/db.py b/app/db/db.py index 9b1eca8..ebdc5ce 100644 --- a/app/db/db.py +++ b/app/db/db.py @@ -5,3 +5,4 @@ client = MongoClient(Config.MONGO_URI) db = client.get_database(Config.MONGO_DB) anime_map_collection = db.get_collection(Config.MONGO_ANIME_MAP) +UID_map_collection = db.get_collection(Config.MONGO_UID_MAP) diff --git a/app/routes/auth.py b/app/routes/auth.py index c95b4c3..08d0ff0 100644 --- a/app/routes/auth.py +++ b/app/routes/auth.py @@ -1,6 +1,7 @@ -from flask import Blueprint, request, render_template +from flask import Blueprint, request, render_template, session from werkzeug.utils import redirect +from app.db.db import UID_map_collection from app.routes import mal_client from config import Config @@ -26,6 +27,17 @@ def redirect_url(): auth_data = mal_client.get_token(code) access_token = auth_data['access_token'] - manifest_url = f'{Config.PROTOCOL}://{Config.REDIRECT_URL}/{access_token}/manifest.json' - manifest_magnet = f'stremio://{Config.REDIRECT_URL}/{access_token}/manifest.json' + # Get the user's username + user_details = mal_client.get_user_details(access_token) + user_id = str(user_details['id']) + + # Add the user to the database + user = UID_map_collection.find_one({'uid': user_id}) + if user: + UID_map_collection.update_one(user, {'$set': {'access_token': access_token}}) + else: + UID_map_collection.insert_one({'uid': user_id, 'access_token': access_token}) + + manifest_url = f'{Config.PROTOCOL}://{Config.REDIRECT_URL}/{user_id}/manifest.json' + manifest_magnet = f'stremio://{Config.REDIRECT_URL}/{user_id}/manifest.json' return render_template('index.html', manifest_url=manifest_url, manifest_magnet=manifest_magnet) diff --git a/app/routes/catalog.py b/app/routes/catalog.py index 36b9ed4..078ad2a 100644 --- a/app/routes/catalog.py +++ b/app/routes/catalog.py @@ -3,17 +3,17 @@ from . import mal_client from .manifest import MANIFEST -from .utils import respond_with, mal_to_meta +from .utils import respond_with, mal_to_meta, get_token catalog_bp = Blueprint('catalog', __name__) -@catalog_bp.route('//catalog//.json') -@catalog_bp.route('//catalog///skip=.json') -def addon_catalog(token: str, catalog_type: str, catalog_id: str, offset: str = None): +@catalog_bp.route('//catalog//.json') +@catalog_bp.route('//catalog///skip=.json') +def addon_catalog(user_id: str, catalog_type: str, catalog_id: str, offset: str = None): """ Provides a list of anime from MyAnimeList - :param token: The user's API token for MyAnimeList + :param user_id: The user's MyAnimeList ID :param catalog_type: The type of catalog to return :param catalog_id: The ID of the catalog to return, MAL divides a user's anime list into different categories (e.g. plan to watch, watching, completed, on hold, dropped) @@ -32,6 +32,8 @@ def addon_catalog(token: str, catalog_type: str, catalog_id: str, offset: str = if not catalog_exists: abort(404) + token = get_token(user_id) + field_params = 'media_type genres mean start_date end_date synopsis' # Additional fields to return response_data = mal_client.get_user_anime_list(token, status=catalog_id, offset=offset, fields=field_params) response_data = response_data['data'] # Get array of node objects @@ -46,11 +48,11 @@ def addon_catalog(token: str, catalog_type: str, catalog_id: str, offset: str = return respond_with({'metas': meta_previews}) -@catalog_bp.route('//catalog///search=.json') -def search_metas(token: str, catalog_type: str, catalog_id: str, search_query: str): +@catalog_bp.route('//catalog///search=.json') +def search_metas(user_id: str, catalog_type: str, catalog_id: str, search_query: str): """ Provides a list of anime from MyAnimeList based on a search query - :param token: The user's API token for MyAnimeList + :param user_id: The user's MyAnimeList ID :param catalog_type: The type of catalog to return :param catalog_id: The ID of the catalog to return, MAL divides a user's anime list into different categories (e.g. plan to watch, watching, completed, on hold, dropped) @@ -69,6 +71,8 @@ def search_metas(token: str, catalog_type: str, catalog_id: str, search_query: s if not catalog_exists: abort(404) + token = get_token(user_id) + field_params = 'media_type alternative_titles' # Additional fields to return response = mal_client.get_anime_list(token, query=search_query, fields=field_params) response_data: list = response['data'] # Get array of node objects diff --git a/app/routes/manifest.py b/app/routes/manifest.py index a12b58b..54265d1 100644 --- a/app/routes/manifest.py +++ b/app/routes/manifest.py @@ -1,7 +1,8 @@ -from flask import Blueprint +from flask import Blueprint, abort from . import MAL_ID_PREFIX, IMDB_ID_PREFIX from .utils import respond_with +from ..db.db import UID_map_collection manifest_blueprint = Blueprint('manifest', __name__) @@ -34,11 +35,16 @@ } -@manifest_blueprint.route('//manifest.json') -def addon_manifest(token: str): +@manifest_blueprint.route('//manifest.json') +def addon_manifest(user_id: str): """ Provides the manifest for the addon - :param token: The user's API token for MyAnimeList + :param user_id: The user's MyAnimeList ID :return: JSON response """ + + user = UID_map_collection.find_one({'uid': user_id}) + if not user: + return abort(404, f'User ID: {user_id} not found') + return respond_with(MANIFEST) diff --git a/app/routes/meta.py b/app/routes/meta.py index a86d377..5d20811 100644 --- a/app/routes/meta.py +++ b/app/routes/meta.py @@ -1,9 +1,8 @@ -import requests -from flask import Blueprint, abort +from flask import Blueprint, abort, session from . import mal_client, MAL_ID_PREFIX from .manifest import MANIFEST -from .utils import mal_to_meta, respond_with +from .utils import mal_to_meta, respond_with, get_token from ..db.db import anime_map_collection meta = Blueprint('meta', __name__) @@ -12,11 +11,11 @@ kitsu_API = "https://anime-kitsu.strem.fun/meta" -@meta.route('//meta//.json') -def addon_meta(token: str, meta_type: str, meta_id: str): +@meta.route('//meta//.json') +def addon_meta(user_id: str, meta_type: str, meta_id: str): """ Provides metadata for a specific content - :param token: The user's API token for MyAnimeList + :param user_id: The user's API token for MyAnimeList :param meta_type: The type of metadata to return :param meta_id: The ID of the content :return: JSON response @@ -25,6 +24,8 @@ def addon_meta(token: str, meta_type: str, meta_id: str): if meta_type not in MANIFEST['types']: abort(404) + token = get_token(user_id) + # Fetch anime details from MAL anime_id = meta_id.replace(MAL_ID_PREFIX, '') # Extract anime id from addon meta id field_params = 'media_type genres mean start_date end_date synopsis pictures' # Additional fields to return diff --git a/app/routes/stream.py b/app/routes/stream.py index 00212ae..00d7e40 100644 --- a/app/routes/stream.py +++ b/app/routes/stream.py @@ -9,11 +9,11 @@ torrentio_lite_API = "https://torrentio.strem.fun/lite/stream/" -@stream_bp.route('//stream//.json') -def addon_stream(token: str, stream_type: str, content_id: str): +@stream_bp.route('//stream//.json') +def addon_stream(user_id: str, stream_type: str, content_id: str): """ Provides a stream for a specific content - :param token: The user's API token for MyAnimeList + :param user_id: The user's MyAnimeList ID :param stream_type: The type of stream of the content :param content_id: The ID of the content :return: JSON response diff --git a/app/routes/utils.py b/app/routes/utils.py index 71e0a96..dd9cc69 100644 --- a/app/routes/utils.py +++ b/app/routes/utils.py @@ -1,7 +1,8 @@ import random -from flask import jsonify +from flask import jsonify, abort +from app.db.db import UID_map_collection from app.routes import MAL_ID_PREFIX @@ -71,3 +72,11 @@ def mal_to_meta(anime_item: dict): 'releaseInfo': start_date, 'description': synopsis } + + +def get_token(user_id: str): + user = UID_map_collection.find_one({'uid': user_id}) + if not user: + return abort(404, 'User not found') + + return user['access_token'] diff --git a/config.py b/config.py index 0b30d36..f6a0c91 100644 --- a/config.py +++ b/config.py @@ -18,6 +18,7 @@ class Config: MONGO_URI = os.getenv('MONGO_URI', "") MONGO_DB = os.getenv('MONGO_DB', "") MONGO_ANIME_MAP = os.getenv('MONGO_ANIME_MAP_COLLECTION', "") + MONGO_UID_MAP = os.getenv('MONGO_UID_MAP_COLLECTION', "") # Addon API # redirect URI depending on environment