Просмотр исходного кода

Merge pull request #1473 from itglob/master

Ability to create predefined calendar or(and) addressbook for new user
Peter Bieringer 1 год назад
Родитель
Сommit
e9c7d4a671
4 измененных файлов с 63 добавлено и 2 удалено
  1. 20 0
      DOCUMENTATION.md
  2. 18 0
      config
  3. 8 1
      radicale/app/__init__.py
  4. 17 1
      radicale/config.py

+ 20 - 0
DOCUMENTATION.md

@@ -878,6 +878,26 @@ Command that is run after changes to storage. Take a look at the
 
 Default:
 
+##### predefined_collections
+
+Create predefined user collections
+
+ Example:
+
+     {
+       "def-addressbook": {
+          "D:displayname": "Personal Address Book",
+          "tag": "VADDRESSBOOK"
+       },
+       "def-calendar": {
+          "C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
+          "D:displayname": "Personal Calendar",
+          "tag": "VCALENDAR"
+       }
+     }
+
+Default:
+
 #### web
 
 ##### type

+ 18 - 0
config

@@ -106,6 +106,24 @@
 # Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
 #hook =
 
+# Create predefined user collections
+#
+# json format:
+#
+#  {
+#    "def-addressbook": {
+#       "D:displayname": "Personal Address Book",
+#       "tag": "VADDRESSBOOK"
+#    },
+#    "def-calendar": {
+#       "C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
+#       "D:displayname": "Personal Calendar",
+#       "tag": "VCALENDAR"
+#    }
+#  }
+#
+#predefined_collections =
+
 
 [web]
 

+ 8 - 1
radicale/app/__init__.py

@@ -274,7 +274,14 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
                 if "W" in self._rights.authorization(user, principal_path):
                     with self._storage.acquire_lock("w", user):
                         try:
-                            self._storage.create_collection(principal_path)
+                            new_coll = self._storage.create_collection(principal_path)
+                            if new_coll:
+                                jsn_coll = self.configuration.get("storage", "predefined_collections")
+                                for (name_coll, props) in jsn_coll.items():
+                                    try:
+                                        self._storage.create_collection(principal_path + name_coll, props=props)
+                                    except ValueError as e:
+                                        logger.warning("Failed to create predefined collection %r: %s", name_coll, e)
                         except ValueError as e:
                             logger.warning("Failed to create principal "
                                            "collection %r: %s", user, e)

+ 17 - 1
radicale/config.py

@@ -27,6 +27,7 @@ Use ``load()`` to obtain an instance of ``Configuration`` for use with
 """
 
 import contextlib
+import json
 import math
 import os
 import string
@@ -37,6 +38,7 @@ from typing import (Any, Callable, ClassVar, Iterable, List, Optional,
                     Sequence, Tuple, TypeVar, Union)
 
 from radicale import auth, hook, rights, storage, types, web
+from radicale.item import check_and_sanitize_props
 
 DEFAULT_CONFIG_PATH: str = os.pathsep.join([
     "?/etc/radicale/config",
@@ -102,6 +104,16 @@ def _convert_to_bool(value: Any) -> bool:
     return RawConfigParser.BOOLEAN_STATES[value.lower()]
 
 
+def json_str(value: Any) -> dict:
+    if not value:
+        return {}
+    ret = json.loads(value)
+    for (name_coll, props) in ret.items():
+        checked_props = check_and_sanitize_props(props)
+        ret[name_coll] = checked_props
+    return ret
+
+
 INTERNAL_OPTIONS: Sequence[str] = ("_allow_extra",)
 # Default configuration
 DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
@@ -222,7 +234,11 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
         ("_filesystem_fsync", {
             "value": "True",
             "help": "sync all changes to filesystem during requests",
-            "type": bool})])),
+            "type": bool}),
+        ("predefined_collections", {
+            "value": "",
+            "help": "predefined user collections",
+            "type": json_str})])),
     ("hook", OrderedDict([
         ("type", {
             "value": "none",