def doWork(self): try: home = (yield self.transaction.calendarHomeWithResourceID(self.homeResourceID)) resource = (yield home.objectResourceWithID(self.resourceID)) organizerAddress = yield calendarUserFromCalendarUserUID(home.uid(), self.transaction) organizer = organizerAddress.record.canonicalCalendarUserAddress() calendar_old = Component.fromString(self.icalendarTextOld) if self.icalendarTextOld else None calendar_new = Component.fromString(self.icalendarTextNew) if self.icalendarTextNew else None log.debug("ScheduleOrganizerWork - running for ID: {id}, UID: {uid}, organizer: {org}", id=self.workID, uid=self.icalendarUID, org=organizer) # We need to get the UID lock for implicit processing. yield NamedLock.acquire(self.transaction, "ImplicitUIDLock:%s" % (hashlib.md5(self.icalendarUID).hexdigest(),)) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.queuedOrganizerProcessing( self.transaction, scheduleActionFromSQL[self.scheduleAction], home, resource, self.icalendarUID, calendar_old, calendar_new, self.smartMerge ) self._dequeued() except Exception, e: log.debug("ScheduleOrganizerWork - exception ID: {id}, UID: '{uid}', {err}", id=self.workID, uid=self.icalendarUID, err=str(e)) log.debug(traceback.format_exc()) raise
def _sendAttendeeAutoReply(self): """ Auto-process the calendar option to generate automatic accept/decline status and send a reply if needed. We used to have logic to suppress attendee refreshes until after all auto-replies have been processed. We can't do that with the work queue (easily) so we are going to ignore that for now. It may not be a big deal given that the refreshes are themselves done in the queue and we only do the refresh when the last queued work item is processed. @param resource: calendar resource to process @type resource: L{CalendarObject} @param partstat: new partstat value @type partstat: C{str} """ home = (yield self.transaction.calendarHomeWithResourceID(self.homeResourceID)) resource = (yield home.objectResourceWithID(self.resourceID)) if resource is not None: try: # We need to get the UID lock for implicit processing whilst we send the auto-reply # as the Organizer processing will attempt to write out data to other attendees to # refresh them. To prevent a race we need a lock. yield NamedLock.acquire(self.transaction, "ImplicitUIDLock:%s" % (hashlib.md5(resource.uid()).hexdigest(),)) # Send out a reply log.debug("ImplicitProcessing - recipient '%s' processing UID: '%s' - auto-reply: %s" % (home.uid(), resource.uid(), self.partstat)) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.sendAttendeeReply(self.transaction, resource) except Exception, e: log.debug("ImplicitProcessing - auto-reply exception UID: '%s', %s" % (resource.uid(), str(e))) raise except:
def _sendAttendeeAutoReply(self): """ Auto-process the calendar option to generate automatic accept/decline status and send a reply if needed. We used to have logic to suppress attendee refreshes until after all auto-replies have been processed. We can't do that with the work queue (easily) so we are going to ignore that for now. It may not be a big deal given that the refreshes are themselves done in the queue and we only do the refresh when the last queued work item is processed. @param resource: calendar resource to process @type resource: L{CalendarObject} @param partstat: new partstat value @type partstat: C{str} """ home = (yield self.transaction.calendarHomeWithResourceID(self.homeResourceID)) resource = (yield home.objectResourceWithID(self.resourceID)) if resource is not None: try: # We need to get the UID lock for implicit processing whilst we send the auto-reply # as the Organizer processing will attempt to write out data to other attendees to # refresh them. To prevent a race we need a lock. yield NamedLock.acquire(self.transaction, "ImplicitUIDLock:%s" % (hashlib.md5(resource.uid()).hexdigest(),)) # Send out a reply log.debug("ImplicitProcessing - recipient '{recip}' processing UID: '{uid}' - auto-reply: {partstat}", recip=home.uid(), uid=resource.uid(), partstat=self.partstat) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.sendAttendeeReply(self.transaction, resource) except Exception, e: log.debug("ImplicitProcessing - auto-reply exception UID: '{uid}', {ex}", uid=resource.uid(), ex=str(e)) raise except:
def doWork(self): try: home = (yield self.transaction.calendarHomeWithResourceID(self.homeResourceID)) resource = (yield home.objectResourceWithID(self.resourceID)) organizerAddress = yield calendarUserFromCalendarUserUID(home.uid(), self.transaction) organizer = organizerAddress.record.canonicalCalendarUserAddress() calendar_old = Component.fromString(self.icalendarTextOld) if self.icalendarTextOld else None calendar_new = Component.fromString(self.icalendarTextNew) if self.icalendarTextNew else None log.debug("ScheduleOrganizerWork - running for ID: {id}, UID: {uid}, organizer: {org}", id=self.workID, uid=self.icalendarUid, org=organizer) # We need to get the UID lock for implicit processing. yield NamedLock.acquire(self.transaction, "ImplicitUIDLock:%s" % (hashlib.md5(self.icalendarUid).hexdigest(),)) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.queuedOrganizerProcessing( self.transaction, scheduleActionFromSQL[self.scheduleAction], home, resource, self.icalendarUid, calendar_old, calendar_new, self.smartMerge ) self._dequeued() except Exception, e: log.debug("ScheduleOrganizerWork - exception ID: {id}, UID: '{uid}', {err}", id=self.workID, uid=self.icalendarUid, err=str(e)) log.debug(traceback.format_exc()) raise
def doWork(self): try: home = (yield self.transaction.calendarHomeWithResourceID(self.homeResourceID)) resource = (yield home.objectResourceWithID(self.resourceID)) itipmsg = Component.fromString(self.itipMsg) organizerAddress = yield calendarUserFromCalendarUserUID(home.uid(), self.transaction) organizer = organizerAddress.record.canonicalCalendarUserAddress() log.debug( "ScheduleOrganizerSendWork - running for ID: {id}, UID: {uid}, organizer: {org}, attendee: {att}", id=self.workID, uid=self.icalendarUID, org=organizer, att=self.attendee ) # We need to get the UID lock for implicit processing. yield NamedLock.acquire(self.transaction, "ImplicitUIDLock:%s" % (hashlib.md5(self.icalendarUID).hexdigest(),)) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.queuedOrganizerSending( self.transaction, scheduleActionFromSQL[self.scheduleAction], home, resource, self.icalendarUID, organizer, self.attendee, itipmsg, self.noRefresh ) # Handle responses - update the actual resource in the store. Note that for a create the resource did not previously # exist and is stored as None for the work item, but the scheduler will attempt to find the new resources and use # that. We need to grab the scheduler's resource for further processing. resource = scheduler.resource if resource is not None: responses, all_delivered = self.extractSchedulingResponse(scheduler.queuedResponses) if not all_delivered: # Check for all connection failed yield self.checkTemporaryFailure(responses) # Update calendar data to reflect error status calendar = (yield resource.componentForUser()) changed = self.handleSchedulingResponse(responses, calendar, True) if changed: yield resource._setComponentInternal(calendar, internal_state=ComponentUpdateState.ORGANIZER_ITIP_UPDATE) self._dequeued() except Exception, e: log.debug("ScheduleOrganizerSendWork - exception ID: {id}, UID: '{uid}', {err}", id=self.workID, uid=self.icalendarUID, err=str(e)) log.debug(traceback.format_exc()) raise
def test_testImplicitSchedulingPUT_FixScheduleState(self): """ Test that testImplicitSchedulingPUT will fix an old cached schedule object state by re-evaluating the calendar data. """ calendarOld = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """) calendarNew = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """) calendar_collection = (yield self.calendarUnderTest(home="user01")) calresource = (yield calendar_collection.createCalendarObjectWithName( "1.ics", calendarOld )) calresource.isScheduleObject = False scheduler = ImplicitScheduler() try: doAction, isScheduleObject = (yield scheduler.testImplicitSchedulingPUT(calendar_collection, calresource, calendarNew, False)) except Exception as e: print e self.fail("Exception must not be raised") self.assertTrue(doAction) self.assertTrue(isScheduleObject)
def test_testImplicitSchedulingPUT_NoChangeScheduleState(self): """ Test that testImplicitSchedulingPUT will prevent attendees from changing the schedule object state. """ calendarOld = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z END:VEVENT END:VCALENDAR """) calendarNew = Component.fromString("""BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTAMP:20080601T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 02":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """) calendar_collection = (yield self.calendarUnderTest(home="user01")) calresource = (yield calendar_collection.createCalendarObjectWithName( "1.ics", calendarOld )) calresource.isScheduleObject = False scheduler = ImplicitScheduler() try: yield scheduler.testImplicitSchedulingPUT(calendar_collection, calresource, calendarNew, False) except HTTPError: pass except: self.fail("HTTPError exception must be raised") else: self.fail("Exception must be raised")
def _doRefresh(self, organizer_resource, only_attendees): """ Do a refresh of attendees. @param organizer_resource: the resource for the organizer's calendar data @type organizer_resource: L{DAVResource} @param only_attendees: list of attendees to refresh (C{None} - refresh all) @type only_attendees: C{tuple} """ log.debug("ImplicitProcessing - refreshing UID: '{uid}', Attendees: {att}", uid=organizer_resource.uid(), att=", ".join(only_attendees) if only_attendees else "all") from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.refreshAllAttendeesExceptSome( self.transaction, organizer_resource, only_attendees=only_attendees, )
def _doRefresh(self, organizer_resource, exclude_attendees=(), only_attendees=None): """ Do a refresh of attendees. @param organizer_resource: the resource for the organizer's calendar data @type organizer_resource: L{DAVResource} @param exclude_attendees: list of attendees to not refresh @type exclude_attendees: C{tuple} @param only_attendees: list of attendees to refresh (C{None} - refresh all) @type only_attendees: C{tuple} """ log.debug("ImplicitProcessing - refreshing UID: '%s', Attendees: %s" % (self.uid, ", ".join(only_attendees) if only_attendees else "all")) from txdav.caldav.datastore.scheduling.implicit import ImplicitScheduler scheduler = ImplicitScheduler() yield scheduler.refreshAllAttendeesExceptSome( self.txn, organizer_resource, exclude_attendees, only_attendees=only_attendees, )
def test_testImplicitSchedulingPUT_ScheduleState(self): """ Test that checkImplicitState() always returns True for any organizer, valid or not. """ data = ( ( """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z END:VEVENT END:VCALENDAR """, False, ), ( """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, True, ), ( """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, True, ), ) calendar_collection = (yield self.calendarUnderTest(home="user01")) for calendar, result in data: calendar = Component.fromString(calendar) scheduler = ImplicitScheduler() doAction, isScheduleObject = (yield scheduler.testImplicitSchedulingPUT(calendar_collection, None, calendar, False)) self.assertEqual(doAction, result) self.assertEqual(isScheduleObject, result)
def test_removed_attendees(self): data = ( ( "#1.1 Simple component, no change", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, (), ), ( "#1.2 Simple component, one removal", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, (("mailto:[email protected]", None),), ), ( "#1.3 Simple component, two removals", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", None), ("mailto:[email protected]", None), ), ), ( "#2.1 Simple recurring component, two removals", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", None), ("mailto:[email protected]", None), ), ), ( "#2.2 Simple recurring component, add exdate", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY EXDATE:20080801T120000Z END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#2.3 Simple recurring component, add multiple comma exdates", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY EXDATE:20080801T120000Z,20080901T120000Z END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#2.3 Simple recurring component, add multiple comma/property exdates", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY EXDATE:20080801T120000Z,20080901T120000Z EXDATE:20081201T120000Z END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 9, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 12, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 12, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 12, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#3.1 Complex recurring component with same attendees, no change", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, (), ), ( "#3.2 Complex recurring component with same attendees, change master/override", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", None), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#3.3 Complex recurring component with same attendees, change override", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#3.4 Complex recurring component with same attendees, change master", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", None), ), ), ( "#3.5 Complex recurring component with same attendees, remove override - no exdate", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, (), ), ( "#3.6 Complex recurring component with same attendees, remove override - exdate", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY EXDATE:20080801T120000Z END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#4.1 Complex recurring component with different attendees, change master/override", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", None), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#4.2 Complex recurring component with different attendees, remove override - no exdate", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ( "#4.3 Complex recurring component with different attendees, remove override - exdate", """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY END:VEVENT BEGIN:VEVENT UID:12345-67890 RECURRENCE-ID:20080801T120000Z DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """, """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] RRULE:FREQ=MONTHLY EXDATE:20080801T120000Z END:VEVENT END:VCALENDAR """, ( ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ("mailto:[email protected]", DateTime(2008, 8, 1, 12, 0, 0, tzid=Timezone(utc=True))), ), ), ) for description, calendar1, calendar2, result in data: scheduler = ImplicitScheduler() scheduler.resource = None scheduler.oldcalendar = Component.fromString(calendar1) scheduler.oldAttendeesByInstance = scheduler.oldcalendar.getAttendeesByInstance(True, onlyScheduleAgentServer=True) scheduler.oldInstances = set(scheduler.oldcalendar.getComponentInstances()) scheduler.calendar = Component.fromString(calendar2) scheduler.calendar_home = FakeCalendarHome("user01") yield scheduler.extractCalendarData() scheduler.findRemovedAttendees() self.assertEqual(scheduler.cancelledAttendees, set(result), msg=description)
def test_process_request_excludes_includes(self): """ Test that processRequests correctly excludes or includes the specified attendees. """ data = ( ((), None, 3, ("mailto:[email protected]", "mailto:[email protected]", "mailto:[email protected]",),), (("mailto:[email protected]",), None, 2, ("mailto:[email protected]", "mailto:[email protected]",),), ((), ("mailto:[email protected]", "mailto:[email protected]",) , 2, ("mailto:[email protected]", "mailto:[email protected]",),), ) calendar = """BEGIN:VCALENDAR VERSION:2.0 PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN BEGIN:VEVENT UID:12345-67890 DTSTART:20080601T120000Z DTEND:20080601T130000Z ORGANIZER;CN="User 01":mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] ATTENDEE:mailto:[email protected] END:VEVENT END:VCALENDAR """ for excludes, includes, result_count, result_set in data: scheduler = ImplicitScheduler() scheduler.resource = None scheduler.calendar = Component.fromString(calendar) scheduler.state = "organizer" scheduler.action = "modify" scheduler.internal_request = True scheduler.except_attendees = excludes scheduler.only_refresh_attendees = includes scheduler.changed_rids = None scheduler.reinvites = None scheduler.calendar_home = FakeCalendarHome("user1") # Get some useful information from the calendar yield scheduler.extractCalendarData() scheduler.organizerPrincipal = buildDirectoryRecord(scheduler.calendar_home.uid()) recipients = [] def makeFakeScheduler(): return FakeScheduler(recipients) scheduler.makeScheduler = makeFakeScheduler count = (yield scheduler.processRequests()) self.assertEqual(count, result_count) self.assertEqual(len(recipients), result_count) self.assertEqual(set(recipients), set(result_set))