mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Use runtime_data in google (#144331)
* Use runtime_data in google * Quality scale
This commit is contained in:
parent
1447392847
commit
253217958b
@ -14,7 +14,6 @@ from gcal_sync.model import DateOrDatetime, Event
|
||||
import voluptuous as vol
|
||||
import yaml
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE_ID,
|
||||
CONF_ENTITIES,
|
||||
@ -34,8 +33,6 @@ from homeassistant.helpers.entity import generate_entity_id
|
||||
|
||||
from .api import ApiAuthImpl, get_feature_access
|
||||
from .const import (
|
||||
DATA_SERVICE,
|
||||
DATA_STORE,
|
||||
DOMAIN,
|
||||
EVENT_DESCRIPTION,
|
||||
EVENT_END_DATE,
|
||||
@ -50,7 +47,7 @@ from .const import (
|
||||
EVENT_TYPES_CONF,
|
||||
FeatureAccess,
|
||||
)
|
||||
from .store import LocalCalendarStore
|
||||
from .store import GoogleConfigEntry, GoogleRuntimeData, LocalCalendarStore
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -139,11 +136,8 @@ ADD_EVENT_SERVICE_SCHEMA = vol.All(
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: GoogleConfigEntry) -> bool:
|
||||
"""Set up Google from a config entry."""
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
hass.data[DOMAIN][entry.entry_id] = {}
|
||||
|
||||
# Validate google_calendars.yaml (if present) as soon as possible to return
|
||||
# helpful error messages.
|
||||
try:
|
||||
@ -181,9 +175,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
calendar_service = GoogleCalendarService(
|
||||
ApiAuthImpl(async_get_clientsession(hass), session)
|
||||
)
|
||||
hass.data[DOMAIN][entry.entry_id][DATA_SERVICE] = calendar_service
|
||||
hass.data[DOMAIN][entry.entry_id][DATA_STORE] = LocalCalendarStore(
|
||||
hass, entry.entry_id
|
||||
entry.runtime_data = GoogleRuntimeData(
|
||||
service=calendar_service,
|
||||
store=LocalCalendarStore(hass, entry.entry_id),
|
||||
)
|
||||
|
||||
if entry.unique_id is None:
|
||||
@ -207,27 +201,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def async_entry_has_scopes(entry: ConfigEntry) -> bool:
|
||||
def async_entry_has_scopes(entry: GoogleConfigEntry) -> bool:
|
||||
"""Verify that the config entry desired scope is present in the oauth token."""
|
||||
access = get_feature_access(entry)
|
||||
token_scopes = entry.data.get("token", {}).get("scope", [])
|
||||
return access.scope in token_scopes
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: GoogleConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
return unload_ok
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
|
||||
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
async def async_reload_entry(hass: HomeAssistant, entry: GoogleConfigEntry) -> None:
|
||||
"""Reload config entry if the access options change."""
|
||||
if not async_entry_has_scopes(entry):
|
||||
await hass.config_entries.async_reload(entry.entry_id)
|
||||
|
||||
|
||||
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
async def async_remove_entry(hass: HomeAssistant, entry: GoogleConfigEntry) -> None:
|
||||
"""Handle removal of a local storage."""
|
||||
store = LocalCalendarStore(hass, entry.entry_id)
|
||||
await store.async_remove()
|
||||
|
@ -17,7 +17,6 @@ from oauth2client.client import (
|
||||
)
|
||||
|
||||
from homeassistant.components.application_credentials import AuthImplementation
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from homeassistant.helpers.event import (
|
||||
@ -27,6 +26,7 @@ from homeassistant.helpers.event import (
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import CONF_CALENDAR_ACCESS, DEFAULT_FEATURE_ACCESS, FeatureAccess
|
||||
from .store import GoogleConfigEntry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -155,7 +155,7 @@ class DeviceFlow:
|
||||
self._listener()
|
||||
|
||||
|
||||
def get_feature_access(config_entry: ConfigEntry) -> FeatureAccess:
|
||||
def get_feature_access(config_entry: GoogleConfigEntry) -> FeatureAccess:
|
||||
"""Return the desired calendar feature access."""
|
||||
if config_entry.options and CONF_CALENDAR_ACCESS in config_entry.options:
|
||||
return FeatureAccess[config_entry.options[CONF_CALENDAR_ACCESS]]
|
||||
|
@ -37,7 +37,6 @@ from homeassistant.components.calendar import (
|
||||
extract_offset,
|
||||
is_offset_reached,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_DEVICE_ID, CONF_ENTITIES, CONF_NAME, CONF_OFFSET
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
from homeassistant.exceptions import HomeAssistantError, PlatformNotReady
|
||||
@ -52,7 +51,6 @@ from . import (
|
||||
CONF_SEARCH,
|
||||
CONF_TRACK,
|
||||
DEFAULT_CONF_OFFSET,
|
||||
DOMAIN,
|
||||
YAML_DEVICES,
|
||||
get_calendar_info,
|
||||
load_config,
|
||||
@ -60,8 +58,6 @@ from . import (
|
||||
)
|
||||
from .api import get_feature_access
|
||||
from .const import (
|
||||
DATA_SERVICE,
|
||||
DATA_STORE,
|
||||
EVENT_END_DATE,
|
||||
EVENT_END_DATETIME,
|
||||
EVENT_IN,
|
||||
@ -72,6 +68,7 @@ from .const import (
|
||||
FeatureAccess,
|
||||
)
|
||||
from .coordinator import CalendarQueryUpdateCoordinator, CalendarSyncUpdateCoordinator
|
||||
from .store import GoogleConfigEntry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -109,7 +106,7 @@ class GoogleCalendarEntityDescription(CalendarEntityDescription):
|
||||
|
||||
def _get_entity_descriptions(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: GoogleConfigEntry,
|
||||
calendar_item: Calendar,
|
||||
calendar_info: Mapping[str, Any],
|
||||
) -> list[GoogleCalendarEntityDescription]:
|
||||
@ -202,12 +199,12 @@ def _get_entity_descriptions(
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: GoogleConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the google calendar platform."""
|
||||
calendar_service = hass.data[DOMAIN][config_entry.entry_id][DATA_SERVICE]
|
||||
store = hass.data[DOMAIN][config_entry.entry_id][DATA_STORE]
|
||||
calendar_service = config_entry.runtime_data.service
|
||||
store = config_entry.runtime_data.store
|
||||
try:
|
||||
result = await calendar_service.async_list_calendars()
|
||||
except ApiException as err:
|
||||
|
@ -11,12 +11,7 @@ from gcal_sync.api import GoogleCalendarService
|
||||
from gcal_sync.exceptions import ApiException, ApiForbiddenException
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_REAUTH,
|
||||
ConfigEntry,
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlowResult, OptionsFlow
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import config_entry_oauth2_flow
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
@ -38,6 +33,7 @@ from .const import (
|
||||
CredentialType,
|
||||
FeatureAccess,
|
||||
)
|
||||
from .store import GoogleConfigEntry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -240,7 +236,7 @@ class OAuth2FlowHandler(
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: GoogleConfigEntry,
|
||||
) -> OptionsFlow:
|
||||
"""Create an options flow."""
|
||||
return OptionsFlowHandler()
|
||||
|
@ -9,9 +9,7 @@ DOMAIN = "google"
|
||||
CONF_CALENDAR_ACCESS = "calendar_access"
|
||||
CONF_CREDENTIAL_TYPE = "credential_type"
|
||||
DATA_CALENDARS = "calendars"
|
||||
DATA_SERVICE = "service"
|
||||
DATA_CONFIG = "config"
|
||||
DATA_STORE = "store"
|
||||
|
||||
|
||||
class FeatureAccess(Enum):
|
||||
|
@ -14,12 +14,13 @@ from gcal_sync.sync import CalendarEventSyncManager
|
||||
from gcal_sync.timeline import Timeline
|
||||
from ical.iter import SortableItemValue
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .store import GoogleConfigEntry
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15)
|
||||
@ -47,12 +48,12 @@ def _truncate_timeline(timeline: Timeline, max_events: int) -> Timeline:
|
||||
class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]):
|
||||
"""Coordinator for calendar RPC calls that use an efficient sync."""
|
||||
|
||||
config_entry: ConfigEntry
|
||||
config_entry: GoogleConfigEntry
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: GoogleConfigEntry,
|
||||
sync: CalendarEventSyncManager,
|
||||
name: str,
|
||||
) -> None:
|
||||
@ -108,12 +109,12 @@ class CalendarQueryUpdateCoordinator(DataUpdateCoordinator[list[Event]]):
|
||||
for limitations in the calendar API for supporting search.
|
||||
"""
|
||||
|
||||
config_entry: ConfigEntry
|
||||
config_entry: GoogleConfigEntry
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
config_entry: GoogleConfigEntry,
|
||||
calendar_service: GoogleCalendarService,
|
||||
name: str,
|
||||
calendar_id: str,
|
||||
|
@ -4,11 +4,10 @@ import datetime
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .const import DATA_STORE, DOMAIN
|
||||
from .store import GoogleConfigEntry
|
||||
|
||||
TO_REDACT = {
|
||||
"id",
|
||||
@ -40,7 +39,7 @@ def redact_store(data: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
hass: HomeAssistant, config_entry: GoogleConfigEntry
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
payload: dict[str, Any] = {
|
||||
@ -49,7 +48,7 @@ async def async_get_config_entry_diagnostics(
|
||||
"system_timezone": str(datetime.datetime.now().astimezone().tzinfo),
|
||||
}
|
||||
|
||||
store = hass.data[DOMAIN][config_entry.entry_id][DATA_STORE]
|
||||
data = await store.async_load()
|
||||
payload["store"] = redact_store(data)
|
||||
store = config_entry.runtime_data.store
|
||||
if data := await store.async_load():
|
||||
payload["store"] = redact_store(data)
|
||||
return payload
|
||||
|
@ -40,11 +40,7 @@ rules:
|
||||
to increase functionality such as checking for the specific contents
|
||||
of a unique id assigned to a config entry.
|
||||
docs-actions: done
|
||||
runtime-data:
|
||||
status: todo
|
||||
comment: |
|
||||
The integration stores config entry data in `hass.data` and should be
|
||||
updated to use `runtime_data`.
|
||||
runtime-data: done
|
||||
|
||||
# Silver
|
||||
log-when-unavailable: done
|
||||
|
@ -2,11 +2,14 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from gcal_sync.api import GoogleCalendarService
|
||||
from gcal_sync.store import CalendarStore
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.storage import Store
|
||||
|
||||
@ -19,6 +22,16 @@ STORAGE_VERSION = 1
|
||||
# Buffer writes every few minutes (plus guaranteed to be written at shutdown)
|
||||
STORAGE_SAVE_DELAY_SECONDS = 120
|
||||
|
||||
type GoogleConfigEntry = ConfigEntry[GoogleRuntimeData]
|
||||
|
||||
|
||||
@dataclass
|
||||
class GoogleRuntimeData:
|
||||
"""Google runtime data."""
|
||||
|
||||
service: GoogleCalendarService
|
||||
store: LocalCalendarStore
|
||||
|
||||
|
||||
class LocalCalendarStore(CalendarStore):
|
||||
"""Storage for local persistence of calendar and event data."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user