[CalendarServer-changes] [14150] CalendarServer/trunk/calendarserver/tools

source_changes at macosforge.org source_changes at macosforge.org
Mon Nov 10 11:44:51 PST 2014


Revision: 14150
          http://trac.calendarserver.org//changeset/14150
Author:   sagen at apple.com
Date:     2014-11-10 11:44:51 -0800 (Mon, 10 Nov 2014)
Log Message:
-----------
Adding test for import of events to attendee calendar (not working yet)

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/tools/importer.py
    CalendarServer/trunk/calendarserver/tools/test/test_importer.py

Modified: CalendarServer/trunk/calendarserver/tools/importer.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/importer.py	2014-11-09 19:58:30 UTC (rev 14149)
+++ CalendarServer/trunk/calendarserver/tools/importer.py	2014-11-10 19:44:51 UTC (rev 14150)
@@ -178,8 +178,8 @@
     ownerUID, collectionResourceName = sourceURI.strip("/").split("/")[-2:]
 
     dir = store.directoryService()
-    record = yield dir.recordWithUID(ownerUID)
-    if not record:
+    ownerRecord = yield dir.recordWithUID(ownerUID)
+    if not ownerRecord:
         raise ImportException("{} is not in the directory".format(ownerUID))
 
     # Set properties on the collection
@@ -201,29 +201,81 @@
     # want to batch them?
     groupedComponents = Component.componentsFromComponent(component)
     for groupedComponent in groupedComponents:
-        resourceName = "{}.ics".format(str(uuid.uuid4()))
-        try:
-            yield storeComponentInHomeAndCalendar(
-                store, groupedComponent, ownerUID, collectionResourceName, resourceName
-            )
-        except UIDExistsError:
-            # That event is already in the home
+
+        # If event is unscheduled or the organizer matches homeUID, store the
+        # component
+
+        storeDirectly = True
+        organizer = groupedComponent.getOrganizer()
+        if organizer is not None:
+            organizerRecord = yield dir.recordWithCalendarUserAddress(organizer)
+            if organizerRecord is None:
+                # Organizer does not exist, so skip this event
+                continue
+            else:
+                if ownerRecord.uid != organizerRecord.uid:
+                    # Owner is not the organizer
+                    storeDirectly = False
+
+        if storeDirectly:
+            resourceName = "{}.ics".format(str(uuid.uuid4()))
             try:
-                uid = list(groupedComponent.subcomponents())[0].propertyValue("UID")
-            except:
-                uid = "unknown"
+                yield storeComponentInHomeAndCalendar(
+                    store, groupedComponent, ownerUID, collectionResourceName, resourceName
+                )
+            except UIDExistsError:
+                # That event is already in the home
+                try:
+                    uid = list(groupedComponent.subcomponents())[0].propertyValue("UID")
+                except:
+                    uid = "unknown"
 
-            print("Skipping since UID already exists: {}".format(uid))
+                print("Skipping since UID already exists: {}".format(uid))
 
-        except Exception, e:
-            print(
-                "Failed to import due to: {error}\n{comp}".format(
-                    error=e,
-                    comp=groupedComponent
+            except Exception, e:
+                print(
+                    "Failed to import due to: {error}\n{comp}".format(
+                        error=e,
+                        comp=groupedComponent
+                    )
                 )
-            )
 
+        else:
+            # Owner is not the organizer
+            print("OTHER")
+            txn = store.newTransaction()
+            organizerHome = yield txn.calendarHomeWithUID(organizerRecord.uid)
+            if organizerHome is None:
+                continue
+            # Iterate owner's calendars to find the one containing the event
+            # UID
+            uid = list(groupedComponent.subcomponents())[0].propertyValue("UID")
+            for collection in (yield organizerHome.children()):
+                if collection.name() != "inbox":
+                    resourceName = yield collection.resourceNameForUID(uid)
+                    print("Resource name", collection, resourceName)
+                    object = yield collection.objectResourceWithName(resourceName)
+                    component = yield object.component()
+                    print ("Comp", component)
 
+                    ownerCUA = ownerRecord.canonicalCalendarUserAddress()
+                    print("CUA", ownerCUA)
+                    attendeeProp = component.getAttendeeProperty((ownerCUA,))
+                    print("att prop", attendeeProp)
+                    if attendeeProp is not None:
+                        print("Before", attendeeProp)
+                        attendeeProp.setParameter("PARTSTAT", "NEEDS-ACTION")
+                        attendeeProp.removeParameter("SCHEDULE-STATUS")
+                        print("I modified", attendeeProp)
+                        result = yield object.setComponent(component)
+                        print("Set component result", result)
+
+                    break
+
+            yield txn.commit()
+
+
+
 @inlineCallbacks
 def storeComponentInHomeAndCalendar(
     store, component, homeUID, collectionResourceName, objectResourceName

Modified: CalendarServer/trunk/calendarserver/tools/test/test_importer.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/test/test_importer.py	2014-11-09 19:58:30 UTC (rev 14149)
+++ CalendarServer/trunk/calendarserver/tools/test/test_importer.py	2014-11-10 19:44:51 UTC (rev 14150)
@@ -18,7 +18,10 @@
 Unit tests for L{calendarsever.tools.importer}.
 """
 
-from calendarserver.tools.importer import importCollectionComponent, ImportException
+from calendarserver.tools.importer import (
+    importCollectionComponent, ImportException,
+    storeComponentInHomeAndCalendar
+)
 from twext.enterprise.jobqueue import JobItem
 from twisted.internet import reactor
 from twisted.internet.defer import inlineCallbacks
@@ -145,6 +148,54 @@
 """
 
 
+DATA_OTHER_ORGANIZER_EVENT = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:6DB84FB1-C943-4144-BE65-9B0DD9A9E2C7
+DTSTART;TZID=America/Los_Angeles:20151008T053000
+DTEND;TZID=America/Los_Angeles:20151008T070000
+ATTENDEE;CN=User 01;CUTYPE=INDIVIDUAL:urn:x-uid:user01
+ATTENDEE;CN=User 02;CUTYPE=INDIVIDUAL;ROLE=CHAIR:urn:x-uid:user02
+ATTENDEE;CN=User 03;CUTYPE=INDIVIDUAL:urn:x-uid:user03
+ATTENDEE;CN=Mercury Seven;CUTYPE=ROOM:urn:x-uid:mercury
+CREATED:20141107T172645Z
+DTSTAMP:20141107T172645Z
+LOCATION:Mercury
+ORGANIZER;CN=User 02:urn:x-uid:user02
+SEQUENCE:0
+SUMMARY:Other organizer
+END:VEVENT
+END:VCALENDAR
+"""
+# TRANSP:OPAQUE
+
+DATA_ATTENDEE_EVENT = """BEGIN:VCALENDAR
+VERSION:2.0
+NAME:I'm an attendee
+COLOR:#0000FFFF
+SOURCE;VALUE=URI:http://example.com/calendars/__uids__/user01/calendar/
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:6DB84FB1-C943-4144-BE65-9B0DD9A9E2C7
+DTSTART;TZID=America/Los_Angeles:20151008T053000
+DTEND;TZID=America/Los_Angeles:20151008T070000
+ATTENDEE;CN=User 01;CUTYPE=INDIVIDUAL:urn:x-uid:user01
+ATTENDEE;CN=User 02;CUTYPE=INDIVIDUAL;ROLE=CHAIR:urn:x-uid:user02
+ATTENDEE;CN=User 03;CUTYPE=INDIVIDUAL:urn:x-uid:user03
+ATTENDEE;CN=Mercury Seven;CUTYPE=ROOM:urn:x-uid:mercury
+CREATED:20141107T172645Z
+DTSTAMP:20141107T172645Z
+LOCATION:Mercury
+ORGANIZER;CN=User 02:urn:x-uid:user02
+SEQUENCE:0
+SUMMARY:Other organizer
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+"""
+
+
 class ImportTests(StoreTestCase):
     """
     Tests for importing data to a live store.
@@ -277,3 +328,74 @@
         self.assertEquals(len(objects), 1)
 
         yield txn.commit()
+
+
+    @inlineCallbacks
+    def test_ImportComponentAttendee(self):
+
+        # Have another principal invite this principal
+
+        yield storeComponentInHomeAndCalendar(
+            self.store,
+            Component.allFromString(DATA_OTHER_ORGANIZER_EVENT),
+            "user02",
+            "calendar",
+            "invite.ics"
+        )
+
+        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
+
+        # Delete the attendee's copy, thus declining the event
+        txn = self.store.newTransaction()
+        home = yield txn.calendarHomeWithUID("user01")
+        collection = yield home.childWithName("calendar")
+        objects = yield collection.objectResources()
+        self.assertEquals(len(objects), 1)
+        yield objects[0].remove()
+        yield txn.commit()
+        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
+
+        # Make sure attendee's copy is gone
+        txn = self.store.newTransaction()
+        home = yield txn.calendarHomeWithUID("user01")
+        collection = yield home.childWithName("calendar")
+        objects = yield collection.objectResources()
+        self.assertEquals(len(objects), 0)
+        yield txn.commit()
+
+        # Make sure attendee shows as declined to the organizer
+        txn = self.store.newTransaction()
+        home = yield txn.calendarHomeWithUID("user02")
+        collection = yield home.childWithName("calendar")
+        objects = yield collection.objectResources()
+        self.assertEquals(len(objects), 1)
+        component = yield objects[0].component()
+        prop = component.getAttendeeProperty(("urn:x-uid:user01",))
+        self.assertEquals(
+            prop.parameterValue("PARTSTAT"),
+            "DECLINED"
+        )
+        yield txn.commit()
+
+        # When importing the event again, instead trigger a re-invite
+        # from the organizer
+        component = Component.allFromString(DATA_ATTENDEE_EVENT)
+        yield importCollectionComponent(self.store, component)
+
+        yield JobItem.waitEmpty(self.store.newTransaction, reactor, 60)
+
+        # Make sure attendee now has a new invite
+        txn = self.store.newTransaction()
+        home = yield txn.calendarHomeWithUID("user01")
+        collection = yield home.childWithName("calendar")
+        objects = yield collection.objectResources()
+        self.assertEquals(len(objects), 1)
+        component = yield objects[0].component()
+        prop = component.getAttendeeProperty(("urn:x-uid:user01",))
+        self.assertEquals(
+            prop.parameterValue("PARTSTAT"),
+            "NEEDS-ACTION"
+        )
+        yield txn.commit()
+
+    test_ImportComponentAttendee.todo = "Debug"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20141110/4fa0e6bd/attachment.html>


More information about the calendarserver-changes mailing list