diff --git a/app/internal/notifications.py b/app/internal/notifications.py index 98a1e32..a1ab674 100644 --- a/app/internal/notifications.py +++ b/app/internal/notifications.py @@ -46,28 +46,6 @@ def replace_variables( return title, body -async def send_all_notifications( - event_type: EventEnum, - requester_username: Optional[str] = None, - book_asin: Optional[str] = None, - other_replacements: dict[str, str] = {}, -): - with open_session() as session: - notifications = session.exec( - select(Notification).where(Notification.event == event_type) - ).all() - for notification in notifications: - if not notification.enabled: - continue - await send_notification( - session=session, - notification=notification, - requester_username=requester_username, - book_asin=book_asin, - other_replacements=other_replacements, - ) - - async def send_notification( session: Session, notification: Notification, @@ -99,6 +77,10 @@ async def send_notification( other_replacements, ) + logger.info( + f"Sending notification to {notification.apprise_url} with title: '{title}', event type: {notification.event.value}" + ) + async with client_session.post( notification.apprise_url, json={ @@ -111,6 +93,28 @@ async def send_notification( return await response.json() +async def send_all_notifications( + event_type: EventEnum, + requester_username: Optional[str] = None, + book_asin: Optional[str] = None, + other_replacements: dict[str, str] = {}, +): + with open_session() as session: + notifications = session.exec( + select(Notification).where( + Notification.event == event_type, Notification.enabled + ) + ).all() + for notification in notifications: + await send_notification( + session=session, + notification=notification, + requester_username=requester_username, + book_asin=book_asin, + other_replacements=other_replacements, + ) + + async def send_manual_notification( notification: Notification, book: ManualBookRequest, @@ -131,6 +135,10 @@ async def send_manual_notification( other_replacements, ) + logger.info( + f"Sending manual notification to {notification.apprise_url} with title: '{title}', event type: {notification.event.value}" + ) + async with client_session.post( notification.apprise_url, json={ @@ -144,3 +152,23 @@ async def send_manual_notification( except Exception as e: logger.error("Failed to send notification", e) return None + + +async def send_all_manual_notifications( + event_type: EventEnum, + book_request: ManualBookRequest, + other_replacements: dict[str, str] = {}, +): + with open_session() as session: + notifications = session.exec( + select(Notification).where( + Notification.event == event_type, Notification.enabled + ) + ).all() + for notif in notifications: + await send_manual_notification( + notification=notif, + book=book_request, + requester_username=book_request.user_username, + other_replacements=other_replacements, + ) diff --git a/app/routers/search.py b/app/routers/search.py index 04a8b97..14c620d 100644 --- a/app/routers/search.py +++ b/app/routers/search.py @@ -1,6 +1,6 @@ from typing import Annotated, Optional -import sqlalchemy as sa +from sqlalchemy.exc import IntegrityError from aiohttp import ClientSession from fastapi import ( APIRouter, @@ -26,11 +26,10 @@ from app.internal.models import ( EventEnum, GroupEnum, ManualBookRequest, - Notification, ) from app.internal.notifications import ( + send_all_manual_notifications, send_all_notifications, - send_manual_notification, ) from app.internal.prowlarr.prowlarr import prowlarr_config from app.internal.query import query_sources @@ -169,7 +168,7 @@ async def add_request( try: session.add(book) session.commit() - except sa.exc.IntegrityError: + except IntegrityError: pass # ignore if already exists background_task.add_task( @@ -293,16 +292,12 @@ async def add_manual( session.expunge_all() # so that we can pass down the object without the session session.commit() - notifications = session.exec( - select(Notification).where(Notification.event == EventEnum.on_new_request) - ).all() - for notif in notifications: - background_task.add_task( - send_manual_notification, - notification=notif, - book=book_request, - requester_username=user.username, - ) + background_task.add_task( + send_all_manual_notifications, + event_type=EventEnum.on_new_request, + book_request=book_request, + ) + auto_download = quality_config.get_auto_download(session) return template_response( diff --git a/app/routers/settings.py b/app/routers/settings.py index fb9883a..e318cc6 100644 --- a/app/routers/settings.py +++ b/app/routers/settings.py @@ -636,9 +636,7 @@ async def test_notification( ], session: Annotated[Session, Depends(get_session)], ): - notification = session.exec( - select(Notification).where(Notification.id == notification_id) - ).one_or_none() + notification = session.get(Notification, notification_id) if not notification: raise HTTPException(status_code=404, detail="Notification not found") diff --git a/app/routers/wishlist.py b/app/routers/wishlist.py index b79cbbe..166b5c9 100644 --- a/app/routers/wishlist.py +++ b/app/routers/wishlist.py @@ -17,9 +17,14 @@ from sqlmodel import Session, asc, col, select from app.internal.models import ( BookRequest, BookWishlistResult, + EventEnum, GroupEnum, ManualBookRequest, ) +from app.internal.notifications import ( + send_all_manual_notifications, + send_all_notifications, +) from app.internal.prowlarr.prowlarr import ( ProwlarrMisconfigured, prowlarr_config, @@ -118,13 +123,23 @@ async def update_downloaded( DetailedUser, Depends(get_authenticated_user(GroupEnum.admin)) ], session: Annotated[Session, Depends(get_session)], + background_task: BackgroundTasks, ): books = session.exec(select(BookRequest).where(BookRequest.asin == asin)).all() + requested_by = [book.user_username for book in books if book.user_username] for book in books: book.downloaded = True session.add(book) session.commit() + if len(requested_by) > 0: + background_task.add_task( + send_all_notifications, + event_type=EventEnum.on_successful_download, + requester_username=", ".join(requested_by), + book_asin=asin, + ) + username = None if admin_user.is_admin() else admin_user.username books = get_wishlist_books(session, username, "not_downloaded") return template_response( @@ -161,16 +176,24 @@ async def downloaded_manual( DetailedUser, Depends(get_authenticated_user(GroupEnum.admin)) ], session: Annotated[Session, Depends(get_session)], + background_task: BackgroundTasks, ): - book = session.get(ManualBookRequest, id) - if book: - book.downloaded = True - session.add(book) + book_request = session.get(ManualBookRequest, id) + if book_request: + book_request.downloaded = True + session.add(book_request) session.commit() + background_task.add_task( + send_all_manual_notifications, + event_type=EventEnum.on_successful_download, + book_request=book_request, + ) + books = session.exec( select(ManualBookRequest).order_by(asc(ManualBookRequest.downloaded)) ).all() + return template_response( "wishlist_page/manual.html", request,