diff --git a/sync_calendar.py b/sync_calendar.py index f428e0b..5f4c6f5 100644 --- a/sync_calendar.py +++ b/sync_calendar.py @@ -4,6 +4,7 @@ from caldav.elements import dav, cdav from datetime import datetime import os import time +import concurrent.futures # --- CONFIGURACIÓN --- # Default to 5 minutes @@ -17,12 +18,48 @@ ICS_URL = os.getenv("ICS_URL") BAIKAL_URL = os.getenv("BAIKAL_URL") BAIKAL_USER = os.getenv("BAIKAL_USER") BAIKAL_PASS = os.getenv("BAIKAL_PASS") +CALENDAR_ID = os.getenv("CALENDAR_ID") # Headers para parecer un navegador real y evitar 'Connection Reset' HEADERS = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Unraid-Sync/1.0" } +def delete_event(event): + """Helper function to delete a single event.""" + try: + event.delete() + return True + except Exception as e: + print(f"!!! Error deleting event {event}: {e}") + return False + +def delete_all_events(calendar): + """ + Deletes all events in the calendar as fast as possible using threads. + """ + print("-> Buscando eventos para borrar...") + try: + events = calendar.events() + except Exception as e: + print(f"!!! Error al obtener eventos: {e}") + return + + total_events = len(events) + if total_events == 0: + print("-> El calendario ya está vacío.") + return + + print(f"-> Borrando {total_events} eventos rápidamente...") + + # Usamos ThreadPoolExecutor para borrar en paralelo + deleted_count = 0 + with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor: + results = list(executor.map(delete_event, events)) + deleted_count = results.count(True) + + print(f"-> Limpieza completada. Borrados {deleted_count}/{total_events} eventos.") + def sync(): if not all([ICS_URL, BAIKAL_URL, BAIKAL_USER, BAIKAL_PASS]): print(f"[{datetime.now()}] !!! Error: Faltan variables de entorno. Asegúrate de configurar ICS_URL, BAIKAL_URL, BAIKAL_USER y BAIKAL_PASS.") @@ -54,22 +91,42 @@ def sync(): principal = client.principal() calendars = principal.calendars() - # Buscar el calendario correcto o usar el primero que encuentre en esa URL - if calendars: - calendar = calendars[0] - print(f"-> Calendario encontrado: {calendar}") + # Buscar el calendario correcto por ID si se proporciona + calendar = None + if CALENDAR_ID: + print(f"-> Buscando calendario con ID: {CALENDAR_ID}") + for cal in calendars: + # Comprobamos si el ID está en la URL del calendario + if CALENDAR_ID in str(cal.url): + calendar = cal + break + + if not calendar: + print(f"!!! Error: No se encontró ningún calendario con el ID '{CALENDAR_ID}'. Calendarios disponibles:") + for c in calendars: + print(f" - {c.url}") + return else: - print("!!! No se encontró ningún calendario en esa URL.") - return + # Si no hay ID, usar el primero como antes + if calendars: + calendar = calendars[0] + else: + print("!!! No se encontró ningún calendario en esa URL.") + return - # 3. Importar eventos + print(f"-> Calendario seleccionado: {calendar}") + + # 3. Borrar eventos antiguos (NUEVO) + delete_all_events(calendar) + + # 4. Importar eventos print("-> Procesando archivo ICS...") from icalendar import Calendar cal = Calendar.from_ical(ics_data) events = cal.walk('vevent') total_events = len(events) - print(f"-> Encontrados {total_events} eventos.") + print(f"-> Encontrados {total_events} eventos para importar.") success_count = 0 error_count = 0