diff options
| author | Fuwn <[email protected]> | 2023-07-28 21:34:34 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2023-07-28 21:34:34 -0700 |
| commit | c32dd8832580d5850dbe6d2146a0d1d50a14756d (patch) | |
| tree | 15f7abd8d2315f53624a9ff28a73b003e1953c7d | |
| parent | feat(index): username route (diff) | |
| download | old.due.moe-c32dd8832580d5850dbe6d2146a0d1d50a14756d.tar.xz old.due.moe-c32dd8832580d5850dbe6d2146a0d1d50a14756d.zip | |
refactor(due): like-functions to modules
| -rw-r--r-- | src/due/__init__.py | 2 | ||||
| -rw-r--r-- | src/due/anilist/__init__.py | 0 | ||||
| -rw-r--r-- | src/due/anilist/collection.py | 52 | ||||
| -rw-r--r-- | src/due/anilist/media.py | 31 | ||||
| -rw-r--r-- | src/due/anilist/utilities.py | 48 | ||||
| -rw-r--r-- | src/due/html/__init__.py | 0 | ||||
| -rw-r--r-- | src/due/html/anime.py | 51 | ||||
| -rw-r--r-- | src/due/html/manga.py (renamed from src/due/html.py) | 122 | ||||
| -rw-r--r-- | src/due/html/utilities.py | 72 | ||||
| -rw-r--r-- | src/due/media.py | 129 | ||||
| -rw-r--r-- | src/due/routes/index.py | 7 |
11 files changed, 261 insertions, 253 deletions
diff --git a/src/due/__init__.py b/src/due/__init__.py index 6b10591..863a817 100644 --- a/src/due/__init__.py +++ b/src/due/__init__.py @@ -1,6 +1,6 @@ from flask import Flask from due.routes import auth, oauth, index -from due.html import page +from due.html.utilities import page from flask_cors import CORS from dotenv import load_dotenv from due.cache import cache diff --git a/src/due/anilist/__init__.py b/src/due/anilist/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/due/anilist/__init__.py diff --git a/src/due/anilist/collection.py b/src/due/anilist/collection.py new file mode 100644 index 0000000..0e67602 --- /dev/null +++ b/src/due/anilist/collection.py @@ -0,0 +1,52 @@ +import requests +from .utilities import user_id + + +def create_collection(anilist, type, username=None): + current_collection = media_list_collection(anilist, type, username) + current = [] + + for list in current_collection["MediaListCollection"]["lists"]: + current += list["entries"] + + return (current, current_collection["MediaListCollection"]["user"]["name"]) + + +def media_list_collection(anilist, type, username=None): + return requests.post( + "https://graphql.anilist.co", + json={ + "query": media_list_collection_query( + user_id(anilist) if username is None else user_name_to_id(username), + type, + ) + }, + headers={ + "Authorization": anilist["token_type"] + " " + anilist["access_token"], + "Content-Type": "application/json", + "Accept": "application/json", + }, + ).json()["data"] + + +def media_list_collection_query(user_id: int, type) -> str: + return f"""{{ + MediaListCollection(userId: {user_id}, type: {"ANIME" if type == "ANIME" else "MANGA"}, status_not_in: [COMPLETED]) {{ + hasNextChunk + lists {{ + entries {{ + media {{ + id + status + type + episodes + title {{ romaji english native }} + nextAiringEpisode {{ episode }} + mediaListEntry {{ progress }} + startDate {{ year }} + }} + }} + }} + user {{ name }} + }} + }}""" diff --git a/src/due/anilist/media.py b/src/due/anilist/media.py new file mode 100644 index 0000000..b8fadfa --- /dev/null +++ b/src/due/anilist/media.py @@ -0,0 +1,31 @@ +# import requests + +# def media_list(anilist, pageNumber): +# return requests.post( +# "https://graphql.anilist.co", +# json={"query": media_list_query(user_id(anilist), pageNumber)}, +# headers={ +# "Authorization": anilist["token_type"] + " " + anilist["access_token"], +# "Content-Type": "application/json", +# "Accept": "application/json", +# }, +# ).json()["data"] + + +# def media_list_query(user_id: int, page_number: int) -> str: +# return f"""{{ +# Page(page: {page_number}) {{ +# mediaList(userId: {user_id}, status_not_in: [COMPLETED]) {{ +# media {{ +# id +# status +# type +# title {{ romaji english }} +# nextAiringEpisode {{ episode }} +# mediaListEntry {{ progress }} +# startDate {{ year }} +# }} +# }} +# pageInfo {{ hasNextPage }} +# }} +# }}""" diff --git a/src/due/anilist/utilities.py b/src/due/anilist/utilities.py new file mode 100644 index 0000000..033939e --- /dev/null +++ b/src/due/anilist/utilities.py @@ -0,0 +1,48 @@ +import requests + + +def user_id(anilist): + viewer = requests.post( + "https://graphql.anilist.co", + json={"query": "{ Viewer { id } }"}, + headers={ + "Authorization": anilist["token_type"] + " " + anilist["access_token"], + "Content-Type": "application/json", + "Accept": "application/json", + }, + ).json()["data"]["Viewer"] + + if viewer is None: + return -1 + + return int(viewer["id"]) + + +def last_activity(id): + return int( + requests.post( + "https://graphql.anilist.co", + json={ + "query": f"""{{ Activity(userId: {id}, type: MEDIA_LIST, sort: ID_DESC) {{ + __typename ... on ListActivity {{ createdAt }} + }} }}""" + }, + headers={ + "Content-Type": "application/json", + "Accept": "application/json", + }, + ).json()["data"]["Activity"]["createdAt"] + ) + + +def user_name_to_id(name): + return int( + requests.post( + "https://graphql.anilist.co", + json={"query": f'{{ User(name: "{name}") {{ id }} }}'}, + headers={ + "Content-Type": "application/json", + "Accept": "application/json", + }, + ).json()["data"]["User"]["id"] + ) diff --git a/src/due/html/__init__.py b/src/due/html/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/due/html/__init__.py diff --git a/src/due/html/anime.py b/src/due/html/anime.py new file mode 100644 index 0000000..1113965 --- /dev/null +++ b/src/due/html/anime.py @@ -0,0 +1,51 @@ +from flask import request +from .utilities import seen + + +def anime_to_html(releasing_outdated_anime): + current_html = [] + ids = [] + + for media in releasing_outdated_anime: + anime = media["media"] + title = anime["title"]["english"] + id = anime["id"] + + if id in ids: + continue + else: + ids.append(id) + + progress = (anime["mediaListEntry"] or {"progress": 0})["progress"] + available = ( + {"episode": 0} + if media["media"]["nextAiringEpisode"] is None + else media["media"]["nextAiringEpisode"] + )["episode"] - 1 + + if available <= 0: + available = "?" + + if title is None: + title = anime["title"]["romaji"] + + if request.cookies.get("show_missing") is not None and str(available)[0] == "?": + ids.pop() + + continue + + episodes = anime["episodes"] + total_html = ( + "" if episodes is None else f'<span style="opacity: 50%">/{episodes}</span>' + ) + + current_html.append( + f'<li><a href="https://anilist.co/anime/{id}" target="_blank">{title}</a> {progress}{total_html} [{available}]</li>' + ) + + current_html = sorted(current_html, key=seen) + + current_html.insert(0, "<ul>") + current_html.append("</ul>") + + return ("".join(current_html), len(ids)) diff --git a/src/due/html.py b/src/due/html/manga.py index a43753b..8e74a63 100644 --- a/src/due/html.py +++ b/src/due/html/manga.py @@ -1,91 +1,9 @@ import requests import joblib from due.cache import cache -from flask import request import math -import re import os - - -def seen(element, manga=False): - read = 0 - - if manga: - available_matches = re.search(r"\[<a.*?>(\d+)<\/a>\]", element) - read_matches = re.search(r"\[<a.*?>(?=\d+)<\/a>\]", element) - - if read_matches: - read = int(read_matches.group()) - print(read) - - if available_matches: - return int(available_matches.group(1)) - read - else: - return 0 - - available_matches = re.findall(r"\d+\]|\[\d+", element) - seen_matches = re.search( - r"\s(\d+)*?(<span style=\"opacity: 50%\">/(\d+)</span>)*\s", element - ) - - if seen_matches: - read = int(seen_matches.group(1)) - - if len(available_matches) > 1: - return int(available_matches[1].strip("[]")) - read - elif len(available_matches) == 1: - return int(available_matches[0].strip("[]")) - read - else: - return 0 - - -def anime_to_html(releasing_outdated_anime): - current_html = [] - ids = [] - - for media in releasing_outdated_anime: - anime = media["media"] - title = anime["title"]["english"] - id = anime["id"] - - if id in ids: - continue - else: - ids.append(id) - - progress = (anime["mediaListEntry"] or {"progress": 0})["progress"] - available = ( - {"episode": 0} - if media["media"]["nextAiringEpisode"] is None - else media["media"]["nextAiringEpisode"] - )["episode"] - 1 - - if available <= 0: - available = "?" - - if title is None: - title = anime["title"]["romaji"] - - if request.cookies.get("show_missing") is not None and str(available)[0] == "?": - ids.pop() - - continue - - episodes = anime["episodes"] - total_html = ( - "" if episodes is None else f'<span style="opacity: 50%">/{episodes}</span>' - ) - - current_html.append( - f'<li><a href="https://anilist.co/anime/{id}" target="_blank">{title}</a> {progress}{total_html} [{available}]</li>' - ) - - current_html = sorted(current_html, key=seen) - - current_html.insert(0, "<ul>") - current_html.append("</ul>") - - return ("".join(current_html), len(ids)) +from .utilities import seen def manga_to_html(releasing_outdated_manga, show_missing): @@ -242,41 +160,3 @@ def manga_to_html(releasing_outdated_manga, show_missing): current_html.append("</ul>") return ("".join(current_html), len(ids)) - - -def page(main_content, footer): - message = '<blockquote>Slow loads? If your media hasn\'t been cached in a while, the first load will take a couple seconds longer than the rest. Subsequent requests on cached media should be faster. <a href="/?hide_message">Hide <i>forever</i></a></blockquote>' - - if request.cookies.get("hide_message") == "1": - message = "" - - return f""" -<!DOCTYPE html> -<html> - <head> - <title>期限</title> - - <link rel="stylesheet" type="text/css" href="https://latex.now.sh/style.css"> - <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/palettes/base16-light.css"> - <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/risotto.css"> - <!-- <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/custom.css"> --> - <link rel="shortcut icon" type="image/x-icon" href="https://ps.fuwn.me/-tePaWtKW2y/angry-miku-nakano.ico"> - </head> - - <body> - <style>text-align: center;</style> - - <h1><a href="/">期限</a></h1> - - {main_content} - - <p></p> - - <hr> - - <p>{footer}</p> - - {message} - </body> -</html> -""" diff --git a/src/due/html/utilities.py b/src/due/html/utilities.py new file mode 100644 index 0000000..367b434 --- /dev/null +++ b/src/due/html/utilities.py @@ -0,0 +1,72 @@ +from flask import request +import re + + +def seen(element, manga=False): + read = 0 + + if manga: + available_matches = re.search(r"\[<a.*?>(\d+)<\/a>\]", element) + read_matches = re.search(r"\[<a.*?>(?=\d+)<\/a>\]", element) + + if read_matches: + read = int(read_matches.group()) + print(read) + + if available_matches: + return int(available_matches.group(1)) - read + else: + return 0 + + available_matches = re.findall(r"\d+\]|\[\d+", element) + seen_matches = re.search( + r"\s(\d+)*?(<span style=\"opacity: 50%\">/(\d+)</span>)*\s", element + ) + + if seen_matches: + read = int(seen_matches.group(1)) + + if len(available_matches) > 1: + return int(available_matches[1].strip("[]")) - read + elif len(available_matches) == 1: + return int(available_matches[0].strip("[]")) - read + else: + return 0 + + +def page(main_content, footer): + message = '<blockquote>Slow loads? If your media hasn\'t been cached in a while, the first load will take a couple seconds longer than the rest. Subsequent requests on cached media should be faster. <a href="/?hide_message">Hide <i>forever</i></a></blockquote>' + + if request.cookies.get("hide_message") == "1": + message = "" + + return f""" +<!DOCTYPE html> +<html> + <head> + <title>期限</title> + + <link rel="stylesheet" type="text/css" href="https://latex.now.sh/style.css"> + <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/palettes/base16-light.css"> + <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/risotto.css"> + <!-- <link rel="stylesheet" type="text/css" href="https://skybox.sh/css/custom.css"> --> + <link rel="shortcut icon" type="image/x-icon" href="https://ps.fuwn.me/-tePaWtKW2y/angry-miku-nakano.ico"> + </head> + + <body> + <style>text-align: center;</style> + + <h1><a href="/">期限</a></h1> + + {main_content} + + <p></p> + + <hr> + + <p>{footer}</p> + + {message} + </body> +</html> +""" diff --git a/src/due/media.py b/src/due/media.py deleted file mode 100644 index e97cc83..0000000 --- a/src/due/media.py +++ /dev/null @@ -1,129 +0,0 @@ -import requests - - -def user_id(anilist): - viewer = requests.post( - "https://graphql.anilist.co", - json={"query": "{ Viewer { id } }"}, - headers={ - "Authorization": anilist["token_type"] + " " + anilist["access_token"], - "Content-Type": "application/json", - "Accept": "application/json", - }, - ).json()["data"]["Viewer"] - - if viewer is None: - return -1 - - return int(viewer["id"]) - - -def last_activity(id): - return int( - requests.post( - "https://graphql.anilist.co", - json={ - "query": f"""{{ Activity(userId: {id}, type: MEDIA_LIST, sort: ID_DESC) {{ - __typename ... on ListActivity {{ createdAt }} - }} }}""" - }, - headers={ - "Content-Type": "application/json", - "Accept": "application/json", - }, - ).json()["data"]["Activity"]["createdAt"] - ) - - -def user_name_to_id(name): - return int( - requests.post( - "https://graphql.anilist.co", - json={"query": f'{{ User(name: "{name}") {{ id }} }}'}, - headers={ - "Content-Type": "application/json", - "Accept": "application/json", - }, - ).json()["data"]["User"]["id"] - ) - - -def create_collection(anilist, type, username=None): - current_collection = media_list_collection(anilist, type, username) - current = [] - - for list in current_collection["MediaListCollection"]["lists"]: - current += list["entries"] - - return (current, current_collection["MediaListCollection"]["user"]["name"]) - - -# def media_list(anilist, pageNumber): -# return requests.post( -# "https://graphql.anilist.co", -# json={"query": media_list_query(user_id(anilist), pageNumber)}, -# headers={ -# "Authorization": anilist["token_type"] + " " + anilist["access_token"], -# "Content-Type": "application/json", -# "Accept": "application/json", -# }, -# ).json()["data"] - - -# def media_list_query(user_id: int, page_number: int) -> str: -# return f"""{{ -# Page(page: {page_number}) {{ -# mediaList(userId: {user_id}, status_not_in: [COMPLETED]) {{ -# media {{ -# id -# status -# type -# title {{ romaji english }} -# nextAiringEpisode {{ episode }} -# mediaListEntry {{ progress }} -# startDate {{ year }} -# }} -# }} -# pageInfo {{ hasNextPage }} -# }} -# }}""" - - -def media_list_collection(anilist, type, username=None): - return requests.post( - "https://graphql.anilist.co", - json={ - "query": media_list_collection_query( - user_id(anilist) if username is None else user_name_to_id(username), - type, - ) - }, - headers={ - "Authorization": anilist["token_type"] + " " + anilist["access_token"], - "Content-Type": "application/json", - "Accept": "application/json", - }, - ).json()["data"] - - -def media_list_collection_query(user_id: int, type) -> str: - return f"""{{ - MediaListCollection(userId: {user_id}, type: {"ANIME" if type == "ANIME" else "MANGA"}, status_not_in: [COMPLETED]) {{ - hasNextChunk - lists {{ - entries {{ - media {{ - id - status - type - episodes - title {{ romaji english native }} - nextAiringEpisode {{ episode }} - mediaListEntry {{ progress }} - startDate {{ year }} - }} - }} - }} - user {{ name }} - }} - }}""" diff --git a/src/due/routes/index.py b/src/due/routes/index.py index 49f5acc..c029e01 100644 --- a/src/due/routes/index.py +++ b/src/due/routes/index.py @@ -1,6 +1,9 @@ import time -from due.html import anime_to_html, manga_to_html, page -from due.media import create_collection, last_activity, user_id, user_name_to_id +from due.html.utilities import page +from due.html.anime import anime_to_html +from due.html.manga import manga_to_html +from due.anilist.collection import create_collection +from due.anilist.utilities import last_activity, user_id, user_name_to_id from flask import make_response, redirect, request, Blueprint import json import os |