Feed parser: Changed behaviour to use RR id for tracking chapters instead of using the extraced chapter number (which was dumb anyway)
All checks were successful
Build & Publish to GHCR / build (push) Successful in 23s

This commit is contained in:
Florian 2025-10-30 09:26:20 +01:00
parent 18904abcec
commit eda004626a
3 changed files with 17 additions and 22 deletions

View File

@ -7,14 +7,6 @@ from typing import Tuple
logger = setup_logger(__name__)
def extract_number(s: str)->int | None:
"""Extracts the first integer found in a string and returns either it or None"""
match = re.search(r"\d+", s)
if match:
return int(match.group())
else:
return None
def grab_latest_chapter_information(id: str, max_retries: int = 3) -> Tuple[int | None, str, str]:
"""
Fetches the latest chapter information from a Royalroad RSS feed, with retries on network-related errors.
@ -43,12 +35,15 @@ def grab_latest_chapter_information(id: str, max_retries: int = 3) -> Tuple[int
raise ValueError(f"No entries found for feed {id}")
latest_chapter_data = feed["entries"][0]
chapter_number = extract_number(latest_chapter_data["title"])
chapter_link = latest_chapter_data["link"]
story_title = feed["feed"]["title"]
chapter_title_with_story_title = latest_chapter_data["title"]
chapter_title = chapter_title_with_story_title.replace(story_title, "")[3:] # " - " is left after replace
chapter_id = int(latest_chapter_data["id"])
logger.info(f"[Feed] Latest chapter for story '{story_title}' (ID {id}): {chapter_number} -> {chapter_link}")
return chapter_number, chapter_link, story_title
logger.info(f"[Feed] Latest chapter for story '{story_title}': {chapter_title}")
logger.debug(f"[Feed] Latest chapter for story '{story_title}' (ID {id}): {chapter_title} (ID {chapter_id}) -> {chapter_link}")
return chapter_title, chapter_link, story_title, chapter_id
except (URLError, OSError) as e:
logger.warning(f"[Feed] Network error on attempt {attempt} for feed {id}: {e}")

View File

@ -42,7 +42,7 @@ async def prometheus_middleware(request: Request, call_next):
response = await call_next(request)
status = response.status_code
logger.debug(f"[Metrics] Request processed with status {status}")
except Exception:
except Exception as e:
logger.error(f"[Metrics] Exception occurred: {e}", exc_info=True)
raise
finally:
@ -73,14 +73,14 @@ def get_chapters(request: Request, db = Depends(get_db)):
logger.debug(f"[Royalroad] Found {len(stories)} active stories to check.")
for id, royalroadId, last_chapter_db in stories:
chapter_number, chapter_link, story_title = grab_latest_chapter_information(royalroadId)
logger.debug(f"[Royalroad] Story {id}: last={last_chapter_db}, latest={chapter_number}")
chapter_title, chapter_link, story_title, chapter_id = grab_latest_chapter_information(royalroadId)
logger.debug(f"[Royalroad] Story {id}: last={last_chapter_db}, latest={chapter_id}")
if chapter_number > last_chapter_db:
if chapter_id > last_chapter_db:
logger.info(f"[Royalroad] New chapter detected for story ID {id}: {story_title}")
cursor.execute("UPDATE stories SET lastChapter = %s WHERE id = %s", (chapter_number, id))
cursor.execute("UPDATE stories SET lastChapter = %s WHERE id = %s", (chapter_id, id))
db.commit()
send_notification(story_title, chapter_number, chapter_link)
send_notification(story_title, chapter_title, chapter_link)
logger.debug(f"[Royalroad] Notification sent for story ID {id}")
logger.info("[Royalroad] Chapter check completed successfully.")

View File

@ -12,13 +12,13 @@ api_key= return_credentials("/etc/secrets/api_key")
logger = setup_logger(__name__)
def send_notification(title: str,chapter: int,link: str,max_retries: int = 5,timeout: int = 5):
def send_notification(title: str, chapter_title: str,link: str,max_retries: int = 5,timeout: int = 5):
"""
Sends a notification to the internal backend service when a new Royalroad chapter is released.
Parameters:
title: Name of the story.
chapter: Latest chapter number.
chapter_title: Title of the chapter.
link: Direct link to the new chapter.
"""
@ -31,14 +31,14 @@ def send_notification(title: str,chapter: int,link: str,max_retries: int = 5,tim
"receipent_user_id": 1,
"message": {
"title": title,
"body": f"Chapter {chapter} has been released",
"body": chapter_title,
"link": link,
"category":"royal-road",
"timestamp": int(time.time())
}
}
logger.debug(f"[Notify] Preparing to send notification: title='{title}', chapter={chapter}, link='{link}'")
logger.debug(f"[Notify] Preparing to send notification: title='{title}', chapter={chapter_title}, link='{link}'")
with requests.Session() as session:
for attempt in range(1, max_retries + 1):
@ -46,7 +46,7 @@ def send_notification(title: str,chapter: int,link: str,max_retries: int = 5,tim
logger.debug(f"[Notify] Sending request to backend (attempt {attempt}/{max_retries})")
response = session.post(backend_api_url, headers=headers, json=data, timeout=timeout)
response.raise_for_status()
logger.info(f"[Notify] Notification sent successfully for '{title}' (chapter {chapter})")
logger.info(f"[Notify] Notification sent successfully for '{title}' (chapter {chapter_title})")
return response.text
except (Timeout, ConnectionError) as e: