From b01c9bf79f98e31f478262f0162948afb9033c72 Mon Sep 17 00:00:00 2001 From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org> Date: Tue, 23 Jul 2024 14:41:03 +0200 Subject: [PATCH] fix(program-generation): fix undefined behaviour around start and end query parameters The radio program is a continuous stream of program slots. Clients can expect that the program generated for their queries fit the start and end parameters given by the client. However, they *cannot* expect the actual radio program (in the form of Timeslot objects) to fit these artifical boundaries. As the program endpoint should always output the actual program broadcasted by the radio we must include timeslots that * have started before the specified start query but end after it * or end after the specified end query but start before it. The changes in this commit ensure that the program matches the given range exactly and that planned timeslots in that range are always included. --- program/services.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/program/services.py b/program/services.py index 23497ed6..86b9f0cd 100644 --- a/program/services.py +++ b/program/services.py @@ -720,13 +720,23 @@ def generate_program_entries( ) def create_timeslot_entry(timeslot: TimeSlot): - return create_entry(timeslot.start, timeslot.end, timeslot.schedule.show, timeslot) + return create_entry( + # Ensure the program entry never starts before the requested start + # and never ends after the requested end. + max(timeslot.start, start), + min(timeslot.end, end), + timeslot.schedule.show, + timeslot, + ) if start is None: start = timezone.now() if end is None: end = start + timedelta(days=1) - queryset = queryset.filter(start__gte=start, start__lt=end) + # Find all timeslots that + # * have started before the specified start value but end after it + # * or end after the specified end value but start before it + queryset = queryset.filter(end__gt=start, start__lt=end).order_by("start") if not include_virtual: yield from (create_timeslot_entry(timeslot) for timeslot in queryset) @@ -744,5 +754,5 @@ def generate_program_entries( yield create_entry(entry_start, timeslot.start, fallback_show) yield create_timeslot_entry(timeslot) entry_start = timeslot.end - if entry_start != end: + if entry_start < end: yield create_entry(entry_start, end, fallback_show) -- GitLab