Initial Home Assistant commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
""" Base class for all data providers """
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .coordinator import TeamTrackerCoordinator
|
||||
|
||||
DEFAULT_DATA_FORMAT = "espn_json"
|
||||
|
||||
class BaseSportProvider(ABC):
|
||||
"""Base class for all sport data providers."""
|
||||
|
||||
def __init__(self, coordinator: TeamTrackerCoordinator | None = None) -> None:
|
||||
# Define the attributes that must be available on all providers
|
||||
self.DATA_PROVIDER: str = "default"
|
||||
self.ATTRIBUTION: str = ""
|
||||
self.DEFAULT_REFRESH_RATE: timedelta = timedelta(minutes=10)
|
||||
self.RAPID_REFRESH_RATE: timedelta = timedelta(seconds=5)
|
||||
self.data_format = DEFAULT_DATA_FORMAT
|
||||
self._coordinator = coordinator
|
||||
if self._coordinator:
|
||||
self.data_cache = self._coordinator.hass.data.setdefault(DOMAIN, {}).setdefault("data_cache", {})
|
||||
else: # coordinator is None when called from Config Flow
|
||||
self.data_cache = {}
|
||||
self._USER_AGENT = (
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 11_6) AppleWebKit/605.1.15 (KHTML, like "
|
||||
"Gecko) Version/15.0 Safari/605.1.15"
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# async_update_sport_data()
|
||||
#
|
||||
async def async_update_sport_data(self) -> dict:
|
||||
"""Determines to use cached data or API call (if exprired)"""
|
||||
|
||||
if not self._coordinator:
|
||||
return {"data": None, "url": None, "timestamp": None}
|
||||
#
|
||||
# Return cached response if not expired
|
||||
#
|
||||
key = self._get_cache_key()
|
||||
response = self.data_cache.get(key, {}).get("response", None)
|
||||
if response:
|
||||
expiration = datetime.fromisoformat(response["timestamp"]) + self._coordinator.update_interval
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
if now < expiration:
|
||||
response.update({"cache_flag": True}) # Add key to indicate cache was used
|
||||
return response
|
||||
|
||||
#
|
||||
# Call API to get refreshed response and cache it
|
||||
#
|
||||
response = await self.async_fetch_scoreboard_data(self._coordinator.hass, self._coordinator.get_lang())
|
||||
if response["data"] is not None:
|
||||
self.data_cache.update({key: {"response": response}})
|
||||
|
||||
return response
|
||||
|
||||
|
||||
#
|
||||
# _get_cache_key()
|
||||
#
|
||||
@abstractmethod
|
||||
def _get_cache_key(self) -> str:
|
||||
"""Return cache key"""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
|
||||
@abstractmethod
|
||||
async def async_fetch_team_data(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
sport_path: str="",
|
||||
league_path: str=""
|
||||
) -> dict:
|
||||
"""Fetch and return team data in the standard format."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
@abstractmethod
|
||||
async def async_fetch_scoreboard_data(
|
||||
self,
|
||||
hass,
|
||||
lang: str,
|
||||
) -> dict:
|
||||
"""Fetch and return sport data in the standard format."""
|
||||
pass # pylint: disable=unnecessary-pass
|
||||
|
||||
async def async_fetch_team_conference_id(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
sport_path: str,
|
||||
league_path: str,
|
||||
team_id: str
|
||||
) -> str:
|
||||
"""Fetch conference/group ID for a single team from the ESPN team detail API."""
|
||||
return ""
|
||||
Reference in New Issue
Block a user