def complexExpand()

in src/pycalendar/icalendar/recurrence.py [0:0]


    def complexExpand(self, start, range, items, float_offset, maxInstances=None):
        start_iter = start.duplicate()
        ctr = 0

        if self.mUseUntil:
            float_until = self.mUntil.duplicate()
            if start.floating():
                float_until.setTimezoneID(None)
                float_until.offsetSeconds(float_offset)

        # Always add the initial instance DTSTART
        if self.mUseCount:
            # Bump counter and exit if over
            ctr += 1
            if ctr >= self.mCount:
                return True

        # Need to re-initialise start based on BYxxx rules
        while True:
            # Behaviour is based on frequency
            set_items = []

            if self.mFreq == definitions.eRecurrence_SECONDLY:
                self.generateSecondlySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_MINUTELY:
                self.generateMinutelySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_HOURLY:
                self.generateHourlySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_DAILY:
                self.generateDailySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_WEEKLY:
                self.generateWeeklySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_MONTHLY:
                self.generateMonthlySet(start_iter, set_items)

            elif self.mFreq == definitions.eRecurrence_YEARLY:
                self.generateYearlySet(start_iter, set_items)

            # Always sort the set as BYxxx rules may not be sorted
            # set_items.sort(cmp=DateTime.sort)
            set_items.sort(key=lambda x: x.getPosixTime())

            # Process each one in the generated set
            for iter in set_items:

                # Ignore if it is before the actual start - we need this
                # because the expansion
                # can go back in time from the real start, but we must exclude
                # those when counting
                # even if they are not within the requested range
                if iter < start:
                    continue

                # Exit if after period we want
                if range.isDateAfterPeriod(iter):
                    return False

                # Exit if beyond the UNTIL limit
                if self.mUseUntil:
                    # Exit if next item is after until (its OK if its the same
                    # as UNTIL as UNTIL is inclusive)
                    if iter > float_until:
                        return True

                # Special for start instance
                if (ctr == 1) and (start == iter):
                    continue

                # Add current one to list
                items.append(iter)
                if maxInstances and len(items) > maxInstances:
                    raise TooManyInstancesError("Too many instances")

                # Check limits
                if self.mUseCount:
                    # Bump counter and exit if over
                    ctr += 1
                    if ctr >= self.mCount:
                        return True

            # Exit if after period we want
            if range.isDateAfterPeriod(start_iter):
                return False

            # Get next item
            start_iter.recur(self.mFreq, self.mInterval, allow_invalid=True)