diff --git a/app-hooks/post-installation/install-calendar-app.sh b/app-hooks/post-installation/install-calendar-app.sh index e0c9d66..eb142a1 100755 --- a/app-hooks/post-installation/install-calendar-app.sh +++ b/app-hooks/post-installation/install-calendar-app.sh @@ -9,15 +9,11 @@ php /var/www/html/occ app:enable calendar # Wait for calendar app to be fully initialized echo "Waiting for calendar app to initialize..." -sleep 10 +sleep 5 # Ensure maintenance mode is off before calendar operations php /var/www/html/occ maintenance:mode --off -# Create a default calendar for the admin user (may already exist, ignore errors) -echo "Creating default calendar..." -php /var/www/html/occ dav:create-calendar admin personal "Personal" "Default personal calendar" || true - # Sync DAV system to ensure proper initialization echo "Syncing DAV system..." php /var/www/html/occ dav:sync-system-addressbook @@ -28,6 +24,6 @@ php /var/www/html/occ maintenance:repair --include-expensive # Final wait to ensure CalDAV service is fully ready echo "Final CalDAV initialization wait..." -sleep 10 +sleep 5 echo "Calendar app installation complete!" diff --git a/nextcloud_mcp_server/client/calendar.py b/nextcloud_mcp_server/client/calendar.py index b75e5a9..f75278e 100644 --- a/nextcloud_mcp_server/client/calendar.py +++ b/nextcloud_mcp_server/client/calendar.py @@ -1,6 +1,5 @@ """CalDAV client for NextCloud calendar operations.""" -import asyncio import xml.etree.ElementTree as ET import datetime as dt from typing import Dict, Any, List, Optional, Tuple @@ -46,23 +45,10 @@ class CalendarClient(BaseNextcloudClient): "Accept": "application/xml", } - # Retry logic for CalDAV initialization issues - max_retries = 3 - for attempt in range(max_retries): - try: - response = await self._client.request( - "PROPFIND", caldav_path, content=propfind_body, headers=headers - ) - response.raise_for_status() - break - except HTTPStatusError as e: - if e.response.status_code == 401 and attempt < max_retries - 1: - logger.warning( - f"CalDAV auth failed (attempt {attempt + 1}/{max_retries}), retrying in 2s..." - ) - await asyncio.sleep(2) - continue - raise + response = await self._client.request( + "PROPFIND", caldav_path, content=propfind_body, headers=headers + ) + response.raise_for_status() # Parse XML response root = ET.fromstring(response.content) diff --git a/tests/integration/test_calendar_operations.py b/tests/integration/test_calendar_operations.py index 2ac0239..31ff512 100644 --- a/tests/integration/test_calendar_operations.py +++ b/tests/integration/test_calendar_operations.py @@ -26,23 +26,34 @@ async def temporary_calendar(nc_client: NextcloudClient, test_calendar_name: str calendar_name = test_calendar_name try: - # Create a test calendar if possible - # Note: Calendar creation might require admin permissions - # For now, we'll use an existing calendar or create events in default calendar + # Create a test calendar + logger.info(f"Creating temporary calendar: {calendar_name}") + result = await nc_client.calendar.create_calendar( + calendar_name=calendar_name, + display_name=f"Test Calendar {calendar_name}", + description="Temporary calendar for integration testing", + color="#FF5722", + ) - # Try to find an existing calendar to use - calendars = await nc_client.calendar.list_calendars() - if calendars: - calendar_name = calendars[0]["name"] - logger.info(f"Using existing calendar: {calendar_name}") - yield calendar_name - else: - pytest.skip("No calendars available for testing") + if result["status_code"] not in [200, 201]: + pytest.skip(f"Failed to create temporary calendar: {result}") + + logger.info(f"Created temporary calendar: {calendar_name}") + yield calendar_name except Exception as e: logger.error(f"Error setting up temporary calendar: {e}") pytest.skip(f"Calendar setup failed: {e}") + finally: + # Cleanup: Delete the temporary calendar + try: + logger.info(f"Cleaning up temporary calendar: {calendar_name}") + await nc_client.calendar.delete_calendar(calendar_name) + logger.info(f"Successfully deleted temporary calendar: {calendar_name}") + except Exception as e: + logger.error(f"Error deleting temporary calendar {calendar_name}: {e}") + @pytest.fixture async def temporary_event(nc_client: NextcloudClient, temporary_calendar: str): @@ -236,11 +247,14 @@ async def test_list_events_in_range(nc_client: NextcloudClient, temporary_event: calendar_name = temporary_event["calendar_name"] # Get events for the next week - start_date = datetime.now().strftime("%Y%m%dT000000Z") - end_date = (datetime.now() + timedelta(days=7)).strftime("%Y%m%dT235959Z") + start_datetime = datetime.now() + end_datetime = datetime.now() + timedelta(days=7) events = await nc_client.calendar.get_calendar_events( - calendar_name=calendar_name, start_date=start_date, end_date=end_date, limit=50 + calendar_name=calendar_name, + start_datetime=start_datetime, + end_datetime=end_datetime, + limit=50, ) assert isinstance(events, list)