Initial commit

master
Valentin Ochs 2020-07-17 21:38:56 +02:00
commit 9de30d0cbf
3 changed files with 131 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
auth.yaml
data.yaml

10
auth.yaml.example Normal file
View File

@ -0,0 +1,10 @@
logins:
test_login:
password: hoarse_battery_steeple
url: https://example.com/remote.php/dav
user: root
cals:
- login: test_login
url: https://example.com/remote.php/dav/calendars/root/cal_1
- login: test_login
url: https://example.com/remote.php/dav/calendars/root/cal_2

119
sync.py Normal file
View File

@ -0,0 +1,119 @@
import yaml
import caldav
import sys
with open('auth.yaml') as f:
auth = yaml.full_load(f)
try:
with open('data.yaml') as f:
known = yaml.full_load(f)
except:
known = {}
logins = {}
for login, content in auth['logins'].items():
logins[login] = caldav.DAVClient(url=content['url'], username=content['user'], password=content['password'])
cals = []
for cal in auth['cals']:
cals.append(caldav.Calendar(client = logins[cal['login']], url = cal['url']))
new = {}
changed = {}
deleted = {}
def cal_contains_uid(cal, uid):
try:
event = cal.event_by_uid(uid)
return True
except caldav.lib.error.NotFoundError:
return False
for cal in cals:
for event in cal.events():
uid = event.vobject_instance.vevent.uid.value
data = event.data
entry = (cal.canonical_url, data)
if uid not in known:
if uid not in new:
new[uid] = [entry]
else:
new[uid].append(entry)
else:
if data != known[uid]:
if uid not in changed:
changed[uid] = [entry]
else:
changed[uid].append(entry)
for uid, data in known.items():
for cal in cals:
if not cal_contains_uid(cal, uid):
if uid not in deleted:
deleted[uid] = [cal.canonical_url]
else:
deleted[uid].append(cal.canonical_url)
print("New:")
print(new)
print()
print("Changed:")
print(changed)
print()
print("Deleted:")
print(deleted)
print()
for uid, arr in new.items():
if len(set([entry[1] for entry in arr])) != 1:
print("Multiple new entries with the same UID (%s) detected:" % (uid,), file=sys.stderr)
for ev in arr:
print(" %s: %s" % (ev[0], ev[1].vobject_instance.vevent.summary.value), file = sys.stderr)
print("", file=sys.stderr)
continue
entry = arr[0]
known_cals = [ entry[0] for entry in arr ]
for cal in cals:
if cal.canonical_url not in known_cals:
cal.save_event(entry[1], no_overwrite=True)
known[uid] = entry[1]
for uid, arr in changed.items():
if uid in deleted:
print("Changed entry with UID (%s) and was also deleted:" % (uid, ), file=sys.stderr)
print("Deletions in:", file=sys.stderr)
for cal in deleted[uid]:
print(" - %s" % (cal,), file=sys.stderr)
print("Changes in:", file=sys.stderr)
for entry in arr:
print(" - %s" % (entry[0],), file=sys.stderr)
print("", file=sys.stderr)
continue
if len(set([entry[1] for entry in arr])) != 1:
print("Multiple changed entries with the same UID (%s) detected:" % (uid,), file=sys.stderr)
for ev in arr:
print(" %s: %s" % (ev[0], ev[1].vobject_instance.vevent.summary.value), file = sys.stderr)
del deleted[uid]
continue
entry = arr[0]
changed_cals = [ entry[0] for entry in arr ]
for cal in cals:
if cal.canonical_url not in changed_cals:
cal.save_event(entry[1], no_create=True)
known[uid] = entry[1]
for uid in deleted:
for cal in cals:
try:
cal.event_by_uid(uid).delete()
except:
pass
print(known)
with open("data.yaml", "w") as f:
yaml.dump(known, f)