Quellcode durchsuchen

Extract method prepare

Unrud vor 6 Jahren
Ursprung
Commit
b4230c4249
1 geänderte Dateien mit 96 neuen und 93 gelöschten Zeilen
  1. 96 93
      radicale/app/put.py

+ 96 - 93
radicale/app/put.py

@@ -31,6 +31,96 @@ from radicale import pathutils, storage, xmlutils
 from radicale.log import logger
 
 
+def prepare(vobject_items, path, content_type, permissions, parent_permissions,
+            tag=None, write_whole_collection=None):
+    if (write_whole_collection or
+            permissions and not parent_permissions):
+        write_whole_collection = True
+        tags = {value: key
+                for key, value in xmlutils.MIMETYPES.items()}
+        tag = radicale_item.predict_tag_of_whole_collection(
+            vobject_items, tags.get(content_type))
+        if not tag:
+            raise ValueError("Can't determine collection tag")
+        collection_path = pathutils.strip_path(path)
+    elif (write_whole_collection is not None and
+            not write_whole_collection or
+            not permissions and parent_permissions):
+        write_whole_collection = False
+        if tag is None:
+            tag = radicale_item.predict_tag_of_parent_collection(
+                vobject_items)
+        collection_path = posixpath.dirname(
+            pathutils.strip_path(path))
+    props = None
+    stored_exc_info = None
+    items = []
+    try:
+        if tag:
+            radicale_item.check_and_sanitize_items(
+                vobject_items, is_collection=write_whole_collection,
+                tag=tag)
+            if write_whole_collection and tag == "VCALENDAR":
+                vobject_components = []
+                vobject_item, = vobject_items
+                for content in ("vevent", "vtodo", "vjournal"):
+                    vobject_components.extend(
+                        getattr(vobject_item, "%s_list" % content, []))
+                vobject_components_by_uid = itertools.groupby(
+                    sorted(vobject_components,
+                           key=radicale_item.get_uid),
+                    radicale_item.get_uid)
+                for uid, components in vobject_components_by_uid:
+                    vobject_collection = vobject.iCalendar()
+                    for component in components:
+                        vobject_collection.add(component)
+                    item = radicale_item.Item(
+                        collection_path=collection_path,
+                        vobject_item=vobject_collection)
+                    item.prepare()
+                    items.append(item)
+            elif write_whole_collection and tag == "VADDRESSBOOK":
+                for vobject_item in vobject_items:
+                    item = radicale_item.Item(
+                        collection_path=collection_path,
+                        vobject_item=vobject_item)
+                    item.prepare()
+                    items.append(item)
+            elif not write_whole_collection:
+                vobject_item, = vobject_items
+                item = radicale_item.Item(
+                    collection_path=collection_path,
+                    vobject_item=vobject_item)
+                item.prepare()
+                items.append(item)
+
+        if write_whole_collection:
+            props = {}
+            if tag:
+                props["tag"] = tag
+            if tag == "VCALENDAR" and vobject_items:
+                if hasattr(vobject_items[0], "x_wr_calname"):
+                    calname = vobject_items[0].x_wr_calname.value
+                    if calname:
+                        props["D:displayname"] = calname
+                if hasattr(vobject_items[0], "x_wr_caldesc"):
+                    caldesc = vobject_items[0].x_wr_caldesc.value
+                    if caldesc:
+                        props["C:calendar-description"] = caldesc
+            radicale_item.check_and_sanitize_props(props)
+    except Exception:
+        stored_exc_info = sys.exc_info()
+
+    # Use generator for items and delete references to free memory
+    # early
+    def items_generator():
+        while items:
+            yield items.pop(0)
+
+    return (items_generator(), tag, write_whole_collection, props,
+            stored_exc_info)
+
+
 class ApplicationPutMixin:
     def do_PUT(self, environ, base_prefix, path, user):
         """Manage PUT request."""
@@ -45,101 +135,11 @@ class ApplicationPutMixin:
             logger.debug("client timed out", exc_info=True)
             return httputils.REQUEST_TIMEOUT
         # Prepare before locking
+        content_type = environ.get("CONTENT_TYPE", "").split(";")[0]
         parent_path = pathutils.unstrip_path(
             posixpath.dirname(pathutils.strip_path(path)), True)
         permissions = self._rights.authorized(user, path, "Ww")
         parent_permissions = self._rights.authorized(user, parent_path, "w")
-
-        def prepare(vobject_items, tag=None, write_whole_collection=None):
-            if (write_whole_collection or
-                    permissions and not parent_permissions):
-                write_whole_collection = True
-                content_type = environ.get("CONTENT_TYPE",
-                                           "").split(";")[0]
-                tags = {value: key
-                        for key, value in xmlutils.MIMETYPES.items()}
-                tag = radicale_item.predict_tag_of_whole_collection(
-                    vobject_items, tags.get(content_type))
-                if not tag:
-                    raise ValueError("Can't determine collection tag")
-                collection_path = pathutils.strip_path(path)
-            elif (write_whole_collection is not None and
-                    not write_whole_collection or
-                    not permissions and parent_permissions):
-                write_whole_collection = False
-                if tag is None:
-                    tag = radicale_item.predict_tag_of_parent_collection(
-                        vobject_items)
-                collection_path = posixpath.dirname(
-                    pathutils.strip_path(path))
-            props = None
-            stored_exc_info = None
-            items = []
-            try:
-                if tag:
-                    radicale_item.check_and_sanitize_items(
-                        vobject_items, is_collection=write_whole_collection,
-                        tag=tag)
-                    if write_whole_collection and tag == "VCALENDAR":
-                        vobject_components = []
-                        vobject_item, = vobject_items
-                        for content in ("vevent", "vtodo", "vjournal"):
-                            vobject_components.extend(
-                                getattr(vobject_item, "%s_list" % content, []))
-                        vobject_components_by_uid = itertools.groupby(
-                            sorted(vobject_components,
-                                   key=radicale_item.get_uid),
-                            radicale_item.get_uid)
-                        for uid, components in vobject_components_by_uid:
-                            vobject_collection = vobject.iCalendar()
-                            for component in components:
-                                vobject_collection.add(component)
-                            item = radicale_item.Item(
-                                collection_path=collection_path,
-                                vobject_item=vobject_collection)
-                            item.prepare()
-                            items.append(item)
-                    elif write_whole_collection and tag == "VADDRESSBOOK":
-                        for vobject_item in vobject_items:
-                            item = radicale_item.Item(
-                                collection_path=collection_path,
-                                vobject_item=vobject_item)
-                            item.prepare()
-                            items.append(item)
-                    elif not write_whole_collection:
-                        vobject_item, = vobject_items
-                        item = radicale_item.Item(
-                            collection_path=collection_path,
-                            vobject_item=vobject_item)
-                        item.prepare()
-                        items.append(item)
-
-                if write_whole_collection:
-                    props = {}
-                    if tag:
-                        props["tag"] = tag
-                    if tag == "VCALENDAR" and vobject_items:
-                        if hasattr(vobject_items[0], "x_wr_calname"):
-                            calname = vobject_items[0].x_wr_calname.value
-                            if calname:
-                                props["D:displayname"] = calname
-                        if hasattr(vobject_items[0], "x_wr_caldesc"):
-                            caldesc = vobject_items[0].x_wr_caldesc.value
-                            if caldesc:
-                                props["C:calendar-description"] = caldesc
-                    radicale_item.check_and_sanitize_props(props)
-            except Exception:
-                stored_exc_info = sys.exc_info()
-
-            # Use generator for items and delete references to free memory
-            # early
-            def items_generator():
-                while items:
-                    yield items.pop(0)
-
-            return (items_generator(), tag, write_whole_collection, props,
-                    stored_exc_info)
-
         try:
             vobject_items = tuple(vobject.readComponents(content or ""))
         except Exception as e:
@@ -147,7 +147,9 @@ class ApplicationPutMixin:
                 "Bad PUT request on %r: %s", path, e, exc_info=True)
             return httputils.BAD_REQUEST
         (prepared_items, prepared_tag, prepared_write_whole_collection,
-         prepared_props, prepared_exc_info) = prepare(vobject_items)
+         prepared_props, prepared_exc_info) = prepare(
+             vobject_items, path, content_type, permissions,
+             parent_permissions)
 
         with self._storage.acquire_lock("w", user):
             item = next(self._storage.discover(path), None)
@@ -188,7 +190,8 @@ class ApplicationPutMixin:
                     prepared_write_whole_collection != write_whole_collection):
                 (prepared_items, prepared_tag, prepared_write_whole_collection,
                  prepared_props, prepared_exc_info) = prepare(
-                    vobject_items, tag, write_whole_collection)
+                    vobject_items, path, content_type, permissions,
+                    parent_permissions, tag, write_whole_collection)
             props = prepared_props
             if prepared_exc_info:
                 logger.warning(