From f37b22b68288c764346e22a42cee71b2e5955656 Mon Sep 17 00:00:00 2001 From: Unrud Date: Tue, 29 Aug 2017 20:08:26 +0200 Subject: [PATCH] Correct ;component=... in getcontenttype --- radicale/tests/test_base.py | 38 +++++++++++++++++++++++++++++++++++++ radicale/xmlutils.py | 21 +++++++++++++------- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/radicale/tests/test_base.py b/radicale/tests/test_base.py index 122ec5a..608d4b7 100644 --- a/radicale/tests/test_base.py +++ b/radicale/tests/test_base.py @@ -1140,6 +1140,44 @@ class BaseRequestsMixIn: sync_token) assert sync_token == new_sync_token + def test_calendar_getcontenttype(self): + """Test report request on an item""" + status, _, _ = self.request("MKCALENDAR", "/test/") + assert status == 201 + for component in ("event", "todo", "journal"): + event = get_file_content("{}1.ics".format(component)) + status, _, _ = self.request("PUT", "/test/test.ics", event) + assert status == 201 + status, _, answer = self.request( + "REPORT", "/test/", + """ + + + + + """) + assert status == 207 + assert ">text/calendar;charset=utf-8;component=V{}<".format( + component.upper()) in answer + + def test_addressbook_getcontenttype(self): + """Test report request on an item""" + status, _, _ = self._create_addressbook("/test/") + assert status == 201 + contact = get_file_content("contact1.vcf") + status, _, _ = self.request("PUT", "/test/test.vcf", contact) + assert status == 201 + status, _, answer = self.request( + "REPORT", "/test/", + """ + + + + + """) + assert status == 207 + assert ">text/vcard;charset=utf-8<" in answer + def test_authorization(self): authorization = "Basic " + base64.b64encode(b"user:").decode() status, _, answer = self.request( diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index adfb363..9fbb5b5 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -602,6 +602,18 @@ def simplify_prefilters(filters): return None, TIMESTAMP_MIN, TIMESTAMP_MAX, simple +def get_content_type(item): + """Get the content-type of an item with charset and component parameters. + """ + mimetype = OBJECT_MIMETYPES[item.name] + encoding = item.collection.configuration.get("encoding", "request") + tag = find_tag(item) + content_type = "%s;charset=%s" % (mimetype, encoding) + if tag: + content_type += ";component=%s" % tag + return content_type + + def find_tag(vobject_item): """Find tag from ``vobject_item``.""" if vobject_item.name == "VCALENDAR": @@ -967,9 +979,7 @@ def _propfind_response(base_prefix, path, item, props, user, write=False, is404 = True # Not for collections elif tag == _tag("D", "getcontenttype"): - name = item.name.lower() - mimetype = "text/vcard" if name == "vcard" else "text/calendar" - element.text = "%s; component=%s" % (mimetype, name) + element.text = get_content_type(item) elif tag == _tag("D", "resourcetype"): # resourcetype must be returned empty for non-collection elements pass @@ -1182,10 +1192,7 @@ def report(base_prefix, path, xml_request, collection): element.text = item.etag found_props.append(element) elif tag == _tag("D", "getcontenttype"): - name = item.name.lower() - mimetype = ( - "text/vcard" if name == "vcard" else "text/calendar") - element.text = "%s; component=%s" % (mimetype, name) + element.text = get_content_type(item) found_props.append(element) elif tag in ( _tag("C", "calendar-data"),