From a1cdcf2fba4956de6d83d7a7012ae92e5bfed96b Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Tue, 12 Apr 2016 22:43:10 +0200 Subject: [PATCH 1/4] Don't crash if propsfile doesn't exist --- radicale/storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radicale/storage.py b/radicale/storage.py index 5a63434..157920c 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -349,7 +349,7 @@ class Collection: with open(props_path, encoding=STORAGE_ENCODING) as prop_file: properties.update(json.load(prop_file)) properties[key] = value - with open(props_path, "w", encoding=STORAGE_ENCODING) as prop_file: + with open(props_path, "w+", encoding=STORAGE_ENCODING) as prop_file: json.dump(properties, prop_file) @property From f169f2f19b7c2c45c7a9d513ad2d6feaa0bff248 Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 13 Apr 2016 22:08:57 +0200 Subject: [PATCH 2/4] Don't crash if collection doesn't exist yet --- radicale/storage.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/radicale/storage.py b/radicale/storage.py index 157920c..410ce95 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -227,7 +227,12 @@ class Collection: def list(self): """List collection items.""" - for href in os.listdir(self._filesystem_path): + try: + hrefs = os.listdir(self._filesystem_path) + except IOError: + return + + for href in hrefs: path = os.path.join(self._filesystem_path, href) if not href.endswith(".props") and os.path.isfile(path): with open(path, encoding=STORAGE_ENCODING) as fd: From 472d016d1e1c360efb508d043957ddef67387b6f Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 13 Apr 2016 22:56:57 +0200 Subject: [PATCH 3/4] Fix crash when fetching nonexistent href --- radicale/xmlutils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 2e09993..beae90c 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -522,13 +522,14 @@ def report(path, xml_request, collection): if name: # Reference is an item path = "/".join(hreference.split("/")[:-1]) + "/" - try: - items = [collection.get(name)] - except KeyError: + item = collection.get(name) + if item is None: multistatus.append( _item_response(hreference, found_item=False)) continue + items = [item] + else: # Reference is a collection path = hreference From e8c1defe6add7aad4979bb49fc2935947bb0db0f Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Wed, 13 Apr 2016 23:02:00 +0200 Subject: [PATCH 4/4] Update PROPPATCH to new storage API --- radicale/storage.py | 7 ++++++- radicale/xmlutils.py | 20 +++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/radicale/storage.py b/radicale/storage.py index 410ce95..016afb6 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -353,7 +353,12 @@ class Collection: if os.path.exists(props_path): with open(props_path, encoding=STORAGE_ENCODING) as prop_file: properties.update(json.load(prop_file)) - properties[key] = value + + if value: + properties[key] = value + else: + properties.pop(key, None) + with open(props_path, "w+", encoding=STORAGE_ENCODING) as prop_file: json.dump(properties, prop_file) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index beae90c..81d6f28 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -442,19 +442,13 @@ def proppatch(path, xml_request, collection): href.text = _href(path) response.append(href) - with collection.props as collection_props: - for short_name, value in props_to_set.items(): - if short_name.split(":")[-1] == "calendar-timezone": - collection.replace(None, value) - collection_props[short_name] = value - _add_propstat_to(response, short_name, 200) - for short_name in props_to_remove: - try: - del collection_props[short_name] - except KeyError: - _add_propstat_to(response, short_name, 412) - else: - _add_propstat_to(response, short_name, 200) + for short_name, value in props_to_set.items(): + collection.set_meta(short_name, value) + _add_propstat_to(response, short_name, 200) + + for short_name in props_to_remove: + collection.set_meta(short_name, '') + _add_propstat_to(response, short_name, 200) return _pretty_xml(multistatus)