diff options
| author | Bobby <[email protected]> | 2024-10-06 11:53:26 -0400 |
|---|---|---|
| committer | Bobby <[email protected]> | 2024-10-06 11:53:26 -0400 |
| commit | c816451a7172934bc1a7a7bff0a38433db74455c (patch) | |
| tree | e22f81560cefc097060b25cc303ca661e325bb42 /read | |
| parent | 256b91d90c90aa0b84cd8084b56a4d45decf156a (diff) | |
| download | yugen-c816451a7172934bc1a7a7bff0a38433db74455c.tar.xz yugen-c816451a7172934bc1a7a7bff0a38433db74455c.zip | |
mangadex main provider for manga
Diffstat (limited to 'read')
| -rw-r--r-- | read/urls.py | 3 | ||||
| -rw-r--r-- | read/utils.py | 144 | ||||
| -rw-r--r-- | read/views.py | 21 |
3 files changed, 105 insertions, 63 deletions
diff --git a/read/urls.py b/read/urls.py index 2f1f3a4..bd1c9ce 100644 --- a/read/urls.py +++ b/read/urls.py @@ -1,9 +1,8 @@ from django.urls import path - from . import views app_name = "read" urlpatterns = [ path('', views.index, name='index'), - path('/<str:manga_encoded_string>', views.read, name='read'), + path('/<int:manga_id>/<str:chapter_id>', views.read, name='read'), ] diff --git a/read/utils.py b/read/utils.py index 3789faa..0463296 100644 --- a/read/utils.py +++ b/read/utils.py @@ -1,45 +1,11 @@ -import base64 import json import os - import requests +from functools import lru_cache from watch.utils import get_from_redis_cache, store_in_redis_cache -def encode_chapter_info(provider, chapter_id): - data = json.dumps({"p": provider, "id": chapter_id}) - return base64.urlsafe_b64encode(data.encode()).rstrip(b'=').decode() - -def decode_chapter_info(encoded_info): - padding = 4 - (len(encoded_info) % 4) - encoded_info += "=" * padding - data = json.loads(base64.urlsafe_b64decode(encoded_info).decode()) - return data["p"], data["id"] - -def process_mangareader_chapters(manga_data): - manga_data["chapters"] = list(filter(lambda x: "/en/" in x["id"], manga_data["chapters"])) - for chapter in manga_data["chapters"]: - chapter["encoded_id"] = encode_chapter_info("mangareader", chapter["id"]) - return manga_data - -def process_generic_chapters(manga_data): - for chapter in manga_data["chapters"]: - chapter["encoded_id"] = encode_chapter_info("generic", chapter["id"]) - return manga_data - -def get_data_from_managareader(manga_id): - base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist-manga/info/{manga_id}?provider=mangareader" - print(f"Trying URL: {base_url}") - response = requests.get(base_url, timeout=10) - manga_data = response.json() - - if "message" in manga_data: - return None - else: - manga_data = process_mangareader_chapters(manga_data) - - return manga_data - -def get_data_from_generic(manga_id): +@lru_cache(maxsize=128) +def get_manga_info(manga_id): base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist-manga/info/{manga_id}" print(f"Trying URL: {base_url}") response = requests.get(base_url, timeout=10) @@ -48,41 +14,107 @@ def get_data_from_generic(manga_id): if "message" in manga_data: return None else: - manga_data = process_generic_chapters(manga_data) + mangadex_id = fetch_mangadex_id(manga_data['title']['romaji']) + print(f"Mangadex ID: {mangadex_id}") + if mangadex_id: + manga_data["mangadex_id"] = mangadex_id + manga_data["chapters"] = fetch_mangadex_chapters(mangadex_id) + else: + manga_data["mangadex_id"] = None return manga_data +@lru_cache(maxsize=128) +def fetch_mangadex_id(title): + url = "https://api.mangadex.org/manga" + params = { + "title": title, + "limit": 1, + "order[relevance]": "desc", + "includes[]": ["cover_art"], + "contentRating[]": ["safe", "suggestive", "erotica", "pornographic"], + "hasAvailableChapters": "true" + } + response = requests.get(url, params=params) + if response.status_code == 200: + data = response.json() + if data["data"]: + return data["data"][0]["id"] + print(response.json()) + return None + +@lru_cache(maxsize=128) +def fetch_mangadex_chapters(mangadex_id): + url = f"https://api.mangadex.org/manga/{mangadex_id}/feed" + params = { + "translatedLanguage[]": ["en"], + "order[chapter]": "asc", + "limit": 500, + "offset": 0 + } + all_chapters = [] + total = float('inf') + + while len(all_chapters) < total: + response = requests.get(url, params=params) + if response.status_code != 200: + print(f"Error fetching chapters: {response.status_code}") + print(response.json()) + return None + + data = response.json() + total = data['total'] + all_chapters.extend(data['data']) + params['offset'] += params['limit'] + + if len(data['data']) < params['limit']: + break + + filtered_chapters = [] + seen_chapters = set() + + for chapter in all_chapters: + if chapter["type"] == "chapter": + attributes = chapter["attributes"] + chapter_number = attributes.get("chapter") + pages = attributes.get("pages", 0) + + if pages == 0: + continue + + seen_chapters.add(chapter_number) + filtered_chapters.append(chapter) + + return filtered_chapters + def get_manga_data(manga_id): print(f"Fetching manga data: ID={manga_id}") - cache_key = f"manga_{manga_id}_manga_data" manga_data = get_from_redis_cache(cache_key) - generic_only_ids = [30013,101517] - provider = "generic" if manga_id in generic_only_ids else "mangareader" if not manga_data: - manga_data = None - if provider == "mangareader": - manga_data = get_data_from_managareader(manga_id) - - if not manga_data or provider == "generic": - manga_data = get_data_from_generic(manga_id) + manga_data = get_manga_info(manga_id) - if "status" in manga_data and manga_data["status"] == "Completed": + if manga_data and "status" in manga_data and manga_data["status"] == "Completed": store_in_redis_cache(cache_key, json.dumps(manga_data), 3600 * 24 * 30) - else: + elif manga_data: store_in_redis_cache(cache_key, json.dumps(manga_data), 3600 * 24) else: manga_data = json.loads(manga_data) return manga_data -def get_chapter_pages(provider, chapter_id): - base_url = f"{os.getenv('CONSUMET_URL')}/meta/anilist-manga/read?chapterId={chapter_id}" - if provider == "mangareader": - base_url += "&provider=mangareader" - print(f"Trying URL: {base_url}") +@lru_cache(maxsize=128) +def get_chapter_pages(chapter_id): + url = f"https://api.mangadex.org/at-home/server/{chapter_id}" + response = requests.get(url) + if response.status_code != 200: + print(f"Failed to fetch data for chapter {chapter_id}") + return None - response = requests.get(base_url, timeout=10) - return response.json() + chapter_data = response.json() + base_url = chapter_data['baseUrl'] + chapter_hash = chapter_data['chapter']['hash'] + data = chapter_data['chapter']['data'] + return [{"page": i + 1, "img": f"{base_url}/data/{chapter_hash}/{page}"} for i, page in enumerate(data)]
\ No newline at end of file diff --git a/read/views.py b/read/views.py index 77be1ed..e3820b5 100644 --- a/read/views.py +++ b/read/views.py @@ -1,18 +1,29 @@ from django.shortcuts import redirect, render -from read.utils import decode_chapter_info, get_chapter_pages +from read.utils import get_chapter_pages, get_manga_data # Create your views here. def index(request): return redirect("home:index") -def read(request, manga_encoded_string): - provider, chapter_id = decode_chapter_info(manga_encoded_string) - print(f"Reading: {provider} - {chapter_id}") - pages = get_chapter_pages(provider, chapter_id) +def read(request, manga_id, chapter_id): + manga = get_manga_data(manga_id) + + pages = get_chapter_pages(chapter_id) + + chapters = manga["chapters"] + current_chapter_index = next((i for i, chapter in enumerate(chapters) if chapter["id"] == chapter_id), None) + next_chapter = chapters[current_chapter_index + 1] if current_chapter_index is not None and current_chapter_index + 1 < len(chapters) else None + prev_chapter = chapters[current_chapter_index - 1] if current_chapter_index is not None and current_chapter_index - 1 >= 0 else None context = { "pages": pages, + "manga": manga, + "chapter_id": chapter_id, + "next_chapter": next_chapter, + "prev_chapter": prev_chapter, } return render(request, "read/read.html", context) + + |
