[CalendarServer-changes] [9469] CalendarServer/branches/users/gaya/inviteclean

source_changes at macosforge.org source_changes at macosforge.org
Fri Jul 20 13:04:53 PDT 2012


Revision: 9469
          http://trac.macosforge.org/projects/calendarserver/changeset/9469
Author:   gaya at apple.com
Date:     2012-07-20 13:04:52 -0700 (Fri, 20 Jul 2012)
Log Message:
-----------
add updateShare() and shareWithOptions() in sql.py.  Use them in sharing.py

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py
    CalendarServer/branches/users/gaya/inviteclean/txdav/common/datastore/sql.py

Modified: CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py	2012-07-20 18:59:37 UTC (rev 9468)
+++ CalendarServer/branches/users/gaya/inviteclean/twistedcaldav/sharing.py	2012-07-20 20:04:52 UTC (rev 9469)
@@ -65,6 +65,9 @@
         self._state = state
         self._summary = summary
         self._homeChild = homeChild
+    
+    def homeChild(self):
+        return self._homeChild
 
     def uid(self):
         return self._homeChild.inviteUID() if self._homeChild else self._uid
@@ -205,7 +208,7 @@
         
         # Only certain states are sharer controlled
         if invitation.state() in ("NEEDS-ACTION", "ACCEPTED", "DECLINED",):
-            invitation = yield self._updateInvitationForUID(invitation.uid(), state=state, summary=summary)
+            yield self._updateInvitation(invitation, state=state, summary=summary)
 
 
     @inlineCallbacks
@@ -451,13 +454,11 @@
         """
         Make sure each userid in an invite is valid - if not re-write status.
         """
-        
         invitations = yield self._allInvitations()
         for invitation in invitations:
             if not self.principalForUID(invitation.shareeUID()) and invitation.state() != "INVALID":
-                yield self._updateInvitationForUID(invitation.uid(), state="INVALID")
+                yield self._updateInvitation(invitation, state="INVALID")
 
-
     def inviteUserToShare(self, userid, cn, ace, summary, request):
         """ Send out in invite first, and then add this user to the share list
             @param userid: 
@@ -563,7 +564,8 @@
                       summary=invitation.summary() )
 
     @inlineCallbacks
-    def _createInvitation(self, uid, shareeUID, shareeAccess, state, summary,):
+    def _createInvitation(self, shareeUID, shareeAccess, summary,):
+        '''
         invitation = Invitation(uid=uid,
                       shareeUID=shareeUID,
                       shareeAccess=shareeAccess,
@@ -571,20 +573,30 @@
                       summary=summary, )
         yield self.invitesDB().addOrUpdateRecord(self._legacyInviteFromInvitation(invitation))
         invitation = yield self._invitationForUID(uid)
+        '''
+        if self.isCalendarCollection():
+            shareeHome = yield self._newStoreObject._txn.calendarHomeWithUID(shareeUID, create=True)
+        elif self.isAddressBookCollection():
+            shareeHome = yield self._newStoreObject._txn.addressbookHomeWithUID(shareeUID, create=True)
+
+        homeChild =  yield self._newStoreObject.shareWithOptions(shareeHome,
+                                                    mode=invitationShareeAccessToBindModeMap[shareeAccess],
+                                                    status=_BIND_STATUS_INVITED,
+                                                    message=summary )
+        invitation = Invitation(homeChild=homeChild)
         returnValue(invitation)
 
 
     @inlineCallbacks
-    def _updateInvitationForUID(self, uid, shareeAccess=None, state=None, summary=None):
-        oldInvitation = yield self._invitationForUID(uid)
-        invitation = Invitation(uid=oldInvitation.uid(),
-                      shareeUID=oldInvitation.shareeUID(),
-                      shareeAccess=shareeAccess if shareeAccess else oldInvitation.shareeAccess(),
-                      state=state if state else oldInvitation.state(),
-                      summary=summary if summary else oldInvitation.summary(), )
-        yield self.invitesDB().addOrUpdateRecord(self._legacyInviteFromInvitation(invitation))
-        invitation = yield self._invitationForUID(uid)
-        returnValue(invitation)
+    def _updateInvitation(self, invitation, shareeAccess=None, state=None, summary=None):
+        mode = invitation.homeChild().shareMode() if shareeAccess is None else invitationShareeAccessToBindModeMap[shareeAccess]
+        status = invitation.homeChild().shareStatus() if state is None else invitationStateToBindStatusMap[state]
+        message = invitation.summary() if summary is None else summary
+        
+        yield self._newStoreObject.updateShare(invitation.homeChild(), mode, status, message )
+        assert not shareeAccess or shareeAccess == invitation.shareeAccess(), "shareeAccess=%s, invitation.shareeAccess()=%s" % (shareeAccess, invitation.shareeAccess())
+        assert not state or state == invitation.state(), "state=%s, invitation.state()=%s" % (state, invitation.state())
+        assert not summary or summary == invitation.summary(), "summary=%s, invitation.summary()=%s" % (summary, invitation.summary())
 
 
     @inlineCallbacks
@@ -626,6 +638,8 @@
         if oinvitationsTestStrings != invitationsTestStrings:
             print("MISMATCH old: %s" % oinvitationsTestStrings)
             print("MISMATCH new: %s" % invitationsTestStrings)
+            assert False
+
         
         returnValue(invitations)
 
@@ -676,14 +690,13 @@
             # Look for existing invite and update its fields or create new one
             invitation = yield self._invitationForShareeUID(shareeUID)
             if invitation:
-                invitation = yield self._updateInvitationForUID(invitation.uid(), shareeAccess=inviteAccessMapFromXML[type(ace)], summary=summary)
+                yield self._updateInvitation(invitation, shareeAccess=inviteAccessMapFromXML[type(ace)], summary=summary)
             else:
-                invitation = yield self._createInvitation(uid=str(uuid4()), 
+                invitation = yield self._createInvitation( 
                                     shareeUID=shareeUID, 
                                     shareeAccess=inviteAccessMapFromXML[type(ace)],
-                                    state="NEEDS-ACTION", 
                                     summary=summary)
-            # Send invite
+            # Send invite notification
             yield self.sendInviteNotification(invitation, request)
 
         finally:
@@ -738,18 +751,10 @@
             if invitation and invitation.state() != "ACCEPTED":
                 yield self.removeInviteNotification(invitation, request)
             elif invitation:
-                yield self.sendInviteNotification(invitation, request, fakeState="DELETED")
+                yield self.sendInviteNotification(invitation, request, notificationState="DELETED")
         
         # use new API
-        from twistedcaldav.directory.util import transactionFromRequest
-        transaction = transactionFromRequest(request, self._newStoreObject)
-        
-        if self.isCalendarCollection():
-            shareeHome = yield transaction.calendarHomeWithUID(invitation.shareeUID(), create=True)
-        elif self.isAddressBookCollection():
-            shareeHome = yield transaction.addressbookHomeWithUID(invitation.shareeUID(), create=True)
-
-        yield self._newStoreObject.unshareWith(shareeHome)
+        yield self._newStoreObject.unshareWith(invitation.homeChild()._home)
     
         #old code
         #  yield self.invitesDB().removeRecordForInviteUID(invitation.uid())
@@ -762,7 +767,7 @@
         return self.inviteSingleUserToShare(userid, commonName, aceNEW, summary, request) 
 
     @inlineCallbacks
-    def sendInviteNotification(self, invitation, request, fakeState=None):
+    def sendInviteNotification(self, invitation, request, notificationState=None):
         
         ownerPrincipal = (yield self.ownerPrincipal(request))
         owner = ownerPrincipal.principalURL()
@@ -786,7 +791,7 @@
         
         # Generate invite XML
         userid = "urn:uuid:" + invitation.shareeUID()
-        state = fakeState if fakeState else invitation.state()
+        state = notificationState if notificationState else invitation.state()
 
         typeAttr = {'shared-type':self.sharedResourceType()}
         xmltype = customxml.InviteNotification(**typeAttr)

Modified: CalendarServer/branches/users/gaya/inviteclean/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/inviteclean/txdav/common/datastore/sql.py	2012-07-20 18:59:37 UTC (rev 9468)
+++ CalendarServer/branches/users/gaya/inviteclean/txdav/common/datastore/sql.py	2012-07-20 20:04:52 UTC (rev 9469)
@@ -56,7 +56,7 @@
 
 from txdav.common.datastore.sql_tables import schema
 from txdav.common.datastore.sql_tables import _BIND_MODE_OWN, \
-    _BIND_STATUS_ACCEPTED, NOTIFICATION_OBJECT_REVISIONS_TABLE
+    _BIND_STATUS_INVITED, _BIND_STATUS_ACCEPTED, NOTIFICATION_OBJECT_REVISIONS_TABLE
 from txdav.common.icommondatastore import HomeChildNameNotAllowedError, \
     HomeChildNameAlreadyExistsError, NoSuchHomeChildError, \
     ObjectResourceNameNotAllowedError, ObjectResourceNameAlreadyExistsError, \
@@ -2074,7 +2074,8 @@
             L{_BIND_MODE_WRITE}.
         @type mode: L{str}
 
-        @param recipient: The sharing recipient if not "urn:uuid:" + shareeHome.uid()
+        @param recipient: The sharing recipient
+            if None, defaults to "urn:uuid:" + shareeHome.uid()
         @type recipient: L{str}
 
         @return: the name of the shared calendar in the new calendar home.
@@ -2127,6 +2128,124 @@
 
 
     @inlineCallbacks
+    def shareWithOptions(self, shareeHome, mode, status, message):
+        """
+        Share this (owned) L{CommonHomeChild} with another home.
+
+        @param shareeHome: The home of the sharee.
+        @type shareeHome: L{CommonHome}
+
+        @param mode: The sharing mode; L{_BIND_MODE_READ} or
+            L{_BIND_MODE_WRITE}.
+        @type mode: L{str}
+
+        @param status: The sharing mode; L{_BIND_STATUS_INVITED} or
+            L{_BIND_STATUS_ACCEPTED} or L{_BIND_STATUS_DECLINED} or
+            L{_BIND_STATUS_INVALID}.
+        @type mode: L{str}
+
+        @param message: The proposed share name
+        @type recipient: L{str}
+
+        @return: the name of the shared calendar in the new calendar home.
+        @rtype: L{str}
+        """
+        
+        # recipient is needed for current legacy invites
+        recipient = "urn:uuid:" + shareeHome.uid()
+
+        dn = PropertyName.fromElement(DisplayName)
+        dnprop = (self.properties().get(dn) or
+                  DisplayName.fromString(self.name()))
+
+        @inlineCallbacks
+        def doInsert(subt):
+            newName = str(uuid4())
+            yield self._bindInsertQuery.on(
+                subt, homeID=shareeHome._resourceID,
+                resourceID=self._resourceID, name=newName, mode=mode,
+                seenByOwner=True, seenBySharee=True,
+                bindStatus=status, message=message
+            )
+            yield self._insertInviteQuery.on(
+                subt, uid=newName, name=str(dnprop),
+                homeID=shareeHome._resourceID, resourceID=self._resourceID,
+                recipient=recipient
+            )
+            returnValue(newName)
+
+        sharedName = yield self._txn.subtransaction(doInsert)
+
+        shareeProps = yield PropertyStore.load(shareeHome.uid(), self._txn,
+                                               self._resourceID)
+        shareeProps[dn] = dnprop
+        
+        # Must send notification to ensure cache invalidation occurs
+        yield self.notifyChanged()
+        
+        # return homeChild
+        cls = self.__class__ # for ease of grepping...
+        homeChild = cls(
+            home=(yield self._txn.homeWithResourceID(shareeHome._homeType,
+                                                shareeHome._resourceID)),
+            name=sharedName, resourceID=self._resourceID,
+            owned=False, mode=mode, status=status, 
+            message=message, inviteUID=sharedName,
+        )
+        yield homeChild.initFromStore()
+
+        returnValue(homeChild)
+
+
+
+    @inlineCallbacks
+    def updateShare(self, homeChild, mode, status, message):
+        """
+        Update share mode, status, and message for a home child
+            shared with this (owned) L{CommonHomeChild].
+
+        @param shared: The sharee home child that shares this.
+        @type shareeHome: L{CommonHomeChild}
+
+        @param mode: The sharing mode; L{_BIND_MODE_READ} or
+            L{_BIND_MODE_WRITE}.
+
+        @param status: The sharing mode; L{_BIND_STATUS_INVITED} or
+            L{_BIND_STATUS_ACCEPTED} or L{_BIND_STATUS_DECLINED} or
+            L{_BIND_STATUS_INVALID}.
+        @type mode: L{str}
+
+        @param message: The proposed share name
+        @type recipient: L{str}
+
+        @return: the name of the shared calendar in the new calendar home.
+        @rtype: L{str}
+        """
+        # yield self.shareWith(shared._home, mode, status, message)
+        dn = PropertyName.fromElement(DisplayName)
+        dnprop = (self.properties().get(dn) or
+                  DisplayName.fromString(self.name()))
+
+        yield self._updateBindQuery.on(
+            self._txn,
+            mode=mode, status=status, message=message,
+            resourceID=self._resourceID, homeID=homeChild._home._resourceID
+        )
+
+        shareeProps = yield PropertyStore.load(homeChild._home.uid(), self._txn,
+                                               self._resourceID)
+        shareeProps[dn] = dnprop
+        
+        # Must send notification to ensure cache invalidation occurs
+        yield self.notifyChanged()
+        
+        #update affected attributes
+        homeChild._bindMode = mode
+        homeChild._bindStatus = status
+        homeChild._bindMessage = message
+
+
+    @inlineCallbacks
     def unshareWith(self, shareeHome):
         """
         Remove the shared version of this (owned) L{CommonHomeChild} from the
@@ -2315,15 +2434,14 @@
             # TODO: this could all be issued in parallel; no need to serialize
             # the loop.
             new = cls(
-                (yield self._txn.homeWithResourceID(self._home._homeType,
+                home=(yield self._txn.homeWithResourceID(self._home._homeType,
                                                     homeResourceID)),
-                sharedResourceName, self._resourceID, False, bindMode
+                name=sharedResourceName, resourceID=self._resourceID,
+                owned=False, mode=bindMode, status=bindStatus, 
+                message=bindMessage, inviteUID= inviteUID,
             )
             yield new.initFromStore()
-            new._bindStatus = bindStatus
-            new._bindMessage = bindMessage
-            new._inviteUID = inviteUID
-            
+
             result.append(new)
         returnValue(result)
 
@@ -2537,6 +2655,7 @@
             bind.RESOURCE_NAME: Parameter("name"),
             bind.BIND_MODE: Parameter("mode"),
             bind.BIND_STATUS: Parameter("bindStatus"),
+            bind.MESSAGE: Parameter("message"),
             bind.SEEN_BY_OWNER: Parameter("seenByOwner"),
             bind.SEEN_BY_SHAREE: Parameter("seenBySharee"),
         })
@@ -2565,7 +2684,8 @@
         yield cls._bindInsertQuery.on(
             home._txn, homeID=home._resourceID, resourceID=resourceID,
             name=name, mode=_BIND_MODE_OWN, seenByOwner=True,
-            seenBySharee=True, bindStatus=_BIND_STATUS_ACCEPTED
+            seenBySharee=True, bindStatus=_BIND_STATUS_ACCEPTED,
+            message=None,
         )
 
         # Initialize other state
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120720/ab24b786/attachment-0001.html>


More information about the calendarserver-changes mailing list