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)
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
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)