diff --git a/Makefile b/Makefile index d3c8cef122742051f08d5907b9a4696a241fa2f1..7dcbf364374dc7565702d6917ec52290ff6e93b7 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,9 @@ loaddata.test: addpermissions: $(POETRY_RUN_MANAGE) addpermissions +addtimeslots: + $(POETRY_RUN_MANAGE) addtimeslots + removestaleimages: $(POETRY_RUN_MANAGE) removestaleimages diff --git a/program/management/commands/addtimeslots.py b/program/management/commands/addtimeslots.py new file mode 100644 index 0000000000000000000000000000000000000000..2950221203f23510667a47bde518f14c15cab7a9 --- /dev/null +++ b/program/management/commands/addtimeslots.py @@ -0,0 +1,70 @@ +from datetime import datetime + +from dateutil.rrule import rrule + +from django.core.management import BaseCommand +from django.utils.timezone import make_aware +from program.models import RRule, Schedule, TimeSlot + + +class Command(BaseCommand): + help = "adds timeslots to the repeating schedules for one year" + + def add_arguments(self, parser): + parser.add_argument( + "year", + help="The year ", + type=int, + ) + parser.add_argument( + "--dry-run", + action="store_true", + help="Does not add the timeslots, just prints the number of timeslots to be added.", + ) + + def handle(self, *args, **options): + year = options["year"] + dry_run = options["dry_run"] + + begin_of_year = datetime(year, 1, 1) + end_of_year = datetime(year, 12, 31) + + once = RRule.objects.get(freq=0, count=1) + + for schedule in ( + Schedule.objects.exclude(rrule=once).filter(last_date=None).order_by("show__name") + ): + last_timeslot = schedule.timeslots.last() + + # add timeslots to the schedules with no timeslot this year + # `begin_of_year` needs to be timezone aware for the comparison to work + if last_timeslot and last_timeslot.start < make_aware(begin_of_year): + freq = schedule.rrule.freq + interval = schedule.rrule.interval + dtstart = {"start": last_timeslot.start, "end": last_timeslot.end} + # `until` needs to be timezone aware because `dtstart` is + until = {"start": make_aware(end_of_year), "end": make_aware(end_of_year)} + + # will need to skip the first recurrences, since they’re from the previous year + starts = rrule( + freq=freq, interval=interval, dtstart=dtstart["start"], until=until["start"] + ) + ends = rrule( + freq=freq, interval=interval, dtstart=dtstart["end"], until=until["end"] + ) + + timeslots = [ + TimeSlot(schedule=schedule, start=start, end=end) + for start, end in zip(starts[1:], ends[1:]) + ] + + if dry_run: + self.stdout.write( + self.style.WARNING(f"would add {len(timeslots)} timeslots to {schedule}") + ) + else: + TimeSlot.objects.bulk_create(timeslots, ignore_conflicts=True) + + self.stdout.write( + self.style.SUCCESS(f"added {len(timeslots)} timeslots to {schedule}") + )