1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-06-26 16:45:52 +00:00

Ability to create predefined calendar or(and) addressbook for new user

This commit is contained in:
IM 2024-04-22 12:23:24 +03:00
parent 7340ddc9d2
commit f7e01d55ed
4 changed files with 60 additions and 2 deletions

View file

@ -870,6 +870,26 @@ Command that is run after changes to storage. Take a look at the
Default: 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 #### web
##### type ##### type

18
config
View file

@ -103,6 +103,24 @@
# Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"") # Example: ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
#hook = #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] [web]

View file

@ -48,6 +48,7 @@ from radicale.app.propfind import ApplicationPartPropfind
from radicale.app.proppatch import ApplicationPartProppatch from radicale.app.proppatch import ApplicationPartProppatch
from radicale.app.put import ApplicationPartPut from radicale.app.put import ApplicationPartPut
from radicale.app.report import ApplicationPartReport from radicale.app.report import ApplicationPartReport
from radicale.item import check_and_sanitize_props
from radicale.log import logger from radicale.log import logger
# Combination of types.WSGIStartResponse and WSGI application return value # Combination of types.WSGIStartResponse and WSGI application return value
@ -268,7 +269,15 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
if "W" in self._rights.authorization(user, principal_path): if "W" in self._rights.authorization(user, principal_path):
with self._storage.acquire_lock("w", user): with self._storage.acquire_lock("w", user):
try: 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:
checked_props = check_and_sanitize_props(props)
self._storage.create_collection(principal_path + name_coll, props=checked_props)
except ValueError as e:
logger.warning("Failed to create predefined collection %r: %s", name_coll, e)
except ValueError as e: except ValueError as e:
logger.warning("Failed to create principal " logger.warning("Failed to create principal "
"collection %r: %s", user, e) "collection %r: %s", user, e)

View file

@ -26,6 +26,7 @@ Use ``load()`` to obtain an instance of ``Configuration`` for use with
""" """
import contextlib import contextlib
import json
import math import math
import os import os
import string import string
@ -101,6 +102,12 @@ def _convert_to_bool(value: Any) -> bool:
return RawConfigParser.BOOLEAN_STATES[value.lower()] return RawConfigParser.BOOLEAN_STATES[value.lower()]
def json_str(value: Any) -> dict:
if not value:
return {}
return json.loads(value)
INTERNAL_OPTIONS: Sequence[str] = ("_allow_extra",) INTERNAL_OPTIONS: Sequence[str] = ("_allow_extra",)
# Default configuration # Default configuration
DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
@ -217,7 +224,11 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
("_filesystem_fsync", { ("_filesystem_fsync", {
"value": "True", "value": "True",
"help": "sync all changes to filesystem during requests", "help": "sync all changes to filesystem during requests",
"type": bool})])), "type": bool}),
("predefined_collections", {
"value": "",
"help": "predefined user collections",
"type": json_str})])),
("hook", OrderedDict([ ("hook", OrderedDict([
("type", { ("type", {
"value": "none", "value": "none",