def generateCancel(original, attendees, instances=None, full_cancel=False): """ This assumes that SEQUENCE is not already at its new value in the original calendar data. This is because the component passed in is the one that originally contained the attendee that is being removed. """ itip = Component("VCALENDAR") itip.addProperty(Property("VERSION", "2.0")) itip.addProperty(Property("PRODID", iCalendarProductID)) itip.addProperty(Property("METHOD", "CANCEL")) if instances is None: instances = (None,) tzids = set() added = False for instance_rid in instances: # Create a new component matching the type of the original comp = Component(original.mainType()) # Use the master component when the instance is None if not instance_rid: instance = original.masterComponent() assert instance is not None, "Need a master component" else: instance = original.overriddenComponent(instance_rid) if instance is None: instance = original.deriveInstance(instance_rid) # If the instance to be cancelled did not exist in the original, then # do nothing if instance is None: continue # Add some required properties extracted from the original comp.addProperty(Property("DTSTAMP", instance.propertyValue("DTSTAMP"))) comp.addProperty(Property("UID", instance.propertyValue("UID"))) seq = instance.propertyValue("SEQUENCE") seq = int(seq) + 1 if seq else 1 comp.addProperty(Property("SEQUENCE", seq)) comp.addProperty(instance.getOrganizerProperty()) if instance_rid: comp.addProperty(Property("RECURRENCE-ID", instance_rid.duplicate().adjustToUTC())) def addProperties(propname): for icalproperty in instance.properties(propname): comp.addProperty(icalproperty) addProperties("SUMMARY") addProperties("DTSTART") addProperties("DTEND") addProperties("DURATION") if not instance_rid: addProperties("RRULE") addProperties("RDATE") addProperties("EXDATE") # Extract the matching attendee property for attendee in attendees: if full_cancel: attendeeProp = original.getAttendeeProperty((attendee,)) else: attendeeProp = instance.getAttendeeProperty((attendee,)) assert attendeeProp is not None, "Must have matching ATTENDEE property" comp.addProperty(attendeeProp) tzids.update(comp.timezoneIDs()) itip.addComponent(comp) added = True if added: # Now include any referenced tzids for comp in original.subcomponents(): if comp.name() == "VTIMEZONE": tzid = comp.propertyValue("TZID") if tzid in tzids: itip.addComponent(comp) # Strip out unwanted bits iTipGenerator.prepareSchedulingMessage(itip) return itip else: return None
def generateCancel(original, attendees, instances=None, full_cancel=False): itip = Component("VCALENDAR") itip.addProperty(Property("VERSION", "2.0")) itip.addProperty(Property("PRODID", iCalendarProductID)) itip.addProperty(Property("METHOD", "CANCEL")) if instances is None: instances = (None,) tzids = set() for instance_rid in instances: # Create a new component matching the type of the original comp = Component(original.mainType()) itip.addComponent(comp) # Use the master component when the instance is None if not instance_rid: instance = original.masterComponent() else: instance = original.overriddenComponent(instance_rid) if instance is None: instance = original.deriveInstance(instance_rid) assert instance is not None, "Need a master component" # Add some required properties extracted from the original comp.addProperty(Property("DTSTAMP", datetime.datetime.now(tz=utc))) comp.addProperty(Property("UID", instance.propertyValue("UID"))) seq = instance.propertyValue("SEQUENCE") seq = str(int(seq) + 1) if seq else "1" comp.addProperty(Property("SEQUENCE", seq)) comp.addProperty(instance.getOrganizerProperty()) if instance_rid: comp.addProperty(Property("RECURRENCE-ID", asUTC(instance_rid))) def addProperties(propname): for property in instance.properties(propname): comp.addProperty(property) addProperties("SUMMARY") addProperties("DTSTART") addProperties("DTEND") addProperties("DURATION") if not instance_rid: addProperties("RRULE") addProperties("RDATE") addProperties("EXDATE") # Extract the matching attendee property for attendee in attendees: if full_cancel: attendeeProp = original.getAttendeeProperty((attendee,)) else: attendeeProp = instance.getAttendeeProperty((attendee,)) assert attendeeProp is not None, "Must have matching ATTENDEE property" comp.addProperty(attendeeProp) tzids.update(comp.timezoneIDs()) # Now include any referenced tzids for comp in original.subcomponents(): if comp.name() == "VTIMEZONE": tzid = comp.propertyValue("TZID") if tzid in tzids: itip.addComponent(comp) # Strip out unwanted bits iTipGenerator.prepareSchedulingMessage(itip) return itip