mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Limit and sort transmission torrents_info attribute (#35411)
This commit is contained in:
parent
15165a3c93
commit
4a374f0378
@ -24,9 +24,13 @@ from homeassistant.helpers.event import async_track_time_interval
|
||||
from .const import (
|
||||
ATTR_DELETE_DATA,
|
||||
ATTR_TORRENT,
|
||||
CONF_LIMIT,
|
||||
CONF_ORDER,
|
||||
DATA_UPDATED,
|
||||
DEFAULT_DELETE_DATA,
|
||||
DEFAULT_LIMIT,
|
||||
DEFAULT_NAME,
|
||||
DEFAULT_ORDER,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
DOMAIN,
|
||||
@ -238,7 +242,13 @@ class TransmissionClient:
|
||||
scan_interval = self.config_entry.data.get(
|
||||
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
||||
)
|
||||
options = {CONF_SCAN_INTERVAL: scan_interval}
|
||||
limit = self.config_entry.data.get(CONF_LIMIT, DEFAULT_LIMIT)
|
||||
order = self.config_entry.data.get(CONF_ORDER, DEFAULT_ORDER)
|
||||
options = {
|
||||
CONF_SCAN_INTERVAL: scan_interval,
|
||||
CONF_LIMIT: limit,
|
||||
CONF_ORDER: order,
|
||||
}
|
||||
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.config_entry, options=options
|
||||
@ -260,9 +270,9 @@ class TransmissionClient:
|
||||
@staticmethod
|
||||
async def async_options_updated(hass, entry):
|
||||
"""Triggered by config entry options updates."""
|
||||
hass.data[DOMAIN][entry.entry_id].set_scan_interval(
|
||||
entry.options[CONF_SCAN_INTERVAL]
|
||||
)
|
||||
tm_client = hass.data[DOMAIN][entry.entry_id]
|
||||
tm_client.set_scan_interval(entry.options[CONF_SCAN_INTERVAL])
|
||||
await hass.async_add_executor_job(tm_client.api.update)
|
||||
|
||||
|
||||
class TransmissionData:
|
||||
|
@ -13,7 +13,17 @@ from homeassistant.const import (
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import get_api
|
||||
from .const import DEFAULT_NAME, DEFAULT_PORT, DEFAULT_SCAN_INTERVAL, DOMAIN
|
||||
from .const import (
|
||||
CONF_LIMIT,
|
||||
CONF_ORDER,
|
||||
DEFAULT_LIMIT,
|
||||
DEFAULT_NAME,
|
||||
DEFAULT_ORDER,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
DOMAIN,
|
||||
SUPPORTED_ORDER_MODES,
|
||||
)
|
||||
from .errors import AuthenticationError, CannotConnect, UnknownError
|
||||
|
||||
DATA_SCHEMA = vol.Schema(
|
||||
@ -94,7 +104,15 @@ class TransmissionOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
default=self.config_entry.options.get(
|
||||
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
||||
),
|
||||
): int
|
||||
): int,
|
||||
vol.Optional(
|
||||
CONF_LIMIT,
|
||||
default=self.config_entry.options.get(CONF_LIMIT, DEFAULT_LIMIT),
|
||||
): vol.All(vol.Coerce(int), vol.Range(min=1, max=500)),
|
||||
vol.Optional(
|
||||
CONF_ORDER,
|
||||
default=self.config_entry.options.get(CONF_ORDER, DEFAULT_ORDER),
|
||||
): vol.All(vol.Coerce(str), vol.In(SUPPORTED_ORDER_MODES.keys())),
|
||||
}
|
||||
|
||||
return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
|
||||
|
@ -1,10 +1,30 @@
|
||||
"""Constants for the Transmission Bittorent Client component."""
|
||||
|
||||
DOMAIN = "transmission"
|
||||
|
||||
SWITCH_TYPES = {"on_off": "Switch", "turtle_mode": "Turtle Mode"}
|
||||
|
||||
ORDER_NEWEST_FIRST = "newest_first"
|
||||
ORDER_OLDEST_FIRST = "oldest_first"
|
||||
ORDER_BEST_RATIO_FIRST = "best_ratio_first"
|
||||
ORDER_WORST_RATIO_FIRST = "worst_ratio_first"
|
||||
|
||||
SUPPORTED_ORDER_MODES = {
|
||||
ORDER_NEWEST_FIRST: lambda torrents: sorted(
|
||||
torrents, key=lambda t: t.addedDate, reverse=True
|
||||
),
|
||||
ORDER_OLDEST_FIRST: lambda torrents: sorted(torrents, key=lambda t: t.addedDate),
|
||||
ORDER_WORST_RATIO_FIRST: lambda torrents: sorted(torrents, key=lambda t: t.ratio),
|
||||
ORDER_BEST_RATIO_FIRST: lambda torrents: sorted(
|
||||
torrents, key=lambda t: t.ratio, reverse=True
|
||||
),
|
||||
}
|
||||
|
||||
CONF_LIMIT = "limit"
|
||||
CONF_ORDER = "order"
|
||||
|
||||
DEFAULT_DELETE_DATA = False
|
||||
DEFAULT_LIMIT = 10
|
||||
DEFAULT_ORDER = ORDER_OLDEST_FIRST
|
||||
DEFAULT_NAME = "Transmission"
|
||||
DEFAULT_PORT = 9091
|
||||
DEFAULT_SCAN_INTERVAL = 120
|
||||
|
@ -6,7 +6,13 @@ from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN, STATE_ATTR_TORRENT_INFO
|
||||
from .const import (
|
||||
CONF_LIMIT,
|
||||
CONF_ORDER,
|
||||
DOMAIN,
|
||||
STATE_ATTR_TORRENT_INFO,
|
||||
SUPPORTED_ORDER_MODES,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -143,28 +149,45 @@ class TransmissionTorrentsSensor(TransmissionSensor):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes, if any."""
|
||||
limit = self._tm_client.config_entry.options[CONF_LIMIT]
|
||||
order = self._tm_client.config_entry.options[CONF_ORDER]
|
||||
torrents = self._tm_client.api.torrents[0:limit]
|
||||
info = _torrents_info(
|
||||
self._tm_client.api.torrents, self.SUBTYPE_MODES[self._sub_type]
|
||||
torrents, order=order, statuses=self.SUBTYPE_MODES[self._sub_type],
|
||||
)
|
||||
return {STATE_ATTR_TORRENT_INFO: info}
|
||||
return {
|
||||
STATE_ATTR_TORRENT_INFO: info,
|
||||
}
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data from Transmission and updates the state."""
|
||||
self._state = len(self.device_state_attributes[STATE_ATTR_TORRENT_INFO])
|
||||
torrents = _filter_torrents(
|
||||
self._tm_client.api.torrents, statuses=self.SUBTYPE_MODES[self._sub_type]
|
||||
)
|
||||
self._state = len(torrents)
|
||||
|
||||
|
||||
def _torrents_info(torrents, statuses=None):
|
||||
def _filter_torrents(torrents, statuses=None):
|
||||
return [
|
||||
torrent
|
||||
for torrent in torrents
|
||||
if statuses is None or torrent.status in statuses
|
||||
]
|
||||
|
||||
|
||||
def _torrents_info(torrents, order, statuses=None):
|
||||
infos = {}
|
||||
for torrent in torrents:
|
||||
if statuses is None or torrent.status in statuses:
|
||||
info = infos[torrent.name] = {
|
||||
"added_date": torrent.addedDate,
|
||||
"percent_done": f"{torrent.percentDone * 100:.2f}",
|
||||
"status": torrent.status,
|
||||
"id": torrent.id,
|
||||
}
|
||||
try:
|
||||
info["eta"] = str(torrent.eta)
|
||||
except ValueError:
|
||||
pass
|
||||
torrents = _filter_torrents(torrents, statuses)
|
||||
torrents = SUPPORTED_ORDER_MODES[order](torrents)
|
||||
for torrent in _filter_torrents(torrents, statuses):
|
||||
info = infos[torrent.name] = {
|
||||
"added_date": torrent.addedDate,
|
||||
"percent_done": f"{torrent.percentDone * 100:.2f}",
|
||||
"status": torrent.status,
|
||||
"id": torrent.id,
|
||||
}
|
||||
try:
|
||||
info["eta"] = str(torrent.eta)
|
||||
except ValueError:
|
||||
pass
|
||||
return infos
|
||||
|
@ -8,7 +8,9 @@
|
||||
"host": "[%key:common::config_flow::data::host%]",
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"port": "[%key:common::config_flow::data::port%]"
|
||||
"port": "[%key:common::config_flow::data::port%]",
|
||||
"limit": "Limit",
|
||||
"order": "Order"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -12,6 +12,8 @@
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "Host",
|
||||
"limit": "Limit",
|
||||
"order": "Order",
|
||||
"name": "Name",
|
||||
"password": "Password",
|
||||
"port": "Port",
|
||||
@ -25,7 +27,9 @@
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"scan_interval": "Update frequency"
|
||||
"scan_interval": "Update frequency",
|
||||
"limit": "Limit",
|
||||
"order": "Order"
|
||||
},
|
||||
"title": "Configure options for Transmission"
|
||||
}
|
||||
|
@ -8,7 +8,11 @@ from homeassistant import data_entry_flow
|
||||
from homeassistant.components import transmission
|
||||
from homeassistant.components.transmission import config_flow
|
||||
from homeassistant.components.transmission.const import (
|
||||
CONF_LIMIT,
|
||||
CONF_ORDER,
|
||||
DEFAULT_LIMIT,
|
||||
DEFAULT_NAME,
|
||||
DEFAULT_ORDER,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
)
|
||||
@ -158,6 +162,8 @@ async def test_import(hass, api):
|
||||
CONF_HOST: HOST,
|
||||
CONF_PORT: DEFAULT_PORT,
|
||||
CONF_SCAN_INTERVAL: timedelta(seconds=DEFAULT_SCAN_INTERVAL),
|
||||
CONF_LIMIT: DEFAULT_LIMIT,
|
||||
CONF_ORDER: DEFAULT_ORDER,
|
||||
}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
@ -176,6 +182,8 @@ async def test_import(hass, api):
|
||||
CONF_PASSWORD: PASSWORD,
|
||||
CONF_PORT: PORT,
|
||||
CONF_SCAN_INTERVAL: timedelta(seconds=SCAN_INTERVAL),
|
||||
CONF_LIMIT: DEFAULT_LIMIT,
|
||||
CONF_ORDER: DEFAULT_ORDER,
|
||||
}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
|
@ -81,7 +81,9 @@ async def test_successful_config_entry(hass, api):
|
||||
|
||||
assert await transmission.async_setup_entry(hass, entry) is True
|
||||
assert entry.options == {
|
||||
transmission.CONF_SCAN_INTERVAL: transmission.DEFAULT_SCAN_INTERVAL
|
||||
transmission.CONF_SCAN_INTERVAL: transmission.DEFAULT_SCAN_INTERVAL,
|
||||
transmission.CONF_LIMIT: transmission.DEFAULT_LIMIT,
|
||||
transmission.CONF_ORDER: transmission.DEFAULT_ORDER,
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user