Add Jellyfin integration (#44401)

* Initial commit after scaffold setup

* Add initial config flow

* Create initial entity

* Ready for testing

* Can browse, no result yet

* Further improvements. Browsing is working.
Now need to work on proper stream URL

* Two valid URLs. Do not play in HA

* First working version for music

* Add thumbnail

* Includes Artist->Album hierarchy

* Add sorting of artists, albums and tracks

* Remove code for video libraries

* Improved code styling

* Optimize configuration flow

* Fix unit tests for config flow

* Fix import order

* Conform to style requirements

* Use empty string as media type for non playables

* 100% code coverage config_flow

* Type async_get_media_source

* Final docsctring fix after rebase

* Add __init__ and media_source files to .coveragerc

* Fix testing issues after rebase

* Fix string format issues and relative const import

* Remove unused manifest entries

* Raise ConfigEntry exceptions, not log errors

* Upgrade dependency to avoid WARNING on startup

* Change to builtin tuple and list (deprecation)

* Log broad exceptions

* Add strict typing

* Further type fixes after rebase

* Retry when cannot connect, otherwise fail setup

* Remove unused CONFIG_SCHEMA

* Enable strict typing checks

* FlowResultDict -> FlowResult

* Code quality improvements

* Resolve mypy.ini merge conflict

* Use unique userid generated by Jellyfin

* Update homeassistant/components/jellyfin/config_flow.py

Remove connection class from config flow

Co-authored-by: Milan Meulemans <milan.meulemans@live.be>

* Minor changes for additional checks after rebase

* Remove title from string and translations

* Changes wrt review

* Fixes based on rebase and review suggestions

* Move client initialization to separate file

* Remove persistent_notification, add test const.py

Co-authored-by: Milan Meulemans <milan.meulemans@live.be>
This commit is contained in:
j-stienstra 2021-11-12 14:57:40 +01:00 committed by GitHub
parent 733193b5ad
commit 0ae5b9e880
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 817 additions and 0 deletions

View file

@ -0,0 +1,62 @@
"""Config flow for the Jellyfin integration."""
from __future__ import annotations
import logging
from typing import Any
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME
from homeassistant.data_entry_flow import FlowResult
from .client_wrapper import CannotConnect, InvalidAuth, create_client, validate_input
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_URL): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
)
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Jellyfin."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle a user defined configuration."""
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
errors: dict[str, str] = {}
if user_input is not None:
client = create_client()
try:
userid = await validate_input(self.hass, user_input, client)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception as ex: # pylint: disable=broad-except
errors["base"] = "unknown"
_LOGGER.exception(ex)
else:
await self.async_set_unique_id(userid)
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=user_input[CONF_URL], data=user_input
)
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)