Add config option to ignore Plex Web clients (#34708)

This commit is contained in:
jjlawren 2020-05-08 11:49:15 -05:00 committed by GitHub
parent e56dd8ed50
commit ad419911bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 3 deletions

View File

@ -30,6 +30,7 @@ from .const import ( # pylint: disable=unused-import
AUTOMATIC_SETUP_STRING,
CONF_CLIENT_IDENTIFIER,
CONF_IGNORE_NEW_SHARED_USERS,
CONF_IGNORE_PLEX_WEB_CLIENTS,
CONF_MONITORED_USERS,
CONF_SERVER,
CONF_SERVER_IDENTIFIER,
@ -329,6 +330,9 @@ class PlexOptionsFlowHandler(config_entries.OptionsFlow):
self.options[MP_DOMAIN][CONF_IGNORE_NEW_SHARED_USERS] = user_input[
CONF_IGNORE_NEW_SHARED_USERS
]
self.options[MP_DOMAIN][CONF_IGNORE_PLEX_WEB_CLIENTS] = user_input[
CONF_IGNORE_PLEX_WEB_CLIENTS
]
account_data = {
user: {"enabled": bool(user in user_input[CONF_MONITORED_USERS])}
@ -373,6 +377,10 @@ class PlexOptionsFlowHandler(config_entries.OptionsFlow):
CONF_IGNORE_NEW_SHARED_USERS,
default=plex_server.option_ignore_new_shared_users,
): bool,
vol.Required(
CONF_IGNORE_PLEX_WEB_CLIENTS,
default=plex_server.option_ignore_plexweb_clients,
): bool,
}
),
)

View File

@ -30,6 +30,7 @@ CONF_SERVER_IDENTIFIER = "server_id"
CONF_USE_EPISODE_ART = "use_episode_art"
CONF_SHOW_ALL_CONTROLS = "show_all_controls"
CONF_IGNORE_NEW_SHARED_USERS = "ignore_new_shared_users"
CONF_IGNORE_PLEX_WEB_CLIENTS = "ignore_plex_web_clients"
CONF_MONITORED_USERS = "monitored_users"
AUTH_CALLBACK_PATH = "/auth/plex/callback"

View File

@ -19,6 +19,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
from .const import (
CONF_CLIENT_IDENTIFIER,
CONF_IGNORE_NEW_SHARED_USERS,
CONF_IGNORE_PLEX_WEB_CLIENTS,
CONF_MONITORED_USERS,
CONF_SERVER,
CONF_USE_EPISODE_ART,
@ -50,6 +51,7 @@ class PlexServer:
"""Initialize a Plex server instance."""
self.hass = hass
self._plex_server = None
self._created_clients = set()
self._known_clients = set()
self._known_idle = set()
self._url = server_config.get(CONF_URL)
@ -217,7 +219,23 @@ class PlexServer:
self._known_idle.discard(device.machineIdentifier)
available_clients.setdefault(device.machineIdentifier, {"device": device})
if device.machineIdentifier not in self._known_clients:
if device.machineIdentifier not in ignored_clients:
if self.option_ignore_plexweb_clients and device.product == "Plex Web":
ignored_clients.add(device.machineIdentifier)
if device.machineIdentifier not in self._known_clients:
_LOGGER.debug(
"Ignoring %s %s: %s",
"Plex Web",
source,
device.machineIdentifier,
)
return
if (
device.machineIdentifier not in self._created_clients
and device.machineIdentifier not in ignored_clients
and device.machineIdentifier not in new_clients
):
new_clients.add(device.machineIdentifier)
_LOGGER.debug(
"New %s %s: %s", device.product, source, device.machineIdentifier
@ -250,6 +268,7 @@ class PlexServer:
continue
if client_id in new_clients:
new_entity_configs.append(client_data)
self._created_clients.add(client_id)
else:
self.async_refresh_entity(
client_id, client_data["device"], client_data.get("session")
@ -327,6 +346,11 @@ class PlexServer:
"""Return dict of monitored users option."""
return self.options[MP_DOMAIN].get(CONF_MONITORED_USERS, {})
@property
def option_ignore_plexweb_clients(self):
"""Return ignore_plex_web_clients option."""
return self.options[MP_DOMAIN].get(CONF_IGNORE_PLEX_WEB_CLIENTS, False)
@property
def library(self):
"""Return library attribute from server object."""

View File

@ -51,7 +51,8 @@
"data": {
"use_episode_art": "Use episode art",
"ignore_new_shared_users": "Ignore new managed/shared users",
"monitored_users": "Monitored users"
"monitored_users": "Monitored users",
"ignore_plex_web_clients": "Ignore Plex Web clients"
}
}
}

View File

@ -134,6 +134,7 @@ class MockPlexClient:
"""Initialize the object."""
self.machineIdentifier = f"client-{index+1}"
self._baseurl = url
self._index = index
def url(self, key):
"""Mock the url method."""
@ -152,6 +153,8 @@ class MockPlexClient:
@property
def product(self):
"""Mock the product attribute."""
if self._index == 1:
return "Plex Web"
return "PRODUCT"
@property

View File

@ -10,6 +10,7 @@ from homeassistant.components.plex import config_flow
from homeassistant.components.plex.const import (
AUTOMATIC_SETUP_STRING,
CONF_IGNORE_NEW_SHARED_USERS,
CONF_IGNORE_PLEX_WEB_CLIENTS,
CONF_MONITORED_USERS,
CONF_SERVER,
CONF_SERVER_IDENTIFIER,
@ -428,6 +429,7 @@ async def test_option_flow(hass):
CONF_MONITORED_USERS: {
user: {"enabled": True} for user in mock_plex_server.accounts
},
CONF_IGNORE_PLEX_WEB_CLIENTS: False,
}
}

View File

@ -4,6 +4,7 @@ import copy
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
from homeassistant.components.plex.const import (
CONF_IGNORE_NEW_SHARED_USERS,
CONF_IGNORE_PLEX_WEB_CLIENTS,
CONF_MONITORED_USERS,
DOMAIN,
PLEX_UPDATE_PLATFORMS_SIGNAL,
@ -94,7 +95,7 @@ async def test_new_ignored_users_available(hass, caplog):
ignored_client = [
x.players[0]
for x in mock_plex_server.sessions()
if x.usernames[0] in ignored_users
if x.usernames[0] == ignored_user
][0]
assert (
f"Ignoring {ignored_client.product} client owned by '{ignored_user}'"
@ -208,3 +209,38 @@ async def test_new_ignored_users_available(hass, caplog):
# await self.advance(DEBOUNCE_TIMEOUT)
# await hass.async_block_till_done()
# assert mock_update.call_count == 3
async def test_ignore_plex_web_client(hass):
"""Test option to ignore Plex Web clients."""
OPTIONS = copy.deepcopy(DEFAULT_OPTIONS)
OPTIONS[MP_DOMAIN][CONF_IGNORE_PLEX_WEB_CLIENTS] = True
entry = MockConfigEntry(
domain=DOMAIN,
data=DEFAULT_DATA,
options=OPTIONS,
unique_id=DEFAULT_DATA["server_id"],
)
mock_plex_server = MockPlexServer(config_entry=entry)
with patch("plexapi.server.PlexServer", return_value=mock_plex_server), patch(
"homeassistant.components.plex.PlexWebsocket.listen"
):
entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
server_id = mock_plex_server.machineIdentifier
async_dispatcher_send(hass, PLEX_UPDATE_PLATFORMS_SIGNAL.format(server_id))
await hass.async_block_till_done()
sensor = hass.states.get("sensor.plex_plex_server_1")
assert sensor.state == str(len(mock_plex_server.accounts))
media_players = hass.states.async_entity_ids("media_player")
assert len(media_players) == int(sensor.state) - 1