[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