From 8118c0645e5fe502d82f075181eec839d28390bf Mon Sep 17 00:00:00 2001 From: midas Date: Sat, 12 Jul 2025 08:52:17 +0000 Subject: [PATCH] library/calendar_sync.py aktualisiert --- library/calendar_sync.py | 111 ++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 31 deletions(-) diff --git a/library/calendar_sync.py b/library/calendar_sync.py index 705134e..0e9c037 100644 --- a/library/calendar_sync.py +++ b/library/calendar_sync.py @@ -5,16 +5,33 @@ from caldav import DAVClient import vobject import requests from urllib.parse import urlparse +import logging + +# Logging für Debugging einrichten +logging.basicConfig(level=logging.WARNING) def fetch_ics_events(url, user=None, password=None): try: response = requests.get(url, auth=(user, password) if user else None) response.raise_for_status() events = [] - for calendar in vobject.readComponents(response.text): - for component in calendar.components(): - if component.name == 'VEVENT': - events.append(component) + ics_data = response.text + + # Debug-Ausgabe für ungültige Daten + if not ics_data.strip(): + logging.warning("Leere ICS-Daten empfangen") + return events + + try: + for calendar in vobject.readComponents(ics_data): + for component in calendar.components(): + if component.name == 'VEVENT': + if hasattr(component, 'uid') and component.uid.value: + events.append(component) + else: + logging.warning("VEVENT ohne UID übersprungen") + except vobject.base.ParseError as e: + logging.error(f"Parse-Fehler in ICS-Daten: {str(e)}") return events except Exception as e: raise Exception(f"ICS-Fehler: {str(e)}") @@ -37,6 +54,27 @@ def connect_caldav(url, user=None, password=None, verify_ssl=True): except Exception as e: raise Exception(f"CalDAV-Fehler: {str(e)}") +def safe_caldav_event_processing(event): + try: + if event is None or not hasattr(event, 'data') or not event.data: + return None + + for calendar in vobject.readComponents(event.data): + for component in calendar.components(): + if component.name == 'VEVENT' and hasattr(component, 'uid'): + return { + 'uid': str(component.uid), + 'event_object': event, + 'data': event.data + } + return None + except vobject.base.ParseError: + logging.warning("Parse-Fehler in CalDAV-Event, überspringe") + return None + except Exception as e: + logging.error(f"Fehler bei Event-Verarbeitung: {str(e)}") + return None + def sync_ics_to_caldav(module): ics_events = fetch_ics_events( module.params['source_url'], @@ -53,43 +91,54 @@ def sync_ics_to_caldav(module): existing_events = {} for event in target_cal.events(): - if event is None: - continue - data = getattr(event, 'data', None) - if not data: - continue - try: - for calendar in vobject.readComponents(data): - for component in calendar.components(): - if component.name == 'VEVENT' and hasattr(component, 'uid'): - uid = str(component.uid) - existing_events[uid] = event - except Exception: - continue + processed = safe_caldav_event_processing(event) + if processed: + existing_events[processed['uid']] = processed changed = False results = {'added': [], 'updated': [], 'removed': []} for vevent in ics_events: uid = str(vevent.uid) - ical_data = vevent.serialize() + try: + ical_data = vevent.serialize() + except Exception as e: + logging.error(f"Serialisierungsfehler für UID {uid}: {str(e)}") + continue + + if not ical_data.strip(): + logging.warning(f"Leere iCal-Daten für UID {uid}, überspringe") + continue if uid not in existing_events: - target_cal.add_event(ical_data) - results['added'].append(uid) - changed = True - elif ical_data != existing_events[uid].data: - existing_events[uid].data = ical_data - existing_events[uid].save() - results['updated'].append(uid) - changed = True + try: + target_cal.add_event(ical_data) + results['added'].append(uid) + changed = True + except Exception as e: + logging.error(f"Hinzufügen fehlgeschlagen für UID {uid}: {str(e)}") + else: + existing_data = existing_events[uid]['data'] + if ical_data != existing_data: + try: + event_obj = existing_events[uid]['event_object'] + event_obj.data = ical_data + event_obj.save() + results['updated'].append(uid) + changed = True + except Exception as e: + logging.error(f"Aktualisieren fehlgeschlagen für UID {uid}: {str(e)}") if module.params['purge']: current_uids = {str(e.uid) for e in ics_events} - for uid in set(existing_events.keys()) - current_uids: - existing_events[uid].delete() - results['removed'].append(uid) - changed = True + for uid, event_info in existing_events.items(): + if uid not in current_uids: + try: + event_info['event_object'].delete() + results['removed'].append(uid) + changed = True + except Exception as e: + logging.error(f"Löschen fehlgeschlagen für UID {uid}: {str(e)}") return changed, results @@ -114,4 +163,4 @@ def run_module(): module.fail_json(msg=str(e)) if __name__ == '__main__': - run_module() + run_module() \ No newline at end of file