Răsfoiți Sursa

Clean and reorder calendar functions

Guillaume Ayoub 14 ani în urmă
părinte
comite
022b2aa91f
4 a modificat fișierele cu 90 adăugiri și 89 ștergeri
  1. 1 1
      radicale/__init__.py
  2. 39 41
      radicale/ical.py
  3. 48 45
      radicale/storage/filesystem.py
  4. 2 2
      radicale/xmlutils.py

+ 1 - 1
radicale/__init__.py

@@ -269,7 +269,7 @@ class Application(object):
         """Manage DELETE request."""
         calendar = calendars[0]
 
-        if calendar.local_path == environ["PATH_INFO"].strip("/"):
+        if calendar.path == environ["PATH_INFO"].strip("/"):
             # Path matching the calendar, the item to delete is the calendar
             item = calendar
         else:

+ 39 - 41
radicale/ical.py

@@ -143,7 +143,11 @@ class Timezone(Item):
 
 
 class Calendar(object):
-    """Internal calendar class."""
+    """Internal calendar class.
+
+    This class must be overridden and replaced by a storage backend.
+
+    """
     tag = "VCALENDAR"
 
     def __init__(self, path, principal=False):
@@ -155,7 +159,7 @@ class Calendar(object):
         """
         self.encoding = "utf-8"
         split_path = path.split("/")
-        self.path = path
+        self.path = path if path != '.' else ''
         if principal and split_path and self.is_collection(self.path):
             # Already existing principal calendar
             self.owner = split_path[0]
@@ -164,7 +168,6 @@ class Calendar(object):
             self.owner = split_path[0]
         else:
             self.owner = None
-        self.local_path = path if path != '.' else ''
         self.is_principal = principal
 
     @classmethod
@@ -209,8 +212,22 @@ class Calendar(object):
                 result.extend(calendar.components)
         return result
 
-    def open(self, path):
-        """Return the content of the calendar under ``path``."""
+    def save(self, text):
+        """Save the text into the calendar."""
+        raise NotImplemented
+
+    def delete(self):
+        """Delete the calendar."""
+        raise NotImplemented
+
+    @property
+    def text(self):
+        """Calendar as plain text."""
+        raise NotImplemented
+
+    @classmethod
+    def children(cls, path):
+        """Yield the children of the collection at local ``path``."""
         raise NotImplemented
 
     @classmethod
@@ -223,16 +240,25 @@ class Calendar(object):
         """Return ``True`` if relative ``path`` is a collection item."""
         raise NotImplemented
 
-    def is_vcalendar(self, path):
-        """Return ``True`` if there is a VCALENDAR under relative ``path``."""
-        with self.open(path) as stream:
-            return 'BEGIN:VCALENDAR' == stream.read(15)
+    @property
+    def last_modified(self):
+        """Get the last time the calendar has been modified.
 
-    @classmethod
-    def children(cls, path):
-        """Yield the children of the collection at local ``path``."""
+        The date is formatted according to rfc1123-5.2.14.
+
+        """
         raise NotImplemented
 
+    @property
+    @contextmanager
+    def props(self):
+        """Get the calendar properties."""
+        raise NotImplemented
+
+    def is_vcalendar(self, path):
+        """Return ``True`` if there is a VCALENDAR under relative ``path``."""
+        return self.text.startswith('BEGIN:VCALENDAR')
+
     @staticmethod
     def _parse(text, item_types, name=None):
         """Find items with type in ``item_types`` in ``text``.
@@ -295,10 +321,6 @@ class Calendar(object):
 
         self.write(items=items)
 
-    def delete(self):
-        """Delete the calendar."""
-        raise NotImplemented
-
     def remove(self, name):
         """Remove object named ``name`` from calendar."""
         components = [
@@ -323,10 +345,6 @@ class Calendar(object):
         text = serialize(headers, items)
         self.save(text)
 
-    def save(self, text):
-        """Save the text into the calendar."""
-        raise NotImplemented
-
     @property
     def etag(self):
         """Etag from calendar."""
@@ -339,11 +357,6 @@ class Calendar(object):
             return props.get('D:displayname',
                 self.path.split(os.path.sep)[-1])
 
-    @property
-    def text(self):
-        """Calendar as plain text."""
-        raise NotImplemented
-
     @property
     def headers(self):
         """Find headers items in calendar."""
@@ -389,21 +402,6 @@ class Calendar(object):
         """Get list of ``Timezome`` items in calendar."""
         return self._parse(self.text, (Timezone,))
 
-    @property
-    def last_modified(self):
-        """Get the last time the calendar has been modified.
-
-        The date is formatted according to rfc1123-5.2.14.
-
-        """
-        raise NotImplemented
-
-    @property
-    @contextmanager
-    def props(self):
-        """Get the calendar properties."""
-        raise NotImplemented
-
     @property
     def owner_url(self):
         """Get the calendar URL according to its owner."""
@@ -415,4 +413,4 @@ class Calendar(object):
     @property
     def url(self):
         """Get the standard calendar URL."""
-        return "/%s/" % self.local_path
+        return "/%s/" % self.path

+ 48 - 45
radicale/storage/filesystem.py

@@ -33,33 +33,15 @@ from radicale import config, ical
 FOLDER = os.path.expanduser(config.get("storage", "filesystem_folder"))
 
 
-class Calendar(ical.Calendar):
-    @staticmethod
-    def open(path, mode="r"):
-        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
-        return codecs.open(abs_path, mode, config.get("encoding", "stock"))
+# This function overrides the builtin ``open`` function for this module
+# pylint: disable=W0622
+def open(path, mode="r"):
+    abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
+    return codecs.open(abs_path, mode, config.get("encoding", "stock"))
+# pylint: enable=W0622
 
-    @classmethod
-    def is_collection(cls, path):
-        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
-        return os.path.isdir(abs_path)
-
-    @classmethod
-    def is_item(cls, path):
-        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
-        return os.path.isfile(abs_path)
-
-    @classmethod
-    def children(cls, path):
-        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
-        for filename in next(os.walk(abs_path))[2]:
-            if cls.is_collection(path):
-                yield cls(path)
-
-    def delete(self):
-        os.remove(self._path)
-        os.remove(self._props_path)
 
+class Calendar(ical.Calendar):
     @property
     def _path(self):
         """Absolute path of the file at local ``path``."""
@@ -75,19 +57,37 @@ class Calendar(ical.Calendar):
         if not os.path.exists(os.path.dirname(self._path)):
             os.makedirs(os.path.dirname(self._path))
 
-    @property
-    @contextmanager
-    def props(self):
-        # On enter
-        properties = {}
-        if os.path.exists(self._props_path):
-            with open(self._props_path) as prop_file:
-                properties.update(json.load(prop_file))
-        yield properties
-        # On exit
+    def save(self, text):
         self._create_dirs()
-        with open(self._props_path, 'w') as prop_file:
-            json.dump(properties, prop_file)
+        open(self._path, "w").write(text)
+
+    def delete(self):
+        os.remove(self._path)
+        os.remove(self._props_path)
+
+    @property
+    def text(self):
+        try:
+            return open(self._path).read()
+        except IOError:
+            return ""
+
+    @classmethod
+    def children(cls, path):
+        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
+        for filename in next(os.walk(abs_path))[2]:
+            if cls.is_collection(path):
+                yield cls(path)
+
+    @classmethod
+    def is_collection(cls, path):
+        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
+        return os.path.isdir(abs_path)
+
+    @classmethod
+    def is_item(cls, path):
+        abs_path = os.path.join(FOLDER, path.replace("/", os.sep))
+        return os.path.isfile(abs_path)
 
     @property
     def last_modified(self):
@@ -99,15 +99,18 @@ class Calendar(ical.Calendar):
         return time.strftime("%a, %d %b %Y %H:%M:%S +0000", modification_time)
 
     @property
-    def text(self):
-        try:
-            return open(self._path).read()
-        except IOError:
-            return ""
-
-    def save(self, text):
+    @contextmanager
+    def props(self):
+        # On enter
+        properties = {}
+        if os.path.exists(self._props_path):
+            with open(self._props_path) as prop_file:
+                properties.update(json.load(prop_file))
+        yield properties
+        # On exit
         self._create_dirs()
-        self.open(self._path, "w").write(text)
+        with open(self._props_path, 'w') as prop_file:
+            json.dump(properties, prop_file)
 
 
 ical.Calendar = Calendar

+ 2 - 2
radicale/xmlutils.py

@@ -120,7 +120,7 @@ def _response(code):
 
 def name_from_path(path, calendar):
     """Return Radicale item name from ``path``."""
-    calendar_parts = calendar.local_path.strip("/").split("/")
+    calendar_parts = calendar.path.split("/")
     path_parts = path.strip("/").split("/")
     return path_parts[-1] if (len(path_parts) - len(calendar_parts)) else None
 
@@ -153,7 +153,7 @@ def delete(path, calendar):
 
     """
     # Reading request
-    if calendar.local_path == path.strip("/"):
+    if calendar.path == path.strip("/"):
         # Delete the whole calendar
         calendar.delete()
     else: