2019-09-05 17:50:26 +00:00
|
|
|
"""Shared class to maintain Plex server instances."""
|
2019-09-11 18:21:08 +00:00
|
|
|
import plexapi.myplex
|
2019-10-07 04:02:58 +00:00
|
|
|
import plexapi.playqueue
|
2019-09-05 17:50:26 +00:00
|
|
|
import plexapi.server
|
|
|
|
from requests import Session
|
|
|
|
|
2019-09-26 09:10:20 +00:00
|
|
|
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
2019-09-05 17:50:26 +00:00
|
|
|
from homeassistant.const import CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL
|
|
|
|
|
2019-09-26 09:10:20 +00:00
|
|
|
from .const import (
|
|
|
|
CONF_SERVER,
|
|
|
|
CONF_SHOW_ALL_CONTROLS,
|
|
|
|
CONF_USE_EPISODE_ART,
|
|
|
|
DEFAULT_VERIFY_SSL,
|
2019-10-01 15:20:30 +00:00
|
|
|
X_PLEX_DEVICE_NAME,
|
|
|
|
X_PLEX_PLATFORM,
|
|
|
|
X_PLEX_PRODUCT,
|
|
|
|
X_PLEX_VERSION,
|
2019-09-26 09:10:20 +00:00
|
|
|
)
|
2019-09-19 21:29:26 +00:00
|
|
|
from .errors import NoServersFound, ServerNotSpecified
|
2019-09-05 17:50:26 +00:00
|
|
|
|
2019-10-01 15:20:30 +00:00
|
|
|
# Set default headers sent by plexapi
|
|
|
|
plexapi.X_PLEX_DEVICE_NAME = X_PLEX_DEVICE_NAME
|
|
|
|
plexapi.X_PLEX_PLATFORM = X_PLEX_PLATFORM
|
|
|
|
plexapi.X_PLEX_PRODUCT = X_PLEX_PRODUCT
|
|
|
|
plexapi.X_PLEX_VERSION = X_PLEX_VERSION
|
|
|
|
plexapi.myplex.BASE_HEADERS = plexapi.reset_base_headers()
|
|
|
|
plexapi.server.BASE_HEADERS = plexapi.reset_base_headers()
|
|
|
|
|
2019-09-05 17:50:26 +00:00
|
|
|
|
|
|
|
class PlexServer:
|
|
|
|
"""Manages a single Plex server connection."""
|
|
|
|
|
2019-09-26 09:10:20 +00:00
|
|
|
def __init__(self, server_config, options=None):
|
2019-09-05 17:50:26 +00:00
|
|
|
"""Initialize a Plex server instance."""
|
|
|
|
self._plex_server = None
|
|
|
|
self._url = server_config.get(CONF_URL)
|
|
|
|
self._token = server_config.get(CONF_TOKEN)
|
2019-09-11 18:21:08 +00:00
|
|
|
self._server_name = server_config.get(CONF_SERVER)
|
2019-09-05 17:50:26 +00:00
|
|
|
self._verify_ssl = server_config.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)
|
2019-09-26 09:10:20 +00:00
|
|
|
self.options = options
|
2019-10-18 00:31:53 +00:00
|
|
|
self.server_choice = None
|
2019-09-05 17:50:26 +00:00
|
|
|
|
|
|
|
def connect(self):
|
|
|
|
"""Connect to a Plex server directly, obtaining direct URL if necessary."""
|
|
|
|
|
2019-10-18 00:31:53 +00:00
|
|
|
def _connect_with_token():
|
2019-09-11 18:21:08 +00:00
|
|
|
account = plexapi.myplex.MyPlexAccount(token=self._token)
|
|
|
|
available_servers = [
|
2019-09-19 21:29:26 +00:00
|
|
|
(x.name, x.clientIdentifier)
|
|
|
|
for x in account.resources()
|
|
|
|
if "server" in x.provides
|
2019-09-11 18:21:08 +00:00
|
|
|
]
|
2019-09-19 21:29:26 +00:00
|
|
|
|
|
|
|
if not available_servers:
|
|
|
|
raise NoServersFound
|
|
|
|
if not self._server_name and len(available_servers) > 1:
|
|
|
|
raise ServerNotSpecified(available_servers)
|
|
|
|
|
2019-10-18 00:31:53 +00:00
|
|
|
self.server_choice = (
|
2019-10-08 15:54:01 +00:00
|
|
|
self._server_name if self._server_name else available_servers[0][0]
|
2019-09-11 18:21:08 +00:00
|
|
|
)
|
2019-10-18 00:31:53 +00:00
|
|
|
self._plex_server = account.resource(self.server_choice).connect()
|
2019-09-11 18:21:08 +00:00
|
|
|
|
2019-09-05 17:50:26 +00:00
|
|
|
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
|
|
|
|
)
|
|
|
|
|
2019-10-18 00:31:53 +00:00
|
|
|
if self._url:
|
|
|
|
_connect_with_url()
|
|
|
|
else:
|
|
|
|
_connect_with_token()
|
2019-09-05 17:50:26 +00:00
|
|
|
|
|
|
|
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
|
2019-09-26 09:10:20 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def use_episode_art(self):
|
|
|
|
"""Return use_episode_art option."""
|
|
|
|
return self.options[MP_DOMAIN][CONF_USE_EPISODE_ART]
|
|
|
|
|
|
|
|
@property
|
|
|
|
def show_all_controls(self):
|
|
|
|
"""Return show_all_controls option."""
|
|
|
|
return self.options[MP_DOMAIN][CONF_SHOW_ALL_CONTROLS]
|
2019-10-07 04:02:58 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def library(self):
|
|
|
|
"""Return library attribute from server object."""
|
|
|
|
return self._plex_server.library
|
|
|
|
|
|
|
|
def playlist(self, title):
|
|
|
|
"""Return playlist from server object."""
|
|
|
|
return self._plex_server.playlist(title)
|
|
|
|
|
|
|
|
def create_playqueue(self, media, **kwargs):
|
|
|
|
"""Create playqueue on Plex server."""
|
|
|
|
return plexapi.playqueue.PlayQueue.create(self._plex_server, media, **kwargs)
|