117 lines
3.5 KiB
Python
117 lines
3.5 KiB
Python
"""Adds config flow for Folder watcher."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Mapping
|
|
import os
|
|
from typing import Any
|
|
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.components.homeassistant import DOMAIN as HOMEASSISTANT_DOMAIN
|
|
from homeassistant.config_entries import ConfigFlowResult
|
|
from homeassistant.core import callback
|
|
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
|
from homeassistant.helpers.schema_config_entry_flow import (
|
|
SchemaCommonFlowHandler,
|
|
SchemaConfigFlowHandler,
|
|
SchemaFlowError,
|
|
SchemaFlowFormStep,
|
|
)
|
|
from homeassistant.helpers.selector import (
|
|
SelectSelector,
|
|
SelectSelectorConfig,
|
|
SelectSelectorMode,
|
|
TextSelector,
|
|
)
|
|
|
|
from .const import CONF_FOLDER, CONF_PATTERNS, DEFAULT_PATTERN, DOMAIN
|
|
|
|
|
|
async def validate_setup(
|
|
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
|
) -> dict[str, Any]:
|
|
"""Check path is a folder."""
|
|
value: str = user_input[CONF_FOLDER]
|
|
dir_in = os.path.expanduser(str(value))
|
|
handler.parent_handler._async_abort_entries_match({CONF_FOLDER: value}) # noqa: SLF001
|
|
|
|
if not os.path.isdir(dir_in):
|
|
raise SchemaFlowError("not_dir")
|
|
if not os.access(dir_in, os.R_OK):
|
|
raise SchemaFlowError("not_readable_dir")
|
|
if not handler.parent_handler.hass.config.is_allowed_path(value):
|
|
raise SchemaFlowError("not_allowed_dir")
|
|
|
|
return user_input
|
|
|
|
|
|
async def validate_import_setup(
|
|
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
|
) -> dict[str, Any]:
|
|
"""Create issue on successful import."""
|
|
async_create_issue(
|
|
handler.parent_handler.hass,
|
|
HOMEASSISTANT_DOMAIN,
|
|
f"deprecated_yaml_{DOMAIN}",
|
|
breaks_in_ha_version="2024.11.0",
|
|
is_fixable=False,
|
|
is_persistent=False,
|
|
issue_domain=DOMAIN,
|
|
severity=IssueSeverity.WARNING,
|
|
translation_key="deprecated_yaml",
|
|
translation_placeholders={
|
|
"domain": DOMAIN,
|
|
"integration_title": "Folder Watcher",
|
|
},
|
|
)
|
|
return user_input
|
|
|
|
|
|
OPTIONS_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional(CONF_PATTERNS, default=[DEFAULT_PATTERN]): SelectSelector(
|
|
SelectSelectorConfig(
|
|
options=[DEFAULT_PATTERN],
|
|
multiple=True,
|
|
custom_value=True,
|
|
mode=SelectSelectorMode.DROPDOWN,
|
|
)
|
|
),
|
|
}
|
|
)
|
|
DATA_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Required(CONF_FOLDER): TextSelector(),
|
|
}
|
|
).extend(OPTIONS_SCHEMA.schema)
|
|
|
|
CONFIG_FLOW = {
|
|
"user": SchemaFlowFormStep(schema=DATA_SCHEMA, validate_user_input=validate_setup),
|
|
"import": SchemaFlowFormStep(
|
|
schema=DATA_SCHEMA, validate_user_input=validate_import_setup
|
|
),
|
|
}
|
|
OPTIONS_FLOW = {
|
|
"init": SchemaFlowFormStep(schema=OPTIONS_SCHEMA),
|
|
}
|
|
|
|
|
|
class FolderWatcherConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
|
|
"""Handle a config flow for Folder Watcher."""
|
|
|
|
config_flow = CONFIG_FLOW
|
|
options_flow = OPTIONS_FLOW
|
|
|
|
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
|
|
"""Return config entry title."""
|
|
return f"Folder Watcher {options[CONF_FOLDER]}"
|
|
|
|
@callback
|
|
def async_create_entry(
|
|
self, data: Mapping[str, Any], **kwargs: Any
|
|
) -> ConfigFlowResult:
|
|
"""Finish config flow and create a config entry."""
|
|
self._async_abort_entries_match({CONF_FOLDER: data[CONF_FOLDER]})
|
|
return super().async_create_entry(data, **kwargs)
|