From 4dfa2b3b7cf38ab01bfec3b145a00cd106621edc Mon Sep 17 00:00:00 2001 From: Florian Date: Sat, 31 Oct 2026 15:52:30 +0100 Subject: [PATCH] Added path to track RSS feeds --- src/main.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main.py b/src/main.py index 4370290..fba3760 100644 --- a/src/main.py +++ b/src/main.py @@ -5,18 +5,20 @@ from contextlib import asynccontextmanager import uvicorn from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request from fastapi.responses import JSONResponse +from requests.exceptions import RequestException from auth_config import Caller, auth from db_module import close_connection_pool, create_connection_pool, get_db, start_healthcheck_thread -from feed_errors import FeedError +from feed_errors import FeedCheckFailedError, FeedError from feed_handler import ( build_gitea_runner, ensure_feed_exists, + fetch_latest, grab_gitea_release_information, grab_royal_road_chapter_information, ) from metrics_server import REQUEST_COUNTER, metrics_api -from models import FeedEntry, fetch_latest +from models import FeedEntry from secret_manager import cleanup_secret_files, get_secret from send_notifications import NotificationClient, NotificationError, NotificationUnavailableError from service_auth import UserId @@ -112,12 +114,12 @@ def get_release_information(request: Request, db = Depends(get_db)): results["checked"] += 1 try: gitea_release_information = grab_gitea_release_information(rss_feed) - logger.debug(f"[FastAPI] ID:{feed_id},RSS Feed {rss_feed}: db={last_entry}, online={gitea_release_information.link}") + logger.debug(f"[FastAPI] ID:{feed_id},RSS Feed {rss_feed}: db={last_entry}, online={gitea_release_information.entry_id}") - if gitea_release_information.link == last_entry: + if gitea_release_information.entry_id == last_entry: continue - logger.info(f"[FastAPI] Release change for ID {feed_id}: {gitea_release_information.release_title}") + logger.info(f"[FastAPI] Release change for ID {feed_id}: {gitea_release_information.body_title}") with db.cursor() as cursor: cursor.execute( @@ -130,12 +132,12 @@ def get_release_information(request: Request, db = Depends(get_db)): sent = 0 failed = 0 + repo = gitea_release_information.link.split("/releases")[0].removeprefix("https://") for user_id,feed_name in subscribers: try: - repo = gitea_release_information.link.split("/releases")[0].removeprefix("https://") request.app.state.notifier.send( title=feed_name or repo, - body=gitea_release_information.release_title, + body=gitea_release_information.body_title, link=gitea_release_information.link, category="utility", user_id=user_id, @@ -143,7 +145,7 @@ def get_release_information(request: Request, db = Depends(get_db)): sent += 1 except NotificationUnavailableError: failed = len(subscribers) - sent - logger.error(f"[FastAPI] Notifications backend unavailable, skipping" + logger.error(f"[FastAPI] Notifications backend unavailable, skipping " f"{failed} remaining user(s) for feed_id={feed_id}") break except NotificationError as e: @@ -157,14 +159,14 @@ def get_release_information(request: Request, db = Depends(get_db)): with db.cursor() as cursor: cursor.execute( "UPDATE rss_feeds SET last_entry = %s WHERE id = %s", - (gitea_release_information.link, feed_id), + (gitea_release_information.entry_id, feed_id), ) db.commit() logger.debug(f"[FastAPI] Notification sent and database updated for Gitea feed ID {feed_id}") results["new"] += 1 if gitea_release_information.link.startswith("https://gitea.com/gitea/runner/releases/tag/v"): - gitea_build_success = build_gitea_runner(gitea_release_information.release_title, request.app.state.gitea_token) + gitea_build_success = build_gitea_runner(gitea_release_information.body_title, request.app.state.gitea_token) logger.info(f"[FastAPI] Gitea build ran successfully:{gitea_build_success}") except Exception as e: @@ -285,24 +287,26 @@ def add_feed( ): url = feed_entry.rss_feed_url logger.info(f"[FastAPI] Subscribe request: RSS URL={url}, user_id={user_id}") + with db.cursor() as cursor: - cursor.execute("SELECT id FROM rss_feeds WHERE rss_feed = %s", (feed_entry.rss_feed_url,),) + cursor.execute("SELECT id FROM rss_feeds WHERE rss_feed = %s", (url,),) known = cursor.fetchone() - last_entry = None + last_entry_id = None if known is None: ensure_feed_exists(url) logger.info(f"[FastApi] Adding new RSS feed, type={feed_entry.type}, rss_feed_url={url}") try: - last_entry = fetch_latest(feed_entry.type, url) - except ValueError: + last_entry_id = fetch_latest(feed_entry.type, url).entry_id + except (ValueError, RequestException) as e: logger.warning(f"[FastAPI] Could not read latest entry for {url}, storing none") + raise FeedCheckFailedError(url) from e try: with db.cursor() as cursor: cursor.execute( "INSERT into rss_feeds (type,rss_feed,last_entry) VALUES (%s,%s,%s) " "ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id), active = 1", - (feed_entry.type, url, last_entry.entry_id), + (feed_entry.type, url, last_entry_id), ) feed_id = cursor.lastrowid @@ -319,7 +323,7 @@ def add_feed( raise HTTPException(status_code=500) from e logger.info(f"[FastAPI] user_id={user_id} subscribed to feed_id={feed_id}, url={url}") - return {"status":"ok","detail":"Subscribed to feed","feed_id":{feed_id}} + return {"status":"ok","detail":"Subscribed to feed","feed_id":feed_id} api.include_router(user_router) api.include_router(scheduler_router)