async def report( self, environ, body, resources_by_hrefs, properties, base_href, base_resource, depth, ): requested = None filter_el = None limit = None for el in body: if el.tag in ("{DAV:}prop", "{DAV:}allprop", "{DAV:}propname"): requested = el elif el.tag == ("{%s}filter" % NAMESPACE): filter_el = el elif el.tag == ("{%s}limit" % NAMESPACE): limit = el else: raise webdav.BadRequestError("Unknown tag %s in report %s" % (el.tag, self.name)) if limit is not None: try: [nresults_el] = list(limit) except ValueError: raise webdav.BadRequestError( "Invalid number of subelements in limit") try: nresults = int(nresults_el.text) except ValueError: raise webdav.BadRequestError("nresults not a number") else: nresults = None i = 0 async for (href, resource) in webdav.traverse_resource( base_resource, base_href, depth): if not apply_filter(filter_el, resource): continue if nresults is not None and i >= nresults: break propstat = davcommon.get_properties_with_data( self.data_property, href, resource, properties, environ, requested, ) yield webdav.Status(href, "200 OK", propstat=[s async for s in propstat]) i += 1
def report(self, environ, body, resources_by_hrefs, properties, base_href, base_resource, depth): # TODO(jelmer): Verify that resource is an addressbook requested = None filter_el = None tztext = None for el in body: if el.tag in ('{DAV:}prop', '{DAV:}propname', '{DAV:}allprop'): requested = el elif el.tag == '{urn:ietf:params:xml:ns:caldav}filter': filter_el = el elif el.tag == '{urn:ietf:params:xml:ns:caldav}timezone': tztext = el.text else: raise webdav.BadRequestError('Unknown tag %s in report %s' % (el.tag, self.name)) if tztext is not None: tz = get_pytz_from_text(tztext) else: tz = get_calendar_timezone(base_resource) tzify = lambda dt: as_tz_aware_ts(dt, tz) for (href, resource) in webdav.traverse_resource(base_resource, base_href, depth): if not apply_filter(filter_el, resource, tzify): continue propstat = davcommon.get_properties_with_data( self.data_property, href, resource, properties, environ, requested) yield webdav.Status(href, '200 OK', propstat=list(propstat))
async def report( self, environ, body, resources_by_hrefs, properties, base_href, base_resource, depth, ): # TODO(jelmer): Verify that resource is a calendar requested = None filter_el = None tztext = None for el in body: if el.tag in ("{DAV:}prop", "{DAV:}propname", "{DAV:}allprop"): requested = el elif el.tag == "{urn:ietf:params:xml:ns:caldav}filter": filter_el = el elif el.tag == "{urn:ietf:params:xml:ns:caldav}timezone": tztext = el.text else: raise webdav.BadRequestError("Unknown tag %s in report %s" % (el.tag, self.name)) if tztext is not None: tz = get_pytz_from_text(tztext) else: tz = get_calendar_timezone(base_resource) def filter_fn(cls): return parse_filter(filter_el, cls(tz)) def members(collection): return itertools.chain( collection.calendar_query(filter_fn), collection.subcollections(), ) async for (href, resource) in webdav.traverse_resource(base_resource, base_href, depth, members=members): # Ideally traverse_resource would only return the right things. if getattr(resource, "content_type", None) == "text/calendar": propstat = davcommon.get_properties_with_data( self.data_property, href, resource, properties, environ, requested, ) yield webdav.Status(href, "200 OK", propstat=[s async for s in propstat])
async def handle(self, request, environ, app): content_type = request.content_type base_content_type, params = webdav.parse_type(content_type) if base_content_type not in ( "text/xml", "application/xml", None, "text/plain", "application/octet-stream", ): raise webdav.UnsupportedMediaType(content_type) href, path, resource = app._get_resource_from_environ(request, environ) if resource is not None: return webdav._send_simple_dav_error( request, "403 Forbidden", error=ET.Element("{DAV:}resource-must-be-null"), description=("Something already exists at %r" % path), ) try: resource = app.backend.create_collection(path) except FileNotFoundError: return webdav.Response(status="409 Conflict") el = ET.Element("{DAV:}resourcetype") await app.properties["{DAV:}resourcetype"].get_value( href, resource, el, environ) ET.SubElement(el, "{urn:ietf:params:xml:ns:caldav}calendar") app.properties["{DAV:}resourcetype"].set_value(href, resource, el) if base_content_type in ("text/xml", "application/xml"): et = await webdav._readXmlBody( request, "{urn:ietf:params:xml:ns:caldav}mkcalendar", strict=app.strict, ) propstat = [] for el in et: if el.tag != "{DAV:}set": raise webdav.BadRequestError( "Unknown tag %s in mkcalendar" % el.tag) propstat.extend( webdav.apply_modify_prop(el, href, resource, app.properties)) ret = ET.Element( "{urn:ietf:params:xml:ns:carldav:}mkcalendar-response") for propstat_el in webdav.propstat_as_xml(propstat): ret.append(propstat_el) return webdav._send_xml_response("201 Created", ret, webdav.DEFAULT_ENCODING) else: return webdav.Response(status="201 Created")
def handle(self, environ, start_response, app): try: content_type = environ['CONTENT_TYPE'] except KeyError: base_content_type = None else: base_content_type, params = webdav.parse_type(content_type) if base_content_type not in ('text/xml', 'application/xml', None, 'text/plain'): raise webdav.UnsupportedMediaType(content_type) href, path, resource = app._get_resource_from_environ(environ) if resource is not None: return webdav._send_simple_dav_error( environ, start_response, '403 Forbidden', error=ET.Element('{DAV:}resource-must-be-null'), description=('Something already exists at %r' % path)) try: resource = app.backend.create_collection(path) except FileNotFoundError: start_response('409 Conflict', []) return [] el = ET.Element('{DAV:}resourcetype') app.properties['{DAV:}resourcetype'].get_value(href, resource, el, environ) ET.SubElement(el, '{urn:ietf:params:xml:ns:caldav}calendar') app.properties['{DAV:}resourcetype'].set_value(href, resource, el) if base_content_type in ('text/xml', 'application/xml'): et = webdav._readXmlBody( environ, '{urn:ietf:params:xml:ns:caldav}mkcalendar') propstat = [] for el in et: if el.tag != '{DAV:}set': raise webdav.BadRequestError( 'Unknown tag %s in mkcalendar' % el.tag) propstat.extend( webdav.apply_modify_prop(el, href, resource, app.properties)) ret = ET.Element( '{urn:ietf:params:xml:ns:carldav:}mkcalendar-response') for propstat_el in webdav.propstat_as_xml(propstat): ret.append(propstat_el) return webdav._send_xml_response(start_response, '201 Created', ret, webdav.DEFAULT_ENCODING) else: start_response('201 Created', []) return []
def report(self, environ, body, resources_by_hrefs, properties, base_href, resource, depth): # TODO(jelmer): Verify that depth == "0" # TODO(jelmer): Verify that resource is an the right resource type requested = None hrefs = [] for el in body: if el.tag in ('{DAV:}prop', '{DAV:}allprop', '{DAV:}propname'): requested = el elif el.tag == '{DAV:}href': hrefs.append(webdav.read_href_element(el)) else: raise webdav.BadRequestError('Unknown tag %s in report %s' % (el.tag, self.name)) for (href, resource) in resources_by_hrefs(hrefs): if resource is None: yield webdav.Status(href, '404 Not Found', propstat=[]) else: propstat = get_properties_with_data(self.data_property, href, resource, properties, environ, requested) yield webdav.Status(href, '200 OK', propstat=list(propstat))
async def report( self, environ, body, resources_by_hrefs, properties, base_href, resource, depth, ): # TODO(jelmer): Verify that depth == "0" # TODO(jelmer): Verify that resource is an the right resource type requested = None hrefs = [] for el in body: if el.tag in ("{DAV:}prop", "{DAV:}allprop", "{DAV:}propname"): requested = el elif el.tag == "{DAV:}href": hrefs.append(webdav.read_href_element(el)) else: raise webdav.BadRequestError("Unknown tag %s in report %s" % (el.tag, self.name)) for (href, resource) in resources_by_hrefs(hrefs): if resource is None: yield webdav.Status(href, "404 Not Found", propstat=[]) else: propstat = get_properties_with_data( self.data_property, href, resource, properties, environ, requested, ) yield webdav.Status(href, "200 OK", propstat=[s async for s in propstat])
async def report(self, environ, request_body, resources_by_hrefs, properties, href, resource, depth): old_token = None sync_level = None limit = None requested = None for el in request_body: if el.tag == '{DAV:}sync-token': old_token = el.text elif el.tag == '{DAV:}sync-level': sync_level = el.text elif el.tag == '{DAV:}limit': limit = el.text elif el.tag == '{DAV:}prop': requested = list(el) else: raise webdav.BadRequestError('unknown tag %s' % el.tag) # TODO(jelmer): Implement sync_level infinite if sync_level not in ("1", ): raise webdav.BadRequestError("sync level %r unsupported" % sync_level) new_token = resource.get_sync_token() try: diff_iter = resource.iter_differences_since(old_token, new_token) except NotImplementedError: yield webdav.Status( href, '403 Forbidden', error=ET.Element('{DAV:}sync-traversal-supported')) return if limit is not None: try: [nresults_el] = list(limit) except ValueError: raise webdav.BadRequestError( 'Invalid number of subelements in limit') try: nresults = int(nresults_el.text) except ValueError: raise webdav.BadRequestError('nresults not a number') diff_iter = itertools.islice(diff_iter, nresults) for (name, old_resource, new_resource) in diff_iter: subhref = urllib.parse.urljoin(webdav.ensure_trailing_slash(href), name) if new_resource is None: yield webdav.Status(subhref, status='404 Not Found') else: propstat = [] for prop in requested: if old_resource is not None: old_propstat = webdav.get_property_from_element( href, old_resource, properties, environ, prop) else: old_propstat = None new_propstat = webdav.get_property_from_element( href, new_resource, properties, environ, prop) if old_propstat != new_propstat: propstat.append(new_propstat) yield webdav.Status(subhref, propstat=propstat) yield SyncToken(new_token)