Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 38 additions & 12 deletions homeassistant/components/github/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
GitHubException,
GitHubLoginDeviceModel,
GitHubLoginOauthModel,
GitHubRepositoryModel,
)
from aiogithubapi.const import OAUTH_USER_LOGIN
import voluptuous as vol
Expand All @@ -34,11 +33,12 @@
)


async def starred_repositories(hass: HomeAssistant, access_token: str) -> list[str]:
"""Return a list of repositories that the user has starred."""
async def get_repositories(hass: HomeAssistant, access_token: str) -> list[str]:
"""Return a list of repositories that the user owns or has starred."""
client = GitHubAPI(token=access_token, session=async_get_clientsession(hass))
repositories = set()

async def _get_starred() -> list[GitHubRepositoryModel] | None:
async def _get_starred_repositories() -> None:
response = await client.user.starred(**{"params": {"per_page": 100}})
if not response.is_last_page:
results = await asyncio.gather(
Expand All @@ -54,16 +54,44 @@ async def _get_starred() -> list[GitHubRepositoryModel] | None:
for result in results:
response.data.extend(result.data)

return response.data
repositories.update(response.data)

async def _get_personal_repositories() -> None:
response = await client.user.repos(**{"params": {"per_page": 100}})
if not response.is_last_page:
results = await asyncio.gather(
*(
client.user.repos(
**{"params": {"per_page": 100, "page": page_number}},
)
for page_number in range(
response.next_page_number, response.last_page_number + 1
)
)
)
for result in results:
response.data.extend(result.data)

repositories.update(response.data)

try:
result = await _get_starred()
await asyncio.gather(
*(
_get_starred_repositories(),
_get_personal_repositories(),
)
)

except GitHubException:
return DEFAULT_REPOSITORIES

if not result or len(result) == 0:
if len(repositories) == 0:
return DEFAULT_REPOSITORIES
return sorted((repo.full_name for repo in result), key=str.casefold)

return sorted(
(repo.full_name for repo in repositories),
key=str.casefold,
)


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
Expand Down Expand Up @@ -153,9 +181,7 @@ async def async_step_repositories(
assert self._login is not None

if not user_input:
repositories = await starred_repositories(
self.hass, self._login.access_token
)
repositories = await get_repositories(self.hass, self._login.access_token)
return self.async_show_form(
step_id="repositories",
data_schema=vol.Schema(
Expand Down Expand Up @@ -205,7 +231,7 @@ async def async_step_init(
configured_repositories: list[str] = self.config_entry.options[
CONF_REPOSITORIES
]
repositories = await starred_repositories(
repositories = await get_repositories(
self.hass, self.config_entry.data[CONF_ACCESS_TOKEN]
)

Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/github/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"name": "GitHub",
"documentation": "https://www.home-assistant.io/integrations/github",
"requirements": [
"aiogithubapi==22.1.0"
"aiogithubapi==22.2.0"
],
"codeowners": [
"@timmo001",
"@ludeeus"
],
"iot_class": "cloud_polling",
"config_flow": true,
"loggers": ["aiogithubapi"]
"loggers": [
"aiogithubapi"
]
}
2 changes: 1 addition & 1 deletion requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ aioflo==2021.11.0
aioftp==0.12.0

# homeassistant.components.github
aiogithubapi==22.1.0
aiogithubapi==22.2.0

# homeassistant.components.guardian
aioguardian==2021.11.0
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ aioesphomeapi==10.8.1
aioflo==2021.11.0

# homeassistant.components.github
aiogithubapi==22.1.0
aiogithubapi==22.2.0

# homeassistant.components.guardian
aioguardian==2021.11.0
Expand Down
26 changes: 20 additions & 6 deletions tests/components/github/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from aiogithubapi import GitHubException

from homeassistant import config_entries
from homeassistant.components.github.config_flow import starred_repositories
from homeassistant.components.github.config_flow import get_repositories
from homeassistant.components.github.const import (
CONF_ACCESS_TOKEN,
CONF_REPOSITORIES,
Expand Down Expand Up @@ -161,11 +161,19 @@ async def test_starred_pagination_with_paginated_result(hass: HomeAssistant) ->
last_page_number=2,
data=[MagicMock(full_name="home-assistant/core")],
)
)
),
repos=AsyncMock(
return_value=MagicMock(
is_last_page=False,
next_page_number=2,
last_page_number=2,
data=[MagicMock(full_name="awesome/reposiotry")],
)
),
)
),
):
repos = await starred_repositories(hass, MOCK_ACCESS_TOKEN)
repos = await get_repositories(hass, MOCK_ACCESS_TOKEN)

assert len(repos) == 2
assert repos[-1] == DEFAULT_REPOSITORIES[0]
Expand All @@ -182,11 +190,17 @@ async def test_starred_pagination_with_no_starred(hass: HomeAssistant) -> None:
is_last_page=True,
data=[],
)
)
),
repos=AsyncMock(
return_value=MagicMock(
is_last_page=True,
data=[],
)
),
)
),
):
repos = await starred_repositories(hass, MOCK_ACCESS_TOKEN)
repos = await get_repositories(hass, MOCK_ACCESS_TOKEN)

assert len(repos) == 2
assert repos == DEFAULT_REPOSITORIES
Expand All @@ -200,7 +214,7 @@ async def test_starred_pagination_with_exception(hass: HomeAssistant) -> None:
user=MagicMock(starred=AsyncMock(side_effect=GitHubException("Error")))
),
):
repos = await starred_repositories(hass, MOCK_ACCESS_TOKEN)
repos = await get_repositories(hass, MOCK_ACCESS_TOKEN)

assert len(repos) == 2
assert repos == DEFAULT_REPOSITORIES
Expand Down