Initial commit
This commit is contained in:
commit
9de30d0cbf
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
auth.yaml
|
||||
data.yaml
|
10
auth.yaml.example
Normal file
10
auth.yaml.example
Normal 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
119
sync.py
Normal 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)
|
||||
|
Loading…
Reference in New Issue
Block a user