Example #1
0
    def getCoveringInterval(self, timeStamp):
        """
        Get the interval that covers the time stamp. This iterates over the two
        repetitive interval sets and find the shortest interval that allows a
        group member to access the data. If there is no interval covering the
        time stamp, this returns False for isPositive and a negative interval.

        :param float timeStamp: The time stamp as milliseconds since Jan 1,
          1970 UTC.
        :return: An object with fields "isPositive" and "interval" where
          isPositive is True if the returned interval is positive or False if
          negative, and interval is the Interval covering the time stamp, or a
          negative interval if not found.
        :rtype: Schedule.Result
        """
        blackPositiveResult = Interval(True)
        whitePositiveResult = Interval(True)

        blackNegativeResult = Interval()
        whiteNegativeResult = Interval()

        # Get the black result.
        Schedule._calculateIntervalResult(
          self._blackIntervalList, timeStamp, blackPositiveResult,
          blackNegativeResult)

        # If the black positive result is not empty, then isPositive must be False.
        if not blackPositiveResult.isEmpty():
            return Schedule.Result(False, blackPositiveResult)

        # Get the whiteResult.
        Schedule._calculateIntervalResult(
          self._whiteIntervalList, timeStamp, whitePositiveResult,
          whiteNegativeResult)

        if whitePositiveResult.isEmpty() and not whiteNegativeResult.isValid():
            # There is no white interval covering the time stamp.
            # Return False and a 24-hour interval.
            timeStampDateOnly = RepetitiveInterval._toDateOnlyMilliseconds(
              timeStamp)
            return Schedule.Result(False, Interval(
              timeStampDateOnly,
              timeStampDateOnly + RepetitiveInterval.MILLISECONDS_IN_DAY))

        if not whitePositiveResult.isEmpty():
            # There is white interval covering the time stamp.
            # Return True and calculate the intersection.
            if blackNegativeResult.isValid():
                return Schedule.Result(
                  True, whitePositiveResult.intersectWith(blackNegativeResult))
            else:
                return Schedule.Result(True, whitePositiveResult)
        else:
            # There is no white interval covering the time stamp.
            # Return False.
            return Schedule.Result(False, whiteNegativeResult)
Example #2
0
    def getInterval(self, timePoint):
        """
        Get an interval that covers the time point. If there is no interval
        covering the time point, this returns False for isPositive and returns a
        negative interval.

        :param float timePoint: The time point as milliseconds since Jan 1,
          1970 UTC.
        :return: An object with fields "isPositive" and "interval" where
          isPositive is True if the returned interval is positive or False if
          negative, and interval is the Interval covering the time point or a
          negative interval if not found.
        :rtype: RepetitiveInterval.Result
        """
        if not self._hasIntervalOnDate(timePoint):
            # There is no interval on the date of timePoint.
            startTime = RepetitiveInterval._toDateOnlyMilliseconds(timePoint)
            endTime = (RepetitiveInterval._toDateOnlyMilliseconds(timePoint) +
                       24 * RepetitiveInterval.MILLISECONDS_IN_HOUR)
            isPositive = False
        else:
            # There is an interval on the date of timePoint.
            startTime = (
                RepetitiveInterval._toDateOnlyMilliseconds(timePoint) +
                self._intervalStartHour *
                RepetitiveInterval.MILLISECONDS_IN_HOUR)
            endTime = (RepetitiveInterval._toDateOnlyMilliseconds(timePoint) +
                       self._intervalEndHour *
                       RepetitiveInterval.MILLISECONDS_IN_HOUR)

            # Check if in the time duration.
            if timePoint < startTime:
                endTime = startTime
                startTime = RepetitiveInterval._toDateOnlyMilliseconds(
                    timePoint)
                isPositive = False
            elif timePoint > endTime:
                startTime = endTime
                endTime = (
                    RepetitiveInterval._toDateOnlyMilliseconds(timePoint) +
                    RepetitiveInterval.MILLISECONDS_IN_DAY)
                isPositive = False
            else:
                isPositive = True

        return RepetitiveInterval.Result(isPositive,
                                         Interval(startTime, endTime))
Example #3
0
    def getCoveringInterval(self, timeStamp):
        """
        Get the interval that covers the time stamp. This iterates over the two
        repetitive interval sets and find the shortest interval that allows a
        group member to access the data. If there is no interval covering the
        time stamp, this returns False for isPositive and a negative interval.

        :param float timeStamp: The time stamp as milliseconds since Jan 1,
          1970 UTC.
        :return: An object with fields "isPositive" and "interval" where
          isPositive is True if the returned interval is positive or False if
          negative, and interval is the Interval covering the time stamp, or a
          negative interval if not found.
        :rtype: Schedule.Result
        """
        blackPositiveResult = Interval(True)
        whitePositiveResult = Interval(True)

        blackNegativeResult = Interval()
        whiteNegativeResult = Interval()

        # Get the black result.
        Schedule._calculateIntervalResult(self._blackIntervalList, timeStamp,
                                          blackPositiveResult,
                                          blackNegativeResult)

        # If the black positive result is not empty, then isPositive must be False.
        if not blackPositiveResult.isEmpty():
            return Schedule.Result(False, blackPositiveResult)

        # Get the whiteResult.
        Schedule._calculateIntervalResult(self._whiteIntervalList, timeStamp,
                                          whitePositiveResult,
                                          whiteNegativeResult)

        if whitePositiveResult.isEmpty() and not whiteNegativeResult.isValid():
            # There is no white interval covering the time stamp.
            # Return False and a 24-hour interval.
            timeStampDateOnly = RepetitiveInterval._toDateOnlyMilliseconds(
                timeStamp)
            return Schedule.Result(
                False,
                Interval(
                    timeStampDateOnly, timeStampDateOnly +
                    RepetitiveInterval.MILLISECONDS_IN_DAY))

        if not whitePositiveResult.isEmpty():
            # There is white interval covering the time stamp.
            # Return True and calculate the intersection.
            if blackNegativeResult.isValid():
                return Schedule.Result(
                    True,
                    whitePositiveResult.intersectWith(blackNegativeResult))
            else:
                return Schedule.Result(True, whitePositiveResult)
        else:
            # There is no white interval covering the time stamp.
            # Return False.
            return Schedule.Result(False, whiteNegativeResult)
Example #4
0
    def _calculateInterval(self, timeSlot, unsortedMemberKeys):
        """
        Calculate an Interval that covers the timeSlot.

        :param float timeSlot: The time slot to cover as milliseconds since
          Jan 1, 1970 UTC.
        :param dictionary<Name, Blob> unsortedMemberKeys: First clear
          unsortedMemberKeys then fill it with the info of members who are
          allowed to access the interval. The dictionary's key is the Name of
          the public key and the value is the Blob of the public key DER. The
          dictionary keys are not sorted. (You can use
          sorted(unsortedMemberKeys.keys()).)
        :return: The Interval covering the time slot.
        :rtype: Interval
        :raises GroupManagerDb.Error: For a database error.
        :raises SecurityException: For an error using the security KeyChain.
        """
        # Prepare.
        positiveResult = Interval()
        negativeResult = Interval()
        unsortedMemberKeys.clear()

        # Get the all intervals from the schedules.
        scheduleNames = self._database.listAllScheduleNames()
        for i in range(len(scheduleNames)):
            scheduleName = scheduleNames[i]

            schedule = self._database.getSchedule(scheduleName)
            result = schedule.getCoveringInterval(timeSlot)
            tempInterval = result.interval

            if result.isPositive:
                if not positiveResult.isValid():
                    positiveResult = tempInterval
                positiveResult.intersectWith(tempInterval)

                map = self._database.getScheduleMembers(scheduleName)
                # Add all to unsortedMemberKeys.
                for name in map:
                    unsortedMemberKeys[name] = map[name]
            else:
                if not negativeResult.isValid():
                    negativeResult = tempInterval
                negativeResult.intersectWith(tempInterval)

        if not positiveResult.isValid():
            # Return an invalid interval when there is no member which has an
            # interval covering the time slot.
            return Interval(False)

        # Get the final interval result.
        if negativeResult.isValid():
            finalInterval = positiveResult.intersectWith(negativeResult)
        else:
            finalInterval = positiveResult

        return finalInterval
Example #5
0
    def _calculateInterval(self, timeSlot, unsortedMemberKeys):
        """
        Calculate an Interval that covers the timeSlot.

        :param float timeSlot: The time slot to cover as milliseconds since
          Jan 1, 1970 UTC.
        :param dictionary<Name, Blob> unsortedMemberKeys: First clear
          unsortedMemberKeys then fill it with the info of members who are
          allowed to access the interval. The dictionary's key is the Name of
          the public key and the value is the Blob of the public key DER. The
          dictionary keys are not sorted. (You can use
          sorted(unsortedMemberKeys.keys()).)
        :return: The Interval covering the time slot.
        :rtype: Interval
        :raises GroupManagerDb.Error: For a database error.
        :raises SecurityException: For an error using the security KeyChain.
        """
        # Prepare.
        positiveResult = Interval()
        negativeResult = Interval()
        unsortedMemberKeys.clear()

        # Get the all intervals from the schedules.
        scheduleNames = self._database.listAllScheduleNames()
        for i in range(len(scheduleNames)):
            scheduleName = scheduleNames[i]

            schedule = self._database.getSchedule(scheduleName)
            result = schedule.getCoveringInterval(timeSlot)
            tempInterval = result.interval

            if result.isPositive:
                if not positiveResult.isValid():
                    positiveResult = tempInterval
                positiveResult.intersectWith(tempInterval)

                map = self._database.getScheduleMembers(scheduleName)
                # Add all to unsortedMemberKeys.
                for name in map:
                    unsortedMemberKeys[name] = map[name]
            else:
                if not negativeResult.isValid():
                    negativeResult = tempInterval
                negativeResult.intersectWith(tempInterval)

        if not positiveResult.isValid():
            # Return an invalid interval when there is no member which has an
            # interval covering the time slot.
            return Interval(False)

        # Get the final interval result.
        if negativeResult.isValid():
            finalInterval = positiveResult.intersectWith(negativeResult)
        else:
            finalInterval = positiveResult

        return finalInterval