aboutsummaryrefslogtreecommitdiff
path: root/read
diff options
context:
space:
mode:
authorBobby <[email protected]>2024-10-06 11:53:26 -0400
committerBobby <[email protected]>2024-10-06 11:53:26 -0400
commitc816451a7172934bc1a7a7bff0a38433db74455c (patch)
treee22f81560cefc097060b25cc303ca661e325bb42 /read
parent256b91d90c90aa0b84cd8084b56a4d45decf156a (diff)
downloadyugen-c816451a7172934bc1a7a7bff0a38433db74455c.tar.xz
yugen-c816451a7172934bc1a7a7bff0a38433db74455c.zip
mangadex main provider for manga
Diffstat (limited to 'read')
-rw-r--r--read/urls.py3
-rw-r--r--read/utils.py144
-rw-r--r--read/views.py21
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)
+
+