Exemplo n.º 1
0
    def test_has_occurrence_with_other_event(self):
        other_occ = Occurrence.objects.create(event=self.event2,
                                              start=self.start,
                                              end=self.end,
                                              original_start=self.start,
                                              original_end=self.end)
        occ_replacer = OccurrenceReplacer([self.occ])

        self.assertTrue(occ_replacer.has_occurrence(self.occ))
        self.assertFalse(occ_replacer.has_occurrence(other_occ))
Exemplo n.º 2
0
    def test_has_occurrence_with_other_event(self):
        other_occ = Occurrence.objects.create(
            event=self.event2,
            start=self.start,
            end=self.end,
            original_start=self.start,
            original_end=self.end)
        occ_replacer = OccurrenceReplacer([self.occ])

        self.assertTrue(occ_replacer.has_occurrence(self.occ))
        self.assertFalse(occ_replacer.has_occurrence(other_occ))
Exemplo n.º 3
0
    def test_has_occurrence_with_other_event(self):
        other_occ = Occurrence(event=self.event2,
                               start=self.start,
                               end=self.end,
                               original_start=self.start,
                               original_end=self.end)
        other_occ.save()
        occ_replacer = OccurrenceReplacer([self.occ])

        assert occ_replacer.has_occurrence(self.occ)

        assert not occ_replacer.has_occurrence(other_occ)
Exemplo n.º 4
0
    def get_occurrences(self, start, end):
        """
        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00 to 2008-02-02 00:00:00', '2008-03-01 00:00:00 to 2008-03-02 00:00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []

        """
        persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(
                        occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
Exemplo n.º 5
0
    def get_occurrences(self, start, end, skip_booster=False, persisted_occurrences=None):
        """
        :param persisted_occurrences - In some contexts (such as models
        post_constraints), we need to ensure that we get the latest set of
        persisted_occurrences and avoid using the prefetch cache which may be
        stale. Client code can pass its own persisted_occurrences using the
        `all().all()` pattern in these cases.

        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1,tzinfo=pytz.utc), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00+00:00 to 2008-02-02 00:00:00+00:00', '2008-03-01 00:00:00+00:00 to 2008-03-02 00:00:00+00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []
        """

        if self.pk and not skip_booster:
            # performance booster for occurrences relationship
            Event.objects.prefetch_related('occurrence_set').get(pk=self.pk)

        if persisted_occurrences is None:
            persisted_occurrences = self.occurrence_set.all()

        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start <= end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(start, end)
        return final_occurrences
Exemplo n.º 6
0
    def get_occurrences(self, start, end):
        """
        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1,tzinfo=pytz.utc), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00+00:00 to 2008-02-02 00:00:00+00:00', '2008-03-01 00:00:00+00:00 to 2008-03-02 00:00:00+00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []
`
        """
        if self.pk:
            # performance booster for occurrences relationship
            Event.objects.select_related('occurrence').get(pk=self.pk)
        persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(
            start, end)
        return final_occurrences
Exemplo n.º 7
0
    def get_occurrences(self, start, end):
        """
        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1,tzinfo=pytz.utc), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00+00:00 to 2008-02-02 00:00:00+00:00', '2008-03-01 00:00:00+00:00 to 2008-03-02 00:00:00+00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []
`
        """
        if self.pk:
            # performance booster for occurrences relationship
            Event.objects.select_related('occurrence').get(pk=self.pk)
        persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(start, end)
        return final_occurrences
Exemplo n.º 8
0
    def get_occurrences(self, start, end):

        if self.pk:
            # performance booster for occurrences relationship
            Event.objects.select_related('occurrence').get(pk=self.pk)
        persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(
            start, end)
        return final_occurrences
Exemplo n.º 9
0
    def get_occurrences(self, start, end, clear_prefetch=True):
        """
        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1,tzinfo=pytz.utc), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00+00:00 to 2008-02-02 00:00:00+00:00', '2008-03-01 00:00:00+00:00 to 2008-03-02 00:00:00+00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []
        """

        # Explanation of clear_prefetch:
        #
        # Periods, and their subclasses like Week, call
        # prefetch_related('occurrence_set') on all events in their
        # purview. This reduces the database queries they make from
        # len()+1 to 2. However, having a cached occurrence_set on the
        # Event model instance can sometimes cause Events to have a
        # different view of the state of occurrences than the Period
        # managing them.
        #
        # E.g., if you create an unsaved occurrence, move it to a
        # different time [which saves the event], keep a reference to
        # the moved occurrence, & refetch all occurrences from the
        # Period without clearing the prefetch cache, you'll end up
        # with two Occurrences for the same event but different moved
        # states. It's a complicated scenario, but can happen. (See
        # tests/test_occurrence.py#test_moved_occurrences, which caught
        # this bug in the first place.)
        #
        # To prevent this, we clear the select_related cache by default
        # before we call an event's get_occurrences, but allow Period
        # to override this cache clear since it already fetches all
        # occurrence_sets via prefetch_related in its get_occurrences.
        if clear_prefetch:
            persisted_occurrences = self.occurrence_set.select_related(
                None).all()
        else:
            persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(
            start, end)
        return final_occurrences
Exemplo n.º 10
0
    def get_occurrences(self, start, end, clear_prefetch=True):
        """
        >>> rule = Rule(frequency = "MONTHLY", name = "Monthly")
        >>> rule.save()
        >>> event = Event(rule=rule, start=datetime.datetime(2008,1,1,tzinfo=pytz.utc), end=datetime.datetime(2008,1,2))
        >>> event.rule
        <Rule: Monthly>
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        ['2008-02-01 00:00:00+00:00 to 2008-02-02 00:00:00+00:00', '2008-03-01 00:00:00+00:00 to 2008-03-02 00:00:00+00:00']

        Ensure that if an event has no rule, that it appears only once.

        >>> event = Event(start=datetime.datetime(2008,1,1,8,0), end=datetime.datetime(2008,1,1,9,0))
        >>> occurrences = event.get_occurrences(datetime.datetime(2008,1,24), datetime.datetime(2008,3,2))
        >>> ["%s to %s" %(o.start, o.end) for o in occurrences]
        []
        """

        # Explanation of clear_prefetch:
        #
        # Periods, and their subclasses like Week, call
        # prefetch_related('occurrence_set') on all events in their
        # purview. This reduces the database queries they make from
        # len()+1 to 2. However, having a cached occurrence_set on the
        # Event model instance can sometimes cause Events to have a
        # different view of the state of occurrences than the Period
        # managing them.
        #
        # E.g., if you create an unsaved occurrence, move it to a
        # different time [which saves the event], keep a reference to
        # the moved occurrence, & refetch all occurrences from the
        # Period without clearing the prefetch cache, you'll end up
        # with two Occurrences for the same event but different moved
        # states. It's a complicated scenario, but can happen. (See
        # tests/test_occurrence.py#test_moved_occurrences, which caught
        # this bug in the first place.)
        #
        # To prevent this, we clear the select_related cache by default
        # before we call an event's get_occurrences, but allow Period
        # to override this cache clear since it already fetches all
        # occurrence_sets via prefetch_related in its get_occurrences.
        if clear_prefetch:
            persisted_occurrences = self.occurrence_set.select_related(None).all()
        else:
            persisted_occurrences = self.occurrence_set.all()
        occ_replacer = OccurrenceReplacer(persisted_occurrences)
        occurrences = self._get_occurrence_list(start, end)
        final_occurrences = []
        for occ in occurrences:
            # replace occurrences with their persisted counterparts
            if occ_replacer.has_occurrence(occ):
                p_occ = occ_replacer.get_occurrence(occ)
                # ...but only if they are within this period
                if p_occ.start < end and p_occ.end >= start:
                    final_occurrences.append(p_occ)
            else:
                final_occurrences.append(occ)
        # then add persisted occurrences which originated outside of this period but now
        # fall within it
        final_occurrences += occ_replacer.get_additional_occurrences(start, end)
        return final_occurrences