From 2621da7d36860d6b6521840cd6f10e7311e5e7af Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Tue, 13 Feb 2018 19:22:11 -0800 Subject: [PATCH] Add server selection dropdown to settings --- data/interfaces/default/css/plexpy.css | 66 +++-- data/interfaces/default/notifier_config.html | 1 - data/interfaces/default/settings.html | 174 +++++++++--- data/interfaces/default/welcome.html | 279 ++++++++----------- plexpy/http_handler.py | 6 +- plexpy/plextv.py | 3 +- plexpy/webserve.py | 4 +- 7 files changed, 305 insertions(+), 228 deletions(-) diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css index c00f6db0..bba5bfac 100644 --- a/data/interfaces/default/css/plexpy.css +++ b/data/interfaces/default/css/plexpy.css @@ -60,7 +60,8 @@ select[multiple] option { -moz-border-radius: 2px; border-radius: 2px; } -select.form-control { +select.form-control, +div.form-control .selectize-input { margin: 5px 0 5px 0; color: #fff; border: 0px solid #444; @@ -80,14 +81,36 @@ select.form-control { transition: background-color .3s; } .selectize-control.form-control .selectize-input { - display: flex; + display: flex !important; align-items: center; flex-wrap: wrap; margin-bottom: 4px; padding-left: 5px; } -.selectize-control.form-control.wizard-pms-ip .selectize-input { - padding: 6px 12px !important; +.selectize-control.form-control.selectize-pms-ip .selectize-input { + padding-left: 12px !important; + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + min-height: 32px !important; +} +.input-group .selectize-control.form-control.selectize-pms-ip .selectize-input > div { + max-width: 450px; + overflow: hidden; + text-overflow: ellipsis; +} +.wizard-input-section .selectize-control.form-control.selectize-pms-ip .selectize-input > div { + max-width: 360px; + overflow: hidden; + text-overflow: ellipsis; +} +.selectize-dropdown.form-control.selectize-pms-ip { + margin-top: -4px; +} +.wizard-input-section .selectize-control.form-control.selectize-pms-ip .selectize-dropdown .selectize-dropdown-content { + max-height: 150px; +} +.wizard-input-section .selectize-dropdown.form-control.selectize-pms-ip { + margin-top: 0 !important; } .react-selectize.root-node .react-selectize-control .react-selectize-placeholder { color: #fff !important; @@ -137,33 +160,38 @@ select.form-control:focus, .react-selectize.root-node.open .react-selectize-control .react-selectize-toggle-button path { fill: #999 !important; } -.selectize-control .selectize-input > div .item-value { +.selectize-input > div .item-text { + white-space: nowrap; +} +.selectize-input > div .item-value { opacity: 0.8; font-size: 12px; + white-space: nowrap; } -.selectize-control .selectize-input > div .item-text + .item-value { +.selectize-input > div .item-text + .item-value { margin-left: 5px; } -.selectize-control .selectize-input > div .item-value:before { +.selectize-input > div .item-value:before { content: '<'; opacity: 0.8; font-size: 12px; } -.selectize-control .selectize-input > div .item-value:after { +.selectize-input > div .item-value:after { content: '>'; opacity: 0.8; font-size: 12px; } -.selectize-control .selectize-dropdown .caption { +.selectize-dropdown .caption { font-size: 12px; display: block; color: #a0a0a0; + white-space: nowrap; } -.selectize-control .selectize-dropdown .select-all, -.selectize-control .selectize-dropdown .remove-all { +.selectize-dropdown .select-all, +.selectize-dropdown .remove-all { font-weight: bold; } -.selectize-control .selectize-dropdown .border-all { +.selectize-dropdown .border-all { pointer-events: none; display: block; height: 1px; @@ -172,7 +200,7 @@ select.form-control:focus, overflow: hidden; background-color: #e5e5e5; } -.selectize-control .selectize-dropdown .border-all:last-child { +.selectize-dropdown .border-all:last-child { display: none; } .selectize-dropdown .optgroup-header { @@ -622,18 +650,8 @@ textarea.form-control:focus { color: #fff; } .form-control-feedback { - position: absolute; color: #F9AA03; - top: 0; - right: 0; - margin: 5px 10px 5px 0; - z-index: 2; - display: block; - width: 32px; - height: 32px; - line-height: 32px; - text-align: center; - pointer-events: none; + margin: 5px 40px 5px 0; } .form-control[readonly] { background-color: #555; diff --git a/data/interfaces/default/notifier_config.html b/data/interfaces/default/notifier_config.html index 3a8091a9..22d62be2 100644 --- a/data/interfaces/default/notifier_config.html +++ b/data/interfaces/default/notifier_config.html @@ -518,7 +518,6 @@ '(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)'; var $email_selectors = $('#email_to, #email_cc, #email_bcc').selectize({ plugins: ['remove_button'], - persist: false, maxItems: null, render: { item: function(item, escape) { diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 745219e5..717eda43 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -623,9 +623,11 @@
-
+
- + @@ -634,7 +636,7 @@
-

IP Address or hostname for Plex Media Server.

+

Select your Plex Media Server from the dropdown menu or enter an IP address or hostname.

@@ -659,16 +661,10 @@

If you have secure connections enabled on your Plex Server, communicate with it securely.

- % if config['pms_is_cloud']: - - Not available for Plex Cloud servers. - % else: - % endif +

Use the user defined connection details. Do not retrieve the server connection URL automatically.

@@ -689,6 +685,7 @@

+ @@ -721,16 +718,10 @@
- % if config['pms_is_cloud']: - - Not available for Plex Cloud servers. - % else: - % endif +

Enable to have Tautulli check if updates are available for the Plex Media Server.

@@ -753,17 +744,11 @@
- % if config['pms_is_cloud']: - - Not available for Plex Cloud servers. - % else: + - % endif

Enable to have Tautulli check if remote access to the Plex Media Server goes down.

@@ -1787,6 +1772,117 @@ $(document).ready(function() { verifyServer(); }); + var $select_pms = $('#pms_ip').selectize({ + createOnBlur: true, + openOnFocus: true, + maxItems: 1, + closeAfterSelect: true, + sortField: 'label', + searchField: ['label', 'value'], + inputClass: 'form-control selectize-input', + dropdownParent: 'body', + render: { + item: function (item, escape) { + var label = item.label || item.value; + var caption = item.label ? item.value : null; + return '
' + + '' + escape(label) + '' + + (caption ? '' + escape(caption) + '' : '') + + '
'; + }, + option: function (item, escape) { + var label = item.label || item.value; + var caption = item.label ? item.value : null; + return '
' + + escape(label) + + (caption ? '' + escape(caption) + '' : '') + + '
'; + } + }, + create: function(input) { + return {label: '', value: input}; + }, + onChange: function (item) { + var pms_ip_selected = this.getItem(item)[0]; + var identifier = $(pms_ip_selected).data('identifier'); + var port = $(pms_ip_selected).data('port'); + var local = $(pms_ip_selected).data('local'); + var ssl = $(pms_ip_selected).data('ssl'); + var is_cloud = $(pms_ip_selected).data('is_cloud'); + + $("#pms_identifier").val(identifier !== 'undefined' ? identifier : ''); + $('#pms_port').val((port !== 'undefined' ? port : 32400)); + $('#pms_is_remote').prop('checked', (local !== 'undefined' && local === 0)); + $('#pms_ssl').prop('checked', (ssl !== 'undefined' && ssl === 1)); + $('#pms_is_cloud').val((is_cloud !== 'undefined' && is_cloud === true ? 1 : 0)); + $('#pms_url_manual').prop('checked', false); + PMSCloudCheck(); + } + }); + var select_pms = $select_pms[0].selectize; + + function getServerOptions(token) { + $.ajax({ + url: 'discover', + data: { + token: token + }, + success: function (result) { + if (result) { + var existing_value = $('#pms_ip').val(); + result.forEach(function (item) { + if (item.value === existing_value) { + select_pms.updateOption(item.value, item); + } else { + select_pms.addOption(item); + } + }); + } + } + }) + } + getServerOptions(); + + function PMSCloudCheck () { + if ($('#pms_is_cloud').val() === "1") { + $('#pms_port').val(443).prop('readonly', true); + $('#pms_is_remote').prop('checked', true).prop('disabled', true); + $('#pms_ssl').prop('checked', true).prop('disabled', true); + $('#pms_url_manual').prop('checked', false).prop('disabled', true); + $('#monitor_pms_updates').prop('checked', false).prop('disabled', true); + $('#pms_update_options').hide(); + $('#monitor_remote_access').prop('checked', false).prop('disabled', true); + $('#cloudManualConnection').show(); + $('#cloudMonitorUpdates').show(); + $('#cloudMonitorRemoteAccess').show(); + $('#remoteAccessCheck').hide(); + } else { + $('#pms_port').prop('readonly', false); + $('#pms_is_remote').prop('disabled', false); + $('#pms_ssl').prop('disabled', false); + $('#pms_url_manual').prop('disabled', false); + $('#monitor_pms_updates').prop('disabled', false); + $('#monitor_remote_access').prop('disabled', false); + $('#cloudManualConnection').hide(); + $('#cloudMonitorUpdates').hide(); + $('#cloudMonitorRemoteAccess').hide(); + remoteAccessEnabledCheck(); + } + } + PMSCloudCheck(); + function verifyServer(_callback) { var pms_ip = $("#pms_ip").val(); var pms_port = $("#pms_port").val(); @@ -1875,6 +1971,7 @@ $(document).ready(function() { $("#pms-token-status").html(' ' + msg); $("#pms_token").val(authToken); $('#pms-auth-modal').modal('hide'); + getServerOptions(authToken); } else { $("#pms-token-status").html(' ' + msg); } @@ -1903,18 +2000,21 @@ $(document).ready(function() { pms_logs_debug = false; pms_logs = false; - $.ajax({ - url: 'get_server_pref', - data: { pref: 'PublishServerOnPlexOnlineKey' }, - async: true, - success: function(data) { - if (data !== 'true') { - $("#remoteAccessCheck").html("Remote access must be enabled on your Plex Server. Click here for help."); - $("#monitor_remote_access").attr("disabled", true); - $("#monitor_remote_access").attr("checked", false); + function remoteAccessEnabledCheck() { + $.ajax({ + url: 'get_server_pref', + data: { pref: 'PublishServerOnPlexOnlineKey' }, + async: true, + success: function(data) { + if (data !== 'true') { + $("#remoteAccessCheck").html("Remote access must be enabled on your Plex Server. Click here for help."); + $("#monitor_remote_access").attr("disabled", true); + $("#monitor_remote_access").attr("checked", false); + } } - } - }); + }); + } + remoteAccessEnabledCheck(); // Sortable home_sections function set_home_sections() { @@ -1940,7 +2040,7 @@ $(document).ready(function() { }); $('[id^=hsec-]').change(function() { set_home_sections(); }); - set_home_sections() + set_home_sections(); // Sortable home_stats_cards function set_home_stats_cards() { @@ -1966,7 +2066,7 @@ $(document).ready(function() { }); $('[id^=hscard-]').change(function() { set_home_stats_cards(); }); - set_home_stats_cards() + set_home_stats_cards(); // Sortable home_library_cards function set_home_library_cards() { diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html index 5ecaa495..1d37e495 100644 --- a/data/interfaces/default/welcome.html +++ b/data/interfaces/default/welcome.html @@ -47,7 +47,7 @@
-
+
@@ -82,17 +82,21 @@
- + Authenticate

Plex Media Server

-

Enter your Plex Server details and then click the Verify button to make sure Tautulli can reach the server.

+

+ Select your Plex Media Server from the dropdown menu or enter an IP address or hostname. +

- +
@@ -105,14 +109,14 @@
@@ -200,127 +204,6 @@ diff --git a/plexpy/http_handler.py b/plexpy/http_handler.py index 189548e5..eef8beee 100644 --- a/plexpy/http_handler.py +++ b/plexpy/http_handler.py @@ -85,9 +85,9 @@ class HTTPHandler(object): if uri: request_urls = [urljoin(url, self.uri) for url in self.urls] - if no_token and headers: - self.headers = headers - elif headers: + if no_token: + self.headers.pop('X-Plex-Token', None) + if headers: self.headers.update(headers) responses = [] diff --git a/plexpy/plextv.py b/plexpy/plextv.py index f701c26d..4bc9771e 100644 --- a/plexpy/plextv.py +++ b/plexpy/plextv.py @@ -646,7 +646,8 @@ class PlexTV(object): 'ip': helpers.get_xml_attr(c, 'address'), 'port': helpers.get_xml_attr(c, 'port'), 'local': helpers.get_xml_attr(c, 'local'), - 'value': helpers.get_xml_attr(c, 'address') + 'value': helpers.get_xml_attr(c, 'address'), + 'is_cloud': is_cloud } clean_servers.append(server) diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 3a30510d..c57d6dcd 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -117,7 +117,7 @@ class WebInterface(object): @cherrypy.tools.json_out() @requireAuth(member_of("admin")) @addtoapi("get_server_list") - def discover(self, token=None, include_cloud=True, all_servers=False, **kwargs): + def discover(self, token=None, include_cloud=True, all_servers=True, **kwargs): """ Get all your servers that are published to Plex.tv. ``` @@ -148,7 +148,7 @@ class WebInterface(object): plexpy.CONFIG.write() include_cloud = not (include_cloud == 'false') - all_servers = (all_servers == 'true') + all_servers = not (all_servers == 'false') plex_tv = plextv.PlexTV() servers_list = plex_tv.discover(include_cloud=include_cloud,