mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 10:17:51 +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 (
|
from .const import (
|
||||||
ATTR_DELETE_DATA,
|
ATTR_DELETE_DATA,
|
||||||
ATTR_TORRENT,
|
ATTR_TORRENT,
|
||||||
|
CONF_LIMIT,
|
||||||
|
CONF_ORDER,
|
||||||
DATA_UPDATED,
|
DATA_UPDATED,
|
||||||
DEFAULT_DELETE_DATA,
|
DEFAULT_DELETE_DATA,
|
||||||
|
DEFAULT_LIMIT,
|
||||||
DEFAULT_NAME,
|
DEFAULT_NAME,
|
||||||
|
DEFAULT_ORDER,
|
||||||
DEFAULT_PORT,
|
DEFAULT_PORT,
|
||||||
DEFAULT_SCAN_INTERVAL,
|
DEFAULT_SCAN_INTERVAL,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -238,7 +242,13 @@ class TransmissionClient:
|
|||||||
scan_interval = self.config_entry.data.get(
|
scan_interval = self.config_entry.data.get(
|
||||||
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
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.hass.config_entries.async_update_entry(
|
||||||
self.config_entry, options=options
|
self.config_entry, options=options
|
||||||
@ -260,9 +270,9 @@ class TransmissionClient:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
async def async_options_updated(hass, entry):
|
async def async_options_updated(hass, entry):
|
||||||
"""Triggered by config entry options updates."""
|
"""Triggered by config entry options updates."""
|
||||||
hass.data[DOMAIN][entry.entry_id].set_scan_interval(
|
tm_client = hass.data[DOMAIN][entry.entry_id]
|
||||||
entry.options[CONF_SCAN_INTERVAL]
|
tm_client.set_scan_interval(entry.options[CONF_SCAN_INTERVAL])
|
||||||
)
|
await hass.async_add_executor_job(tm_client.api.update)
|
||||||
|
|
||||||
|
|
||||||
class TransmissionData:
|
class TransmissionData:
|
||||||
|
@ -13,7 +13,17 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
|
|
||||||
from . import get_api
|
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
|
from .errors import AuthenticationError, CannotConnect, UnknownError
|
||||||
|
|
||||||
DATA_SCHEMA = vol.Schema(
|
DATA_SCHEMA = vol.Schema(
|
||||||
@ -94,7 +104,15 @@ class TransmissionOptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
default=self.config_entry.options.get(
|
default=self.config_entry.options.get(
|
||||||
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
|
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))
|
return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
|
||||||
|
@ -1,10 +1,30 @@
|
|||||||
"""Constants for the Transmission Bittorent Client component."""
|
"""Constants for the Transmission Bittorent Client component."""
|
||||||
|
|
||||||
DOMAIN = "transmission"
|
DOMAIN = "transmission"
|
||||||
|
|
||||||
SWITCH_TYPES = {"on_off": "Switch", "turtle_mode": "Turtle Mode"}
|
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_DELETE_DATA = False
|
||||||
|
DEFAULT_LIMIT = 10
|
||||||
|
DEFAULT_ORDER = ORDER_OLDEST_FIRST
|
||||||
DEFAULT_NAME = "Transmission"
|
DEFAULT_NAME = "Transmission"
|
||||||
DEFAULT_PORT = 9091
|
DEFAULT_PORT = 9091
|
||||||
DEFAULT_SCAN_INTERVAL = 120
|
DEFAULT_SCAN_INTERVAL = 120
|
||||||
|
@ -6,7 +6,13 @@ from homeassistant.core import callback
|
|||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity import Entity
|
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__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -143,28 +149,45 @@ class TransmissionTorrentsSensor(TransmissionSensor):
|
|||||||
@property
|
@property
|
||||||
def device_state_attributes(self):
|
def device_state_attributes(self):
|
||||||
"""Return the state attributes, if any."""
|
"""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(
|
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):
|
def update(self):
|
||||||
"""Get the latest data from Transmission and updates the state."""
|
"""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 = {}
|
infos = {}
|
||||||
for torrent in torrents:
|
torrents = _filter_torrents(torrents, statuses)
|
||||||
if statuses is None or torrent.status in statuses:
|
torrents = SUPPORTED_ORDER_MODES[order](torrents)
|
||||||
info = infos[torrent.name] = {
|
for torrent in _filter_torrents(torrents, statuses):
|
||||||
"added_date": torrent.addedDate,
|
info = infos[torrent.name] = {
|
||||||
"percent_done": f"{torrent.percentDone * 100:.2f}",
|
"added_date": torrent.addedDate,
|
||||||
"status": torrent.status,
|
"percent_done": f"{torrent.percentDone * 100:.2f}",
|
||||||
"id": torrent.id,
|
"status": torrent.status,
|
||||||
}
|
"id": torrent.id,
|
||||||
try:
|
}
|
||||||
info["eta"] = str(torrent.eta)
|
try:
|
||||||
except ValueError:
|
info["eta"] = str(torrent.eta)
|
||||||
pass
|
except ValueError:
|
||||||
|
pass
|
||||||
return infos
|
return infos
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
"host": "[%key:common::config_flow::data::host%]",
|
"host": "[%key:common::config_flow::data::host%]",
|
||||||
"username": "[%key:common::config_flow::data::username%]",
|
"username": "[%key:common::config_flow::data::username%]",
|
||||||
"password": "[%key:common::config_flow::data::password%]",
|
"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": {
|
"user": {
|
||||||
"data": {
|
"data": {
|
||||||
"host": "Host",
|
"host": "Host",
|
||||||
|
"limit": "Limit",
|
||||||
|
"order": "Order",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
@ -25,7 +27,9 @@
|
|||||||
"step": {
|
"step": {
|
||||||
"init": {
|
"init": {
|
||||||
"data": {
|
"data": {
|
||||||
"scan_interval": "Update frequency"
|
"scan_interval": "Update frequency",
|
||||||
|
"limit": "Limit",
|
||||||
|
"order": "Order"
|
||||||
},
|
},
|
||||||
"title": "Configure options for Transmission"
|
"title": "Configure options for Transmission"
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,11 @@ from homeassistant import data_entry_flow
|
|||||||
from homeassistant.components import transmission
|
from homeassistant.components import transmission
|
||||||
from homeassistant.components.transmission import config_flow
|
from homeassistant.components.transmission import config_flow
|
||||||
from homeassistant.components.transmission.const import (
|
from homeassistant.components.transmission.const import (
|
||||||
|
CONF_LIMIT,
|
||||||
|
CONF_ORDER,
|
||||||
|
DEFAULT_LIMIT,
|
||||||
DEFAULT_NAME,
|
DEFAULT_NAME,
|
||||||
|
DEFAULT_ORDER,
|
||||||
DEFAULT_PORT,
|
DEFAULT_PORT,
|
||||||
DEFAULT_SCAN_INTERVAL,
|
DEFAULT_SCAN_INTERVAL,
|
||||||
)
|
)
|
||||||
@ -158,6 +162,8 @@ async def test_import(hass, api):
|
|||||||
CONF_HOST: HOST,
|
CONF_HOST: HOST,
|
||||||
CONF_PORT: DEFAULT_PORT,
|
CONF_PORT: DEFAULT_PORT,
|
||||||
CONF_SCAN_INTERVAL: timedelta(seconds=DEFAULT_SCAN_INTERVAL),
|
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
|
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
@ -176,6 +182,8 @@ async def test_import(hass, api):
|
|||||||
CONF_PASSWORD: PASSWORD,
|
CONF_PASSWORD: PASSWORD,
|
||||||
CONF_PORT: PORT,
|
CONF_PORT: PORT,
|
||||||
CONF_SCAN_INTERVAL: timedelta(seconds=SCAN_INTERVAL),
|
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
|
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 await transmission.async_setup_entry(hass, entry) is True
|
||||||
assert entry.options == {
|
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