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("
", "\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)