def apply(self, obj): url = urlfix(self.request['URL'], 'PROPPATCH') if isDavCollection(obj): url = url + '/' result = StringIO() errors = [] result.write('<?xml version="1.0" encoding="utf-8"?>\n' '<d:multistatus xmlns:d="DAV:">\n' '<d:response>\n' '<d:href>%s</d:href>\n' % quote(url)) propsets = obj.propertysheets for value in self.values: status = '200 OK' if len(value) > 2: name, ns, val, md = value propset = propsets.get(ns, None) if propset is None: propsets.manage_addPropertySheet('', ns) propset = propsets.get(ns) if propset.hasProperty(name): try: propset._updateProperty(name, val, meta=md) except Exception: errors.append(str(sys.exc_info()[1])) status = '409 Conflict' else: try: propset._setProperty(name, val, meta=md) except Exception: errors.append(str(sys.exc_info()[1])) status = '409 Conflict' else: name, ns = value propset = propsets.get(ns, None) if propset is None or not propset.hasProperty(name): # removing a non-existing property is not an error! # according to RFC 2518 status = '200 OK' else: try: propset._delProperty(name) except Exception: errors.append('%s cannot be deleted.' % name) status = '409 Conflict' result.write('<d:propstat xmlns:n="%s">\n' ' <d:prop>\n' ' <n:%s/>\n' ' </d:prop>\n' ' <d:status>HTTP/1.1 %s</d:status>\n' '</d:propstat>\n' % (ns, name, status)) errmsg = '\n'.join(errors) or 'The operation succeded.' result.write('<d:responsedescription>\n' '%s\n' '</d:responsedescription>\n' '</d:response>\n' '</d:multistatus>' % errmsg) result = result.getvalue() if not errors: return result # This is lame, but I cant find a way to keep ZPublisher # from sticking a traceback into my xml response :( transaction.abort() result = result.replace('200 OK', '424 Failed Dependency') return result