Add config option to ignore Plex Web clients (#34708)
This commit is contained in:
parent
e56dd8ed50
commit
ad419911bc
7 changed files with 78 additions and 3 deletions
|
@ -30,6 +30,7 @@ from .const import ( # pylint: disable=unused-import
|
||||||
AUTOMATIC_SETUP_STRING,
|
AUTOMATIC_SETUP_STRING,
|
||||||
CONF_CLIENT_IDENTIFIER,
|
CONF_CLIENT_IDENTIFIER,
|
||||||
CONF_IGNORE_NEW_SHARED_USERS,
|
CONF_IGNORE_NEW_SHARED_USERS,
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS,
|
||||||
CONF_MONITORED_USERS,
|
CONF_MONITORED_USERS,
|
||||||
CONF_SERVER,
|
CONF_SERVER,
|
||||||
CONF_SERVER_IDENTIFIER,
|
CONF_SERVER_IDENTIFIER,
|
||||||
|
@ -329,6 +330,9 @@ class PlexOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
self.options[MP_DOMAIN][CONF_IGNORE_NEW_SHARED_USERS] = user_input[
|
self.options[MP_DOMAIN][CONF_IGNORE_NEW_SHARED_USERS] = user_input[
|
||||||
CONF_IGNORE_NEW_SHARED_USERS
|
CONF_IGNORE_NEW_SHARED_USERS
|
||||||
]
|
]
|
||||||
|
self.options[MP_DOMAIN][CONF_IGNORE_PLEX_WEB_CLIENTS] = user_input[
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS
|
||||||
|
]
|
||||||
|
|
||||||
account_data = {
|
account_data = {
|
||||||
user: {"enabled": bool(user in user_input[CONF_MONITORED_USERS])}
|
user: {"enabled": bool(user in user_input[CONF_MONITORED_USERS])}
|
||||||
|
@ -373,6 +377,10 @@ class PlexOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
CONF_IGNORE_NEW_SHARED_USERS,
|
CONF_IGNORE_NEW_SHARED_USERS,
|
||||||
default=plex_server.option_ignore_new_shared_users,
|
default=plex_server.option_ignore_new_shared_users,
|
||||||
): bool,
|
): bool,
|
||||||
|
vol.Required(
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS,
|
||||||
|
default=plex_server.option_ignore_plexweb_clients,
|
||||||
|
): bool,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,6 +30,7 @@ CONF_SERVER_IDENTIFIER = "server_id"
|
||||||
CONF_USE_EPISODE_ART = "use_episode_art"
|
CONF_USE_EPISODE_ART = "use_episode_art"
|
||||||
CONF_SHOW_ALL_CONTROLS = "show_all_controls"
|
CONF_SHOW_ALL_CONTROLS = "show_all_controls"
|
||||||
CONF_IGNORE_NEW_SHARED_USERS = "ignore_new_shared_users"
|
CONF_IGNORE_NEW_SHARED_USERS = "ignore_new_shared_users"
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS = "ignore_plex_web_clients"
|
||||||
CONF_MONITORED_USERS = "monitored_users"
|
CONF_MONITORED_USERS = "monitored_users"
|
||||||
|
|
||||||
AUTH_CALLBACK_PATH = "/auth/plex/callback"
|
AUTH_CALLBACK_PATH = "/auth/plex/callback"
|
||||||
|
|
|
@ -19,6 +19,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from .const import (
|
from .const import (
|
||||||
CONF_CLIENT_IDENTIFIER,
|
CONF_CLIENT_IDENTIFIER,
|
||||||
CONF_IGNORE_NEW_SHARED_USERS,
|
CONF_IGNORE_NEW_SHARED_USERS,
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS,
|
||||||
CONF_MONITORED_USERS,
|
CONF_MONITORED_USERS,
|
||||||
CONF_SERVER,
|
CONF_SERVER,
|
||||||
CONF_USE_EPISODE_ART,
|
CONF_USE_EPISODE_ART,
|
||||||
|
@ -50,6 +51,7 @@ class PlexServer:
|
||||||
"""Initialize a Plex server instance."""
|
"""Initialize a Plex server instance."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self._plex_server = None
|
self._plex_server = None
|
||||||
|
self._created_clients = set()
|
||||||
self._known_clients = set()
|
self._known_clients = set()
|
||||||
self._known_idle = set()
|
self._known_idle = set()
|
||||||
self._url = server_config.get(CONF_URL)
|
self._url = server_config.get(CONF_URL)
|
||||||
|
@ -217,7 +219,23 @@ class PlexServer:
|
||||||
self._known_idle.discard(device.machineIdentifier)
|
self._known_idle.discard(device.machineIdentifier)
|
||||||
available_clients.setdefault(device.machineIdentifier, {"device": device})
|
available_clients.setdefault(device.machineIdentifier, {"device": device})
|
||||||
|
|
||||||
|
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:
|
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)
|
new_clients.add(device.machineIdentifier)
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"New %s %s: %s", device.product, source, device.machineIdentifier
|
"New %s %s: %s", device.product, source, device.machineIdentifier
|
||||||
|
@ -250,6 +268,7 @@ class PlexServer:
|
||||||
continue
|
continue
|
||||||
if client_id in new_clients:
|
if client_id in new_clients:
|
||||||
new_entity_configs.append(client_data)
|
new_entity_configs.append(client_data)
|
||||||
|
self._created_clients.add(client_id)
|
||||||
else:
|
else:
|
||||||
self.async_refresh_entity(
|
self.async_refresh_entity(
|
||||||
client_id, client_data["device"], client_data.get("session")
|
client_id, client_data["device"], client_data.get("session")
|
||||||
|
@ -327,6 +346,11 @@ class PlexServer:
|
||||||
"""Return dict of monitored users option."""
|
"""Return dict of monitored users option."""
|
||||||
return self.options[MP_DOMAIN].get(CONF_MONITORED_USERS, {})
|
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
|
@property
|
||||||
def library(self):
|
def library(self):
|
||||||
"""Return library attribute from server object."""
|
"""Return library attribute from server object."""
|
||||||
|
|
|
@ -51,7 +51,8 @@
|
||||||
"data": {
|
"data": {
|
||||||
"use_episode_art": "Use episode art",
|
"use_episode_art": "Use episode art",
|
||||||
"ignore_new_shared_users": "Ignore new managed/shared users",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,7 @@ class MockPlexClient:
|
||||||
"""Initialize the object."""
|
"""Initialize the object."""
|
||||||
self.machineIdentifier = f"client-{index+1}"
|
self.machineIdentifier = f"client-{index+1}"
|
||||||
self._baseurl = url
|
self._baseurl = url
|
||||||
|
self._index = index
|
||||||
|
|
||||||
def url(self, key):
|
def url(self, key):
|
||||||
"""Mock the url method."""
|
"""Mock the url method."""
|
||||||
|
@ -152,6 +153,8 @@ class MockPlexClient:
|
||||||
@property
|
@property
|
||||||
def product(self):
|
def product(self):
|
||||||
"""Mock the product attribute."""
|
"""Mock the product attribute."""
|
||||||
|
if self._index == 1:
|
||||||
|
return "Plex Web"
|
||||||
return "PRODUCT"
|
return "PRODUCT"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -10,6 +10,7 @@ from homeassistant.components.plex import config_flow
|
||||||
from homeassistant.components.plex.const import (
|
from homeassistant.components.plex.const import (
|
||||||
AUTOMATIC_SETUP_STRING,
|
AUTOMATIC_SETUP_STRING,
|
||||||
CONF_IGNORE_NEW_SHARED_USERS,
|
CONF_IGNORE_NEW_SHARED_USERS,
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS,
|
||||||
CONF_MONITORED_USERS,
|
CONF_MONITORED_USERS,
|
||||||
CONF_SERVER,
|
CONF_SERVER,
|
||||||
CONF_SERVER_IDENTIFIER,
|
CONF_SERVER_IDENTIFIER,
|
||||||
|
@ -428,6 +429,7 @@ async def test_option_flow(hass):
|
||||||
CONF_MONITORED_USERS: {
|
CONF_MONITORED_USERS: {
|
||||||
user: {"enabled": True} for user in mock_plex_server.accounts
|
user: {"enabled": True} for user in mock_plex_server.accounts
|
||||||
},
|
},
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS: False,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import copy
|
||||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||||
from homeassistant.components.plex.const import (
|
from homeassistant.components.plex.const import (
|
||||||
CONF_IGNORE_NEW_SHARED_USERS,
|
CONF_IGNORE_NEW_SHARED_USERS,
|
||||||
|
CONF_IGNORE_PLEX_WEB_CLIENTS,
|
||||||
CONF_MONITORED_USERS,
|
CONF_MONITORED_USERS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
PLEX_UPDATE_PLATFORMS_SIGNAL,
|
PLEX_UPDATE_PLATFORMS_SIGNAL,
|
||||||
|
@ -94,7 +95,7 @@ async def test_new_ignored_users_available(hass, caplog):
|
||||||
ignored_client = [
|
ignored_client = [
|
||||||
x.players[0]
|
x.players[0]
|
||||||
for x in mock_plex_server.sessions()
|
for x in mock_plex_server.sessions()
|
||||||
if x.usernames[0] in ignored_users
|
if x.usernames[0] == ignored_user
|
||||||
][0]
|
][0]
|
||||||
assert (
|
assert (
|
||||||
f"Ignoring {ignored_client.product} client owned by '{ignored_user}'"
|
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 self.advance(DEBOUNCE_TIMEOUT)
|
||||||
# await hass.async_block_till_done()
|
# await hass.async_block_till_done()
|
||||||
# assert mock_update.call_count == 3
|
# 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue