Files
script.service.ultimate/lib/streaming_providers/base/recording_operations.py
T
2026-03-20 11:50:53 +01:00

148 lines
4.8 KiB
Python

# streaming_providers/base/recording_operations.py
"""
Recording-related operations separated from core registry.
Mirrors the structure of EventOperations.
"""
from typing import Dict, List, Optional
from .models.recording import Recording
from .utils.logger import logger
class RecordingOperations:
"""Handles all recording-related operations."""
def __init__(self, registry):
self.registry = registry
logger.debug("RecordingOperations: Initialized")
def get_recordings(
self,
provider_name: str,
include_deleted: bool = False,
) -> List[Recording]:
"""
Get recordings from a specific provider.
Args:
provider_name: Name of the provider to query.
include_deleted: If True, include recordings marked as deleted.
Returns:
List of Recording objects.
Raises:
ValueError: If the provider is not found or disabled.
"""
provider = self.registry.get_provider(provider_name)
if not provider:
raise ValueError(f"Provider '{provider_name}' not found or disabled")
recordings = provider.get_recordings(include_deleted=include_deleted)
if not include_deleted:
recordings = [r for r in recordings if not r.is_deleted]
logger.info(
f"Retrieved {len(recordings)} recordings from '{provider_name}'"
)
return recordings
def get_all_recordings(
self,
include_deleted: bool = False,
) -> Dict[str, List[Recording]]:
"""
Get recordings from all enabled providers.
Args:
include_deleted: If True, include recordings marked as deleted.
Returns:
Dict mapping provider name → list of Recording objects.
"""
enabled = self.registry.get_enabled_providers()
logger.info(f"Fetching recordings from {len(enabled)} providers")
result = {}
total = 0
for name in enabled:
try:
recordings = self.get_recordings(
name, include_deleted=include_deleted
)
result[name] = recordings
total += len(recordings)
except Exception as e:
logger.error(f"Failed to get recordings from '{name}': {e}")
result[name] = []
logger.info(f"Retrieved {total} total recordings")
return result
def get_recording_manifest(
self, provider_name: str, recording_id: str, **kwargs
) -> Optional[str]:
"""
Get manifest URL for a specific recording.
Delegates to provider.get_manifest() — the same method used for
channels and events — because manifest resolution is content-type-agnostic.
Args:
provider_name: Name of the provider.
recording_id: Recording identifier (== content_id on the model).
**kwargs: Additional provider-specific arguments.
Returns:
Manifest URL string, or None if unavailable.
Raises:
ValueError: If the provider is not found or disabled.
"""
provider = self.registry.get_provider(provider_name)
if not provider:
raise ValueError(f"Provider '{provider_name}' not found or disabled")
manifest_url = provider.get_manifest(content_id=recording_id, **kwargs)
if manifest_url:
logger.debug(
f"Retrieved manifest for recording '{recording_id}' "
f"from '{provider_name}'"
)
return manifest_url
def delete_recording(
self, provider_name: str, recording_id: str, **kwargs
) -> None:
"""
Permanently delete a recording on the provider.
Delegates to provider.delete_recording(recording_id). The provider is
responsible for the actual API call; this layer only resolves the
provider instance and handles registry-level errors.
Args:
provider_name: Name of the provider.
recording_id: Recording identifier (== content_id on the model).
**kwargs: Additional provider-specific arguments.
Returns:
None on success.
Raises:
ValueError: If the provider is not found or disabled.
KeyError: If the recording does not exist on the provider.
RuntimeError: If the provider rejects the deletion (e.g. permission
denied, recording currently in progress).
"""
provider = self.registry.get_provider(provider_name)
if not provider:
raise ValueError(f"Provider '{provider_name}' not found or disabled")
provider.delete_recording(recording_id, **kwargs)
logger.info(
f"Deleted recording '{recording_id}' from '{provider_name}'"
)