171 lines
5.7 KiB
Python
171 lines
5.7 KiB
Python
from quart import Quart, render_template, request, jsonify
|
|
import httpx
|
|
from anilistapi.queries.manga import REQUESTS_QUERY, TAGS_QUERY, GENRES_QUERY
|
|
from anilistapi.schemas.manga import Manga
|
|
from komconfig import KomConfig
|
|
from komcache import KomCache
|
|
from komgapi import komgapi as KOMGAPI
|
|
from typing import Any, Dict, List
|
|
|
|
app = Quart(__name__)
|
|
|
|
cache = KomCache()
|
|
cache.create_table(
|
|
"CREATE TABLE IF NOT EXISTS manga_requests (id INTEGER PRIMARY KEY, manga_id INTEGER, grabbed BOOLEAN DEFAULT 0)"
|
|
)
|
|
cache.create_table(
|
|
"CREATE TABLE IF NOT EXISTS manga_titles (id INTEGER PRIMARY KEY, anilist_id INTEGER DEFAULT 0, komga_title UNIQUE)"
|
|
)
|
|
|
|
settings = KomConfig()
|
|
|
|
komga = KOMGAPI(
|
|
url=settings.komga.url,
|
|
username=settings.komga.user,
|
|
password=settings.komga.password,
|
|
)
|
|
komga_series = komga.seriesList()
|
|
# store the entries in the database table manga_titles, komga_series is a list of strings of the series names
|
|
for series in komga_series:
|
|
# check if the series is already in the database
|
|
existing_series = cache.fetch_one(
|
|
query="SELECT komga_title FROM manga_titles WHERE komga_title = ?",
|
|
args=(series,),
|
|
)
|
|
if existing_series:
|
|
# series already exists, skip
|
|
continue
|
|
else:
|
|
cache.insert(
|
|
# insert into if not in database
|
|
query="INSERT OR IGNORE INTO manga_titles (komga_title) VALUES (?)",
|
|
args=(series,),
|
|
)
|
|
komga_series = [series.lower() for series in komga_series]
|
|
|
|
|
|
# Update type annotations for fetch_data
|
|
async def fetch_data(data: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
variables: Dict[str, Any] = {"search": data["query"]}
|
|
if len(data["genres"]) > 0:
|
|
variables["genres"] = data["genres"]
|
|
if len(data["tags"]) > 0:
|
|
variables["tags"] = data["tags"]
|
|
print(data["query"], variables)
|
|
response = await client.post(
|
|
"https://graphql.anilist.co",
|
|
json={
|
|
"query": REQUESTS_QUERY,
|
|
"variables": variables,
|
|
},
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
results: List[Dict[str, Any]] = []
|
|
for item in data.get("data", {}).get("Page", {}).get("media", []):
|
|
manga = Manga(**item)
|
|
in_komga = komga.getSeries(
|
|
manga.title.english if manga.title.english else manga.title.romaji
|
|
)
|
|
print(in_komga, manga.title.english)
|
|
results.append(
|
|
{
|
|
"id": manga.id,
|
|
"title": manga.title.english
|
|
if manga.title.english
|
|
else manga.title.romaji,
|
|
"image": manga.coverImage.get("large")
|
|
if manga.coverImage
|
|
else "https://demofree.sirv.com/nope-not-here.jpg",
|
|
"status": manga.status,
|
|
"type": manga.type,
|
|
"genres": manga.genres or [],
|
|
"tags": [tag.name for tag in (manga.tags or [])],
|
|
"description": manga.description.replace("<br>", "\n")
|
|
if manga.description
|
|
else "No description available",
|
|
"isAdult": manga.isAdult,
|
|
"in_komga": in_komga,
|
|
}
|
|
)
|
|
|
|
return results
|
|
except httpx.RequestError as e:
|
|
print(f"An error occurred while requesting data: {e}")
|
|
return []
|
|
except Exception as e:
|
|
print(f"Unexpected error: {e}")
|
|
return []
|
|
|
|
|
|
@app.route("/api/genres")
|
|
async def get_genres():
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.post(
|
|
f"https://graphql.anilist.co",
|
|
json={"query": GENRES_QUERY},
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
results = data.get("data", {}).get("genres", [])
|
|
return jsonify(results)
|
|
except Exception as e:
|
|
print(f"Error fetching genres: {e}")
|
|
return jsonify([])
|
|
|
|
|
|
@app.route("/api/tags")
|
|
async def get_tags():
|
|
async with httpx.AsyncClient() as client:
|
|
try:
|
|
response = await client.post(
|
|
f"https://graphql.anilist.co",
|
|
json={"query": TAGS_QUERY},
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
results = data.get("data", {}).get("tags", [])
|
|
return jsonify(results)
|
|
except Exception as e:
|
|
print(f"Error fetching genres: {e}")
|
|
return jsonify([])
|
|
|
|
|
|
@app.route("/search", methods=["POST"])
|
|
async def search():
|
|
data = await request.get_json()
|
|
print(data)
|
|
results = await fetch_data(data)
|
|
if not results:
|
|
return jsonify({"error": "No results found"}), 404
|
|
return jsonify(results)
|
|
|
|
|
|
@app.route("/", methods=["GET"])
|
|
async def index():
|
|
return await render_template("index.html", komga_series=komga_series)
|
|
|
|
|
|
@app.route("/request", methods=["POST"])
|
|
async def log_request():
|
|
data = await request.get_json()
|
|
item = data.get("title")
|
|
if item:
|
|
asynccache = KomCache()
|
|
manga_title = data.get("title")
|
|
asynccache.insert(
|
|
"INSERT INTO manga_requests (manga_id, manga_title) VALUES (?, ?)",
|
|
(item, manga_title),
|
|
)
|
|
return jsonify({"status": "success"})
|
|
return jsonify({"status": "failed"}), 400
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(debug=True, host="0.0.0.0", port=5001)
|