mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 07:07:28 +00:00
Remove deprecated services in SABnzbd (#144405)
Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
parent
04867f6ecc
commit
cb6847b64c
@ -2,148 +2,18 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable, Coroutine
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
import voluptuous as vol
|
|
||||||
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import config_validation as cv, issue_registry as ir
|
|
||||||
from homeassistant.helpers.typing import ConfigType
|
|
||||||
|
|
||||||
from .const import (
|
|
||||||
ATTR_API_KEY,
|
|
||||||
ATTR_SPEED,
|
|
||||||
DEFAULT_SPEED_LIMIT,
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_PAUSE,
|
|
||||||
SERVICE_RESUME,
|
|
||||||
SERVICE_SET_SPEED,
|
|
||||||
)
|
|
||||||
from .coordinator import SabnzbdConfigEntry, SabnzbdUpdateCoordinator
|
from .coordinator import SabnzbdConfigEntry, SabnzbdUpdateCoordinator
|
||||||
from .helpers import get_client
|
from .helpers import get_client
|
||||||
|
|
||||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.NUMBER, Platform.SENSOR]
|
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.NUMBER, Platform.SENSOR]
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
SERVICES = (
|
|
||||||
SERVICE_PAUSE,
|
|
||||||
SERVICE_RESUME,
|
|
||||||
SERVICE_SET_SPEED,
|
|
||||||
)
|
|
||||||
|
|
||||||
SERVICE_BASE_SCHEMA = vol.Schema(
|
|
||||||
{
|
|
||||||
vol.Required(ATTR_API_KEY): cv.string,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SERVICE_SPEED_SCHEMA = SERVICE_BASE_SCHEMA.extend(
|
|
||||||
{
|
|
||||||
vol.Optional(ATTR_SPEED, default=DEFAULT_SPEED_LIMIT): cv.string,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def async_get_entry_for_service_call(
|
|
||||||
hass: HomeAssistant, call: ServiceCall
|
|
||||||
) -> SabnzbdConfigEntry:
|
|
||||||
"""Get the entry ID related to a service call (by device ID)."""
|
|
||||||
call_data_api_key = call.data[ATTR_API_KEY]
|
|
||||||
|
|
||||||
for entry in hass.config_entries.async_entries(DOMAIN):
|
|
||||||
if entry.data[ATTR_API_KEY] == call_data_api_key:
|
|
||||||
return entry
|
|
||||||
|
|
||||||
raise ValueError(f"No api for API key: {call_data_api_key}")
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|
||||||
"""Set up the SabNzbd Component."""
|
|
||||||
|
|
||||||
@callback
|
|
||||||
def extract_api(
|
|
||||||
func: Callable[
|
|
||||||
[ServiceCall, SabnzbdUpdateCoordinator], Coroutine[Any, Any, None]
|
|
||||||
],
|
|
||||||
) -> Callable[[ServiceCall], Coroutine[Any, Any, None]]:
|
|
||||||
"""Define a decorator to get the correct api for a service call."""
|
|
||||||
|
|
||||||
async def wrapper(call: ServiceCall) -> None:
|
|
||||||
"""Wrap the service function."""
|
|
||||||
config_entry = async_get_entry_for_service_call(hass, call)
|
|
||||||
coordinator = config_entry.runtime_data
|
|
||||||
|
|
||||||
try:
|
|
||||||
await func(call, coordinator)
|
|
||||||
except Exception as err:
|
|
||||||
raise HomeAssistantError(
|
|
||||||
f"Error while executing {func.__name__}: {err}"
|
|
||||||
) from err
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
@extract_api
|
|
||||||
async def async_pause_queue(
|
|
||||||
call: ServiceCall, coordinator: SabnzbdUpdateCoordinator
|
|
||||||
) -> None:
|
|
||||||
ir.async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"pause_action_deprecated",
|
|
||||||
is_fixable=False,
|
|
||||||
severity=ir.IssueSeverity.WARNING,
|
|
||||||
breaks_in_ha_version="2025.6",
|
|
||||||
translation_key="pause_action_deprecated",
|
|
||||||
)
|
|
||||||
await coordinator.sab_api.pause_queue()
|
|
||||||
|
|
||||||
@extract_api
|
|
||||||
async def async_resume_queue(
|
|
||||||
call: ServiceCall, coordinator: SabnzbdUpdateCoordinator
|
|
||||||
) -> None:
|
|
||||||
ir.async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"resume_action_deprecated",
|
|
||||||
is_fixable=False,
|
|
||||||
severity=ir.IssueSeverity.WARNING,
|
|
||||||
breaks_in_ha_version="2025.6",
|
|
||||||
translation_key="resume_action_deprecated",
|
|
||||||
)
|
|
||||||
await coordinator.sab_api.resume_queue()
|
|
||||||
|
|
||||||
@extract_api
|
|
||||||
async def async_set_queue_speed(
|
|
||||||
call: ServiceCall, coordinator: SabnzbdUpdateCoordinator
|
|
||||||
) -> None:
|
|
||||||
ir.async_create_issue(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
"set_speed_action_deprecated",
|
|
||||||
is_fixable=False,
|
|
||||||
severity=ir.IssueSeverity.WARNING,
|
|
||||||
breaks_in_ha_version="2025.6",
|
|
||||||
translation_key="set_speed_action_deprecated",
|
|
||||||
)
|
|
||||||
speed = call.data.get(ATTR_SPEED)
|
|
||||||
await coordinator.sab_api.set_speed_limit(speed)
|
|
||||||
|
|
||||||
for service, method, schema in (
|
|
||||||
(SERVICE_PAUSE, async_pause_queue, SERVICE_BASE_SCHEMA),
|
|
||||||
(SERVICE_RESUME, async_resume_queue, SERVICE_BASE_SCHEMA),
|
|
||||||
(SERVICE_SET_SPEED, async_set_queue_speed, SERVICE_SPEED_SCHEMA),
|
|
||||||
):
|
|
||||||
hass.services.async_register(DOMAIN, service, method, schema=schema)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: SabnzbdConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: SabnzbdConfigEntry) -> bool:
|
||||||
"""Set up the SabNzbd Component."""
|
"""Set up the SabNzbd Component."""
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
"""Constants for the Sabnzbd component."""
|
"""Constants for the Sabnzbd component."""
|
||||||
|
|
||||||
DOMAIN = "sabnzbd"
|
DOMAIN = "sabnzbd"
|
||||||
|
|
||||||
ATTR_SPEED = "speed"
|
|
||||||
ATTR_API_KEY = "api_key"
|
|
||||||
|
|
||||||
DEFAULT_SPEED_LIMIT = "100"
|
|
||||||
|
|
||||||
SERVICE_PAUSE = "pause"
|
|
||||||
SERVICE_RESUME = "resume"
|
|
||||||
SERVICE_SET_SPEED = "set_speed"
|
|
||||||
|
@ -13,16 +13,5 @@
|
|||||||
"default": "mdi:speedometer"
|
"default": "mdi:speedometer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"services": {
|
|
||||||
"pause": {
|
|
||||||
"service": "mdi:pause"
|
|
||||||
},
|
|
||||||
"resume": {
|
|
||||||
"service": "mdi:play"
|
|
||||||
},
|
|
||||||
"set_speed": {
|
|
||||||
"service": "mdi:speedometer"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
rules:
|
rules:
|
||||||
# Bronze
|
# Bronze
|
||||||
action-setup: done
|
action-setup:
|
||||||
|
status: exempt
|
||||||
|
comment: |
|
||||||
|
The integration does not provide any actions.
|
||||||
appropriate-polling: done
|
appropriate-polling: done
|
||||||
brands: done
|
brands: done
|
||||||
common-modules: done
|
common-modules: done
|
||||||
@ -10,7 +13,7 @@ rules:
|
|||||||
docs-actions:
|
docs-actions:
|
||||||
status: exempt
|
status: exempt
|
||||||
comment: |
|
comment: |
|
||||||
The integration has deprecated the actions, thus the documentation has been removed.
|
The integration does not provide any actions.
|
||||||
docs-high-level-description: done
|
docs-high-level-description: done
|
||||||
docs-installation-instructions: done
|
docs-installation-instructions: done
|
||||||
docs-removal-instructions: done
|
docs-removal-instructions: done
|
||||||
@ -26,10 +29,7 @@ rules:
|
|||||||
unique-config-entry: done
|
unique-config-entry: done
|
||||||
|
|
||||||
# Silver
|
# Silver
|
||||||
action-exceptions:
|
action-exceptions: done
|
||||||
status: todo
|
|
||||||
comment: |
|
|
||||||
Raise ServiceValidationError in async_get_entry_for_service_call.
|
|
||||||
config-entry-unloading: done
|
config-entry-unloading: done
|
||||||
docs-configuration-parameters:
|
docs-configuration-parameters:
|
||||||
status: exempt
|
status: exempt
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
pause:
|
|
||||||
fields:
|
|
||||||
api_key:
|
|
||||||
required: true
|
|
||||||
selector:
|
|
||||||
text:
|
|
||||||
resume:
|
|
||||||
fields:
|
|
||||||
api_key:
|
|
||||||
required: true
|
|
||||||
selector:
|
|
||||||
text:
|
|
||||||
set_speed:
|
|
||||||
fields:
|
|
||||||
api_key:
|
|
||||||
required: true
|
|
||||||
selector:
|
|
||||||
text:
|
|
||||||
speed:
|
|
||||||
example: 100
|
|
||||||
default: 100
|
|
||||||
selector:
|
|
||||||
text:
|
|
@ -32,7 +32,7 @@
|
|||||||
"name": "[%key:common::action::pause%]"
|
"name": "[%key:common::action::pause%]"
|
||||||
},
|
},
|
||||||
"resume": {
|
"resume": {
|
||||||
"name": "[%key:component::sabnzbd::services::resume::name%]"
|
"name": "Resume"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"number": {
|
"number": {
|
||||||
@ -76,56 +76,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
|
||||||
"pause": {
|
|
||||||
"name": "[%key:common::action::pause%]",
|
|
||||||
"description": "Pauses downloads.",
|
|
||||||
"fields": {
|
|
||||||
"api_key": {
|
|
||||||
"name": "SABnzbd API key",
|
|
||||||
"description": "The SABnzbd API key to pause downloads."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"resume": {
|
|
||||||
"name": "Resume",
|
|
||||||
"description": "Resumes downloads.",
|
|
||||||
"fields": {
|
|
||||||
"api_key": {
|
|
||||||
"name": "[%key:component::sabnzbd::services::pause::fields::api_key::name%]",
|
|
||||||
"description": "The SABnzbd API key to resume downloads."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"set_speed": {
|
|
||||||
"name": "Set speed",
|
|
||||||
"description": "Sets the download speed limit.",
|
|
||||||
"fields": {
|
|
||||||
"api_key": {
|
|
||||||
"name": "[%key:component::sabnzbd::services::pause::fields::api_key::name%]",
|
|
||||||
"description": "The SABnzbd API key to set speed limit."
|
|
||||||
},
|
|
||||||
"speed": {
|
|
||||||
"name": "Speed",
|
|
||||||
"description": "Speed limit. If specified as a number with no units, will be interpreted as a percent. If units are provided (e.g., 500K) will be interpreted absolutely."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"issues": {
|
|
||||||
"pause_action_deprecated": {
|
|
||||||
"title": "SABnzbd pause action deprecated",
|
|
||||||
"description": "The 'Pause' action is deprecated and will be removed in a future version. Please use the 'Pause' button instead. To remove this issue, please adjust automations accordingly and restart Home Assistant."
|
|
||||||
},
|
|
||||||
"resume_action_deprecated": {
|
|
||||||
"title": "SABnzbd resume action deprecated",
|
|
||||||
"description": "The 'Resume' action is deprecated and will be removed in a future version. Please use the 'Resume' button instead. To remove this issue, please adjust automations accordingly and restart Home Assistant."
|
|
||||||
},
|
|
||||||
"set_speed_action_deprecated": {
|
|
||||||
"title": "SABnzbd set_speed action deprecated",
|
|
||||||
"description": "The 'Set speed' action is deprecated and will be removed in a future version. Please use the 'Speedlimit' number entity instead. To remove this issue, please adjust automations accordingly and restart Home Assistant."
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"exceptions": {
|
"exceptions": {
|
||||||
"service_call_exception": {
|
"service_call_exception": {
|
||||||
"message": "Unable to send command to SABnzbd due to a connection error, try again later"
|
"message": "Unable to send command to SABnzbd due to a connection error, try again later"
|
||||||
|
@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, patch
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.sabnzbd import DOMAIN
|
from homeassistant.components.sabnzbd.const import DOMAIN
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_URL
|
from homeassistant.const import CONF_API_KEY, CONF_URL
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
@ -6,7 +6,7 @@ from pysabnzbd import SabnzbdApiException
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.sabnzbd import DOMAIN
|
from homeassistant.components.sabnzbd.const import DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_USER
|
from homeassistant.config_entries import SOURCE_USER
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_URL
|
from homeassistant.const import CONF_API_KEY, CONF_URL
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
"""Tests for the SABnzbd Integration."""
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from homeassistant.components.sabnzbd.const import (
|
|
||||||
ATTR_API_KEY,
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_PAUSE,
|
|
||||||
SERVICE_RESUME,
|
|
||||||
SERVICE_SET_SPEED,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
|
||||||
from homeassistant.helpers import issue_registry as ir
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
("service", "issue_id"),
|
|
||||||
[
|
|
||||||
(SERVICE_RESUME, "resume_action_deprecated"),
|
|
||||||
(SERVICE_PAUSE, "pause_action_deprecated"),
|
|
||||||
(SERVICE_SET_SPEED, "set_speed_action_deprecated"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@pytest.mark.usefixtures("setup_integration")
|
|
||||||
async def test_deprecated_service_creates_issue(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
issue_registry: ir.IssueRegistry,
|
|
||||||
service: str,
|
|
||||||
issue_id: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test that deprecated actions creates an issue."""
|
|
||||||
await hass.services.async_call(
|
|
||||||
DOMAIN,
|
|
||||||
service,
|
|
||||||
{ATTR_API_KEY: "edc3eee7330e4fdda04489e3fbc283d0"},
|
|
||||||
blocking=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
issue = issue_registry.async_get_issue(domain=DOMAIN, issue_id=issue_id)
|
|
||||||
assert issue
|
|
||||||
assert issue.severity == ir.IssueSeverity.WARNING
|
|
||||||
assert issue.breaks_in_ha_version == "2025.6"
|
|
Loading…
x
Reference in New Issue
Block a user