Configurator works, config saving basic implementation

pull/551/head
Tom Duijf 2015-10-25 10:45:15 +00:00
parent 884525df33
commit 847d9736aa
1 changed files with 83 additions and 46 deletions

View File

@ -6,7 +6,7 @@ Provides an interface to the Plex API.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.plex.html https://home-assistant.io/components/media_player.plex.html
""" """
import logging import logging, json, os
from datetime import timedelta from datetime import timedelta
from urllib.parse import urlparse from urllib.parse import urlparse
@ -31,60 +31,91 @@ _LOGGER = logging.getLogger(__name__)
SUPPORT_PLEX = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK SUPPORT_PLEX = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
def config_from_file(filename, config=None):
''' Small configuration file management function'''
if config:
# We're writing configuration
try:
with open(filename,'w') as f:
f.write(json.dumps(config))
except IOError as e:
_LOGGER.error('Saving config file failed: %s'%e)
return False
return True
else:
# We're reading config
if os.path.isfile(filename):
try:
with open(filename,'r') as f:
return json.loads(f.read())
except IOError as e:
_LOGGER.error('Reading config file failed: %s'%e)
return False
else:
return {}
# pylint: disable=abstract-method, unused-argument # pylint: disable=abstract-method, unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Sets up the plex platform. """ """ Sets up the plex platform. """
# Via discovery
if discovery_info is not None: if discovery_info is not None:
# Parse discovery data # Parse discovery data
host = urlparse(discovery_info[1]).netloc host = urlparse(discovery_info[1]).netloc
_LOGGER.info('Discovered PLEX server: %s'%host) _LOGGER.info('Discovered PLEX server: %s'%host)
else:
host = config.get(CONF_HOST, None)
if host in _CONFIGURING: if host in _CONFIGURING:
return return
setup_plexserver(host, hass, add_devices_callback)
def setup_plexserver(host, hass, add_devices_callback):
''' Setup a plexserver based on host parameter'''
import plexapi
# Config parsing & discovery mix
conf_file = hass.config.path(PLEX_CONFIG_FILE)
try:
with open(conf_file,'r') as f:
conf_dict = eval(f.read())
except IOError: # File not found
if host == None:
# No discovery, no config, quit here
return
conf_dict = {}
if host == None:
# Called by module inclusion, let's only use config
host,token = conf_dict.popitem()
token = token['token']
elif host not in conf_dict.keys():
# Not in config
conf_dict[host] = { 'token' : '' }
token = None token = None
else:
# Setup a configured PlexServer
config = config_from_file(hass.config.path(PLEX_CONFIG_FILE))
if len(config):
host,token = config.popitem()
token = token['token']
else:
# Empty config file?
return
setup_plexserver(host, token, hass, add_devices_callback)
def setup_plexserver(host, token, hass, add_devices_callback):
''' Setup a plexserver based on host parameter'''
from plexapi.server import PlexServer
from plexapi.exceptions import BadRequest
import plexapi
_LOGGER.info('Connecting to: htts://%s using token: %s' % _LOGGER.info('Connecting to: htts://%s using token: %s' %
(host, token)) (host, token))
try: try:
plexserver = plexapi.PlexServer('http://%s'%host, token) plexserver = plexapi.server.PlexServer('http://%s'%host, token)
except Exception: except (plexapi.exceptions.BadRequest,
plexapi.exceptions.Unauthorized,
plexapi.exceptions.NotFound) as e:
_LOGGER.info(e)
# No token or wrong token
request_configuration(host, hass, add_devices_callback) request_configuration(host, hass, add_devices_callback)
return return
except plexapi.exceptions.BadRequest as e: except Exception as e:
_LOGGER.error('BLABLA1') _LOGGER.error('Misc Exception : %s'%e)
request_configuration(host, hass, add_devices_callback)
return return
# If we came here and configuring this host, mark as done
if host in _CONFIGURING:
request_id = _CONFIGURING.pop(host)
configurator = get_component('configurator')
configurator.request_done(request_id)
_LOGGER.info('Discovery configuration done!')
# Save config
if not config_from_file(
hass.config.path(PLEX_CONFIG_FILE),
{host: {'token': token}}):
_LOGGER.error('failed to save config file')
_LOGGER.info('Connected to: htts://%s using token: %s' % _LOGGER.info('Connected to: htts://%s using token: %s' %
(host, token)) (host, token))
@ -96,7 +127,7 @@ def setup_plexserver(host, hass, add_devices_callback):
""" Updates the devices objects. """ """ Updates the devices objects. """
try: try:
devices = plexserver.clients() devices = plexserver.clients()
except BadRequest: except plexapi.exceptions.BadRequest:
_LOGGER.exception("Error listing plex devices") _LOGGER.exception("Error listing plex devices")
return return
@ -115,14 +146,14 @@ def setup_plexserver(host, hass, add_devices_callback):
plex_clients[device.machineIdentifier].set_device(device) plex_clients[device.machineIdentifier].set_device(device)
if new_plex_clients: if new_plex_clients:
add_devices(new_plex_clients) add_devices_callback(new_plex_clients)
@util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
def update_sessions(): def update_sessions():
""" Updates the sessions objects. """ """ Updates the sessions objects. """
try: try:
sessions = plexserver.sessions() sessions = plexserver.sessions()
except BadRequest: except plexapi.exceptions.BadRequest:
_LOGGER.exception("Error listing plex sessions") _LOGGER.exception("Error listing plex sessions")
return return
@ -147,14 +178,14 @@ def request_configuration(host, hass, add_devices_callback):
def plex_configuration_callback(data): def plex_configuration_callback(data):
""" Actions to do when our configuration callback is called. """ """ Actions to do when our configuration callback is called. """
setup_plexserver(host, hass, add_devices_callback) setup_plexserver(host, data.get('token'), hass, add_devices_callback)
_CONFIGURING[host] = configurator.request_config( _CONFIGURING[host] = configurator.request_config(
hass, "Plex Media Server", plex_configuration_callback, hass, "Plex Media Server", plex_configuration_callback,
description=('Enter the X-Plex-Token'), description=('Enter the X-Plex-Token'),
description_image="/static/images/config_plex_mediaserver.png", description_image="/static/images/config_plex_mediaserver.png",
submit_caption="Confirm", submit_caption="Confirm",
fields=[{'Token':'token'}] fields=[{'id': 'token', 'name':'X-Plex-Token', 'type':''}]
) )
@ -172,6 +203,17 @@ class PlexClient(MediaPlayerDevice):
""" Sets the device property. """ """ Sets the device property. """
self.device = device self.device = device
@property
def unique_id(self):
""" Returns the id of this plex client """
return "{}.{}".format(
self.__class__, self.device.machineIdentifier or self.device.name )
@property
def name(self):
""" Returns the name of the device. """
return self.device.name or self.device.product or self.device.deviceClass
@property @property
def session(self): def session(self):
""" Returns the session, if any. """ """ Returns the session, if any. """
@ -180,11 +222,6 @@ class PlexClient(MediaPlayerDevice):
return self.plex_sessions[self.device.machineIdentifier] return self.plex_sessions[self.device.machineIdentifier]
@property
def name(self):
""" Returns the name of the device. """
return self.device.name or self.device.product or self.device.device
@property @property
def state(self): def state(self):
""" Returns the state of the device. """ """ Returns the state of the device. """
@ -194,7 +231,7 @@ class PlexClient(MediaPlayerDevice):
return STATE_PLAYING return STATE_PLAYING
elif state == 'paused': elif state == 'paused':
return STATE_PAUSED return STATE_PAUSED
# This is nasty. Need ti find a way to determine alive # This is nasty. Need to find a way to determine alive
elif self.device: elif self.device:
return STATE_IDLE return STATE_IDLE
else: else: