Added tracking or deactivating anime via Anilist ID, it queries Anilist for the name and saves it
This commit is contained in:
1 parent
162f73fe3f
commit
b87c1e1896
3 files changed
+245
-2
No files matched your search
+101
-2
@@ -4,8 +4,11 @@ from datetime import UTC, datetime
|
||||
|
||||
import uvicorn
|
||||
from fastapi import Depends, FastAPI, HTTPException, Request
|
||||
from pydantic import BaseModel, Field
|
||||
from seadex import EntryNotFoundError, SeaDexEntry
|
||||
from send_notifications import NotificationClient
|
||||
|
||||
from anilist_query import AniListError, AnimeNotFoundError, MissingAnimeName, get_anime_name
|
||||
from db_module import (
|
||||
close_connection_pool,
|
||||
create_connection_pool,
|
||||
@@ -14,18 +17,20 @@ from db_module import (
|
||||
)
|
||||
from metrics_server import REQUEST_COUNTER, metrics_api
|
||||
from secret_manager import cleanup_secret_files
|
||||
from send_notifications import NotificationClient
|
||||
from simple_logger_handler import LOG_LEVEL, setup_logger
|
||||
|
||||
logger = setup_logger(__name__)
|
||||
|
||||
class AnimeCreate(BaseModel):
|
||||
anilist_id: int = Field(gt=0)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
logger.info("[App] Starting application...")
|
||||
app.state.notifier = NotificationClient()
|
||||
logger.info("[DB] Creating MySQL connection pool...")
|
||||
create_connection_pool("royalRoadPool")
|
||||
create_connection_pool("seadexPool")
|
||||
|
||||
start_healthcheck_thread()
|
||||
logger.info("[DB] MySQL healthcheck thread started.")
|
||||
@@ -135,6 +140,100 @@ def check_seadex(request:Request, db=Depends(get_db)):
|
||||
logger.info(f"[FastAPI] SeaDex check complete: {results}")
|
||||
return results
|
||||
|
||||
@api.post("/add/anime")
|
||||
def add_anime(anime: AnimeCreate, db=Depends(get_db)):
|
||||
logger.info("[FastAPI] Received request to track anilist_id={anime.anilist_id}")
|
||||
|
||||
try:
|
||||
anime_name = get_anime_name(anime.anilist_id)
|
||||
except AnimeNotFoundError as e:
|
||||
raise HTTPException(status_code=404, detail="Not found on AniList") from e
|
||||
except MissingAnimeName as e:
|
||||
raise HTTPException(status_code=404, detail="The anime exists but has no usable title") from e
|
||||
except AniListError as e:
|
||||
logger.exception("[FastAPI] AniList request failed")
|
||||
raise HTTPException(status_code=502, detail="The AniList request failed") from e
|
||||
logger.debug(f"[FastAPI] Found name={anime_name} for Anilist id={anime.anilist_id}")
|
||||
|
||||
with db.cursor() as cursor:
|
||||
try:
|
||||
cursor.execute(
|
||||
"SELECT id FROM seadex_state WHERE anilist_id = %s",
|
||||
(anime.anilist_id,),
|
||||
)
|
||||
|
||||
if cursor.fetchone():
|
||||
logger.debug(f"[FastAPI] Found existing entry, updating name and setting to active")
|
||||
cursor.execute(
|
||||
"UPDATE seadex_state SET anime_name = %s, active = 1 "
|
||||
"WHERE anilist_id = %s",
|
||||
(anime_name, anime.anilist_id),
|
||||
)
|
||||
db.commit()
|
||||
return {
|
||||
"status": "ok",
|
||||
"detail": f"Updated existing entry name={anime_name}, "
|
||||
f"Anilist ID={anime.anilist_id}",
|
||||
}
|
||||
|
||||
with SeaDexEntry() as seadex:
|
||||
current = check_for_update(seadex, anime.anilist_id)
|
||||
logger.debug("[FastAPI] Inserting new anime with last_updated={current}")
|
||||
|
||||
cursor.execute(
|
||||
"INSERT INTO seadex_state (anilist_id, anime_name, last_updated) "
|
||||
"VALUES (%s, %s, %s)",
|
||||
(anime.anilist_id, anime_name, current),
|
||||
)
|
||||
db.commit()
|
||||
return {
|
||||
"status": "ok",
|
||||
"detail": f"Created new entry name={anime_name}, "
|
||||
f"Anilist ID={anime.anilist_id}",
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
logger.exception(f"[FastAPI] Failed for anilist_id={anime.anilist_id} name={anime_name}")
|
||||
raise HTTPException(status_code=500) from e
|
||||
|
||||
@api.post("/delete/anime")
|
||||
def remove_anime(anime: AnimeCreate, db=Depends(get_db)):
|
||||
logger.info(f"[FastAPI] Received request to deactivate tracking for anilist_id={anime.anilist_id}")
|
||||
with db.cursor() as cursor:
|
||||
try:
|
||||
cursor.execute(
|
||||
"SELECT active FROM seadex_state WHERE anilist_id = %s",
|
||||
(anime.anilist_id,),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
if row and row[0]:
|
||||
cursor.execute(
|
||||
"UPDATE seadex_state SET active = 0 "
|
||||
"WHERE anilist_id = %s",
|
||||
(anime.anilist_id,),
|
||||
)
|
||||
db.commit()
|
||||
logger.debug(f"[FastAPI] Successfully deactivated tracking for anilist_id={anime.anilist_id}")
|
||||
return {
|
||||
"status": "ok",
|
||||
"detail": f"Deactivated entry {anime.anilist_id}",
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
logger.exception(f"[FastAPI] Failed removeing tracking for id={anime.anilist_id}")
|
||||
raise HTTPException(status_code=500) from e
|
||||
|
||||
if row is None:
|
||||
logger.debug(f"[FastAPI] No tracked entry for anilist_id={anime.anilist_id}")
|
||||
raise HTTPException(status_code=404, detail="No tracked entry for this AniList ID")
|
||||
if not row[0]:
|
||||
logger.debug(f"[FastAPI] Tracking was already deactivated for anilist_id={anime.anilist_id}")
|
||||
return {"status": "ok", "detail": f"Entry {anime.anilist_id} was already inactive"}
|
||||
|
||||
|
||||
|
||||
async def start_servers():
|
||||
logger.info("[Server] Starting main API (port 5000) and metrics server (port 9000)...")
|
||||
config_main = uvicorn.Config(api, host="0.0.0.0", port=5000, log_level=LOG_LEVEL.lower(),log_config=None)
|
||||
|
||||
Reference in new issue
Block a user