def calculate_effective_schedule_start_dt(schedule):
    """
    Calculation of the first start date to improve performance
    """
    tz = timezone.get_default_timezone()
    programme_start_dt = tz.localize(
        datetime.datetime.combine(schedule.programme.start_date, datetime.time())
    ).astimezone(pytz.utc) if schedule.programme.start_date else None

    programme_end_dt = tz.localize(
        datetime.datetime.combine(schedule.programme.end_date, datetime.time(23, 59, 59))
    ).astimezone(pytz.utc) if schedule.programme.end_date else None

    # If there are no rrules
    if not schedule.recurrences:
        if programme_start_dt and programme_start_dt > schedule.start_dt:
            return None
        if programme_end_dt and schedule.start_dt > programme_end_dt:
            return None
        return schedule.start_dt

    # Get first date
    after_dt = schedule.start_dt
    if programme_start_dt:
        after_dt = max(schedule.start_dt, programme_start_dt)
    first_start_dt = fix_recurrence_dst(recurrence_after(
        schedule.recurrences, transform_dt_to_default_tz(after_dt), transform_dt_to_default_tz(schedule.start_dt)))
    if first_start_dt:
        if programme_end_dt and programme_end_dt < first_start_dt:
            return None
        return first_start_dt
    return None
示例#2
0
def calculate_effective_schedule_start_dt(schedule):
    """
    Calculation of the first start date to improve performance
    """
    programme_start_dt = schedule.programme.start_dt
    programme_end_dt = schedule.programme.end_dt

    # If there are no rrules
    if not schedule.has_recurrences():
        if programme_start_dt and programme_start_dt > schedule.start_dt:
            return None
        if programme_end_dt and schedule.start_dt > programme_end_dt:
            return None
        return schedule.start_dt

    # Get first date
    after_dt = schedule.start_dt
    if programme_start_dt:
        after_dt = max(schedule.start_dt, programme_start_dt)
    first_start_dt = fix_recurrence_dst(recurrence_after(
        schedule.recurrences, transform_dt_to_default_tz(after_dt), transform_dt_to_default_tz(schedule.start_dt)))
    if first_start_dt:
        if programme_end_dt and programme_end_dt < first_start_dt:
            return None
        return first_start_dt
    return None
示例#3
0
def calculate_effective_schedule_start_dt(schedule):
    """
    Calculation of the first start date to improve performance
    """
    programme_start_dt = schedule.programme.start_dt
    programme_end_dt = schedule.programme.end_dt

    # If there are no rrules
    if not schedule.has_recurrences():
        if programme_start_dt and programme_start_dt > schedule.start_dt:
            return None
        if programme_end_dt and schedule.start_dt > programme_end_dt:
            return None
        return schedule.start_dt

    # Get first date
    after_dt = schedule.start_dt
    if programme_start_dt:
        after_dt = max(schedule.start_dt, programme_start_dt)
    first_start_dt = fix_recurrence_dst(recurrence_after(
        schedule.recurrences, transform_dt_to_default_tz(after_dt), transform_dt_to_default_tz(schedule.start_dt)))
    if first_start_dt:
        if programme_end_dt and programme_end_dt < first_start_dt:
            return None
        return first_start_dt
    return None
示例#4
0
def calculate_effective_schedule_end_dt(schedule):
    """
    Calculation of the last end date to improve performance
    """
    tz = timezone.get_default_timezone()
    programme_start_dt = tz.localize(
        datetime.datetime.combine(
            schedule.programme.start_date, datetime.time())).astimezone(
                pytz.utc) if schedule.programme.start_date else None

    programme_end_dt = tz.localize(
        datetime.datetime.combine(
            schedule.programme.end_date, datetime.time(
                23, 59, 59))).astimezone(
                    pytz.utc) if schedule.programme.end_date else None

    runtime = datetime.timedelta(minutes=schedule.programme._runtime)

    # If there are no rrules
    if not schedule.recurrences:
        if not schedule.effective_start_dt:
            # WARNING: this depends on effective_start_dt
            return None  # returning None if there is no effective_start_dt
        return schedule.start_dt + runtime

    # If we have a programme restriction
    if programme_end_dt:
        last_effective_start_date = fix_recurrence_dst(
            recurrence_before(schedule.recurrences,
                              transform_dt_to_default_tz(programme_end_dt),
                              transform_dt_to_default_tz(schedule.start_dt)))
        if last_effective_start_date:
            if programme_start_dt and programme_start_dt > last_effective_start_date:
                return None
            return last_effective_start_date + runtime

    rrules_until_dates = [
        _rrule.until for _rrule in schedule.recurrences.rrules
    ]

    # If we have a rrule without a until date we don't know the last date
    if any([x is None for x in rrules_until_dates]):
        return None

    possible_limit_dates = schedule.recurrences.rdates + rrules_until_dates
    if not possible_limit_dates:
        return None

    # Get the biggest possible start_date. It could be that the biggest date is excluded
    biggest_date = max(possible_limit_dates)
    last_effective_start_date = schedule.recurrences.before(
        transform_dt_to_default_tz(biggest_date),
        True,
        dtstart=transform_dt_to_default_tz(schedule.start_dt))
    if last_effective_start_date:
        if programme_start_dt and programme_start_dt > last_effective_start_date:
            return None
        return fix_recurrence_dst(last_effective_start_date) + runtime
    return None
示例#5
0
 def date_after(self, after):
     after_date = self._merge_after(after)
     if not after_date:
         return
     after_date = transform_dt_to_default_tz(after_date)
     start_dt = transform_dt_to_default_tz(self.start_dt)
     date = recurrence_after(self.recurrences, after_date, start_dt)
     return fix_recurrence_dst(date)
示例#6
0
 def date_after(self, after):
     after_date = self._merge_after(after)
     if not after_date:
         return
     after_date = transform_dt_to_default_tz(after_date)
     start_dt = transform_dt_to_default_tz(self.start_dt)
     date = recurrence_after(self.recurrences, after_date, start_dt)
     return fix_recurrence_dst(date)
def calculate_effective_schedule_end_dt(schedule):
    """
    Calculation of the last end date to improve performance
    """
    tz = timezone.get_default_timezone()
    programme_start_dt = tz.localize(
        datetime.datetime.combine(schedule.programme.start_date, datetime.time())
    ).astimezone(pytz.utc) if schedule.programme.start_date else None

    programme_end_dt = tz.localize(
        datetime.datetime.combine(schedule.programme.end_date, datetime.time(23, 59, 59))
    ).astimezone(pytz.utc) if schedule.programme.end_date else None

    runtime = datetime.timedelta(minutes=schedule.programme._runtime)

    # If there are no rrules
    if not schedule.recurrences:
        if not schedule.effective_start_dt:
            # WARNING: this depends on effective_start_dt
            return None  # returning None if there is no effective_start_dt
        return schedule.start_dt + runtime

    # If we have a programme restriction
    if programme_end_dt:
        last_effective_start_date = fix_recurrence_dst(recurrence_before(
            schedule.recurrences, transform_dt_to_default_tz(programme_end_dt), transform_dt_to_default_tz(schedule.start_dt)))
        if last_effective_start_date:
            if programme_start_dt and programme_start_dt > last_effective_start_date:
                return None
            return last_effective_start_date + runtime

    rrules_until_dates = [_rrule.until for _rrule in schedule.recurrences.rrules]

    # If we have a rrule without a until date we don't know the last date
    if any([x is None for x in rrules_until_dates]):
        return None

    possible_limit_dates = schedule.recurrences.rdates + rrules_until_dates
    if not possible_limit_dates:
        return None

    # Get the biggest possible start_date. It could be that the biggest date is excluded
    biggest_date = max(possible_limit_dates)
    last_effective_start_date = schedule.recurrences.before(
        transform_dt_to_default_tz(biggest_date), True, dtstart=transform_dt_to_default_tz(schedule.start_dt))
    if last_effective_start_date:
        if programme_start_dt and programme_start_dt > last_effective_start_date:
            return None
        return fix_recurrence_dst(last_effective_start_date) + runtime
    return None
示例#8
0
def calculate_effective_schedule_end_dt(schedule):
    """
    Calculation of the last end date to improve performance
    """
    programme_start_dt = schedule.programme.start_dt
    programme_end_dt = schedule.programme.end_dt

    # If there are no rrules
    if not schedule.has_recurrences():
        if not schedule.effective_start_dt:
            # WARNING: this depends on effective_start_dt
            return None  # returning None if there is no effective_start_dt
        return schedule.start_dt + schedule.runtime

    # If we have a programme restriction
    if programme_end_dt:
        last_effective_start_date = fix_recurrence_dst(
            recurrence_before(schedule.recurrences,
                              transform_dt_to_default_tz(programme_end_dt),
                              transform_dt_to_default_tz(schedule.start_dt)))
        if last_effective_start_date:
            if programme_start_dt and programme_start_dt > last_effective_start_date:
                return None
            return last_effective_start_date + schedule.runtime

    rrules_until_dates = [
        _rrule.until for _rrule in schedule.recurrences.rrules
    ]

    # If we have a rrule without a until date we don't know the last date
    if any([x is None for x in rrules_until_dates]):
        return None

    possible_limit_dates = schedule.recurrences.rdates + rrules_until_dates
    if not possible_limit_dates:
        return None

    # Get the biggest possible start_date. It could be that the biggest date is excluded
    biggest_date = max(possible_limit_dates)
    last_effective_start_date = schedule.recurrences.before(
        transform_dt_to_default_tz(biggest_date),
        True,
        dtstart=transform_dt_to_default_tz(schedule.start_dt))
    if last_effective_start_date:
        if programme_start_dt and programme_start_dt > last_effective_start_date:
            return None
        return fix_recurrence_dst(last_effective_start_date) + schedule.runtime
    return None
示例#9
0
 def test_transform_dt_to_default_tz(self):
     utc_dt = pytz.utc.localize(datetime.datetime(2017, 1, 1, 0, 00, 00))
     spain_dt = transform_dt_to_default_tz(utc_dt)
     self.assertEquals(spain_dt.tzinfo.zone, 'Europe/Madrid')
     self.assertEquals(
         spain_dt, SPAIN_TZ.localize(datetime.datetime(2017, 1, 1, 1, 0,
                                                       0)))
示例#10
0
def recording_schedules(request):
    podcast_config = PodcastConfiguration.get_global()
    default_tz = timezone.get_default_timezone()
    start = default_tz.localize(datetime.datetime.strptime(request.GET.get('start'), '%Y-%m-%d %H:%M:%S'))
    next_hours = int(request.GET.get("next_hours") or podcast_config.next_events)

    json_list = []
    next_transmissions = Transmission.between(
        start, start + datetime.timedelta(hours=next_hours),
        schedules=Schedule.objects.filter(calendar__is_active=True, type='L')
    )

    for transmission in next_transmissions:
        try:
            episode = Episode.objects.get(issue_date=transmission.start, programme=transmission.programme)
        except Episode.DoesNotExist:
            episode = Episode.objects.create_episode(transmission.start, transmission.programme)

        issue_date = transform_dt_to_default_tz(transmission.start)
        start_dt = issue_date + datetime.timedelta(seconds=podcast_config.start_delay)
        duration = transmission.schedule.runtime.seconds - podcast_config.start_delay - podcast_config.end_delay
        json_entry = {
            'id': transmission.programme.id, 'issue_date': issue_date.strftime('%Y-%m-%d %H-%M-%S'),
            'start': start_dt.strftime('%Y-%m-%d %H-%M-%S'), 'duration': str(duration),
            'genre': transmission.programme.get_category_display(), 'programme_name': transmission.programme.slug,
            'title': episode.title, 'author': transmission.programme.name, 'album': _('Season') + ' ' + str(episode.season),
            'track': episode.number_in_season
        }
        json_list.append(json_entry)

    return HttpResponse(json.dumps(json_list), content_type='application/json')
示例#11
0
    def form_valid(self, form):
        cleaned_data = form.clean()
        schedule = cleaned_data['schedule']
        transmission_dt = cleaned_data['transmission_dt']
        action = cleaned_data.get('action')
        if not schedule.has_recurrences() or action == DeleteScheduleForm.DELETE_ALL:
            schedule.delete()
        elif action == DeleteScheduleForm.DELETE_ONLY_THIS:
            schedule.exclude_date(transmission_dt)
            schedule.save()
        elif action == DeleteScheduleForm.DELETE_THIS_AND_FOLLOWING:
            # until_dt is the end of the previous day
            until_dt = timezone.get_default_timezone().localize(
                datetime.datetime.combine(
                    transform_dt_to_default_tz(transmission_dt).date() - datetime.timedelta(days=1),
                    datetime.time(23, 59, 59)
                )
            )
            # removing rdates rules that are bigger than until_dt
            schedule.recurrences.rdates = [_dt for _dt in schedule.recurrences.rdates if _dt > until_dt]
            # Add a until constraint to all rules (except if they have a date more restrictive)
            for rrule in schedule.recurrences.rrules:
                if not rrule.until or rrule.until > until_dt:
                    rrule.until = until_dt
            schedule.save()

        return HttpResponse(
            json.dumps({'result': 'ok'}),
            content_type='application/json'
        )
示例#12
0
    def form_valid(self, form):
        cleaned_data = form.clean()
        schedule = cleaned_data['schedule']
        transmission_dt = cleaned_data['transmission_dt']
        action = cleaned_data.get('action')
        if not schedule.has_recurrences(
        ) or action == DeleteScheduleForm.DELETE_ALL:
            schedule.delete()
        elif action == DeleteScheduleForm.DELETE_ONLY_THIS:
            schedule.exclude_date(transmission_dt)
            schedule.save()
        elif action == DeleteScheduleForm.DELETE_THIS_AND_FOLLOWING:
            # until_dt is the end of the previous day
            until_dt = timezone.get_default_timezone().localize(
                datetime.datetime.combine(
                    transform_dt_to_default_tz(transmission_dt).date() -
                    datetime.timedelta(days=1), datetime.time(23, 59, 59)))
            # removing rdates rules that are bigger than until_dt
            schedule.recurrences.rdates = [
                _dt for _dt in schedule.recurrences.rdates if _dt > until_dt
            ]
            # Add a until constraint to all rules (except if they have a date more restrictive)
            for rrule in schedule.recurrences.rrules:
                if not rrule.until or rrule.until > until_dt:
                    rrule.until = until_dt
            schedule.save()

        return HttpResponse(json.dumps({'result': 'ok'}),
                            content_type='application/json')
示例#13
0
def calculate_effective_schedule_end_dt(schedule):
    """
    Calculation of the last end date to improve performance
    """
    programme_start_dt = schedule.programme.start_dt
    programme_end_dt = schedule.programme.end_dt

    # If there are no rrules
    if not schedule.has_recurrences():
        if not schedule.effective_start_dt:
            # WARNING: this depends on effective_start_dt
            return None  # returning None if there is no effective_start_dt
        return schedule.start_dt + schedule.runtime

    # If we have a programme restriction
    if programme_end_dt:
        last_effective_start_date = fix_recurrence_dst(recurrence_before(
            schedule.recurrences, transform_dt_to_default_tz(programme_end_dt), transform_dt_to_default_tz(schedule.start_dt)))
        if last_effective_start_date:
            if programme_start_dt and programme_start_dt > last_effective_start_date:
                return None
            return last_effective_start_date + schedule.runtime

    rrules_until_dates = [_rrule.until for _rrule in schedule.recurrences.rrules]

    # If we have a rrule without a until date we don't know the last date
    if any([x is None for x in rrules_until_dates]):
        return None

    possible_limit_dates = schedule.recurrences.rdates + rrules_until_dates
    if not possible_limit_dates:
        return None

    # Get the biggest possible start_date. It could be that the biggest date is excluded
    biggest_date = max(possible_limit_dates)
    last_effective_start_date = schedule.recurrences.before(
        transform_dt_to_default_tz(biggest_date), True, dtstart=transform_dt_to_default_tz(schedule.start_dt))
    if last_effective_start_date:
        if programme_start_dt and programme_start_dt > last_effective_start_date:
            return None
        return fix_recurrence_dst(last_effective_start_date) + schedule.runtime
    return None
示例#14
0
 def _update_recurrence_dates(self):
     """
     Fix for django-recurrence 1.3
     We need to update the internal until datetime to include the whole day
     """
     default_tz = timezone.get_default_timezone()
     for rrule in self.recurrences.rrules:
         if rrule.until:
             rrule.until = default_tz.localize(datetime.datetime.combine(
                 transform_dt_to_default_tz(rrule.until).date(),
                 datetime.time(23, 59, 59)))
示例#15
0
 def _update_recurrence_dates(self):
     """
     Fix for django-recurrence 1.3
     We need to update the internal until datetime to include the whole day
     """
     default_tz = timezone.get_default_timezone()
     for rrule in self.recurrences.rrules:
         if rrule.until:
             rrule.until = default_tz.localize(datetime.datetime.combine(
                 transform_dt_to_default_tz(rrule.until).date(),
                 datetime.time(23, 59, 59)))
示例#16
0
    def dates_between(self, after, before):
        """
            Return a sorted list of dates between after and before
        """
        after_date = self._merge_after(after)
        if not after_date:
            return
        after_date = transform_dt_to_default_tz(after_date)
        before_date = transform_dt_to_default_tz(self._merge_before(before))
        start_dt = transform_dt_to_default_tz(self.start_dt)

        # We need to send the dates in the default timezone
        recurrence_dates_between = self.recurrences.between(after_date, before_date, inc=True, dtstart=start_dt)

        # Special case to include started episodes
        date_before = self.date_before(after_date)
        if date_before and date_before < after_date < date_before + self.runtime:
            yield date_before  # Date was already fixed

        for date in recurrence_dates_between:
            yield fix_recurrence_dst(date)  # Fixing date
示例#17
0
    def dates_between(self, after, before):
        """
            Return a sorted list of dates between after and before
        """
        after_date = self._merge_after(after)
        if not after_date:
            return
        after_date = transform_dt_to_default_tz(after_date)
        before_date = transform_dt_to_default_tz(self._merge_before(before))
        start_dt = transform_dt_to_default_tz(self.start_dt)

        # We need to send the dates in the default timezone
        recurrence_dates_between = self.recurrences.between(after_date, before_date, inc=True, dtstart=start_dt)

        # Special case to include started episodes
        date_before = self.date_before(after_date)
        if date_before and date_before < after_date < date_before + self.runtime:
            yield date_before  # Date was already fixed

        for date in recurrence_dates_between:
            yield fix_recurrence_dst(date)  # Fixing date
示例#18
0
def calculate_effective_schedule_start_dt(schedule):
    """
    Calculation of the first start date to improve performance
    """
    tz = timezone.get_default_timezone()
    programme_start_dt = tz.localize(
        datetime.datetime.combine(
            schedule.programme.start_date, datetime.time())).astimezone(
                pytz.utc) if schedule.programme.start_date else None

    programme_end_dt = tz.localize(
        datetime.datetime.combine(
            schedule.programme.end_date, datetime.time(
                23, 59, 59))).astimezone(
                    pytz.utc) if schedule.programme.end_date else None

    # If there are no rrules
    if not schedule.recurrences:
        if programme_start_dt and programme_start_dt > schedule.start_dt:
            return None
        if programme_end_dt and schedule.start_dt > programme_end_dt:
            return None
        return schedule.start_dt

    # Get first date
    after_dt = schedule.start_dt
    if programme_start_dt:
        after_dt = max(schedule.start_dt, programme_start_dt)
    first_start_dt = fix_recurrence_dst(
        recurrence_after(schedule.recurrences,
                         transform_dt_to_default_tz(after_dt),
                         transform_dt_to_default_tz(schedule.start_dt)))
    if first_start_dt:
        if programme_end_dt and programme_end_dt < first_start_dt:
            return None
        return first_start_dt
    return None
示例#19
0
 def date_before(self, before):
     before_date = transform_dt_to_default_tz(self._merge_before(before))
     start_dt = transform_dt_to_default_tz(self.start_dt)
     date = recurrence_before(self.recurrences, before_date, start_dt)
     return fix_recurrence_dst(date)
示例#20
0
 def date(self):
     local_dt = transform_dt_to_default_tz(self.datetime)
     return local_dt.date()
示例#21
0
 def date_before(self, before):
     before_date = transform_dt_to_default_tz(self._merge_before(before))
     start_dt = transform_dt_to_default_tz(self.start_dt)
     date = recurrence_before(self.recurrences, before_date, start_dt)
     return fix_recurrence_dst(date)
示例#22
0
 def include_date(self, dt):
     local_dt = transform_dt_to_default_tz(dt)
     self.recurrences.exdates.remove(fix_recurrence_date(self.start_dt, local_dt))
     ExcludedDates.objects.get(schedule=self, datetime=dt).delete()
示例#23
0
 def exclude_date(self, dt):
     local_dt = transform_dt_to_default_tz(dt)
     self.recurrences.exdates.append(fix_recurrence_date(self.start_dt, local_dt))
     ExcludedDates.objects.create(schedule=self, datetime=dt)
示例#24
0
 def date(self):
     local_dt = transform_dt_to_default_tz(self.datetime)
     return local_dt.date()
示例#25
0
 def test_transform_dt_to_default_tz(self):
     utc_dt = pytz.utc.localize(datetime.datetime(2017, 1, 1, 0, 00, 00))
     spain_dt = transform_dt_to_default_tz(utc_dt)
     self.assertEqual(spain_dt.tzinfo.zone, 'Europe/Madrid')
     self.assertEqual(spain_dt, SPAIN_TZ.localize(datetime.datetime(2017, 1, 1, 1, 0, 0)))
示例#26
0
 def exclude_date(self, dt):
     local_dt = transform_dt_to_default_tz(dt)
     self.recurrences.exdates.append(fix_recurrence_date(self.start_dt, local_dt))
     ExcludedDates.objects.create(schedule=self, datetime=dt)
示例#27
0
 def include_date(self, dt):
     local_dt = transform_dt_to_default_tz(dt)
     self.recurrences.exdates.remove(fix_recurrence_date(self.start_dt, local_dt))
     ExcludedDates.objects.get(schedule=self, datetime=dt).delete()