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 collections.abc import Callable, Coroutine
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv, issue_registry as ir
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
||||
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 .helpers import get_client
|
||||
|
||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.BUTTON, Platform.NUMBER, Platform.SENSOR]
|
||||
_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:
|
||||
"""Set up the SabNzbd Component."""
|
||||
|
@ -1,12 +1,3 @@
|
||||
"""Constants for the Sabnzbd component."""
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"pause": {
|
||||
"service": "mdi:pause"
|
||||
},
|
||||
"resume": {
|
||||
"service": "mdi:play"
|
||||
},
|
||||
"set_speed": {
|
||||
"service": "mdi:speedometer"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
rules:
|
||||
# Bronze
|
||||
action-setup: done
|
||||
action-setup:
|
||||
status: exempt
|
||||
comment: |
|
||||
The integration does not provide any actions.
|
||||
appropriate-polling: done
|
||||
brands: done
|
||||
common-modules: done
|
||||
@ -10,7 +13,7 @@ rules:
|
||||
docs-actions:
|
||||
status: exempt
|
||||
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-installation-instructions: done
|
||||
docs-removal-instructions: done
|
||||
@ -26,10 +29,7 @@ rules:
|
||||
unique-config-entry: done
|
||||
|
||||
# Silver
|
||||
action-exceptions:
|
||||
status: todo
|
||||
comment: |
|
||||
Raise ServiceValidationError in async_get_entry_for_service_call.
|
||||
action-exceptions: done
|
||||
config-entry-unloading: done
|
||||
docs-configuration-parameters:
|
||||
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%]"
|
||||
},
|
||||
"resume": {
|
||||
"name": "[%key:component::sabnzbd::services::resume::name%]"
|
||||
"name": "Resume"
|
||||
}
|
||||
},
|
||||
"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": {
|
||||
"service_call_exception": {
|
||||
"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
|
||||
|
||||
from homeassistant.components.sabnzbd import DOMAIN
|
||||
from homeassistant.components.sabnzbd.const import DOMAIN
|
||||
from homeassistant.const import CONF_API_KEY, CONF_URL
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
@ -6,7 +6,7 @@ from pysabnzbd import SabnzbdApiException
|
||||
import pytest
|
||||
|
||||
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.const import CONF_API_KEY, CONF_URL
|
||||
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