diff --git a/program/filters.py b/program/filters.py index af8421a919ffd1607b6c29dff3c70cec61654275..1c771bfab3631a1a474a4d71dc1d6498dff08899 100644 --- a/program/filters.py +++ b/program/filters.py @@ -300,6 +300,13 @@ class ActiveFilterSet(StaticFilterHelpTextMixin, filters.FilterSet): class VirtualTimeslotFilterSet(filters.FilterSet): start = filters.IsoDateTimeFilter(method="filter_noop") end = filters.IsoDateTimeFilter(method="filter_noop") + cut_at_range_boundaries = filters.BooleanFilter( + help_text=( + "If true guarantees that the first and last program entry match the requested range" + "even if these entries earlier or end later." + ), + method="filter_noop", + ) include_virtual = filters.BooleanFilter( help_text="Include virtual timeslot entries (default: false).", method="filter_noop", @@ -320,6 +327,7 @@ class VirtualTimeslotFilterSet(filters.FilterSet): start=filter_data["start"], end=filter_data["end"], include_virtual=filter_data["include_virtual"], + cut_at_range_boundaries=filter_data["cut_at_range_boundaries"], ) ) diff --git a/program/services.py b/program/services.py index baba59fa17f5cf17b42d26b10c0c9f2b5b3edb7f..d1a17fe27b4ac2c50f536dc62013c5615b893d1e 100644 --- a/program/services.py +++ b/program/services.py @@ -717,26 +717,31 @@ def generate_program_entries( start: datetime | None, end: datetime | None, include_virtual: bool, + cut_at_range_boundaries: bool, ) -> Iterator[ProgramEntry]: """Gets list of timerange entries between the given `timerange_start` and `timerange_end`. Include virtual timerange entries if requested.""" - def create_entry(start: datetime, end: datetime, show: Show, timeslot: TimeSlot | None = None): + def create_entry( + starts_at: datetime, ends_at: datetime, show: Show, timeslot: TimeSlot | None = None + ): + entry_id = f"{starts_at.isoformat()}...{ends_at.isoformat()}" + if cut_at_range_boundaries: + starts_at = max(starts_at, start) + ends_at = min(ends_at, end) return ProgramEntry( - id=f"{start.isoformat()}...{end.isoformat()}", - start=start, - end=end, + id=entry_id, + start=starts_at, + end=ends_at, timeslot=timeslot, show=show, ) def create_timeslot_entry(timeslot: 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.start, + timeslot.end, timeslot.schedule.show, timeslot, )