def processAvailablePeriods(calendar, timerange): """ Extract instance period data from an AVAILABLE component. @param calendar: the L{Component} that is the VAVAILABILITY containing the AVAILABLE's. @param timerange: the time range to restrict free busy data to. """ periods = [] # First we need to group all AVAILABLE sub-components by UID uidmap = {} for component in calendar.subcomponents(): if component.name() == "AVAILABLE": uid = component.propertyValue("UID") uidmap.setdefault(uid, []).append(component) # Then we expand each uid set separately for componentSet in uidmap.itervalues(): instances = InstanceList(ignoreInvalidInstances=True) instances.expandTimeRanges(componentSet, timerange.end) # Now convert instances into period list for key in instances: instance = instances[key] # Ignore any with floating times (which should not happen as the spec requires UTC or local # but we will try and be safe here). start = instance.start if start.floating(): continue end = instance.end if end.floating(): continue # Clip period for this instance - use duration for period end if that # is what original component used if instance.component.hasProperty("DURATION"): period = Period(start, duration=end - start) else: period = Period(start, end) clipped = clipPeriod(period, Period(timerange.start, timerange.end)) if clipped: periods.append(clipped) normalizePeriodList(periods) return periods
def processAvailablePeriods(calendar, timerange): """ Extract instance period data from an AVAILABLE component. @param calendar: the L{Component} that is the VAVAILABILITY containing the AVAILABLE's. @param timerange: the time range to restrict free busy data to. """ periods = [] # First we need to group all AVAILABLE sub-components by UID uidmap = {} for component in calendar.subcomponents(): if component.name() == "AVAILABLE": uid = component.propertyValue("UID") uidmap.setdefault(uid, []).append(component) # Then we expand each uid set separately for componentSet in uidmap.itervalues(): instances = InstanceList(ignoreInvalidInstances=True) instances.expandTimeRanges(componentSet, timerange.end) # Now convert instances into period list for key in instances: instance = instances[key] # Ignore any with floating times (which should not happen as the spec requires UTC or local # but we will try and be safe here). start = instance.start if start.floating(): continue end = instance.end if end.floating(): continue # Clip period for this instance - use duration for period end if that # is what original component used if instance.component.hasProperty("DURATION"): period = PyCalendarPeriod(start, duration=end - start) else: period = PyCalendarPeriod(start, end) clipped = clipPeriod(period, PyCalendarPeriod(timerange.start, timerange.end)) if clipped: periods.append(clipped) normalizePeriodList(periods) return periods
def buildFreeBusyResult(fbinfo, timerange, organizer=None, attendee=None, uid=None, method=None, event_details=None): """ Generate a VCALENDAR object containing a single VFREEBUSY that is the aggregate of the free busy info passed in. @param fbinfo: the array of busy periods to use. @param timerange: the L{TimeRange} for the query. @param organizer: the L{Property} for the Organizer of the free busy request, or None. @param attendee: the L{Property} for the Attendee responding to the free busy request, or None. @param uid: the UID value from the free busy request. @param method: the METHOD property value to insert. @param event_details: VEVENT components to add. @return: the L{Component} containing the calendar data. """ # Merge overlapping time ranges in each fb info section normalizePeriodList(fbinfo[0]) normalizePeriodList(fbinfo[1]) normalizePeriodList(fbinfo[2]) # Now build a new calendar object with the free busy info we have fbcalendar = Component("VCALENDAR") fbcalendar.addProperty(Property("VERSION", "2.0")) fbcalendar.addProperty(Property("PRODID", iCalendarProductID)) if method: fbcalendar.addProperty(Property("METHOD", method)) fb = Component("VFREEBUSY") fbcalendar.addComponent(fb) if organizer is not None: fb.addProperty(organizer) if attendee is not None: fb.addProperty(attendee) fb.addProperty(Property("DTSTART", timerange.start)) fb.addProperty(Property("DTEND", timerange.end)) fb.addProperty(Property("DTSTAMP", DateTime.getNowUTC())) if len(fbinfo[0]) != 0: fb.addProperty(Property("FREEBUSY", fbinfo[0], {"FBTYPE": "BUSY"})) if len(fbinfo[1]) != 0: fb.addProperty( Property("FREEBUSY", fbinfo[1], {"FBTYPE": "BUSY-TENTATIVE"})) if len(fbinfo[2]) != 0: fb.addProperty( Property("FREEBUSY", fbinfo[2], {"FBTYPE": "BUSY-UNAVAILABLE"})) if uid is not None: fb.addProperty(Property("UID", uid)) else: uid = str(uuid.uuid4()) fb.addProperty(Property("UID", uid)) if event_details: for vevent in event_details: fbcalendar.addComponent(vevent) return fbcalendar
def buildFreeBusyResult(self, fbinfo, method=None): """ Generate a VCALENDAR object containing a single VFREEBUSY that is the aggregate of the free busy info passed in. @param fbinfo: the array of busy periods to use. @param method: the METHOD property value to insert. @return: the L{Component} containing the calendar data. """ # Merge overlapping time ranges in each fb info section normalizePeriodList(fbinfo.busy) normalizePeriodList(fbinfo.tentative) normalizePeriodList(fbinfo.unavailable) # Now build a new calendar object with the free busy info we have fbcalendar = Component("VCALENDAR") fbcalendar.addProperty(Property("VERSION", "2.0")) fbcalendar.addProperty(Property("PRODID", iCalendarProductID)) if method: fbcalendar.addProperty(Property("METHOD", method)) fb = Component("VFREEBUSY") fbcalendar.addComponent(fb) if self.organizerProp is not None: fb.addProperty(self.organizerProp) if self.attendeeProp is not None: fb.addProperty(self.attendeeProp) fb.addProperty(Property("DTSTART", self.timerange.getStart())) fb.addProperty(Property("DTEND", self.timerange.getEnd())) fb.addProperty(Property("DTSTAMP", DateTime.getNowUTC())) if len(fbinfo.busy) != 0: fb.addProperty( Property("FREEBUSY", fbinfo.busy, {"FBTYPE": "BUSY"})) if len(fbinfo.tentative) != 0: fb.addProperty( Property("FREEBUSY", fbinfo.tentative, {"FBTYPE": "BUSY-TENTATIVE"})) if len(fbinfo.unavailable) != 0: fb.addProperty( Property("FREEBUSY", fbinfo.unavailable, {"FBTYPE": "BUSY-UNAVAILABLE"})) if self.uid is not None: fb.addProperty(Property("UID", self.uid)) else: uid = str(uuid.uuid4()) fb.addProperty(Property("UID", uid)) if self.event_details: for vevent in self.event_details: fbcalendar.addComponent(vevent) return fbcalendar
def buildFreeBusyResult(fbinfo, timerange, organizer=None, attendee=None, uid=None, method=None, event_details=None): """ Generate a VCALENDAR object containing a single VFREEBUSY that is the aggregate of the free busy info passed in. @param fbinfo: the array of busy periods to use. @param timerange: the L{TimeRange} for the query. @param organizer: the L{Property} for the Organizer of the free busy request, or None. @param attendee: the L{Property} for the Attendee responding to the free busy request, or None. @param uid: the UID value from the free busy request. @param method: the METHOD property value to insert. @param event_details: VEVENT components to add. @return: the L{Component} containing the calendar data. """ # Merge overlapping time ranges in each fb info section normalizePeriodList(fbinfo[0]) normalizePeriodList(fbinfo[1]) normalizePeriodList(fbinfo[2]) # Now build a new calendar object with the free busy info we have fbcalendar = Component("VCALENDAR") fbcalendar.addProperty(Property("VERSION", "2.0")) fbcalendar.addProperty(Property("PRODID", iCalendarProductID)) if method: fbcalendar.addProperty(Property("METHOD", method)) fb = Component("VFREEBUSY") fbcalendar.addComponent(fb) if organizer is not None: fb.addProperty(organizer) if attendee is not None: fb.addProperty(attendee) fb.addProperty(Property("DTSTART", timerange.start)) fb.addProperty(Property("DTEND", timerange.end)) fb.addProperty(Property("DTSTAMP", PyCalendarDateTime.getNowUTC())) if len(fbinfo[0]) != 0: fb.addProperty(Property("FREEBUSY", fbinfo[0], {"FBTYPE": "BUSY"})) if len(fbinfo[1]) != 0: fb.addProperty(Property("FREEBUSY", fbinfo[1], {"FBTYPE": "BUSY-TENTATIVE"})) if len(fbinfo[2]) != 0: fb.addProperty(Property("FREEBUSY", fbinfo[2], {"FBTYPE": "BUSY-UNAVAILABLE"})) if uid is not None: fb.addProperty(Property("UID", uid)) else: uid = str(uuid.uuid4()) fb.addProperty(Property("UID", uid)) if event_details: for vevent in event_details: fbcalendar.addComponent(vevent) return fbcalendar
def buildFreeBusyResult(self, fbinfo, method=None): """ Generate a VCALENDAR object containing a single VFREEBUSY that is the aggregate of the free busy info passed in. @param fbinfo: the array of busy periods to use. @param method: the METHOD property value to insert. @return: the L{Component} containing the calendar data. """ # Merge overlapping time ranges in each fb info section normalizePeriodList(fbinfo.busy) normalizePeriodList(fbinfo.tentative) normalizePeriodList(fbinfo.unavailable) # Now build a new calendar object with the free busy info we have fbcalendar = Component("VCALENDAR") fbcalendar.addProperty(Property("VERSION", "2.0")) fbcalendar.addProperty(Property("PRODID", iCalendarProductID)) if method: fbcalendar.addProperty(Property("METHOD", method)) fb = Component("VFREEBUSY") fbcalendar.addComponent(fb) if self.organizerProp is not None: fb.addProperty(self.organizerProp) if self.attendeeProp is not None: fb.addProperty(self.attendeeProp) fb.addProperty(Property("DTSTART", self.timerange.getStart())) fb.addProperty(Property("DTEND", self.timerange.getEnd())) fb.addProperty(Property("DTSTAMP", DateTime.getNowUTC())) if len(fbinfo.busy) != 0: fb.addProperty(Property("FREEBUSY", fbinfo.busy, {"FBTYPE": "BUSY"})) if len(fbinfo.tentative) != 0: fb.addProperty(Property("FREEBUSY", fbinfo.tentative, {"FBTYPE": "BUSY-TENTATIVE"})) if len(fbinfo.unavailable) != 0: fb.addProperty(Property("FREEBUSY", fbinfo.unavailable, {"FBTYPE": "BUSY-UNAVAILABLE"})) if self.uid is not None: fb.addProperty(Property("UID", self.uid)) else: uid = str(uuid.uuid4()) fb.addProperty(Property("UID", uid)) if self.event_details: for vevent in self.event_details: fbcalendar.addComponent(vevent) return fbcalendar