[CalendarServer-changes] [827] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Dec 14 14:16:47 PST 2006
Revision: 827
http://trac.macosforge.org/projects/calendarserver/changeset/827
Author: wsanchez at apple.com
Date: 2006-12-14 14:16:47 -0800 (Thu, 14 Dec 2006)
Log Message:
-----------
merge branches/users/wsanchez/dropbox
Modified Paths:
--------------
CalendarServer/trunk/testcaldav
CalendarServer/trunk/twistedcaldav/caldavxml.py
CalendarServer/trunk/twistedcaldav/customxml.py
CalendarServer/trunk/twistedcaldav/directory/calendar.py
CalendarServer/trunk/twistedcaldav/directory/principal.py
CalendarServer/trunk/twistedcaldav/dropbox.py
CalendarServer/trunk/twistedcaldav/method/__init__.py
CalendarServer/trunk/twistedcaldav/method/delete.py
CalendarServer/trunk/twistedcaldav/method/mkcol.py
CalendarServer/trunk/twistedcaldav/method/put.py
CalendarServer/trunk/twistedcaldav/notifications.py
CalendarServer/trunk/twistedcaldav/resource.py
CalendarServer/trunk/twistedcaldav/schedule.py
CalendarServer/trunk/twistedcaldav/static.py
CalendarServer/trunk/twistedcaldav/tap.py
CalendarServer/trunk/twistedcaldav/test/data/makelargecalendars.py
Removed Paths:
-------------
CalendarServer/trunk/twistedcaldav/method/x_apple_subscribe.py
CalendarServer/trunk/twistedcaldav/method/x_apple_unsubscribe.py
Modified: CalendarServer/trunk/testcaldav
===================================================================
--- CalendarServer/trunk/testcaldav 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/testcaldav 2006-12-14 22:16:47 UTC (rev 827)
@@ -18,9 +18,6 @@
# DRI: Wilfredo Sanchez, wsanchez at apple.com
##
-set -e
-set -u
-
wd="$(cd "$(dirname "$0")" && pwd)";
cdt="${wd}/../CalDAVTester";
@@ -72,6 +69,6 @@
svn checkout http://svn.macosforge.org/repository/calendarserver/CalDAVTester/trunk "${cdt}"
fi;
-tar -C "${documentroot}/calendars/user/user01/" -x${verbose}zf "${cdt}/Resource/errors/calendar.1000.tgz"
+cd "${documentroot}" && python "makelargecalendars.py";
cd "${cdt}" && python testcaldav.py -s "${serverinfo}" --all;
Modified: CalendarServer/trunk/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/caldavxml.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/caldavxml.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -1525,3 +1525,5 @@
def _isCalendar(self): return bool(self.childrenOfType(Calendar))
davxml.ResourceType.isCalendar = _isCalendar
davxml.ResourceType.calendar = davxml.ResourceType(davxml.Collection(), Calendar())
+davxml.ResourceType.scheduleInbox = davxml.ResourceType(davxml.Collection(), ScheduleInbox())
+davxml.ResourceType.scheduleOutbox = davxml.ResourceType(davxml.Collection(), ScheduleOutbox())
Modified: CalendarServer/trunk/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/customxml.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/customxml.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -28,7 +28,7 @@
from twisted.web2.dav.resource import twisted_dav_namespace
from twisted.web2.dav import davxml
-apple_namespace = "http://apple.com/ns/calendarserver/"
+calendarserver_namespace = "http://org.calendarserver/ns/"
class TwistedGUIDProperty (davxml.WebDAVTextElement):
"""
@@ -86,7 +86,7 @@
Denotes a drop box home collection (a collection that will contain drop boxes).
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "dropbox-home"
class DropBox (davxml.WebDAVEmptyElement):
@@ -94,7 +94,7 @@
Denotes a drop box collection.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "dropbox"
class Notifications (davxml.WebDAVEmptyElement):
@@ -102,7 +102,7 @@
Denotes a notifications collection.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "notifications"
class DropBoxHomeURL (davxml.WebDAVElement):
@@ -110,7 +110,7 @@
A principal property to indicate the location of the drop box home.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "dropbox-home-URL"
hidden = True
protected = True
@@ -122,7 +122,7 @@
A principal property to indicate the location of the notification collection.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "notifications-URL"
hidden = True
protected = True
@@ -133,12 +133,12 @@
"""
Root element for XML data in a notification resource.
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "notification"
allowed_children = {
- (apple_namespace, "time-stamp" ): (1, 1),
- (apple_namespace, "changed" ): (1, 1),
+ (calendarserver_namespace, "time-stamp" ): (1, 1),
+ (calendarserver_namespace, "changed" ): (1, 1),
}
class TimeStamp (davxml.WebDAVTextElement):
@@ -146,7 +146,7 @@
A property to indicate the timestamp of a notification resource.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "time-stamp"
hidden = True
protected = True
@@ -157,7 +157,7 @@
notification resource.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "changed"
hidden = True
protected = True
@@ -169,7 +169,7 @@
A property to indicate which principals will receive notifications.
(Apple Extension to CalDAV)
"""
- namespace = apple_namespace
+ namespace = calendarserver_namespace
name = "subscribed"
hidden = True
protected = True
Modified: CalendarServer/trunk/twistedcaldav/directory/calendar.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/calendar.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/directory/calendar.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -190,6 +190,9 @@
self.putChild(name, child)
def provision(self):
+ return self.provisionDefaultCalendars()
+
+ def provisionDefaultCalendars(self):
# Create a calendar collection
childName = "calendar"
Modified: CalendarServer/trunk/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/principal.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/directory/principal.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -40,7 +40,6 @@
from twistedcaldav.extensions import ReadOnlyResourceMixIn, DAVFile
from twistedcaldav.resource import CalendarPrincipalCollectionResource, CalendarPrincipalResource
from twistedcaldav.static import provisionFile
-from twistedcaldav.dropbox import DropBox
from twistedcaldav.directory.idirectory import IDirectoryService
# FIXME: These should not be tied to DAVFile
@@ -373,10 +372,10 @@
return self._homeChildURL("outbox/")
def dropboxURL(self):
- return self._homeChildURL(DropBox.dropboxName + "/")
+ return self._homeChildURL("dropbox/")
def notificationsURL(self):
- return self._homeChildURL(DropBox.notificationName + "/")
+ return self._homeChildURL("notifications/")
def _homeChildURL(self, name):
home = self._calendarHome()
Modified: CalendarServer/trunk/twistedcaldav/dropbox.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/dropbox.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/dropbox.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -22,80 +22,175 @@
"""
__all__ = [
- "DropBox",
+ "DropBoxHomeResource",
]
-from twistedcaldav.customxml import davxml, apple_namespace
+from twisted.internet.defer import deferredGenerator, waitForDeferred
+from twisted.python import log
+from twisted.web2 import responsecode
+from twisted.web2.dav import davxml
+from twisted.web2.dav.http import HTTPError, ErrorResponse
+from twisted.web2.dav.resource import DAVResource, TwistedACLInheritable
+from twisted.web2.dav.util import parentForURL
-import os
+from twistedcaldav import customxml
+from twistedcaldav.customxml import calendarserver_namespace
+from twistedcaldav.notifications import Notification
-class DropBox(object):
-
- # These are all options that will be set from a .plist configuration file.
+class DropBoxHomeResource (DAVResource):
+ """
+ Drop box collection resource.
+ """
+ def resourceType(self):
+ return davxml.ResourceType(
+ davxml.ResourceType.collection,
+ davxml.ResourceType.dropboxhome,
+ )
- enabled = True # Whether or not drop box functionaility is enabled.
- dropboxName = "dropbox" # Name of the collection in which drop boxes can be created.
- inheritedACLs = True # Whether or not ACLs set on a drop box collection are automatically
- # inherited by child resources.
- notifications = True # Whether to post notification messages into per-user notification collection.
- notificationName = "notifications" # Name of the collection in which notifications will be stored.
-
- @classmethod
- def enable(clzz, enabled, notifications=None):
- """
- This method must be used to enable drop box support as it will setup live properties etc,
- and turn on the notification system. It must only be called once
+ def isCollection(self):
+ return True
- @param enable: C{True} if drop box feature is enabled, C{False} otherwise
- @param notifications: C{True} if automatic notifications are to be sent when a drop box changes, C{False} otherwise.
- """
- DropBox.enabled = enabled
- if notifications:
- DropBox.notifications = notifications
+class DropBoxCollectionResource (DAVResource):
+ """
+ Drop box resource.
+ """
+ def resourceType(self):
+ return davxml.ResourceType(
+ davxml.ResourceType.collection,
+ davxml.ResourceType.dropbox,
+ )
- if DropBox.enabled:
+ def isCollection(self):
+ return True
- # Need to setup live properties
- from twistedcaldav.resource import CalendarPrincipalResource
- assert (apple_namespace, "dropbox-home-URL") not in CalendarPrincipalResource.liveProperties, \
- "DropBox.enable must only be called once"
-
- CalendarPrincipalResource.liveProperties += (
- (apple_namespace, "dropbox-home-URL" ),
- (apple_namespace, "notifications-URL" ),
- )
-
- @classmethod
- def provision(clzz, cuhome):
+ def writeNewACEs(self, newaces):
"""
- Provision user account with appropriate collections for drop box
- and notifications.
+ Write a new ACL to the resource's property store. We override this for calendar collections
+ and force all the ACEs to be inheritable so that all calendar object resources within the
+ calendar collection have the same privileges unless explicitly overridden. The same applies
+ to drop box collections as we want all resources (attachments) to have the same privileges as
+ the drop box collection.
- @param principal: the L{CalendarPrincipalResource} for the principal to provision
- @param cuhome: L{DAVResource} - resource of user calendar home
+ @param newaces: C{list} of L{ACE} for ACL being set.
"""
+ # Add inheritable option to each ACE in the list
+ edited_aces = []
+ for ace in newaces:
+ if TwistedACLInheritable() not in ace.children:
+ children = list(ace.children)
+ children.append(TwistedACLInheritable())
+ edited_aces.append(davxml.ACE(*children))
+ else:
+ edited_aces.append(ace)
- # Only if enabled
- if not DropBox.enabled:
- return
+ # Do inherited with possibly modified set of aces
+ super(DropBoxCollectionResource, self).writeNewACEs(edited_aces)
+
+ def http_DELETE(self, request):
+ #
+ # Handle notificiations
+ #
+ parentURL=parentForURL(request.uri)
+
+ def gotParent(parent):
+ def gotResponse(response):
+ notification = Notification(parentURL=parentURL)
+ d = notification.doNotification(request, parent)
+ d.addCallback(lambda _: response)
+ return d
+
+ d = super(DropBoxCollectionResource, self).http_DELETE(request)
+ d.addCallback(gotResponse)
+ return d
+
+ d = request.locateResource(parentURL)
+ d.addCallback(gotParent)
+ return d
- # Create drop box collection in calendar-home collection resource if not already present.
-
- from twistedcaldav.static import CalDAVFile
- child = CalDAVFile(os.path.join(cuhome.fp.path, DropBox.dropboxName))
- child_exists = child.exists()
- if not child_exists:
- c = child.createSpecialCollection(davxml.ResourceType.dropboxhome)
- assert c.called
- c = c.result
-
- if not DropBox.notifications:
- return
-
- child = CalDAVFile(os.path.join(cuhome.fp.path, DropBox.notificationName))
- child_exists = child.exists()
- if not child_exists:
- c = child.createSpecialCollection(davxml.ResourceType.notifications)
- assert c.called
- c = c.result
-
\ No newline at end of file
+ def http_PUT(self, request):
+ return ErrorResponse(
+ responsecode.FORBIDDEN,
+ (calendarserver_namespace, "valid-drop-box")
+ )
+
+ def http_X_APPLE_SUBSCRIBE(self, request):
+ d = waitForDeferred(self.authorize(request, (davxml.Read(),)))
+ yield d
+ d.getResult()
+ authid = request.authnUser
+
+ # Get current list of subscribed principals
+ principals = []
+ if self.hasDeadProperty(customxml.Subscribed):
+ subs = self.readDeadProperty(customxml.Subscribed).children
+ principals.extend(subs)
+
+ # Error if attempt to subscribe more than once
+ if authid in principals:
+ log.err("Cannot x_apple_subscribe to resource %s as principal %s is already subscribed" % (request.uri, repr(authid),))
+ raise HTTPError(ErrorResponse(
+ responsecode.FORBIDDEN,
+ (calendarserver_namespace, "principal-must-not-be-subscribed"))
+ )
+
+ principals.append(authid)
+ self.writeDeadProperty(customxml.Subscribed(*principals))
+
+ yield responsecode.OK
+
+ http_X_APPLE_SUBSCRIBE = deferredGenerator(http_X_APPLE_SUBSCRIBE)
+
+ def http_X_APPLE_UNSUBSCRIBE(self, request):
+ # We do not check any privileges. If a principal is subscribed we always allow them to
+ # unsubscribe provided they have at least authenticated.
+ d = waitForDeferred(self.authorize(request, ()))
+ yield d
+ d.getResult()
+ authid = request.authnUser
+
+ # Get current list of subscribed principals
+ principals = []
+ if self.hasDeadProperty(customxml.Subscribed):
+ subs = self.readDeadProperty(customxml.Subscribed).children
+ principals.extend(subs)
+
+ # Error if attempt to subscribe more than once
+ if authid not in principals:
+ log.err("Cannot x_apple_unsubscribe from resource %s as principal %s is not currently subscribed" % (request.uri, repr(authid),))
+ raise HTTPError(ErrorResponse(
+ responsecode.FORBIDDEN,
+ (calendarserver_namespace, "principal-must-be-subscribed"))
+ )
+
+ principals.remove(authid)
+ self.writeDeadProperty(customxml.Subscribed(*principals))
+
+ yield responsecode.OK
+
+ http_X_APPLE_UNSUBSCRIBE = deferredGenerator(http_X_APPLE_UNSUBSCRIBE)
+
+class DropBoxChildResource (DAVResource):
+ def http_MKCOL(self, request):
+ return responsecode.FORBIDDEN
+
+ def http_PUT(self, request):
+ #
+ # Handle notificiations
+ #
+ parentURL=parentForURL(request.uri)
+
+ def gotParent(parent):
+ def gotResponse(response):
+ if response.code in (responsecode.OK, responsecode.CREATED, responsecode.NO_CONTENT):
+ notification = Notification(parentURL=parentForURL(request.uri))
+ d = notification.doNotification(request, parent)
+ d.addCallback(lambda _: response)
+ return d
+
+ d = super(DropBoxChildResource, self).http_PUT(request)
+ d.addCallback(gotResponse)
+ return d
+
+ d = request.locateResource(parentURL)
+ d.addCallback(gotParent)
+ return d
Modified: CalendarServer/trunk/twistedcaldav/method/__init__.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/__init__.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/__init__.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -32,6 +32,4 @@
"report_calquery",
"report_freebusy",
"report_multiget",
- "x_apple_subscribe",
- "x_apple_unsubscribe",
]
Modified: CalendarServer/trunk/twistedcaldav/method/delete.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/delete.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/delete.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -22,13 +22,9 @@
__all__ = ["http_DELETE"]
-from twisted.internet.defer import deferredGenerator, waitForDeferred
from twisted.web2 import responsecode
from twisted.web2.dav.util import parentForURL
-from twistedcaldav import customxml
-from twistedcaldav.dropbox import DropBox
-from twistedcaldav.notifications import Notification
from twistedcaldav.resource import isPseudoCalendarCollectionResource
def http_DELETE(self, request):
@@ -36,31 +32,20 @@
# Override base DELETE request handling to ensure that the calendar
# index file has the entry for the deleted calendar component removed.
#
- # Also handle notifications in a drop box collection.
- #
+ def gotParent(parent):
+ def gotResponse(response):
+ if response == responsecode.NO_CONTENT:
+ if isPseudoCalendarCollectionResource(parent):
+ index = parent.index()
+ index.deleteResource(self.fp.basename())
- parentURL = parentForURL(request.uri)
- parent = waitForDeferred(request.locateResource(parentURL))
- yield parent
- parent = parent.getResult()
+ return response
- d = waitForDeferred(super(CalDAVFile, self).http_DELETE(request))
- yield d
- response = d.getResult()
+ d = super(CalDAVFile, self).http_DELETE(request)
+ d.addCallback(gotResponse)
+ return d
- if response == responsecode.NO_CONTENT:
-
- if isPseudoCalendarCollectionResource(parent):
- index = parent.index()
- index.deleteResource(self.fp.basename())
-
- elif DropBox.enabled and parent.isSpecialCollection(customxml.DropBox):
- # We need to handle notificiations
- notification = Notification(parentURL=parentURL)
- d = waitForDeferred(notification.doNotification(request, parent))
- yield d
- d.getResult()
-
- yield response
-
-http_DELETE = deferredGenerator(http_DELETE)
+ parentURL = parentForURL(request.uri)
+ d = request.locateResource(parentURL)
+ d.addCallback(gotParent)
+ return d
Modified: CalendarServer/trunk/twistedcaldav/method/mkcol.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/mkcol.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/mkcol.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -22,49 +22,24 @@
__all__ = ["http_MKCOL"]
-from twisted.internet.defer import deferredGenerator, waitForDeferred
from twisted.web2 import responsecode
-from twisted.web2.dav import davxml
-from twisted.web2.dav.util import parentForURL
-from twisted.web2.http import HTTPError, StatusResponse
+from twisted.web2.http import StatusResponse
-from twistedcaldav import customxml
-from twistedcaldav.icaldav import ICalDAVResource
+from twistedcaldav.resource import isPseudoCalendarCollectionResource
def http_MKCOL(self, request):
#
- # Don't allow DAV collections in a calendar collection for now
+ # Don't allow DAV collections in a calendar collection
#
- def isNonCollectionParentResource(resource):
- try:
- resource = ICalDAVResource(resource)
- except TypeError:
- return False
- else:
- return resource.isPseudoCalendarCollection() or resource.isSpecialCollection(customxml.DropBox)
+ def gotParent(parent):
+ if parent is not None:
+ return StatusResponse(
+ responsecode.FORBIDDEN,
+ "Cannot create collection within calendar collection %s" % (parent,)
+ )
- parent = waitForDeferred(self._checkParents(request, isNonCollectionParentResource))
- yield parent
- parent = parent.getResult()
- if parent is not None:
- raise HTTPError(StatusResponse(
- responsecode.FORBIDDEN,
- "Cannot create collection within special collection %s" % (parent,))
- )
+ return super(CalDAVFile, self).http_MKCOL(request)
- d = waitForDeferred(super(CalDAVFile, self).http_MKCOL(request))
- yield d
- result = d.getResult()
-
- # Check for drop box creation and give it a special resource type
- from twistedcaldav.dropbox import DropBox
- if result == responsecode.CREATED and DropBox.enabled:
- parent = waitForDeferred(request.locateResource(parentForURL(request.uri)))
- yield parent
- parent = parent.getResult()
- if parent.isSpecialCollection(customxml.DropBoxHome):
- self.writeDeadProperty(davxml.ResourceType.dropbox)
-
- yield result
-
-http_MKCOL = deferredGenerator(http_MKCOL)
\ No newline at end of file
+ d = self._checkParents(request, isPseudoCalendarCollectionResource)
+ d.addCallback(gotParent)
+ return d
Modified: CalendarServer/trunk/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/put.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -25,16 +25,12 @@
from twisted.internet.defer import deferredGenerator, waitForDeferred
from twisted.python import log
from twisted.web2 import responsecode
-from twisted.web2.dav.element.base import twisted_dav_namespace
from twisted.web2.dav.http import ErrorResponse
from twisted.web2.dav.util import allDataFromStream, parentForURL
from twisted.web2.http import HTTPError, StatusResponse
-from twistedcaldav import customxml
from twistedcaldav.caldavxml import caldav_namespace
-from twistedcaldav.dropbox import DropBox
from twistedcaldav.method.put_common import storeCalendarObjectResource
-from twistedcaldav.notifications import Notification
from twistedcaldav.resource import isPseudoCalendarCollectionResource
def http_PUT(self, request):
@@ -81,27 +77,6 @@
log.err("Error while handling (calendar) PUT: %s" % (e,))
raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))
- elif DropBox.enabled and parent.isSpecialCollection(customxml.DropBoxHome):
- # Cannot create resources in a drop box home collection
- raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (twisted_dav_namespace, "valid-drop-box")))
-
- elif DropBox.enabled and parent.isSpecialCollection(customxml.DropBox):
- # We need to handle notificiations
-
- # Do the normal http_PUT behavior
- d = waitForDeferred(super(CalDAVFile, self).http_PUT(request))
- yield d
- response = d.getResult()
-
- if response.code in (responsecode.OK, responsecode.CREATED, responsecode.NO_CONTENT):
- notification = Notification(parentURL=parentURL)
- d = waitForDeferred(notification.doNotification(request, parent))
- yield d
- d.getResult()
-
- yield response
- return
-
else:
d = waitForDeferred(super(CalDAVFile, self).http_PUT(request))
yield d
Deleted: CalendarServer/trunk/twistedcaldav/method/x_apple_subscribe.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/x_apple_subscribe.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/x_apple_subscribe.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -1,70 +0,0 @@
-##
-# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# DRI: Cyrus Daboo, cdaboo at apple.com
-##
-
-"""
-CalDAV X_APPLE_SUBSCRIBE method.
-"""
-
-__all__ = ["http_X_APPLE_SUBSCRIBE"]
-
-from twisted.internet.defer import deferredGenerator, waitForDeferred
-from twisted.python import log
-from twisted.web2 import responsecode
-from twisted.web2.dav import davxml
-from twisted.web2.dav.element.base import twisted_dav_namespace
-from twisted.web2.dav.http import ErrorResponse
-from twisted.web2.http import HTTPError, StatusResponse
-
-from twistedcaldav import customxml
-from twistedcaldav.dropbox import DropBox
-
-def http_X_APPLE_SUBSCRIBE(self, request):
-
- # Only for drop box collections
- if not DropBox.enabled or not self.isSpecialCollection(customxml.DropBox):
- log.err("Cannot x-apple-subscribe to resource %s" % (request.uri,))
- raise HTTPError(StatusResponse(
- responsecode.FORBIDDEN,
- "Cannot x-apple-subscribe to resource %s" % (request.uri,))
- )
-
- d = waitForDeferred(self.authorize(request, (davxml.Read(),)))
- yield d
- d.getResult()
- authid = request.authnUser
-
- # Get current list of subscribed principals
- principals = []
- if self.hasDeadProperty(customxml.Subscribed):
- subs = self.readDeadProperty(customxml.Subscribed).children
- principals.extend(subs)
-
- # Error if attempt to subscribe more than once
- if authid in principals:
- log.err("Cannot x_apple_subscribe to resource %s as principal %s is already subscribed" % (request.uri, repr(authid),))
- raise HTTPError(ErrorResponse(
- responsecode.FORBIDDEN,
- (twisted_dav_namespace, "principal-must-not-be-subscribed"))
- )
-
- principals.append(authid)
- self.writeDeadProperty(customxml.Subscribed(*principals))
-
- yield responsecode.OK
-
-http_X_APPLE_SUBSCRIBE = deferredGenerator(http_X_APPLE_SUBSCRIBE)
Deleted: CalendarServer/trunk/twistedcaldav/method/x_apple_unsubscribe.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/x_apple_unsubscribe.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/method/x_apple_unsubscribe.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -1,71 +0,0 @@
-##
-# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# DRI: Cyrus Daboo, cdaboo at apple.com
-##
-
-"""
-CalDAV X_APPLE_UNSUBSCRIBE method.
-"""
-
-__all__ = ["http_X_APPLE_UNSUBSCRIBE"]
-
-from twisted.internet.defer import deferredGenerator, waitForDeferred
-from twisted.python import log
-from twisted.web2 import responsecode
-from twisted.web2.dav.element.base import twisted_dav_namespace
-from twisted.web2.dav.http import ErrorResponse
-from twisted.web2.http import HTTPError, StatusResponse
-
-from twistedcaldav import customxml
-from twistedcaldav.dropbox import DropBox
-
-def http_X_APPLE_UNSUBSCRIBE(self, request):
-
- # Only for drop box collections
- if not DropBox.enabled or not self.isSpecialCollection(customxml.DropBox):
- log.err("Cannot x_apple_unsubscribe to resource %s" % (request.uri,))
- raise HTTPError(StatusResponse(
- responsecode.FORBIDDEN,
- "Cannot x_apple_unsubscribe to resource %s" % (request.uri,))
- )
-
- # We do not check any privileges. If a principal is subscribed we always allow them to
- # unsubscribe provided they have at least authenticated.
- d = waitForDeferred(self.authorize(request, ()))
- yield d
- d.getResult()
- authid = request.authnUser
-
- # Get current list of subscribed principals
- principals = []
- if self.hasDeadProperty(customxml.Subscribed):
- subs = self.readDeadProperty(customxml.Subscribed).children
- principals.extend(subs)
-
- # Error if attempt to subscribe more than once
- if authid not in principals:
- log.err("Cannot x_apple_unsubscribe from resource %s as principal %s is not currently subscribed" % (request.uri, repr(authid),))
- raise HTTPError(ErrorResponse(
- responsecode.FORBIDDEN,
- (twisted_dav_namespace, "principal-must-be-subscribed"))
- )
-
- principals.remove(authid)
- self.writeDeadProperty(customxml.Subscribed(*principals))
-
- yield responsecode.OK
-
-http_X_APPLE_UNSUBSCRIBE = deferredGenerator(http_X_APPLE_UNSUBSCRIBE)
Modified: CalendarServer/trunk/twistedcaldav/notifications.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/notifications.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/notifications.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -23,7 +23,7 @@
from twisted.web2.dav import davxml
from twistedcaldav import customxml
-from twistedcaldav.customxml import apple_namespace
+from twistedcaldav.customxml import calendarserver_namespace
from twistedcaldav.extensions import DAVFile
from twistedcaldav.extensions import DAVResource
@@ -54,7 +54,7 @@
def doNotification(self, request, parent):
"""
- Put the supplied noitification into the notification collection of the specified principal.
+ Put the supplied notification into the notification collection of the specified principal.
@param request: L{Request} for request in progress.
@param parent: L{DAVResource} for parent of resource trigerring the notification.
@@ -143,19 +143,29 @@
doNotification = deferredGenerator(doNotification)
+class NotificationCollectionResource (DAVResource):
+ def resourceType(self):
+ return davxml.ResourceType(
+ davxml.ResourceType.collection,
+ davxml.ResourceType.notifications,
+ )
+
+ def notify(self):
+ # FIXME: Move doNotification() logic from above class to here
+ pass
+
class NotificationResource(DAVResource):
"""
Resource that gets stored in a notification collection and which contains
the notification details in its content as well as via properties.
"""
-
liveProperties = DAVResource.liveProperties + (
- (apple_namespace, "time-stamp" ),
- (apple_namespace, "changed" ),
+ (calendarserver_namespace, "time-stamp"),
+ (calendarserver_namespace, "changed" ),
)
-class NotificationFile(DAVResource, DAVFile):
-
+# FIXME: This needs to be in static.py, but it's referred to in doNotification() above, which is probably incorrect.
+class NotificationFile(NotificationResource, DAVFile):
def __init__(self, path):
super(NotificationFile, self).__init__(path)
@@ -163,7 +173,6 @@
"""
Create the resource, fill out the body, and add properties.
"""
-
# Create body XML
elements = []
elements.append(customxml.TimeStamp.fromString(notification.timestamp))
Modified: CalendarServer/trunk/twistedcaldav/resource.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/resource.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/resource.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -54,9 +54,8 @@
from twistedcaldav.extensions import DAVResource
from twistedcaldav.icaldav import ICalDAVResource, ICalendarPrincipalResource
from twistedcaldav.caldavxml import caldav_namespace
-from twistedcaldav.customxml import apple_namespace
+from twistedcaldav.customxml import calendarserver_namespace
from twistedcaldav.ical import Component as iComponent
-from twistedcaldav.dropbox import DropBox
if twistedcaldav.__version__:
serverVersion = twisted.web2.server.VERSION + " TwistedCalDAV/" + twistedcaldav.__version__
@@ -449,17 +448,20 @@
"""
# Do this only for regular calendar collections and Inbox/Outbox
- if self.isPseudoCalendarCollection() or \
- DropBox.enabled and self.isSpecialCollection(customxml.DropBox):
- # Add inheritable option to each ACE in the list
+ if self.isPseudoCalendarCollection():
+ edited_aces = []
for ace in newaces:
if TwistedACLInheritable() not in ace.children:
children = list(ace.children)
children.append(TwistedACLInheritable())
- ace.children = children
+ edited_aces.append(davxml.ACE(*children))
+ else:
+ edited_aces.append(ace)
+ else:
+ edited_aces = newaces
# Do inherited with possibly modified set of aces
- super(CalDAVResource, self).writeNewACEs(newaces)
+ super(CalDAVResource, self).writeNewACEs(edited_aces)
##
# Utilities
@@ -535,6 +537,8 @@
(caldav_namespace, "calendar-user-address-set"),
(caldav_namespace, "schedule-inbox-URL" ),
(caldav_namespace, "schedule-outbox-URL" ),
+ (calendarserver_namespace, "dropbox-home-URL" ),
+ (calendarserver_namespace, "notifications-URL"),
)
def readProperty(self, property, request):
@@ -573,7 +577,7 @@
else:
return caldavxml.ScheduleOutboxURL(davxml.HRef(url))
- elif namespace == apple_namespace:
+ elif namespace == calendarserver_namespace:
if name == "dropbox-home-URL":
url = self.dropboxURL()
if url is None:
@@ -659,19 +663,21 @@
"""
@return: the drop box home collection URL for this principal.
"""
- # Use the first calendar home only
- for home in self.calendarHomeURLs():
- return joinURL(home, DropBox.dropboxName)
- return None
+ if self.hasDeadProperty((calendarserver_namespace, "dropbox-home-URL")):
+ inbox = self.readDeadProperty((caldav_namespace, "dropbox-home-URL"))
+ return str(inbox.children[0])
+ else:
+ return None
def notificationsURL(self):
"""
@return: the notifications collection URL for this principal.
"""
- # Use the first calendar home only
- for home in self.calendarHomeURLs():
- return joinURL(home, DropBox.notificationName)
- return None
+ if self.hasDeadProperty((calendarserver_namespace, "notifications-URL")):
+ inbox = self.readDeadProperty((caldav_namespace, "notifications-URL"))
+ return str(inbox.children[0])
+ else:
+ return None
##
# Utilities
Modified: CalendarServer/trunk/twistedcaldav/schedule.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/schedule.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/schedule.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -79,7 +79,10 @@
Extends L{DAVResource} to provide CalDAV functionality.
"""
def resourceType(self):
- return davxml.ResourceType(davxml.Collection(), caldavxml.ScheduleInbox())
+ return davxml.ResourceType(
+ davxml.ResourceType.collection,
+ davxml.ResourceType.scheduleInbox,
+ )
def defaultAccessControlList(self):
return davxml.ACL(
@@ -99,7 +102,10 @@
Extends L{DAVResource} to provide CalDAV functionality.
"""
def resourceType(self):
- return davxml.ResourceType(davxml.Collection(), caldavxml.ScheduleOutbox())
+ return davxml.ResourceType(
+ davxml.ResourceType.collection,
+ davxml.ResourceType.scheduleOutbox,
+ )
@deferredGenerator
def http_POST(self, request):
Modified: CalendarServer/trunk/twistedcaldav/static.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/static.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/static.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -22,11 +22,13 @@
__all__ = [
"CalDAVFile",
+ "CalendarHomeProvisioningFile",
"CalendarHomeFile",
- "CalendarHomeProvisioningFile",
- "CalendarPrincipalCollectionFile",
"ScheduleInboxFile",
"ScheduleOutboxFile",
+ "DropBoxHomeFile",
+ "DropBoxCollectionFile",
+ "DropBoxChildFile",
]
import os
@@ -46,14 +48,14 @@
from twistedcaldav import caldavxml
from twistedcaldav import customxml
+from twistedcaldav.config import config
+from twistedcaldav.extensions import DAVFile
from twistedcaldav.ical import Component as iComponent
from twistedcaldav.ical import Property as iProperty
-from twistedcaldav.icaldav import ICalDAVResource
from twistedcaldav.index import Index, IndexSchedule, db_basename
-from twistedcaldav.resource import CalDAVResource, isCalendarCollectionResource
+from twistedcaldav.resource import CalDAVResource, isCalendarCollectionResource, isPseudoCalendarCollectionResource
from twistedcaldav.schedule import ScheduleInboxResource, ScheduleOutboxResource
-from twistedcaldav.extensions import DAVFile
-from twistedcaldav.dropbox import DropBox
+from twistedcaldav.dropbox import DropBoxHomeResource, DropBoxCollectionResource, DropBoxChildResource
from twistedcaldav.directory.calendar import DirectoryCalendarHomeProvisioningResource
from twistedcaldav.directory.calendar import DirectoryCalendarHomeTypeProvisioningResource
from twistedcaldav.directory.calendar import DirectoryCalendarHomeResource
@@ -101,15 +103,7 @@
return self.createCalendarCollection()
- def isNonCalendarCollectionParentResource(resource):
- try:
- resource = ICalDAVResource(resource)
- except TypeError:
- return False
- else:
- return resource.isPseudoCalendarCollection() or resource.isSpecialCollection(customxml.DropBoxHome)
-
- parent = self._checkParents(request, isNonCalendarCollectionParentResource)
+ parent = self._checkParents(request, isPseudoCalendarCollectionResource)
parent.addCallback(_defer)
return parent
@@ -430,19 +424,21 @@
if not provisionFile(self, self._parent):
return succeed(None)
- d = super(CalendarHomeFile, self).provision()
+ return super(CalendarHomeFile, self).provision()
- # FIXME: This should provision itself also
- # Provision a drop box
- if self.record.recordType == "user":
- DropBox.provision(self)
+ def provisionChild(self, name):
+ if config.DropBoxEnabled:
+ DropBoxHomeFileClass = DropBoxHomeFile
+ #NotificationsCollectionFileClass = NotificationsCollectionFile
+ else:
+ DropBoxHomeFileClass = None
+ #NotificationsCollectionFileClass = None
- return d
-
- def provisionChild(self, name):
cls = {
- "inbox" : ScheduleInboxFile,
- "outbox": ScheduleOutboxFile,
+ "inbox" : ScheduleInboxFile,
+ "outbox" : ScheduleOutboxFile,
+ "dropbox" : DropBoxHomeFileClass,
+ #"notifications": NotificationsCollectionFileClass,
}.get(name, None)
if cls is not None:
@@ -526,6 +522,45 @@
def __repr__(self):
return "<%s (calendar outbox collection): %s>" % (self.__class__.__name__, self.fp.path)
+class DropBoxHomeFile (DropBoxHomeResource, CalDAVFile):
+ def __init__(self, path, parent):
+ DropBoxHomeResource.__init__(self)
+ CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
+ self._parent = parent
+
+ def provision(self):
+ provisionFile(self, self._parent)
+
+ def createSimilarFile(self, path):
+ if path == self.fp.path:
+ return self
+ else:
+ return DropBoxCollectionFile(path, self)
+
+class DropBoxCollectionFile (DropBoxCollectionResource, CalDAVFile):
+ def __init__(self, path, parent):
+ DropBoxCollectionResource.__init__(self)
+ CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
+
+ def createSimilarFile(self, path):
+ if path == self.fp.path:
+ return self
+ else:
+ return DropBoxChildFile(path, self)
+
+class DropBoxChildFile (DropBoxChildResource, CalDAVFile):
+ def __init__(self, path, parent):
+ DropBoxChildResource.__init__(self)
+ CalDAVFile.__init__(self, path, principalCollections=parent.principalCollections())
+
+ assert self.fp.isfile() or not self.fp.exists
+
+ def createSimilarFile(self, path):
+ if path == self.fp.path:
+ return self
+ else:
+ return responsecode.NOT_FOUND
+
##
# Utilities
##
Modified: CalendarServer/trunk/twistedcaldav/tap.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/tap.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/tap.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -43,7 +43,6 @@
from twisted.web2.server import Site
from twistedcaldav.config import config, parseConfig
-from twistedcaldav.dropbox import DropBox
from twistedcaldav.logging import RotatingFileAccessLoggingObserver
from twistedcaldav.root import RootResource
from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
@@ -86,16 +85,9 @@
def makeService(self, options):
#
- # Turn on drop box support before setting up the repository
- #
- DropBox.enable(config.DropBoxEnabled, config.NotificationsEnabled)
-
- #
# Setup the Directory
#
-
directoryClass = namedClass(config.DirectoryService['type'])
-
directory = directoryClass(**config.DirectoryService['params'])
#
Modified: CalendarServer/trunk/twistedcaldav/test/data/makelargecalendars.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/data/makelargecalendars.py 2006-12-14 22:04:25 UTC (rev 826)
+++ CalendarServer/trunk/twistedcaldav/test/data/makelargecalendars.py 2006-12-14 22:16:47 UTC (rev 827)
@@ -23,10 +23,17 @@
user_max = 20
calendars = ("calendar.10", "calendar.100", "calendar.1000",)
-for calendar in calendars:
- for ctr in xrange(1, user_max + 1):
- path = "calendars/user/user%02d" % (ctr,)
- if not os.path.exists("%s/%s/" % (path, calendar,)):
- print "Expanding %s to %s" % (calendar, path,)
- cmd = "cd %s; tar zxf ../../../%s.tgz" % (path, calendar,)
+for ctr in xrange(1, user_max + 1):
+ path = "calendars/user/user%02d" % (ctr,)
+
+ try: os.makedirs(path)
+ except OSError: pass
+
+ try: os.makedirs(os.path.join(path, "calendar"))
+ except OSError: pass
+
+ for calendar in calendars:
+ if not os.path.isdir(os.path.join(path, calendar)):
+ print "Expanding %s to %s" % (calendar, path)
+ cmd = "tar -C %r -zx -f %r" % (path, calendar + ".tgz")
os.system(cmd)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061214/fe133baf/attachment.html
More information about the calendarserver-changes
mailing list