library/calendar_sync.py aktualisiert

This commit is contained in:
2025-04-30 09:28:44 +00:00
parent 80ebb92a01
commit 795191292d

View File

@ -4,19 +4,22 @@ from ansible.module_utils.basic import AnsibleModule
from caldav import DAVClient from caldav import DAVClient
import vobject import vobject
def connect_calendar(url, user=None, password=None): def connect_calendar(url, user=None, password=None, verify_ssl=True):
# Verbindung zum Kalender herstellen try:
client = DAVClient(url, username=user, password=password) if user else DAVClient(url) client = DAVClient(
principal = client.principal() url,
calendars = principal.calendars() username=user,
password=password,
if not calendars: ssl_verify_cert=verify_ssl
raise Exception(f"Kein Kalender unter {url} gefunden") )
calendar = client.calendar(url=url)
return calendars[0] # Test-Zugriff um sicherzustellen, dass der Kalender existiert
calendar.get_properties(['displayname'])
return calendar
except Exception as e:
raise Exception(f"Kalenderverbindung fehlgeschlagen: {str(e)}")
def get_event_uid_map(calendar): def get_event_uid_map(calendar):
# Mapping der Ereignis-UIDs zu den Events erstellen
uid_map = {} uid_map = {}
for event in calendar.events(): for event in calendar.events():
try: try:
@ -24,31 +27,32 @@ def get_event_uid_map(calendar):
uid = cal.vevent.uid.value uid = cal.vevent.uid.value
uid_map[uid] = event uid_map[uid] = event
except Exception as e: except Exception as e:
continue # Fehler bei einem Event überspringen continue # Fehlerhafte Events überspringen
return uid_map return uid_map
def sync_calendars(source_cal, target_cal): def sync_calendars(source_cal, target_cal):
# Kalender synchronisieren
src_events = get_event_uid_map(source_cal) src_events = get_event_uid_map(source_cal)
tgt_events = get_event_uid_map(target_cal) tgt_events = get_event_uid_map(target_cal)
changed = False changed = False
added, updated, removed = [], [], [] added, updated, removed = [], [], []
# Neue und aktualisierte Ereignisse hinzufügen # Neue/aktualisierte Events
for uid, src_event in src_events.items(): for uid, src_event in src_events.items():
tgt_event = tgt_events.get(uid)
src_data = src_event.data src_data = src_event.data
if uid not in tgt_events:
if not tgt_event:
target_cal.add_event(src_data) target_cal.add_event(src_data)
added.append(uid) added.append(uid)
changed = True changed = True
elif src_data != tgt_events[uid].data: elif src_data != tgt_event.data:
tgt_events[uid].delete() tgt_event.data = src_data
target_cal.add_event(src_data) tgt_event.save()
updated.append(uid) updated.append(uid)
changed = True changed = True
# Entfernte Ereignisse löschen # Entfernte Events löschen
for uid in set(tgt_events.keys()) - set(src_events.keys()): for uid in set(tgt_events.keys()) - set(src_events.keys()):
tgt_events[uid].delete() tgt_events[uid].delete()
removed.append(uid) removed.append(uid)
@ -57,39 +61,59 @@ def sync_calendars(source_cal, target_cal):
return changed, added, updated, removed return changed, added, updated, removed
def run_module(): def run_module():
# Definieren der Moduleingaben
module_args = dict( module_args = dict(
source_url=dict(type='str', required=True), source_url=dict(type='str', required=True),
source_user=dict(type='str', required=False, default=None), source_user=dict(type='str', required=False, default=None),
source_password=dict(type='str', required=False, no_log=True, default=None), source_password=dict(type='str', required=False, no_log=True, default=None),
target_url=dict(type='str', required=True), target_url=dict(type='str', required=True),
target_user=dict(type='str', required=False, default=None), target_user=dict(type='str', required=False, default=None),
target_password=dict(type='str', required=False, no_log=True, default=None) target_password=dict(type='str', required=False, no_log=True, default=None),
verify_ssl=dict(type='bool', required=False, default=True)
) )
result = dict(changed=False) module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=False
)
module = AnsibleModule(argument_spec=module_args, supports_check_mode=False) result = dict(
changed=False,
added=[],
updated=[],
removed=[]
)
try: try:
# Verbindung zu den Kalendern herstellen # Kalender verbinden
source_cal = connect_calendar(module.params['source_url'], module.params['source_user'], module.params['source_password']) source_cal = connect_calendar(
target_cal = connect_calendar(module.params['target_url'], module.params['target_user'], module.params['target_password']) url=module.params['source_url'],
user=module.params['source_user'],
password=module.params['source_password'],
verify_ssl=module.params['verify_ssl']
)
target_cal = connect_calendar(
url=module.params['target_url'],
user=module.params['target_user'],
password=module.params['target_password'],
verify_ssl=module.params['verify_ssl']
)
# Kalender synchronisieren # Synchronisation durchführen
changed, added, updated, removed = sync_calendars(source_cal, target_cal) changed, added, updated, removed = sync_calendars(source_cal, target_cal)
result.update({ result.update({
"changed": changed, 'changed': changed,
"added": added, 'added': added,
"updated": updated, 'updated': updated,
"removed": removed, 'removed': removed,
'msg': f"Synchronisiert: +{len(added)}/~{len(updated)}/-{len(removed)}"
}) })
except Exception as e: except Exception as e:
module.fail_json(msg=str(e), **result) module.fail_json(msg=f"Fehler bei der Synchronisation: {str(e)}", **result)
module.exit_json(**result) module.exit_json(**result)
if __name__ == '__main__': if __name__ == '__main__':
run_module() run_module()