Feature/subscription table #2
No files matched your search
+47
-30
@@ -85,8 +85,8 @@ def check_seadex(request:Request, db=Depends(get_db)):
|
|||||||
)
|
)
|
||||||
anime = cursor.fetchall()
|
anime = cursor.fetchall()
|
||||||
|
|
||||||
logger.debug(f"[FastAPI] Found {len(anime)} active anime to check.")
|
logger.debug("[FastAPI] Found %s active anime to check.", len(anime))
|
||||||
if not anime[0]:
|
if not anime:
|
||||||
logger.info("[FastAPI] No active Seadex entries")
|
logger.info("[FastAPI] No active Seadex entries")
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@@ -96,12 +96,15 @@ def check_seadex(request:Request, db=Depends(get_db)):
|
|||||||
try:
|
try:
|
||||||
current = check_for_update(seadex, anilist_id)
|
current = check_for_update(seadex, anilist_id)
|
||||||
if current is None:
|
if current is None:
|
||||||
logger.debug(f"[FastAPI] No entry yet for Anime: {anime_name} on SeaDex")
|
logger.debug("[FastAPI] No entry yet for Anime: %s on SeaDex", anime_name)
|
||||||
continue
|
continue
|
||||||
if current == last_updated:
|
if current == last_updated:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info(f"[FastAPI] Anime: {anime_name} updated, Anilist ID: {anilist_id}")
|
logger.info(
|
||||||
|
"[FastAPI] Anime: %s updated, Anilist ID: %s",
|
||||||
|
anime_name,anilist_id,
|
||||||
|
)
|
||||||
with db.cursor() as cursor:
|
with db.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"SELECT user_id, custom_name "
|
"SELECT user_id, custom_name "
|
||||||
@@ -124,16 +127,20 @@ def check_seadex(request:Request, db=Depends(get_db)):
|
|||||||
sent += 1
|
sent += 1
|
||||||
except NotificationUnavailableError:
|
except NotificationUnavailableError:
|
||||||
failed = len(subscribers) - sent
|
failed = len(subscribers) - sent
|
||||||
logger.error (f"[FastAPI] Notifications backend unavailable, skipping "
|
logger.error("[FastAPI] Notifications backend unavailable, skipping "
|
||||||
f"{failed} remaining user(s) for Anime: {anime_name}")
|
"%s remaining user(s) for Anime: %s",
|
||||||
|
failed, anime_name,
|
||||||
|
)
|
||||||
break
|
break
|
||||||
except NotificationError as e:
|
except NotificationError as e:
|
||||||
failed += 1
|
failed += 1
|
||||||
logger.error(f"[FastAPI] Failed to send notification to user_id={user_id} for Anime: {anime_name} "
|
logger.error(
|
||||||
f"status={getattr(e, 'status_code',None)}")
|
"[FastAPI] Failed to send notification to user_id=%s for Anime: %s, status=%s",
|
||||||
|
user_id, anime_name, getattr(e, 'status_code',None),
|
||||||
|
)
|
||||||
if subscribers and sent == 0:
|
if subscribers and sent == 0:
|
||||||
results["errors"] += 1
|
results["errors"] += 1
|
||||||
logger.error(f"[FastAPI] All notifications failed for Anime: {anime_name}, will retry later")
|
logger.error("[FastAPI] All notifications failed for Anime: %s, will retry later", anime_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with db.cursor() as cursor:
|
with db.cursor() as cursor:
|
||||||
@@ -142,22 +149,25 @@ def check_seadex(request:Request, db=Depends(get_db)):
|
|||||||
(current, seadex_state_id),
|
(current, seadex_state_id),
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
logger.debug(f"[FastAPI] Notification sent and database updated for Anime: {anime_name}")
|
logger.debug("[FastAPI] Notification sent and database updated for Anime: %s", anime_name)
|
||||||
results["new"] += 1
|
results["new"] += 1
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
db.rollback()
|
db.rollback()
|
||||||
results["errors"] += 1
|
results["errors"] += 1
|
||||||
logger.exception(f"[FastAPI] Failed for id: {seadex_state_id} Anilist: {anilist_id}",)
|
logger.exception(
|
||||||
|
"[FastAPI] Failed for id: %s Anilist: %s",
|
||||||
|
seadex_state_id, anilist_id,
|
||||||
|
)
|
||||||
|
|
||||||
if results["errors"]:
|
if results["errors"]:
|
||||||
logger.warning(f"[FastAPI] SeaDex check finished with errors: {results}")
|
logger.warning("[FastAPI] SeaDex check finished with errors: %s", results)
|
||||||
raise HTTPException(status_code=500, detail=results)
|
raise HTTPException(status_code=500, detail=results)
|
||||||
|
|
||||||
logger.info(f"[FastAPI] SeaDex check complete: {results}")
|
logger.info("[FastAPI] SeaDex check complete: %s", results)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@user_router.post("/add/anime")
|
@user_router.post("/anime/add")
|
||||||
def add_anime(
|
def add_anime(
|
||||||
anime: AnimeCreate,
|
anime: AnimeCreate,
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
@@ -214,7 +224,7 @@ def add_anime(
|
|||||||
)
|
)
|
||||||
return {"status": "ok", "detail": f"Tracking name={anime.custom_name or anime_name}, Anilist ID={anime.anilist_id}"}
|
return {"status": "ok", "detail": f"Tracking name={anime.custom_name or anime_name}, Anilist ID={anime.anilist_id}"}
|
||||||
|
|
||||||
@user_router.post("/delete/anime")
|
@user_router.post("/anime/delete")
|
||||||
def remove_anime(
|
def remove_anime(
|
||||||
anime: AnimeRemove,
|
anime: AnimeRemove,
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
@@ -273,29 +283,36 @@ def remove_anime(
|
|||||||
)
|
)
|
||||||
return {"status": "ok", "detail": f"Stopped tracking Anilist ID={anime.anilist_id}"}
|
return {"status": "ok", "detail": f"Stopped tracking Anilist ID={anime.anilist_id}"}
|
||||||
|
|
||||||
@user_router.get("/list/anime", response_model=AnimeList)
|
@user_router.get("/anime/list", response_model=AnimeList)
|
||||||
def list_active_and_inactive_anime(user_id: UserId, db=Depends(get_db)):
|
def list_active_and_inactive_anime(
|
||||||
logger.info(f"[FastAPI] Received request to list anime for User ID = {user_id}")
|
user_id: UserId,
|
||||||
with db.cursor() as cursor:
|
db=Depends(get_db),
|
||||||
|
):
|
||||||
|
logger.info("[FastAPI] Received request to list anime for User ID = %s", user_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
with db.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"SELECT anime_name, active, last_updated " \
|
"SELECT s.custom_name AS custom_name, st.anime_name AS anime_name, "
|
||||||
"FROM seadex_state WHERE user_id = %s "
|
"st.anilist_id, s.active, st.last_updated from seadex_state_subscriptions AS s "
|
||||||
"ORDER BY anime_name",
|
"JOIN seadex_state AS st on s.seadex_state_id = st.id "
|
||||||
|
"WHERE s.user_id = %s ORDER BY st.anilist_id",
|
||||||
(user_id,),
|
(user_id,),
|
||||||
)
|
)
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
|
|
||||||
|
anime_list=AnimeList()
|
||||||
|
for custom_name, anime_name, anilist_id, is_active, last_updated in rows:
|
||||||
|
entry = AnimeEntry(
|
||||||
|
name=custom_name or anime_name,
|
||||||
|
anilist_id=anilist_id,
|
||||||
|
last_updated=None if last_updated is None else last_updated,
|
||||||
|
)
|
||||||
|
(anime_list.active if is_active else anime_list.inactive).append(entry)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception("[FastAPI] Failed to list anime")
|
logger.exception("[FastAPI] Failed to list anime")
|
||||||
raise HTTPException(status_code=500) from e
|
raise HTTPException(status_code=500) from e
|
||||||
|
|
||||||
anime_list=AnimeList ()
|
|
||||||
for name, is_active, last_updated in rows:
|
|
||||||
entry = AnimeEntry(
|
|
||||||
name=name,
|
|
||||||
last_updated=None if last_updated is None else str(last_updated),
|
|
||||||
)
|
|
||||||
(anime_list.active if is_active else anime_list.inactive).append(entry)
|
|
||||||
return anime_list
|
return anime_list
|
||||||
|
|
||||||
api.include_router(user_router)
|
api.include_router(user_router)
|
||||||
@@ -303,7 +320,7 @@ api.include_router(scheduler_router)
|
|||||||
|
|
||||||
async def start_servers():
|
async def start_servers():
|
||||||
logger.info("[Server] Starting main API (port 5000) and metrics server (port 9000)...")
|
logger.info("[Server] Starting main API (port 5000) and metrics server (port 9000)...")
|
||||||
logger.info(f"[Server] Build commit id={os.getenv("COMMIT_ID","unknown")}")
|
logger.info("[Server] Build commit id=%s", os.getenv("COMMIT_ID", "unknown"))
|
||||||
|
|
||||||
auth.load_keys(api, Caller.GATEWAY, Caller.SCHEDULER)
|
auth.load_keys(api, Caller.GATEWAY, Caller.SCHEDULER)
|
||||||
cleanup_secret_files(auth.key_paths(Caller.GATEWAY, Caller.SCHEDULER))
|
cleanup_secret_files(auth.key_paths(Caller.GATEWAY, Caller.SCHEDULER))
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class AnimeRemove(BaseModel):
|
|||||||
|
|
||||||
class AnimeEntry(BaseModel):
|
class AnimeEntry(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
|
anilist_id: int
|
||||||
last_updated: str | None = None
|
last_updated: str | None = None
|
||||||
|
|
||||||
class Counts(BaseModel):
|
class Counts(BaseModel):
|
||||||
|
|||||||
Reference in new issue
Block a user