Fix cueout for overlapping starts & ends schedule

This commit is contained in:
jo 2021-09-19 20:48:19 +02:00
parent ffb8c49784
commit d8c5206e2e
3 changed files with 95 additions and 9 deletions

View File

@ -24,21 +24,45 @@ class Schedule(models.Model):
def get_cueout(self):
"""
Returns a cueout that is based on the current show. Cueout of a specific
item can potentially overrun the show that it is scheduled in. In that
case, the cueout should be the end of the show. This prevents the next
show having overlapping items playing.
Returns a scheduled item cueout that is based on the current show instance.
Cueout of a specific item can potentially overrun the show that it is
scheduled in. In that case, the cueout should be the end of the show.
This prevents the next show having overlapping items playing.
Cases:
- When the schedule ends before the end of the show instance,
return the stored cueout.
- When the schedule starts before the end of the show instance
and ends after the show instance ends,
return timedelta between schedule starts and show instance ends.
- When the schedule starts after the end of the show instance,
return the stored cue_out even if the schedule WILL NOT BE PLAYED.
"""
if self.instance.ends < self.ends:
if self.starts < self.instance.ends and self.instance.ends < self.ends:
return self.instance.ends - self.starts
return self.cue_out
def get_ends(self):
"""
Returns an item end that is based on the current show. Ends of a
specific item can potentially overrun the show that it is scheduled in.
In that case, the end should be the end of the show. This prevents the
next show having overlapping items playing.
Returns a scheduled item ends that is based on the current show instance.
End of a specific item can potentially overrun the show that it is
scheduled in. In that case, the end should be the end of the show.
This prevents the next show having overlapping items playing.
Cases:
- When the schedule ends before the end of the show instance,
return the scheduled item ends.
- When the schedule starts before the end of the show instance
and ends after the show instance ends,
return the show instance ends.
- When the schedule starts after the end of the show instance,
return the show instance ends.
"""
if self.instance.ends < self.ends:
return self.instance.ends

View File

@ -0,0 +1,62 @@
from datetime import datetime, timedelta
from django.test import SimpleTestCase
from libretimeapi.models import Schedule, Show, ShowInstance
class TestSchedule(SimpleTestCase):
def test_get_cueout(self):
show_instance = ShowInstance(
created=datetime(year=2021, month=10, day=1, hour=12),
starts=datetime(year=2021, month=10, day=2, hour=1),
ends=datetime(year=2021, month=10, day=2, hour=2),
)
length = timedelta(minutes=10)
cue_in = timedelta(seconds=1)
cue_out = length - timedelta(seconds=4)
# No overlapping schedule datetimes, normal usecase:
s1_starts = datetime(year=2021, month=10, day=2, hour=1, minute=30)
s1_ends = s1_starts + length
s1 = Schedule(
starts=s1_starts,
ends=s1_ends,
cue_in=cue_in,
cue_out=cue_out,
instance=show_instance,
)
self.assertEqual(s1.get_cueout(), cue_out)
self.assertEqual(s1.get_ends(), s1_ends)
# Mixed overlapping schedule datetimes (only ends is overlapping):
s2_starts = datetime(year=2021, month=10, day=2, hour=1, minute=55)
s2_ends = s2_starts + length
s2 = Schedule(
starts=s2_starts,
ends=s2_ends,
cue_in=cue_in,
cue_out=cue_out,
instance=show_instance,
)
self.assertEqual(s2.get_cueout(), timedelta(minutes=5))
self.assertEqual(s2.get_ends(), show_instance.ends)
# Fully overlapping schedule datetimes (starts and ends are overlapping):
s3_starts = datetime(year=2021, month=10, day=2, hour=2, minute=1)
s3_ends = s3_starts + length
s3 = Schedule(
starts=s3_starts,
ends=s3_ends,
cue_in=cue_in,
cue_out=cue_out,
instance=show_instance,
)
self.assertEqual(s3.get_cueout(), cue_out)
self.assertEqual(s3.get_ends(), show_instance.ends)