Ver código fonte

Merge pull request #479 from Kozea/upload_all

Add an upload_all method for subsequent optimizations.
Guillaume Ayoub 9 anos atrás
pai
commit
2e29b0a21c
1 arquivos alterados com 27 adições e 3 exclusões
  1. 27 3
      radicale/storage.py

+ 27 - 3
radicale/storage.py

@@ -321,6 +321,19 @@ class BaseCollection:
         """Upload a new item."""
         raise NotImplementedError
 
+    def upload_all(self, vobject_items):
+        """Upload a new set of items.
+
+        This takes a mapping of href and vobject items and
+        returns a list of uploaded items.
+        Might bring optimizations on some storages.
+
+        """
+        return [
+            self.upload(href, vobject_item)
+            for href, vobject_item in vobject_items.items()
+        ]
+
     def update(self, href, vobject_item):
         """Update an item.
 
@@ -552,12 +565,23 @@ class Collection(BaseCollection):
                         items.extend(
                             getattr(collection, "%s_list" % content, []))
                     items_by_uid = groupby(sorted(items, key=get_uid), get_uid)
+                    collections = {}
                     for uid, items in items_by_uid:
                         new_collection = vobject.iCalendar()
                         for item in items:
                             new_collection.add(item)
-                        self.upload(
-                            self._find_available_file_name(), new_collection)
+
+                        # Prevent infinite loop
+                        for _ in range(10000):
+                            href = self._find_available_file_name()
+                            if href not in collections:
+                                break
+                        else:
+                            raise FileExistsError(
+                                errno.EEXIST, "No usable file name found")
+                        collections[href] = new_collection
+
+                    self.upload_all(collections)
                 elif props.get("tag") == "VCARD":
                     for card in collection:
                         self.upload(self._find_available_file_name(), card)
@@ -796,4 +820,4 @@ class Collection(BaseCollection):
                 if (cls.configuration.getboolean("storage", "close_lock_file")
                         and cls._readers == 0 and not cls._waiters):
                     cls._lock_file.close()
-                    cls._lock_file = None
+                    cls._lock_file = None