From 6d690cc49f3b1916746daf1212f672b6ed1859e3 Mon Sep 17 00:00:00 2001 From: Arrrrr Date: Mon, 16 Dec 2024 02:21:03 -0800 Subject: [PATCH] feat: Active ongoing episode releasing on the time of airing --- src/program/program.py | 43 ++++++++++++++++++++++++++++--------- src/routers/secure/items.py | 23 ++++++++++++++++---- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/program/program.py b/src/program/program.py index a350fbd5..325469af 100644 --- a/src/program/program.py +++ b/src/program/program.py @@ -380,21 +380,44 @@ def _update_item_state(self, item_id: str) -> None: """Update the state of a single item.""" with db.Session() as session: try: - item = session.execute(select(MediaItem).filter_by(id=item_id)).unique().scalar_one_or_none() - if item: - previous_state, new_state = item.store_state() - if previous_state != new_state: - self.em.add_event(Event(emitted_by="UpdateOngoing", item_id=item_id)) - logger.log("RELEASE", f" {item.log_string} has been released!") - logger.debug(f"Changed state for {item.log_string} ({item.id}) from {previous_state.name} to {new_state.name}") - session.merge(item) - session.commit() + item = session.execute( + select(MediaItem).where(MediaItem.id == item_id) + ).scalar_one() + + if not item: + logger.error(f"Item {item_id} not found") + return + + # Check if this item should be scheduled for release today + current_time = datetime.now().astimezone() + if item.aired_at: + delay_minutes = settings_manager.settings.content.trakt.release_delay_minutes + delayed_time = item.aired_at + timedelta(minutes=delay_minutes) + + # If it's a future release for today, schedule it + if (delayed_time > current_time and + item.aired_at.year == current_time.year and + item.aired_at.month == current_time.month and + item.aired_at.day == current_time.day): + release_time_str = delayed_time.strftime("%I:%M %p").lstrip('0') + logger.log("PROGRAM", f"Scheduling {item.log_string} for release at {release_time_str}") + self.scheduled_releases[item.id] = delayed_time + # If it should have been released already, release it now + elif delayed_time <= current_time: + previous_state, new_state = item.store_state() + if previous_state != new_state: + self.em.add_event(Event(emitted_by="UpdateOngoing", item_id=item.id)) + logger.debug(f"Updated state for {item.log_string} ({item.id}) from {previous_state.name} to {new_state.name}") + + session.merge(item) + session.commit() except Exception as e: session.rollback() logger.error(f"Failed to update scheduled state for item with ID {item_id}: {e}") finally: # Remove from scheduled releases after processing - self.scheduled_releases.pop(item_id, None) + if item_id in self.scheduled_releases and self.scheduled_releases[item_id] <= current_time: + del self.scheduled_releases[item_id] def _schedule_functions(self) -> None: """Schedule each service based on its update interval.""" diff --git a/src/routers/secure/items.py b/src/routers/secure/items.py index b5a49808..038dc8b7 100644 --- a/src/routers/secure/items.py +++ b/src/routers/secure/items.py @@ -213,10 +213,11 @@ async def add_items(request: Request, imdb_ids: str = None) -> MessageResponse: return {"message": f"Added {len(valid_ids)} item(s) to the queue"} + @router.get( "/{id}", - summary="Retrieve Media Item", - description="Fetch a single media item by ID", + summary="Retrieve Media Item By ID", + description="Fetch a media item by its ID", operation_id="get_item", ) async def get_item(_: Request, id: str, use_tmdb_id: Optional[bool] = False) -> dict: @@ -227,10 +228,24 @@ async def get_item(_: Request, id: str, use_tmdb_id: Optional[bool] = False) -> query = query.where(MediaItem.tmdb_id == id) else: query = query.where(MediaItem.id == id) - item = session.execute(query).unique().scalar_one() + + # Get all matching items and use the first one + items = session.execute(query).unique().scalars().all() + if not items: + raise HTTPException(status_code=404, detail="Item not found") + + # Use the first item if there are multiple + item = items[0] + if len(items) > 1: + # Log details about each duplicate + logger.warning(f"Multiple items found for ID {id}:") + for i, dupe in enumerate(items): + logger.warning(f" {i+1}. {dupe.type} - {dupe.log_string} (ID: {dupe.id})") + logger.warning(f"Using first item: {item.type} - {item.log_string}") + + return item.to_extended_dict(with_streams=False) except NoResultFound: raise HTTPException(status_code=404, detail="Item not found") - return item.to_extended_dict(with_streams=False) @router.get(