mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 22:57:17 +00:00
Show all YouTube subscriptions in config flow (#94287)
This commit is contained in:
parent
48776f86dc
commit
6a85e227db
@ -1,7 +1,7 @@
|
|||||||
"""Config flow for YouTube integration."""
|
"""Config flow for YouTube integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import AsyncGenerator, Mapping
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@ -31,6 +31,24 @@ from .const import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def _get_subscriptions(hass: HomeAssistant, resource: Resource) -> AsyncGenerator:
|
||||||
|
amount_of_subscriptions = 50
|
||||||
|
received_amount_of_subscriptions = 0
|
||||||
|
next_page_token = None
|
||||||
|
while received_amount_of_subscriptions < amount_of_subscriptions:
|
||||||
|
# pylint: disable=no-member
|
||||||
|
subscription_request: HttpRequest = resource.subscriptions().list(
|
||||||
|
part="snippet", mine=True, maxResults=50, pageToken=next_page_token
|
||||||
|
)
|
||||||
|
res = await hass.async_add_executor_job(subscription_request.execute)
|
||||||
|
amount_of_subscriptions = res["pageInfo"]["totalResults"]
|
||||||
|
if "nextPageToken" in res:
|
||||||
|
next_page_token = res["nextPageToken"]
|
||||||
|
for item in res["items"]:
|
||||||
|
received_amount_of_subscriptions += 1
|
||||||
|
yield item
|
||||||
|
|
||||||
|
|
||||||
async def get_resource(hass: HomeAssistant, token: str) -> Resource:
|
async def get_resource(hass: HomeAssistant, token: str) -> Resource:
|
||||||
"""Get Youtube resource async."""
|
"""Get Youtube resource async."""
|
||||||
|
|
||||||
@ -152,17 +170,12 @@ class OAuth2FlowHandler(
|
|||||||
service = await get_resource(
|
service = await get_resource(
|
||||||
self.hass, self._data[CONF_TOKEN][CONF_ACCESS_TOKEN]
|
self.hass, self._data[CONF_TOKEN][CONF_ACCESS_TOKEN]
|
||||||
)
|
)
|
||||||
# pylint: disable=no-member
|
|
||||||
subscription_request: HttpRequest = service.subscriptions().list(
|
|
||||||
part="snippet", mine=True, maxResults=50
|
|
||||||
)
|
|
||||||
response = await self.hass.async_add_executor_job(subscription_request.execute)
|
|
||||||
selectable_channels = [
|
selectable_channels = [
|
||||||
SelectOptionDict(
|
SelectOptionDict(
|
||||||
value=subscription["snippet"]["resourceId"]["channelId"],
|
value=subscription["snippet"]["resourceId"]["channelId"],
|
||||||
label=subscription["snippet"]["title"],
|
label=subscription["snippet"]["title"],
|
||||||
)
|
)
|
||||||
for subscription in response["items"]
|
async for subscription in _get_subscriptions(self.hass, service)
|
||||||
]
|
]
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="channels",
|
step_id="channels",
|
||||||
@ -191,17 +204,12 @@ class YouTubeOptionsFlowHandler(OptionsFlowWithConfigEntry):
|
|||||||
service = await get_resource(
|
service = await get_resource(
|
||||||
self.hass, self.config_entry.data[CONF_TOKEN][CONF_ACCESS_TOKEN]
|
self.hass, self.config_entry.data[CONF_TOKEN][CONF_ACCESS_TOKEN]
|
||||||
)
|
)
|
||||||
# pylint: disable=no-member
|
|
||||||
subscription_request: HttpRequest = service.subscriptions().list(
|
|
||||||
part="snippet", mine=True, maxResults=50
|
|
||||||
)
|
|
||||||
response = await self.hass.async_add_executor_job(subscription_request.execute)
|
|
||||||
selectable_channels = [
|
selectable_channels = [
|
||||||
SelectOptionDict(
|
SelectOptionDict(
|
||||||
value=subscription["snippet"]["resourceId"]["channelId"],
|
value=subscription["snippet"]["resourceId"]["channelId"],
|
||||||
label=subscription["snippet"]["title"],
|
label=subscription["snippet"]["title"],
|
||||||
)
|
)
|
||||||
for subscription in response["items"]
|
async for subscription in _get_subscriptions(self.hass, service)
|
||||||
]
|
]
|
||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id="init",
|
step_id="init",
|
||||||
|
@ -53,16 +53,31 @@ class YouTubeDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, Any]:
|
async def _async_update_data(self) -> dict[str, Any]:
|
||||||
service = await self._auth.get_resource()
|
service = await self._auth.get_resource()
|
||||||
channels = self.config_entry.options[CONF_CHANNELS]
|
channels = await self._get_channels(service)
|
||||||
channel_request: HttpRequest = service.channels().list(
|
|
||||||
part="snippet,statistics", id=",".join(channels), maxResults=50
|
|
||||||
)
|
|
||||||
response: dict = await self.hass.async_add_executor_job(channel_request.execute)
|
|
||||||
|
|
||||||
return await self.hass.async_add_executor_job(
|
return await self.hass.async_add_executor_job(
|
||||||
self._get_channel_data, service, response["items"]
|
self._get_channel_data, service, channels
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def _get_channels(self, service: Resource) -> list[dict[str, Any]]:
|
||||||
|
data = []
|
||||||
|
received_channels = 0
|
||||||
|
channels = self.config_entry.options[CONF_CHANNELS]
|
||||||
|
while received_channels < len(channels):
|
||||||
|
# We're slicing the channels in chunks of 50 to avoid making the URI too long
|
||||||
|
end = min(received_channels + 50, len(channels) - 1)
|
||||||
|
channel_request: HttpRequest = service.channels().list(
|
||||||
|
part="snippet,statistics",
|
||||||
|
id=",".join(channels[received_channels:end]),
|
||||||
|
maxResults=50,
|
||||||
|
)
|
||||||
|
response: dict = await self.hass.async_add_executor_job(
|
||||||
|
channel_request.execute
|
||||||
|
)
|
||||||
|
data.extend(response["items"])
|
||||||
|
received_channels += len(response["items"])
|
||||||
|
return data
|
||||||
|
|
||||||
def _get_channel_data(
|
def _get_channel_data(
|
||||||
self, service: Resource, channels: list[dict[str, Any]]
|
self, service: Resource, channels: list[dict[str, Any]]
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
|
@ -59,7 +59,13 @@ class MockSubscriptions:
|
|||||||
"""Initialize mock subscriptions."""
|
"""Initialize mock subscriptions."""
|
||||||
self._fixture = fixture
|
self._fixture = fixture
|
||||||
|
|
||||||
def list(self, part: str, mine: bool, maxResults: int | None = None) -> MockRequest:
|
def list(
|
||||||
|
self,
|
||||||
|
part: str,
|
||||||
|
mine: bool,
|
||||||
|
maxResults: int | None = None,
|
||||||
|
pageToken: str | None = None,
|
||||||
|
) -> MockRequest:
|
||||||
"""Return a fixture."""
|
"""Return a fixture."""
|
||||||
return MockRequest(fixture=self._fixture)
|
return MockRequest(fixture=self._fixture)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user