Skip to content

Commit

Permalink
Improve Plex media_player entity naming (#31755)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjlawren authored Feb 12, 2020
1 parent 8498ca3 commit 1b2f4fa
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
1 change: 1 addition & 0 deletions homeassistant/components/plex/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

DOMAIN = "plex"
NAME_FORMAT = "Plex ({})"
COMMON_PLAYERS = ["Plex Web"]

DEFAULT_PORT = 32400
DEFAULT_SSL = False
Expand Down
37 changes: 24 additions & 13 deletions homeassistant/components/plex/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,14 @@
SUPPORT_VOLUME_MUTE,
SUPPORT_VOLUME_SET,
)
from homeassistant.const import (
DEVICE_DEFAULT_NAME,
STATE_IDLE,
STATE_OFF,
STATE_PAUSED,
STATE_PLAYING,
)
from homeassistant.const import STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_registry import async_get_registry
from homeassistant.util import dt as dt_util

from .const import (
COMMON_PLAYERS,
CONF_SERVER_IDENTIFIER,
DISPATCHERS,
DOMAIN as PLEX_DOMAIN,
Expand Down Expand Up @@ -114,6 +109,8 @@ def __init__(self, plex_server, device, session=None):
self._is_player_active = False
self._machine_identifier = device.machineIdentifier
self._make = ""
self._device_product = None
self._device_title = None
self._name = None
self._player_state = "idle"
self._previous_volume_level = 1 # Used in fake muting
Expand Down Expand Up @@ -188,7 +185,6 @@ def update(self):
self._clear_media_details()

self._available = self.device or self.session
name_base = None

if self.device:
try:
Expand All @@ -197,7 +193,8 @@ def update(self):
device_url = "127.0.0.1"
if "127.0.0.1" in device_url:
self.device.proxyThroughServer()
name_base = self.device.title or self.device.product
self._device_product = self.device.product
self._device_title = self.device.title
self._device_protocol_capabilities = self.device.protocolCapabilities
self._player_state = self.device.state

Expand All @@ -215,11 +212,13 @@ def update(self):
if session_device:
self._make = session_device.device or ""
self._player_state = session_device.state
name_base = name_base or session_device.title or session_device.product
self._device_product = self._device_product or session_device.product
self._device_title = self._device_title or session_device.title
else:
_LOGGER.warning("No player associated with active session")

self._session_username = self.session.usernames[0]
if self.session.usernames:
self._session_username = self.session.usernames[0]

# Calculate throttled position for proper progress display.
position = int(self.session.viewOffset / 1000)
Expand All @@ -237,7 +236,14 @@ def update(self):
self._media_content_id = self.session.ratingKey
self._media_content_rating = getattr(self.session, "contentRating", None)

self._name = self._name or NAME_FORMAT.format(name_base or DEVICE_DEFAULT_NAME)
name_parts = [self._device_product, self._device_title]
if (self._device_product in COMMON_PLAYERS) and self.make:
# Add more context in name for likely duplicates
name_parts.append(self.make)
if self.username and self.username != self.plex_server.owner:
# Prepend username for shared/managed clients
name_parts.insert(0, self.username)
self._name = NAME_FORMAT.format(" - ".join(name_parts))
self._set_player_state()

if self._is_player_active and self.session is not None:
Expand Down Expand Up @@ -348,6 +354,11 @@ def name(self):
"""Return the name of the device."""
return self._name

@property
def username(self):
"""Return the username of the client owner."""
return self._session_username

@property
def app_name(self):
"""Return the library name of playing media."""
Expand Down Expand Up @@ -699,7 +710,7 @@ def device_state_attributes(self):
"""Return the scene state attributes."""
attr = {
"media_content_rating": self._media_content_rating,
"session_username": self._session_username,
"session_username": self.username,
"media_library_name": self._app_name,
}

Expand Down
14 changes: 14 additions & 0 deletions homeassistant/components/plex/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def __init__(self, hass, server_config, options=None):
self._verify_ssl = server_config.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)
self.options = options
self.server_choice = None
self._owner_username = None

# Header conditionally added as it is not available in config entry v1
if CONF_CLIENT_IDENTIFIER in server_config:
Expand Down Expand Up @@ -93,6 +94,14 @@ def _connect_with_url():
else:
_connect_with_token()

owner_account = [
account.name
for account in self._plex_server.systemAccounts()
if account.accountID == 1
]
if owner_account:
self._owner_username = owner_account[0]

def refresh_entity(self, machine_identifier, device, session):
"""Forward refresh dispatch to media_player."""
unique_id = f"{self.machine_identifier}:{machine_identifier}"
Expand Down Expand Up @@ -182,6 +191,11 @@ def plex_server(self):
"""Return the plexapi PlexServer instance."""
return self._plex_server

@property
def owner(self):
"""Return the Plex server owner username."""
return self._owner_username

@property
def friendly_name(self):
"""Return name of connected Plex server."""
Expand Down
14 changes: 14 additions & 0 deletions tests/components/plex/mock_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ def resources(self):
return self._resources


class MockPlexSystemAccount:
"""Mock a PlexSystemAccount instance."""

def __init__(self):
"""Initialize the object."""
self.name = "Dummy"
self.accountID = 1


class MockPlexServer:
"""Mock a PlexServer instance."""

Expand All @@ -68,6 +77,11 @@ def __init__(self, index=0, ssl=True):
]
prefix = "https" if ssl else "http"
self._baseurl = f"{prefix}://{host}:{port}"
self._systemAccount = MockPlexSystemAccount()

def systemAccounts(self):
"""Mock the systemAccounts lookup method."""
return [self._systemAccount]

@property
def url_in_use(self):
Expand Down

0 comments on commit 1b2f4fa

Please sign in to comment.