mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +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."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from collections.abc import AsyncGenerator, Mapping
|
||||
import logging
|
||||
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:
|
||||
"""Get Youtube resource async."""
|
||||
|
||||
@ -152,17 +170,12 @@ class OAuth2FlowHandler(
|
||||
service = await get_resource(
|
||||
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 = [
|
||||
SelectOptionDict(
|
||||
value=subscription["snippet"]["resourceId"]["channelId"],
|
||||
label=subscription["snippet"]["title"],
|
||||
)
|
||||
for subscription in response["items"]
|
||||
async for subscription in _get_subscriptions(self.hass, service)
|
||||
]
|
||||
return self.async_show_form(
|
||||
step_id="channels",
|
||||
@ -191,17 +204,12 @@ class YouTubeOptionsFlowHandler(OptionsFlowWithConfigEntry):
|
||||
service = await get_resource(
|
||||
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 = [
|
||||
SelectOptionDict(
|
||||
value=subscription["snippet"]["resourceId"]["channelId"],
|
||||
label=subscription["snippet"]["title"],
|
||||
)
|
||||
for subscription in response["items"]
|
||||
async for subscription in _get_subscriptions(self.hass, service)
|
||||
]
|
||||
return self.async_show_form(
|
||||
step_id="init",
|
||||
|
@ -53,16 +53,31 @@ class YouTubeDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
service = await self._auth.get_resource()
|
||||
channels = self.config_entry.options[CONF_CHANNELS]
|
||||
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)
|
||||
channels = await self._get_channels(service)
|
||||
|
||||
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(
|
||||
self, service: Resource, channels: list[dict[str, Any]]
|
||||
) -> dict[str, Any]:
|
||||
|
@ -59,7 +59,13 @@ class MockSubscriptions:
|
||||
"""Initialize mock subscriptions."""
|
||||
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 MockRequest(fixture=self._fixture)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user