[CalendarServer-changes] [7198] CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 16 14:03:08 PDT 2011
Revision: 7198
http://trac.macosforge.org/projects/calendarserver/changeset/7198
Author: cdaboo at apple.com
Date: 2011-03-16 14:03:07 -0700 (Wed, 16 Mar 2011)
Log Message:
-----------
Tweaks to get bulk POST implementation correct.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/caldavxml.py
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/carddavxml.py
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/customxml.py
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/method/put_common.py
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/stdconfig.py
CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/storebridge.py
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/caldavxml.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/caldavxml.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -340,6 +340,8 @@
else:
raise ValueError("Not a calendar: %s" % (calendar,))
+ fromTextData = fromCalendar
+
def __init__(self, *children, **attributes):
super(CalendarData, self).__init__(*children, **attributes)
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/carddavxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/carddavxml.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/carddavxml.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -200,6 +200,8 @@
"""
return clazz(davxml.PCDATAElement(addressdata))
+ fromTextData = fromAddressData
+
def __init__(self, *children, **attributes):
super(AddressData, self).__init__(*children, **attributes)
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/customxml.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/customxml.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -1063,11 +1063,11 @@
(mm_namespace, "max-bytes") : (1, 1),
}
-class MaxResources (davxml.WebDAVTextElement):
+class MaxBulkResources (davxml.WebDAVTextElement):
namespace = mm_namespace
name = "max-resources"
-class MaxBytes (davxml.WebDAVTextElement):
+class MaxBulkBytes (davxml.WebDAVTextElement):
namespace = mm_namespace
name = "max-bytes"
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/method/put_common.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/method/put_common.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -815,6 +815,9 @@
@inlineCallbacks
def doStore(self, implicit):
+ # Stash the current calendar data as we may need to return it
+ self.returndata = str(self.calendar)
+
# Always do the per-user data merge right before we store
yield self.mergePerUserData()
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/stdconfig.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/stdconfig.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -436,7 +436,10 @@
"EnableDropBox" : False, # Calendar Drop Box
"EnablePrivateEvents" : False, # Private Events
"EnableTimezoneService" : False, # Timezone service
- "EnableBatchUpload" : False, # POST batch uploads
+
+ "EnableBatchUpload" : False, # POST batch uploads
+ "MaxResourcesBatchUpload" : 100, # Maximum number of resources in a batch POST
+ "MaxBytesBatchUpload" : 10485760, # Maximum size of a batch POST (10 MB)
"Sharing": {
"Enabled" : False, # Overall on/off switch
Modified: CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/storebridge.py 2011-03-16 19:26:24 UTC (rev 7197)
+++ CalendarServer/branches/users/cdaboo/batchupload-6699/twistedcaldav/storebridge.py 2011-03-16 21:03:07 UTC (rev 7198)
@@ -37,7 +37,8 @@
DisabledCacheNotifier
from twistedcaldav.caldavxml import caldav_namespace
from twistedcaldav.config import config
-from twistedcaldav.ical import Component as VCalendar, Property as VProperty
+from twistedcaldav.ical import Component as VCalendar, Property as VProperty,\
+ InvalidICalendarDataError
from twistedcaldav.memcachelock import MemcacheLock, MemcacheLockTimeoutError
from twistedcaldav.method.put_addressbook_common import StoreAddressObjectResource
from twistedcaldav.method.put_common import StoreCalendarObjectResource
@@ -45,7 +46,7 @@
from twistedcaldav.resource import CalDAVResource, GlobalAddressBookResource
from twistedcaldav.schedule import ScheduleInboxResource
from twistedcaldav.scheduling.implicit import ImplicitScheduler
-from twistedcaldav.vcard import Component as VCard
+from twistedcaldav.vcard import Component as VCard, InvalidVCardDataError
from txdav.base.propertystore.base import PropertyName
from txdav.common.icommondatastore import NoSuchObjectResourceError
from urlparse import urlsplit
@@ -221,6 +222,9 @@
if config.MaxResourcesPerCollection:
props += (customxml.MaxResources.qname(),)
+ if config.EnableBatchUpload:
+ props += (customxml.BulkRequests.qname(),)
+
return props
@inlineCallbacks
@@ -487,26 +491,18 @@
yield self._newStoreObject.rename(basename)
returnValue(NO_CONTENT)
- def liveProperties(self):
- baseProperties = ()
- if config.EnableBatchUpload:
- baseProperties += (
- customxml.BulkRequests.qname(),
- )
- return super(_CommonHomeChildCollectionMixin, self).liveProperties() + baseProperties
-
@inlineCallbacks
def _readGlobalProperty(self, qname, property, request):
if config.EnableBatchUpload and qname == customxml.BulkRequests.qname():
returnValue(customxml.BulkRequests(
customxml.Simple(
- customxml.MaxResources.fromString("100"),
- customxml.MaxBytes.fromString("%d" % (10*1024*1024,)),
+ customxml.MaxBulkResources.fromString(str(config.MaxResourcesBatchUpload)),
+ customxml.MaxBulkBytes.fromString(str(config.MaxBytesBatchUpload)),
),
customxml.CRUD(
- customxml.MaxResources.fromString("100"),
- customxml.MaxBytes.fromString("%d" % (10*1024*1024,)),
+ customxml.MaxBulkResources.fromString(str(config.MaxResourcesBatchUpload)),
+ customxml.MaxBulkBytes.fromString(str(config.MaxBytesBatchUpload)),
),
))
else:
@@ -547,6 +543,8 @@
data = (yield allDataFromStream(request.stream))
components = self.componentsFromData(data)
+ if components is None:
+ raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Could not parse valid data from request body"))
# Build response
xmlresponses = []
@@ -564,18 +562,8 @@
# Get a resource for the new item
newchildURL = joinURL(request.path, name)
newchild = (yield request.locateResource(newchildURL))
- yield self.storeResourceData(request, newchild, newchildURL, componentdata)
+ dataChanged = (yield self.storeResourceData(request, newchild, newchildURL, componentdata))
- # FIXME: figure out return_changed behavior
- if return_changed:
- pass
-# note = component.getProperty("NOTE")
-# if note is None:
-# component.addProperty(VCardProperty("NOTE", component.resourceUID()))
-# else:
-# note.setValue(component.resourceUID())
-# dataChanged = str(component)
-
except HTTPError, e:
# Extract the pre-condition
code = e.response.code
@@ -587,7 +575,7 @@
if code is None:
- if not return_changed or not dataChanged:
+ if not return_changed or dataChanged is None:
xmlresponses.append(
davxml.PropertyStatusResponse(
davxml.HRef.fromString(newchildURL),
@@ -607,7 +595,7 @@
davxml.PropertyStatus(
davxml.PropertyContainer(
davxml.GETETag.fromString(newchild.etag().generate()),
- self.xmlDataElementType().fromAddressData(dataChanged),
+ self.xmlDataElementType().fromTextData(dataChanged),
),
davxml.Status.fromResponseCode(responsecode.OK),
)
@@ -660,9 +648,14 @@
# Determine the multiput operation: create, update, delete
href = xmlchild.childOfType(davxml.HRef.qname())
set = xmlchild.childOfType(davxml.Set.qname())
- xmldata = set.childOfType(self.xmlDataElementType().qname()) if set is not None else None
+ prop = set.childOfType(davxml.PropertyContainer.qname()) if set is not None else None
+ xmldata_root = prop if prop else set
+ xmldata = xmldata_root.childOfType(self.xmlDataElementType().qname()) if xmldata_root is not None else None
if href is None:
+ if xmldata is None:
+ raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Could not parse valid data from request body without a DAV:Href present"))
+
# Do privilege check on collection once
if checkedBindPrivelege is None:
try:
@@ -679,6 +672,10 @@
if ifmatch:
ifmatch = str(ifmatch.children[0]) if len(ifmatch.children) == 1 else None
if delete is None:
+ if set is None:
+ raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Could not parse valid data from request body - no set of delete operation"))
+ if xmldata is None:
+ raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Could not parse valid data from request body for set operation"))
yield self.crudUpdate(request, str(href), xmldata.generateComponent(), ifmatch, return_changed, xmlresponses)
else:
# Do privilege check on collection once
@@ -979,7 +976,11 @@
results = []
# Split into components by UID and TZID
- vcal = VCalendar.fromString(data)
+ try:
+ vcal = VCalendar.fromString(data)
+ except InvalidICalendarDataError:
+ return None
+
by_uid = {}
by_tzid = {}
for subcomponent in vcal.subcomponents():
@@ -1034,6 +1035,9 @@
calendar = data,
)
yield storer.run()
+
+ returnValue(storer.returndata if hasattr(storer, "returndata") else None)
+
@inlineCallbacks
def storeRemove(self, request, implicitly, where):
@@ -1926,7 +1930,10 @@
@classmethod
def componentsFromData(cls, data):
- return VCard.allFromString(data)
+ try:
+ return VCard.allFromString(data)
+ except InvalidVCardDataError:
+ return None
@classmethod
def resourceSuffix(cls):
@@ -1948,8 +1955,9 @@
vcard = data,
)
yield storer.run()
+
+ returnValue(storer.returndata if hasattr(storer, "returndata") else None)
-
class GlobalAddressBookCollectionResource(GlobalAddressBookResource, AddressBookCollectionResource):
"""
Wrapper around a L{txdav.carddav.iaddressbook.IAddressBook}.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110316/65197624/attachment-0001.html>
More information about the calendarserver-changes
mailing list