Files
2026-03-02 20:27:10 +01:00

117 lines
3.6 KiB
Python

# streaming_providers/base/models/event.py
from dataclasses import dataclass
from datetime import datetime, timezone
from enum import Enum
from typing import Dict, List, Optional
from .content import Content
class EventStatus(Enum):
SCHEDULED = "SCHEDULED"
LIVE = "LIVE"
ENDED = "ENDED"
CANCELLED = "CANCELLED"
@dataclass
class Event(Content):
"""
Represents a one-time live or scheduled event (concert, sports match, etc.)
"""
start_time: Optional[datetime] = None
end_time: Optional[datetime] = None
status: EventStatus = EventStatus.SCHEDULED
subtitle: Optional[str] = None # secondaryTitle
original_name: Optional[str] = None # originalName
competition: Optional[str] = None # txCompetition
venue: Optional[str] = None # txEvent
gender: Optional[str] = None # txGender
discipline: Optional[str] = None # txDiscipline
age_category: Optional[str] = None # txAge
master_event: Optional[str] = None # txMaster-sporting-event
channel: Optional[str] = None # primaryChannel
def __post_init__(self):
if self.status == EventStatus.SCHEDULED and self.start_time and self.end_time:
now = datetime.now(timezone.utc)
if self.start_time <= now <= self.end_time:
self.status = EventStatus.LIVE
elif now > self.end_time:
self.status = EventStatus.ENDED
# Semantic alias
@property
def event_id(self) -> str:
return self.content_id
@event_id.setter
def event_id(self, value: str):
self.content_id = value
@property
def is_live(self) -> bool:
return self.status == EventStatus.LIVE
@property
def is_upcoming(self) -> bool:
return self.status == EventStatus.SCHEDULED
@property
def duration_minutes(self) -> Optional[int]:
if self.start_time and self.end_time:
return int((self.end_time - self.start_time).total_seconds() / 60)
return None
def to_dict(self) -> Dict:
result = super().to_dict()
result.update({
"StartTime": self.start_time.isoformat() if self.start_time else None,
"EndTime": self.end_time.isoformat() if self.end_time else None,
"Status": self.status.value,
"DurationMinutes": self.duration_minutes,
})
return result
def validate(self) -> List[str]:
warnings = []
if not self.manifest and not self.manifest_script:
warnings.append("No manifest URL or manifest script provided")
if self.license_url and not self.drm_config:
warnings.append("License URL provided but no DRM configuration")
if self.start_time and self.end_time and self.start_time >= self.end_time:
warnings.append("start_time must be before end_time")
return warnings
# Factory methods
@classmethod
def create_live_event(
cls, name: str, event_id: str, provider: str, **kwargs
) -> "Event":
return cls(
name=name,
content_id=event_id,
provider=provider,
status=EventStatus.LIVE,
**kwargs,
)
@classmethod
def create_scheduled_event(
cls,
name: str,
event_id: str,
provider: str,
start_time: datetime,
end_time: datetime,
**kwargs,
) -> "Event":
return cls(
name=name,
content_id=event_id,
provider=provider,
start_time=start_time,
end_time=end_time,
**kwargs,
)