Add torrent id to Transmission events (#44187)

* Fire event after object update; clarify code across related methods

* Change var to torrent, clarity

* Add typehints,  _ prefix private attributes
This commit is contained in:
J.P. Hutchins 2021-01-08 07:53:47 -08:00 committed by GitHub
parent d99bc99d9b
commit 793adb7f40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 52 deletions

View File

@ -1,6 +1,7 @@
"""Support for the Transmission BitTorrent client API.""" """Support for the Transmission BitTorrent client API."""
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import List
import transmissionrpc import transmissionrpc
from transmissionrpc.error import TransmissionError from transmissionrpc.error import TransmissionError
@ -152,13 +153,13 @@ class TransmissionClient:
"""Initialize the Transmission RPC API.""" """Initialize the Transmission RPC API."""
self.hass = hass self.hass = hass
self.config_entry = config_entry self.config_entry = config_entry
self.tm_api = None self.tm_api = None # type: transmissionrpc.Client
self._tm_data = None self._tm_data = None # type: TransmissionData
self.unsub_timer = None self.unsub_timer = None
@property @property
def api(self): def api(self) -> "TransmissionData":
"""Return the tm_data object.""" """Return the TransmissionData object."""
return self._tm_data return self._tm_data
async def async_setup(self): async def async_setup(self):
@ -278,18 +279,18 @@ class TransmissionClient:
class TransmissionData: class TransmissionData:
"""Get the latest data and update the states.""" """Get the latest data and update the states."""
def __init__(self, hass, config, api): def __init__(self, hass, config, api: transmissionrpc.Client):
"""Initialize the Transmission RPC API.""" """Initialize the Transmission RPC API."""
self.hass = hass self.hass = hass
self.config = config self.config = config
self.data = None self.data = None # type: transmissionrpc.Session
self.torrents = [] self.available = True # type: bool
self.session = None self._all_torrents = [] # type: List[transmissionrpc.Torrent]
self.available = True self._api = api # type: transmissionrpc.Client
self._api = api self._completed_torrents = [] # type: List[transmissionrpc.Torrent]
self.completed_torrents = [] self._session = None # type: transmissionrpc.Session
self.started_torrents = [] self._started_torrents = [] # type: List[transmissionrpc.Torrent]
self.all_torrents = [] self._torrents = [] # type: List[transmissionrpc.Torrent]
@property @property
def host(self): def host(self):
@ -301,12 +302,17 @@ class TransmissionData:
"""Update signal per transmission entry.""" """Update signal per transmission entry."""
return f"{DATA_UPDATED}-{self.host}" return f"{DATA_UPDATED}-{self.host}"
@property
def torrents(self) -> List[transmissionrpc.Torrent]:
"""Get the list of torrents."""
return self._torrents
def update(self): def update(self):
"""Get the latest data from Transmission instance.""" """Get the latest data from Transmission instance."""
try: try:
self.data = self._api.session_stats() self.data = self._api.session_stats()
self.torrents = self._api.get_torrents() self._torrents = self._api.get_torrents()
self.session = self._api.get_session() self._session = self._api.get_session()
self.check_completed_torrent() self.check_completed_torrent()
self.check_started_torrent() self.check_started_torrent()
@ -321,64 +327,62 @@ class TransmissionData:
def init_torrent_list(self): def init_torrent_list(self):
"""Initialize torrent lists.""" """Initialize torrent lists."""
self.torrents = self._api.get_torrents() self._torrents = self._api.get_torrents()
self.completed_torrents = [ self._completed_torrents = [
x.name for x in self.torrents if x.status == "seeding" torrent for torrent in self._torrents if torrent.status == "seeding"
] ]
self.started_torrents = [ self._started_torrents = [
x.name for x in self.torrents if x.status == "downloading" torrent for torrent in self._torrents if torrent.status == "downloading"
] ]
def check_completed_torrent(self): def check_completed_torrent(self):
"""Get completed torrent functionality.""" """Get completed torrent functionality."""
actual_torrents = self.torrents current_completed_torrents = [
actual_completed_torrents = [ torrent for torrent in self._torrents if torrent.status == "seeding"
var.name for var in actual_torrents if var.status == "seeding"
] ]
freshly_completed_torrents = set(current_completed_torrents).difference(
tmp_completed_torrents = list( self._completed_torrents
set(actual_completed_torrents).difference(self.completed_torrents)
) )
self._completed_torrents = current_completed_torrents
for var in tmp_completed_torrents: for torrent in freshly_completed_torrents:
self.hass.bus.fire(EVENT_DOWNLOADED_TORRENT, {"name": var}) self.hass.bus.fire(
EVENT_DOWNLOADED_TORRENT, {"name": torrent.name, "id": torrent.id}
self.completed_torrents = actual_completed_torrents )
def check_started_torrent(self): def check_started_torrent(self):
"""Get started torrent functionality.""" """Get started torrent functionality."""
actual_torrents = self.torrents current_started_torrents = [
actual_started_torrents = [ torrent for torrent in self._torrents if torrent.status == "downloading"
var.name for var in actual_torrents if var.status == "downloading"
] ]
freshly_started_torrents = set(current_started_torrents).difference(
tmp_started_torrents = list( self._started_torrents
set(actual_started_torrents).difference(self.started_torrents)
) )
self._started_torrents = current_started_torrents
for var in tmp_started_torrents: for torrent in freshly_started_torrents:
self.hass.bus.fire(EVENT_STARTED_TORRENT, {"name": var}) self.hass.bus.fire(
self.started_torrents = actual_started_torrents EVENT_STARTED_TORRENT, {"name": torrent.name, "id": torrent.id}
)
def check_removed_torrent(self): def check_removed_torrent(self):
"""Get removed torrent functionality.""" """Get removed torrent functionality."""
actual_torrents = self.torrents freshly_removed_torrents = set(self._all_torrents).difference(self._torrents)
actual_all_torrents = [var.name for var in actual_torrents] self._all_torrents = self._torrents
for torrent in freshly_removed_torrents:
removed_torrents = list(set(self.all_torrents).difference(actual_all_torrents)) self.hass.bus.fire(
for var in removed_torrents: EVENT_REMOVED_TORRENT, {"name": torrent.name, "id": torrent.id}
self.hass.bus.fire(EVENT_REMOVED_TORRENT, {"name": var}) )
self.all_torrents = actual_all_torrents
def start_torrents(self): def start_torrents(self):
"""Start all torrents.""" """Start all torrents."""
if len(self.torrents) <= 0: if len(self._torrents) <= 0:
return return
self._api.start_all() self._api.start_all()
def stop_torrents(self): def stop_torrents(self):
"""Stop all active torrents.""" """Stop all active torrents."""
torrent_ids = [torrent.id for torrent in self.torrents] torrent_ids = [torrent.id for torrent in self._torrents]
self._api.stop_torrent(torrent_ids) self._api.stop_torrent(torrent_ids)
def set_alt_speed_enabled(self, is_enabled): def set_alt_speed_enabled(self, is_enabled):
@ -387,7 +391,7 @@ class TransmissionData:
def get_alt_speed_enabled(self): def get_alt_speed_enabled(self):
"""Get the alternative speed flag.""" """Get the alternative speed flag."""
if self.session is None: if self._session is None:
return None return None
return self.session.alt_speed_enabled return self._session.alt_speed_enabled

View File

@ -1,9 +1,14 @@
"""Support for monitoring the Transmission BitTorrent client API.""" """Support for monitoring the Transmission BitTorrent client API."""
from typing import List
from transmissionrpc.torrent import Torrent
from homeassistant.const import CONF_NAME, DATA_RATE_MEGABYTES_PER_SECOND, STATE_IDLE from homeassistant.const import CONF_NAME, DATA_RATE_MEGABYTES_PER_SECOND, STATE_IDLE
from homeassistant.core import callback 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 . import TransmissionClient
from .const import ( from .const import (
CONF_LIMIT, CONF_LIMIT,
CONF_ORDER, CONF_ORDER,
@ -38,7 +43,7 @@ class TransmissionSensor(Entity):
def __init__(self, tm_client, client_name, sensor_name, sub_type=None): def __init__(self, tm_client, client_name, sensor_name, sub_type=None):
"""Initialize the sensor.""" """Initialize the sensor."""
self._tm_client = tm_client self._tm_client = tm_client # type: TransmissionClient
self._client_name = client_name self._client_name = client_name
self._name = sensor_name self._name = sensor_name
self._sub_type = sub_type self._sub_type = sub_type
@ -163,7 +168,7 @@ class TransmissionTorrentsSensor(TransmissionSensor):
self._state = len(torrents) self._state = len(torrents)
def _filter_torrents(torrents, statuses=None): def _filter_torrents(torrents: List[Torrent], statuses=None) -> List[Torrent]:
return [ return [
torrent torrent
for torrent in torrents for torrent in torrents