diff --git a/program/models.py b/program/models.py index f49bce0649816a0ed4147cc8ae7a90f8d71f9e28..5457ea2c51b72b23753b0881d5939abb066effdc 100644 --- a/program/models.py +++ b/program/models.py @@ -241,7 +241,10 @@ class RRule(models.Model): (3, "daily"), ] ) - interval = models.IntegerField(default=1) + interval = models.IntegerField( + default=1, + help_text="The interval between each freq iteration.", + ) by_set_pos = models.IntegerField( blank=True, choices=[ @@ -264,11 +267,16 @@ class RRule(models.Model): null=True, max_length=9, ) - count = models.IntegerField(blank=True, null=True) + count = models.IntegerField( + blank=True, + null=True, + help_text="How many occurrences should be generated.", + ) class Meta: ordering = ("pk",) unique_together = ("freq", "interval", "by_set_pos", "by_weekdays") + verbose_name = _("recurrence rule") def __str__(self): return self.name @@ -279,7 +287,7 @@ class Schedule(models.Model): RRule, on_delete=models.CASCADE, related_name="schedules", - help_text="A recurrence rule." + help_text="A recurrence rule.", ) show = models.ForeignKey( Show, @@ -298,7 +306,7 @@ class Schedule(models.Model): (5, "Saturday"), (6, "Sunday"), ], - null=True + null=True, ) first_date = models.DateField(help_text="Start date of schedule.") start_time = models.TimeField(help_text="Start time of schedule.") @@ -345,21 +353,13 @@ class Schedule(models.Model): int(sdl["default_playlist_id"]) if sdl.get("default_playlist_id") else None ) add_days_no = int(sdl["add_days_no"]) if sdl.get("add_days_no") else None - add_business_days_only = ( - True if sdl.get("add_business_days_only") is True else False - ) + add_business_days_only = True if sdl.get("add_business_days_only") is True else False first_date = parse_date(str(sdl["first_date"])) start_time = ( - sdl["start_time"] + ":00" - if len(str(sdl["start_time"])) == 5 - else sdl["start_time"] - ) - end_time = ( - sdl["end_time"] + ":00" - if len(str(sdl["end_time"])) == 5 - else sdl["end_time"] + sdl["start_time"] + ":00" if len(str(sdl["start_time"])) == 5 else sdl["start_time"] ) + end_time = sdl["end_time"] + ":00" if len(str(sdl["end_time"])) == 5 else sdl["end_time"] start_time = parse_time(str(start_time)) end_time = parse_time(str(end_time)) @@ -372,9 +372,7 @@ class Schedule(models.Model): year = timezone.now().year last_date = parse_date(f"{year}-12-31") else: - last_date = first_date + timedelta( - days=+AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE - ) + last_date = first_date + timedelta(days=+AUTO_SET_LAST_DATE_TO_DAYS_IN_FUTURE) schedule = Schedule( pk=pk, @@ -411,9 +409,9 @@ class Schedule(models.Model): if schedule.rrule.freq == 3: # daily: Ignore schedule.by_weekday to set by_weekday by_weekday_start = by_weekday_end = (0, 1, 2, 3, 4, 5, 6) elif ( - schedule.rrule.freq == 2 - and schedule.rrule.interval == 1 - and schedule.rrule.by_weekdays is None + schedule.rrule.freq == 2 + and schedule.rrule.interval == 1 + and schedule.rrule.by_weekdays is None ): # weekly: Use schedule.by_weekday for by_weekday by_weekday_start = by_weekday_end = int(schedule.by_weekday) @@ -421,9 +419,9 @@ class Schedule(models.Model): if schedule.end_time < schedule.start_time: by_weekday_end = by_weekday_start + 1 if by_weekday_start < 6 else 0 elif ( - schedule.rrule.freq == 2 - and schedule.rrule.interval == 1 - and schedule.rrule.by_weekdays == "0,1,2,3,4" + schedule.rrule.freq == 2 + and schedule.rrule.interval == 1 + and schedule.rrule.by_weekdays == "0,1,2,3,4" ): # weekly on business days: Use schedule.rrule.by_weekdays to set by_weekday by_weekday_start = by_weekday_end = [ int(wd) for wd in schedule.rrule.by_weekdays.split(",") @@ -433,9 +431,9 @@ class Schedule(models.Model): if schedule.end_time < schedule.start_time: by_weekday_end = (1, 2, 3, 4, 5) elif ( - schedule.rrule.freq == 2 - and schedule.rrule.interval == 1 - and schedule.rrule.by_weekdays == "5,6" + schedule.rrule.freq == 2 + and schedule.rrule.interval == 1 + and schedule.rrule.by_weekdays == "5,6" ): # weekly on weekends: Use schedule.rrule.by_weekdays to set by_weekday by_weekday_start = by_weekday_end = [ int(wd) for wd in schedule.rrule.by_weekdays.split(",") @@ -486,9 +484,7 @@ class Schedule(models.Model): # produces wrong end dates if the 1st Tuesday is before the 1st Monday # In this case we take the next day instead of rrule's calculated end if starts[k] > ends[k]: - ends[k] = datetime.combine( - starts[k] + relativedelta(days=+1), schedule.end_time - ) + ends[k] = datetime.combine(starts[k] + relativedelta(days=+1), schedule.end_time) """ Add a number of days to the generated dates? @@ -557,9 +553,7 @@ class Schedule(models.Model): collision = TimeSlot.objects.get_colliding_timeslots(ts) if collision: - collisions.append( - collision[0] - ) # TODO: Do we really always retrieve one? + collisions.append(collision[0]) # TODO: Do we really always retrieve one? else: collisions.append(None) @@ -587,9 +581,7 @@ class Schedule(models.Model): solution_choices = set() # Get collisions for each timeslot - collision_list = list( - TimeSlot.objects.get_colliding_timeslots(ts).order_by("start") - ) + collision_list = list(TimeSlot.objects.get_colliding_timeslots(ts).order_by("start")) # Add the projected timeslot projected_entry = { @@ -774,9 +766,7 @@ class Schedule(models.Model): code="no-start-after-end", ) - num_conflicts = len( - [pr for pr in conflicts["projected"] if len(pr["collisions"]) > 0] - ) + num_conflicts = len([pr for pr in conflicts["projected"] if len(pr["collisions"]) > 0]) if len(solutions) != num_conflicts: raise ScheduleConflictError( @@ -803,9 +793,7 @@ class Schedule(models.Model): # - Create the projected timeslot and skip # if "solution_choices" not in ts or len(ts["collisions"]) < 1: - projected_ts = TimeSlot.objects.instantiate( - ts["start"], ts["end"], schedule, show - ) + projected_ts = TimeSlot.objects.instantiate(ts["start"], ts["end"], schedule, show) create.append(projected_ts) continue @@ -827,9 +815,7 @@ class Schedule(models.Model): # - Skip # if not solutions[ts["hash"]] in ts["solution_choices"]: - errors[ts["hash"]] = _( - "Given solution is not accepted for this conflict." - ) + errors[ts["hash"]] = _("Given solution is not accepted for this conflict.") continue """Conflict resolution""" @@ -851,9 +837,7 @@ class Schedule(models.Model): # - Delete the existing collision(s) # if solution == "ours": - projected_ts = TimeSlot.objects.instantiate( - ts["start"], ts["end"], schedule, show - ) + projected_ts = TimeSlot.objects.instantiate(ts["start"], ts["end"], schedule, show) create.append(projected_ts) # Delete collision(s) @@ -881,9 +865,7 @@ class Schedule(models.Model): # - Change the start of the existing collision to projected end # if solution == "ours-end": - projected_ts = TimeSlot.objects.instantiate( - ts["start"], ts["end"], schedule, show - ) + projected_ts = TimeSlot.objects.instantiate(ts["start"], ts["end"], schedule, show) create.append(projected_ts) existing_ts = TimeSlot.objects.get(pk=existing["id"]) @@ -907,9 +889,7 @@ class Schedule(models.Model): # - Change end of existing to projected start # if solution == "ours-start": - projected_ts = TimeSlot.objects.instantiate( - ts["start"], ts["end"], schedule, show - ) + projected_ts = TimeSlot.objects.instantiate(ts["start"], ts["end"], schedule, show) create.append(projected_ts) existing_ts = TimeSlot.objects.get(pk=existing["id"]) @@ -941,9 +921,7 @@ class Schedule(models.Model): # - Create another one with start = projected end and end = existing end # if solution == "ours-both": - projected_ts = TimeSlot.objects.instantiate( - ts["start"], ts["end"], schedule, show - ) + projected_ts = TimeSlot.objects.instantiate(ts["start"], ts["end"], schedule, show) create.append(projected_ts) existing_ts = TimeSlot.objects.get(pk=existing["id"]) @@ -958,24 +936,18 @@ class Schedule(models.Model): # If there were any errors, don't make any db changes yet # but add error messages and return already chosen solutions if len(errors) > 0: - conflicts = Schedule.make_conflicts( - model_to_dict(schedule), schedule.pk, show.pk - ) + conflicts = Schedule.make_conflicts(model_to_dict(schedule), schedule.pk, show.pk) partly_resolved = conflicts["projected"] saved_solutions = {} # Add already chosen resolutions and error message to conflict for index, c in enumerate(conflicts["projected"]): - # The element should only exist if there was a collision if len(c["collisions"]) > 0: saved_solutions[c["hash"]] = "" - if ( - c["hash"] in solutions - and solutions[c["hash"]] in c["solution_choices"] - ): + if c["hash"] in solutions and solutions[c["hash"]] in c["solution_choices"]: saved_solutions[c["hash"]] = solutions[c["hash"]] if c["hash"] in errors: @@ -996,7 +968,7 @@ class Schedule(models.Model): # Collect upcoming timeslots to delete which might still remain del_timeslots = TimeSlot.objects.filter( schedule=schedule, - start__gt=timezone.make_aware(datetime.combine(schedule.last_date, time(0, 0))) + start__gt=timezone.make_aware(datetime.combine(schedule.last_date, time(0, 0))), ) for del_ts in del_timeslots: delete.append(del_ts) @@ -1085,9 +1057,7 @@ class TimeSlotManager(models.Manager): class TimeSlot(models.Model): - schedule = models.ForeignKey( - Schedule, on_delete=models.CASCADE, related_name="timeslots" - ) + schedule = models.ForeignKey(Schedule, on_delete=models.CASCADE, related_name="timeslots") show = models.ForeignKey( Show, editable=False, on_delete=models.CASCADE, related_name="timeslots" ) @@ -1152,16 +1122,12 @@ class Note(models.Model): ) status = models.IntegerField(default=1) start = models.DateTimeField(editable=False) - show = models.ForeignKey( - Show, on_delete=models.CASCADE, related_name="notes", editable=True - ) + show = models.ForeignKey(Show, on_delete=models.CASCADE, related_name="notes", editable=True) cba_id = models.IntegerField(blank=True, null=True) user = models.ForeignKey( User, editable=False, on_delete=models.CASCADE, related_name="users", default=1 ) - host = models.ForeignKey( - Host, on_delete=models.CASCADE, related_name="hosts", null=True - ) + host = models.ForeignKey(Host, on_delete=models.CASCADE, related_name="hosts", null=True) class Meta: ordering = ("timeslot",)