diff --git a/config b/config index 02f92373b..b838deb25 100644 --- a/config +++ b/config @@ -107,6 +107,12 @@ #hook = +[share] + +# Share plugins +#type = read, write, birthday + + [web] # Web interface backend diff --git a/radicale/config.py b/radicale/config.py index d50224b78..9221b0e4a 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -29,7 +29,7 @@ from collections import OrderedDict from configparser import RawConfigParser as ConfigParser -from radicale import auth, rights, storage, web +from radicale import auth, rights, share, storage, web def positive_int(value): @@ -169,6 +169,12 @@ def logging_level(value): "value": "", "help": "command that is run after changes to storage", "type": str})])), + ("share", OrderedDict([ + ("type", { + "value": "read, write, birthday", + "help": "set share plugins", + "type": str, + "internal": share.INTERNAL_TYPES})])), ("web", OrderedDict([ ("type", { "value": "internal", diff --git a/radicale/share/__init__.py b/radicale/share/__init__.py new file mode 100644 index 000000000..74495a993 --- /dev/null +++ b/radicale/share/__init__.py @@ -0,0 +1,62 @@ +# This file is part of Radicale Server - Calendar Server +# Copyright © 2018 Unrud +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +from importlib import import_module + +from radicale.log import logger + +INTERNAL_TYPES = ("read", "write", "birthday") + + +def load(configuration): + """Load the share plugins chosen in configuration.""" + share_types = tuple([ + s.strip() for s in configuration.get("share", "type").split(",")]) + classes = [] + for share_type in share_types: + if share_type in INTERNAL_TYPES: + module = "radicale.share.%s" % share_type + else: + module = share_type + try: + classes.append(import_module(module).Share) + except Exception as e: + raise RuntimeError("Failed to load share module %r: %s" % + (module, e)) from e + logger.info("Share types are %r", share_types) + return tuple([class_(configuration) for class_ in classes]) + + +class BaseShare: + + name = "" + uuid = "" + group = "" + + tags = () + item_writethrough = False + + def __init__(self, configuration): + self.configuration = configuration + + def get(self, item): + raise NotImplementedError + + def get_meta(self, props, base_props): + raise NotImplementedError + + def set_meta(self, props, old_props, old_base_props): + raise NotImplementedError diff --git a/radicale/share/birthday.py b/radicale/share/birthday.py new file mode 100644 index 000000000..ba5e43ea5 --- /dev/null +++ b/radicale/share/birthday.py @@ -0,0 +1,37 @@ +# This file is part of Radicale Server - Calendar Server +# Copyright © 2018 Unrud +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +from radicale.share import BaseShare + + +class Share(BaseShare): + + name = "Birthday" + uuid = "a5ee648a-2240-4400-af49-a2f064ec5678" + group = "birthday" + tags = ("VCALENDAR",) + item_writethrough = False + + def get(self, item): + return None + + def get_meta(self, props, base_props): + return { + "tag": "VCALENDAR", + } + + def set_meta(self, props, old_props, old_base_props): + return old_props, old_base_props diff --git a/radicale/share/read.py b/radicale/share/read.py new file mode 100644 index 000000000..de0d7b94e --- /dev/null +++ b/radicale/share/read.py @@ -0,0 +1,36 @@ +# This file is part of Radicale Server - Calendar Server +# Copyright © 2018 Unrud +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +from radicale.share import BaseShare + + +class Share(BaseShare): + + name = "Read" + uuid = "0d41f7f1-4d93-41e7-98ce-0f2069d6773a" + group = "" + + tags = ("VADDRESSBOOK", "VCALENDAR") + item_writethrough = False + + def get(self, item): + return item + + def get_meta(self, props, base_props): + return base_props + + def set_meta(self, props, old_props, old_base_props): + return old_props, old_base_props diff --git a/radicale/share/write.py b/radicale/share/write.py new file mode 100644 index 000000000..9a059dae5 --- /dev/null +++ b/radicale/share/write.py @@ -0,0 +1,36 @@ +# This file is part of Radicale Server - Calendar Server +# Copyright © 2018 Unrud +# +# This library is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Radicale. If not, see . + +from radicale.share import BaseShare + + +class Share(BaseShare): + + name = "Write" + uuid = "d3027b80-9624-4d88-9aa0-382e9bcd92ad" + group = "" + + tags = ("VADDRESSBOOK", "VCALENDAR") + item_writethrough = True + + def get(self, item): + return item + + def get_meta(self, props, base_props): + return base_props + + def set_meta(self, props, old_props, old_base_props): + return old_props, props