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 /src/due/html | |
| parent | feat(index): username route (diff) | |
| download | old.due.moe-c32dd8832580d5850dbe6d2146a0d1d50a14756d.tar.xz old.due.moe-c32dd8832580d5850dbe6d2146a0d1d50a14756d.zip | |
refactor(due): like-functions to modules
Diffstat (limited to 'src/due/html')
| -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 | 162 | ||||
| -rw-r--r-- | src/due/html/utilities.py | 72 |
4 files changed, 285 insertions, 0 deletions
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/manga.py b/src/due/html/manga.py new file mode 100644 index 0000000..8e74a63 --- /dev/null +++ b/src/due/html/manga.py @@ -0,0 +1,162 @@ +import requests +import joblib +from due.cache import cache +import math +import os +from .utilities import seen + + +def manga_to_html(releasing_outdated_manga, show_missing): + current_html = [] + ids = [] + + def process(media): + manga = media["media"] + title = manga["title"]["native"] + id = manga["id"] + previous_volume_largest_chapter = 0 + + if id in ids: + return + else: + ids.append(id) + + progress = manga["mediaListEntry"]["progress"] + available = ( + {"episode": 0} + if media["media"]["nextAiringEpisode"] is None + else media["media"]["nextAiringEpisode"] + )["episode"] - 1 + + if available <= 0: + available = "?" + + mangadex_data = cache.get(str(manga["id"]) + "id") + mangadex_id = None + + if mangadex_data is None: + mangadex_data = requests.get( + "https://api.mangadex.org/manga", + params={"title": title, "year": manga["startDate"]["year"]}, + ).json()["data"] + + # This is very stupid. It should never get this far, anyway. + if len(mangadex_data) == 0: + mangadex_data = requests.get( + "https://api.mangadex.org/manga", + params={ + "title": manga["title"]["romaji"], + "year": manga["startDate"]["year"], + }, + ).json()["data"] + + if len(mangadex_data) == 0: + mangadex_data = requests.get( + "https://api.mangadex.org/manga", + params={ + "title": manga["title"]["romaji"], + "year": manga["startDate"]["year"], + }, + ).json()["data"] + + cache.set(str(manga["id"]) + "id", mangadex_data) + + if len(mangadex_data) == 0: + available = "?" + else: + mangadex_id = mangadex_data[0]["id"] + manga_chapter_aggregate = cache.get(str(manga["id"]) + "ag") + + if manga_chapter_aggregate is None: + manga_chapter_aggregate = requests.get( + f"https://api.mangadex.org/manga/{mangadex_id}/aggregate", + ).json() + + cache.set(str(manga["id"]) + "ag", manga_chapter_aggregate) + + if "none" in manga_chapter_aggregate["volumes"]: + previous_volume_largest_chapter = list( + manga_chapter_aggregate["volumes"][ + str( + dict(enumerate(manga_chapter_aggregate["volumes"])).get(1) + or "none" + ) + ]["chapters"] + )[0] + available = list( + manga_chapter_aggregate["volumes"]["none"]["chapters"] + )[0] + + if str(available) == "none": + available = list( + manga_chapter_aggregate["volumes"]["none"]["chapters"] + )[1] + else: + try: + available = list( + manga_chapter_aggregate["volumes"][ + str(list(manga_chapter_aggregate["volumes"])[0]) + ]["chapters"] + )[0] + except Exception: + available = "?" + + if not str(available)[0].isdigit(): + if len(manga_chapter_aggregate["volumes"]) == 0: + ids.pop() + + return + + available = math.floor( + float( + list(manga_chapter_aggregate["volumes"]["1"]["chapters"])[0] + ) + ) + + if show_missing is not None and str(available)[0] == "?": + ids.pop() + + return + + # Useful when debugging + # if str(available)[0] != "?": + # ids.pop() + + # return + + if str(available)[0] == "{": + ids.pop() + + return + + if str(available)[0].isdigit(): + available = math.floor(float(available)) + + if math.floor(float(previous_volume_largest_chapter)) > available: + available = math.floor(float(previous_volume_largest_chapter)) + + if str(available) != "?" and int(progress) >= int(available): + ids.pop() + + return + + available_link = ( + available + if mangadex_id is None + else f'<a href="https://mangadex.org/title/{mangadex_id}">{available}</a>' + ) + + current_html.append( + f'<li><a href="https://anilist.co/manga/{id}" target="_blank">{manga["title"]["english"] or manga["title"]["romaji"] or title}</a> {progress} [{available_link}]</li>' + ) + + joblib.Parallel(n_jobs=int(os.getenv("CONCURRENT_JOBS")) or 4, require="sharedmem")( + joblib.delayed(process)(media) for media in releasing_outdated_manga + ) + + current_html = sorted(current_html, key=lambda x: seen(x, manga=True)) + + current_html.insert(0, "<ul>") + current_html.append("</ul>") + + return ("".join(current_html), len(ids)) 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> +""" |