* Add config flow support * Log error on failed connection * Review comments * Unused errors * Move form to step * Use instance var instead of passing argument * Only share servers created by component * Return errors early to avoid try:else * Separate debug for validation vs setup * Unnecessary * Unnecessary checks * Combine import flows, move logic to component * Use config entry discovery handler * Temporary lint fix * Filter out servers already configured * Remove manual config flow * Skip discovery if a config exists * Swap conditional to reduce indenting * Only discover when no configs created or creating * Un-nest function * Proper async use * Move legacy file import to discovery * Fix, bad else * Separate validate step * Unused without manual setup step * Async oops * First attempt at tests * Test cleanup * Full test coverage for config_flow, enable tests * Lint * Fix lint vs black * Add test init * Add test package requirement * Actually run script * Use 'not None' convention * Group exceptions by result * Improve logic, add new error and test * Test cleanup * Add more asserts
82 lines
2.8 KiB
Python
82 lines
2.8 KiB
Python
"""Shared class to maintain Plex server instances."""
|
|
import plexapi.myplex
|
|
import plexapi.server
|
|
from requests import Session
|
|
|
|
from homeassistant.const import CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL
|
|
|
|
from .const import CONF_SERVER, DEFAULT_VERIFY_SSL
|
|
from .errors import NoServersFound, ServerNotSpecified
|
|
|
|
|
|
class PlexServer:
|
|
"""Manages a single Plex server connection."""
|
|
|
|
def __init__(self, server_config):
|
|
"""Initialize a Plex server instance."""
|
|
self._plex_server = None
|
|
self._url = server_config.get(CONF_URL)
|
|
self._token = server_config.get(CONF_TOKEN)
|
|
self._server_name = server_config.get(CONF_SERVER)
|
|
self._verify_ssl = server_config.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)
|
|
|
|
def connect(self):
|
|
"""Connect to a Plex server directly, obtaining direct URL if necessary."""
|
|
|
|
def _set_missing_url():
|
|
account = plexapi.myplex.MyPlexAccount(token=self._token)
|
|
available_servers = [
|
|
(x.name, x.clientIdentifier)
|
|
for x in account.resources()
|
|
if "server" in x.provides
|
|
]
|
|
|
|
if not available_servers:
|
|
raise NoServersFound
|
|
if not self._server_name and len(available_servers) > 1:
|
|
raise ServerNotSpecified(available_servers)
|
|
|
|
server_choice = (
|
|
self._server_name if self._server_name else available_servers[0]
|
|
)
|
|
connections = account.resource(server_choice).connections
|
|
local_url = [x.httpuri for x in connections if x.local]
|
|
remote_url = [x.uri for x in connections if not x.local]
|
|
self._url = local_url[0] if local_url else remote_url[0]
|
|
|
|
def _connect_with_url():
|
|
session = None
|
|
if self._url.startswith("https") and not self._verify_ssl:
|
|
session = Session()
|
|
session.verify = False
|
|
self._plex_server = plexapi.server.PlexServer(
|
|
self._url, self._token, session
|
|
)
|
|
|
|
if self._token and not self._url:
|
|
_set_missing_url()
|
|
|
|
_connect_with_url()
|
|
|
|
def clients(self):
|
|
"""Pass through clients call to plexapi."""
|
|
return self._plex_server.clients()
|
|
|
|
def sessions(self):
|
|
"""Pass through sessions call to plexapi."""
|
|
return self._plex_server.sessions()
|
|
|
|
@property
|
|
def friendly_name(self):
|
|
"""Return name of connected Plex server."""
|
|
return self._plex_server.friendlyName
|
|
|
|
@property
|
|
def machine_identifier(self):
|
|
"""Return unique identifier of connected Plex server."""
|
|
return self._plex_server.machineIdentifier
|
|
|
|
@property
|
|
def url_in_use(self):
|
|
"""Return URL used for connected Plex server."""
|
|
return self._plex_server._baseurl # pylint: disable=W0212
|