From 9b6766e83dd0ffd5602c11e3a787cc4efb8551c4 Mon Sep 17 00:00:00 2001 From: Nirvana Date: Sat, 28 Feb 2026 23:20:41 +0100 Subject: [PATCH] Add discovery --- .../base/event_operations.py | 58 ++++++++++ routes/events.py | 102 ++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 lib/streaming_providers/base/event_operations.py create mode 100644 routes/events.py diff --git a/lib/streaming_providers/base/event_operations.py b/lib/streaming_providers/base/event_operations.py new file mode 100644 index 0000000..57fe2f3 --- /dev/null +++ b/lib/streaming_providers/base/event_operations.py @@ -0,0 +1,58 @@ +# ============================================================================ +# streaming_providers/base/event_operations.py +""" +Event-related operations separated from core registry. +""" + +from datetime import datetime +from typing import Dict, List, Optional + +from .models import Event +from .utils.logger import logger + + +class EventOperations: + """Handles all event-related operations.""" + + def __init__(self, registry): + self.registry = registry + logger.debug("EventOperations: Initialized") + + def get_events( + self, + provider_name: str, + start_time: Optional[datetime] = None, + end_time: Optional[datetime] = None, + ) -> List[Event]: + """Get events from a specific provider.""" + provider = self.registry.get_provider(provider_name) + if not provider: + raise ValueError(f"Provider '{provider_name}' not found or disabled") + + events = provider.get_events(start_time=start_time, end_time=end_time) + logger.info(f"Retrieved {len(events)} events from '{provider_name}'") + return events + + def get_all_events( + self, + start_time: Optional[datetime] = None, + end_time: Optional[datetime] = None, + ) -> Dict[str, List[Event]]: + """Get events from all enabled providers.""" + enabled = self.registry.get_enabled_providers() + logger.info(f"Fetching events from {len(enabled)} providers") + + result = {} + total = 0 + + for name in enabled: + try: + events = self.get_events(name, start_time, end_time) + result[name] = events + total += len(events) + except Exception as e: + logger.error(f"Failed to get events from '{name}': {e}") + result[name] = [] + + logger.info(f"Retrieved {total} total events") + return result \ No newline at end of file diff --git a/routes/events.py b/routes/events.py new file mode 100644 index 0000000..9bb38bb --- /dev/null +++ b/routes/events.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +""" +Event-related route handlers +""" + +from datetime import datetime + +from bottle import request, response +from streaming_providers.base.utils import logger + + +def setup_events_routes(app, manager, service): + """Setup event-related routes""" + + @app.route("/api/providers//events", method="GET") + def get_provider_events(provider): + """ + Get events from a specific provider. + + Query parameters: + - start_time: Optional ISO 8601 timestamp — only return events ending after this time + - end_time: Optional ISO 8601 timestamp — only return events starting before this time + + Returns: + { + "provider": "provider_name", + "events": [ + { + ...Event fields... + } + ], + "count": 1 + } + """ + try: + # Parse optional time range query parameters + start_time = None + end_time = None + + start_time_str = request.params.get("start_time") + end_time_str = request.params.get("end_time") + + if start_time_str: + try: + start_time = datetime.fromisoformat(start_time_str) + except ValueError: + response.status = 400 + return { + "error": "Invalid start_time format", + "message": "Use ISO 8601 format, e.g. 2026-03-01T00:00:00", + } + + if end_time_str: + try: + end_time = datetime.fromisoformat(end_time_str) + except ValueError: + response.status = 400 + return { + "error": "Invalid end_time format", + "message": "Use ISO 8601 format, e.g. 2026-03-01T23:59:59", + } + + try: + events = manager.event_ops.get_events( + provider_name=provider, + start_time=start_time, + end_time=end_time, + ) + except ValueError as e: + response.status = 404 + return { + "error": "Provider not found", + "message": str(e), + "provider": provider, + } + except Exception as e: + logger.error(f"Failed to get events from '{provider}': {e}") + response.status = 500 + return { + "error": "Failed to get events", + "message": str(e), + "provider": provider, + } + + # Serialize Event objects to dicts + serialized = [event.to_dict() for event in events] + + response.status = 200 + return { + "provider": provider, + "events": serialized, + "count": len(serialized), + } + + except Exception as e: + logger.error(f"Unexpected error in get_provider_events: {e}") + response.status = 500 + return { + "error": "Internal server error", + "message": str(e), + "provider": provider, + } \ No newline at end of file