diff --git a/src/aura_engine/plugins/clock.py b/src/aura_engine/plugins/clock.py index 44991ea0bcd33b2e0a967a90ff2e1512117bab62..4942efb28b7e3df3cbf911296e5710887e0f2436 100644 --- a/src/aura_engine/plugins/clock.py +++ b/src/aura_engine/plugins/clock.py @@ -36,8 +36,8 @@ import confuse import aura_engine.scheduling.domain as domain from aura_engine.base.api import SimpleRestApi from aura_engine.base.config import AuraConfig -from aura_engine.base.lang import DotDict from aura_engine.resources import ResourceUtil +from aura_engine.scheduling.scheduler import AuraScheduler class ClockInfoHandler: @@ -69,40 +69,46 @@ class ClockInfoHandler: # This will be part of the coming "default station playlist" logic pass - def on_fallback_active(self, timeslot, fallback_name): + def on_fallback_active(self, timeslot: domain.Timeslot): """ Call when a fallback is activated. - """ - if timeslot: - # Only update the current show to the fallback show, - # in case no timeslot is scheduled - return - self.logger.info(f"Fallback '{fallback_name}' activated, clock update required") - fallback_show_id = self.config.general.fallback_show_id - fallback_show_name = self.config.general.fallback_show_name + Fallback means the station fallback audio source is played when: + 1. no timeslot is available. + 2. the current timefrome of the active timeslot provides no audio source/playlists. - # Interpolate timeslot-less slot - # TODO start time to be calculated based on previous timeslot (future station logic) - scheduler = self.engine.scheduler - upcoming_timeslots: [domain.Timeslot] = scheduler.timetable.get_next_timeslots() - virtual_start_time = datetime.now() - virtual_end_time = virtual_start_time + timedelta(hours=1) - if len(upcoming_timeslots) > 0: - virtual_end_time = upcoming_timeslots[0].get_start() - - fallback_timeslot = DotDict( - { - "timeslotId": -1, - "timeslotStart": virtual_start_time, - "timeslotEnd": virtual_end_time, - "showId": fallback_show_id, - "showName": fallback_show_name, - "playlistId": -1, - "playlistType": -1, - } - ) - self.post_clock_info(-1, None, fallback_timeslot, upcoming_timeslots) + TODO In the future case (1) should technically not happen, as "Virtual Timeslots" ensure + there is always some timeslot available, even without any playlists/media sources assigned. + + Args: + timeslot (Timeslot): The active timeslot, if available. Can be `None`. + """ + + # Check if we are within a valid timeslot + if timeslot: + self.logger.info(f"Fallback activated within timeslot '{timeslot}'") + else: + self.logger.info("Fallback activated outsite of timeslot") + + # Interpolate timeslot-less slot (in the future provided by Virtual Timeslots) + scheduler: AuraScheduler = self.engine.scheduler + upcoming_timeslots: list[domain.Timeslot] = scheduler.timetable.get_next_timeslots() + virtual_start_time = datetime.now() + virtual_end_time = virtual_start_time + timedelta(hours=1) + if len(upcoming_timeslots) > 0: + virtual_end_time = upcoming_timeslots[0].get_start() + + # Create fallback timeslot if event was triggered outsite of a valid timeslot + fallback_show_id = self.config.general.fallback_show_id + fallback_show_name = self.config.general.fallback_show_name + fallback_show = domain.Show( + fallback_show_id, fallback_show_name, None, None, None, None + ) + timeslot = domain.Timeslot( + -1, None, virtual_start_time, virtual_end_time, fallback_show, None + ) + + self.post_clock_info(timeslot, None, upcoming_timeslots) def on_play(self, _): """ @@ -122,13 +128,13 @@ class ClockInfoHandler: active_playlist: domain.Playlist = active_timeslot.get_current_playlist() upcoming_timeslots = scheduler.timetable.get_next_timeslots() - self.post_clock_info(active_playlist, active_timeslot, upcoming_timeslots) + self.post_clock_info(active_timeslot, active_playlist, upcoming_timeslots) def post_clock_info( self, - active_playlist: domain.Playlist, active_timeslot: domain.Timeslot, - upcoming_timeslots: [domain.Timeslot], + active_playlist: domain.Playlist, + upcoming_timeslots: list[domain.Timeslot], ): """ Post current information on timeslots and playlist to the Engine API clock endpoint.