Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
> ⚠️ **Maintenance Notice:** This is an actively maintained fork of 39aldo39/Radicale-DecSync, updated for compatibility with Python 3.12+ and Radicale 3.x.
> ⚠️ **Disclaimer:** I am not adding functionality. These are bug fix and compatibility releases. Thank you for any input.

Radicale DecSync
================

Expand Down
57 changes: 39 additions & 18 deletions radicale_storage_decsync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,26 @@ def resources_listener(path, datetime, key, value, extra):
self.load_hrefs(sync_type)

def upload(self, href, orig_item, update_decsync=True):
item = super().upload(href, orig_item)
result = super().upload(href, orig_item)
if isinstance(result, tuple):
item = next((x for x in result if hasattr(x, "uid")), result[1])
else:
item = result
if update_decsync:
tag = self.get_meta("tag")
if tag == "VCALENDAR":
supported_components = (self.get_meta("C:supported-calendar-component-set") or "VEVENT,VTODO,VJOURNAL").split(",")
component_name = item.component_name
if len(supported_components) > 1 and component_name != "VEVENT":
raise RuntimeError("Component " + component_name + " is not supported by old DecSync collections. Create a new collection in Radicale for support.")
self.set_href(item.uid, href)
self.decsync.set_entry(["resources", item.uid], None, item.serialize())
return item
if hasattr(self, 'decsync'):
tag = self.get_meta("tag")
if tag == "VCALENDAR":
supported = (self.get_meta("C:supported-calendar-component-set") or "VEVENT,VTODO,VJOURNAL").split(",")
if len(supported) > 1 and item.component_name != "VEVENT":
raise RuntimeError("Component not supported by old DecSync.")
self.set_href(item.uid, href)
# Ensure structured data (lists/tuples) are stringified before serialization
for component in item.vobject_item.getChildren():
component_value = getattr(component, 'value', None)
if isinstance(component_value, (list, tuple)):
component.value = ";".join(str(x) for x in component_value)
self.decsync.set_entry(["resources", item.uid], None, item.serialize())
return result

def delete(self, href=None, update_decsync=True):
if update_decsync:
Expand Down Expand Up @@ -157,8 +166,8 @@ def __init__(self, configuration):
self.decsync_dir = ""

def discover(self, path, depth="0", child_context_manager=(
lambda path, href=None: contextlib.ExitStack())):
collections = list(super().discover(path, depth, child_context_manager))
lambda path, href=None: contextlib.ExitStack()),user_groups=set()):
collections = list(super().discover(path, depth, child_context_manager, user_groups))
for collection in collections:
yield collection

Expand All @@ -171,7 +180,11 @@ def discover(self, path, depth="0", child_context_manager=(
return
elif len(attributes) == 1:
username = attributes[0]
known_paths = [collection.path for collection in collections]
known_paths = []
for collection in collections:
if isinstance(collection, tuple):
collection = next((x for x in collection if hasattr(x, "path")), collection[0])
known_paths.append(collection.path)
for sync_type in ["contacts", "calendars", "tasks", "memos"]:
for collection in Decsync.list_collections(self.decsync_dir, sync_type):
child_path = "/%s/%s-%s/" % (username, sync_type, collection)
Expand All @@ -193,7 +206,11 @@ def discover(self, path, depth="0", child_context_manager=(
props["C:supported-calendar-component-set"] = "VJOURNAL"
else:
raise RuntimeError("Unknown sync type " + sync_type)
child = super().create_collection(child_path, props=props)
result = super().create_collection(child_path, props=props)
if isinstance(result, tuple):
child = next((x for x in result if hasattr(x, "decsync")), result[0])
else:
child = result
child.decsync.init_stored_entries()
child.decsync.execute_stored_entries_for_path_exact(["info"], child)
child.decsync.execute_stored_entries_for_path_prefix(["resources"], child)
Expand Down Expand Up @@ -246,12 +263,16 @@ def create_collection(self, href, items=None, props=None):
raise RuntimeError("Unknown tag " + tag)

if collection.startswith(sync_type + "-"):
path = "/%s/%s/" % (username, collection)
path = href
else:
path = "/%s/%s-%s/" % (username, sync_type, collection)
col = super().create_collection(path, None, props)
result = super().create_collection(path, None, props)
if isinstance(result, tuple):
col = next((x for x in result if hasattr(x, "get_href")), result[0])
else:
col = result
if items is not None:
for item in items:
href = col.get_href(item.uid)
col.upload(href, item)
return col
col.upload(href, item)
return result
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name="radicale_storage_decsync",
version="2.1.0",
version="2.1.0+diagonalarg.2",
author="Aldo Gunsing",
author_email="dev@aldogunsing.nl",
url="https://github.com/39aldo39/Radicale-DecSync",
Expand All @@ -16,7 +16,7 @@
packages=["radicale_storage_decsync"],
install_requires=[
"radicale>=3",
"libdecsync>=2.0.0"
"libdecsync @ git+https://github.com/DiagonalArg/libdecsync-bindings-python3.git@master"
],
classifiers=[
"Programming Language :: Python :: 3",
Expand Down