Use the user defined connection details. Do not retrieve the server connection URL automatically.
@@ -866,36 +864,6 @@
-
Users List Refresh Interval
@@ -2158,7 +2126,6 @@ $(document).ready(function() {
initConfigCheckbox('#https_create_cert');
initConfigCheckbox('#check_github');
initConfigCheckbox('#monitor_pms_updates');
- initConfigCheckbox('#monitor_remote_access');
initConfigCheckbox('#newsletter_self_hosted');
$('#menu_link_shutdown').click(function() {
@@ -2404,7 +2371,6 @@ $(document).ready(function() {
$('#pms_is_cloud').val(is_cloud !== 'undefined' && is_cloud === true ? 1 : 0);
$('#pms_url_manual').prop('checked', false);
$('#pms_url').val('Please verify your server above to retrieve the URL');
- PMSCloudCheck();
},
onDropdownOpen: function() {
this.clear();
@@ -2435,38 +2401,6 @@ $(document).ready(function() {
}
getServerOptions();
- function PMSCloudCheck() {
- if ($('#pms_is_cloud').val() === "1") {
- $('#pms_port').val(443).prop('readonly', true);
- $('#pms_is_remote_checkbox').prop('checked', true).prop('disabled', true);
- $('#pms_is_remote').val(1);
- $('#pms_ssl_checkbox').prop('checked', true).prop('disabled', true);
- $('#pms_ssl').val(1);
- $('#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_checkbox').prop('disabled', false);
- $('#pms_is_remote').val($('#pms_is_remote_checkbox').is(':checked') ? 1 : 0);
- $('#pms_ssl_checkbox').prop('disabled', false);
- $('#pms_ssl').val($('#pms_ssl_checkbox').is(':checked') ? 1 : 0);
- $('#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();
@@ -2583,21 +2517,6 @@ $(document).ready(function() {
pms_logs_debug = false;
pms_logs = false;
- function remoteAccessEnabledCheck() {
- $.ajax({
- url: 'get_server_pref',
- data: { pref: 'PublishServerOnPlexOnlineKey' },
- async: true,
- success: function(data) {
- if (data === 'false' || data === '0') {
- $("#remoteAccessCheck").html("Remote access must be enabled on your Plex Server.
Click here for help.");
- $("#monitor_remote_access").attr("checked", false).attr("disabled", true);
- }
- }
- });
- }
- remoteAccessEnabledCheck();
-
// Sortable home_sections
function set_home_sections() {
var home_sections = [];
diff --git a/plexpy/__init__.py b/plexpy/__init__.py
index 68796580..ca59d672 100644
--- a/plexpy/__init__.py
+++ b/plexpy/__init__.py
@@ -136,6 +136,7 @@ DEV = False
WEBSOCKET = None
WS_CONNECTED = False
PLEX_SERVER_UP = None
+PLEX_REMOTE_ACCESS_UP = None
TRACKER = None
@@ -443,10 +444,6 @@ def initialize_scheduler():
schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
hours=12 * (not bool(CONFIG.PMS_URL_MANUAL)), minutes=0, seconds=0)
- pms_remote_access_seconds = CONFIG.REMOTE_ACCESS_PING_INTERVAL if 60 <= CONFIG.REMOTE_ACCESS_PING_INTERVAL else 60
-
- schedule_job(activity_pinger.check_server_access, 'Check for Plex remote access',
- hours=0, minutes=0, seconds=pms_remote_access_seconds * bool(CONFIG.MONITOR_REMOTE_ACCESS))
schedule_job(activity_pinger.check_server_updates, 'Check for Plex updates',
hours=pms_update_check_hours * bool(CONFIG.MONITOR_PMS_UPDATES), minutes=0, seconds=0)
@@ -469,8 +466,6 @@ def initialize_scheduler():
schedule_job(plextv.get_server_resources, 'Refresh Plex server URLs',
hours=0, minutes=0, seconds=0)
- schedule_job(activity_pinger.check_server_access, 'Check for Plex remote access',
- hours=0, minutes=0, seconds=0)
schedule_job(activity_pinger.check_server_updates, 'Check for Plex updates',
hours=0, minutes=0, seconds=0)
diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py
index 91d8d382..1763313b 100644
--- a/plexpy/activity_handler.py
+++ b/plexpy/activity_handler.py
@@ -505,6 +505,55 @@ class TimelineHandler(object):
schedule_callback('rating_key-{}'.format(rating_key), remove_job=True)
+class ReachabilityHandler(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def is_reachable(self):
+ if 'reachability' in self.data:
+ return self.data['reachability']
+ return False
+
+ def remote_access_enabled(self):
+ pms_connect = pmsconnect.PmsConnect()
+ pref = pms_connect.get_server_pref(pref='PublishServerOnPlexOnlineKey')
+ return helpers.bool_true(pref)
+
+ def process(self):
+ # Check if remote access is enabled
+ if not self.remote_access_enabled():
+ return
+
+ # Do nothing if remote access is still up and hasn't changed
+ if self.is_reachable() and plexpy.PLEX_REMOTE_ACCESS_UP:
+ return
+
+ pms_connect = pmsconnect.PmsConnect()
+ server_response = pms_connect.get_server_response()
+
+ if server_response:
+ # Waiting for port mapping
+ if server_response['mapping_state'] == 'waiting':
+ logger.warn("Tautulli Monitor :: Remote access waiting for port mapping.")
+
+ elif plexpy.PLEX_REMOTE_ACCESS_UP is not False and server_response['reason']:
+ logger.warn("Tautulli Monitor :: Remote access failed: %s" % server_response['reason'])
+ logger.info("Tautulli Monitor :: Plex remote access is down.")
+
+ plexpy.PLEX_REMOTE_ACCESS_UP = False
+ plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extdown', 'remote_access_info': server_response})
+
+ elif plexpy.PLEX_REMOTE_ACCESS_UP is False and not server_response['reason']:
+ logger.info("Tautulli Monitor :: Plex remote access is back up.")
+
+ plexpy.PLEX_REMOTE_ACCESS_UP = True
+ plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extup', 'remote_access_info': server_response})
+
+ elif plexpy.PLEX_REMOTE_ACCESS_UP is None:
+ plexpy.PLEX_REMOTE_ACCESS_UP = self.is_reachable()
+
+
def del_keys(key):
if isinstance(key, set):
for child_key in key:
diff --git a/plexpy/activity_pinger.py b/plexpy/activity_pinger.py
index e3b093a1..a28a461c 100644
--- a/plexpy/activity_pinger.py
+++ b/plexpy/activity_pinger.py
@@ -318,47 +318,6 @@ def connect_server(log=True, startup=False):
logger.error("Websocket :: Unable to open connection: %s." % e)
-def check_server_access():
- with monitor_lock:
- pms_connect = pmsconnect.PmsConnect()
- server_response = pms_connect.get_server_response()
-
- global ext_ping_count
- global ext_ping_error
-
- # Check for remote access
- if server_response:
- log = (server_response['mapping_error'] != ext_ping_error)
-
- if server_response['reason']:
- ext_ping_count += 1
- ext_ping_error = server_response['mapping_error']
- if log:
- logger.warn("Tautulli Monitor :: Remote access failed: %s, ping attempt %s."
- % (server_response['reason'], str(ext_ping_count)))
-
- # Waiting for port mapping
- elif server_response['mapping_state'] == 'waiting':
- ext_ping_error = server_response['mapping_error']
- if log:
- logger.warn("Tautulli Monitor :: Remote access waiting for port mapping, ping attempt %s."
- % str(ext_ping_count))
-
- # Reset external ping counter
- else:
- if ext_ping_count >= plexpy.CONFIG.REMOTE_ACCESS_PING_THRESHOLD:
- logger.info("Tautulli Monitor :: Plex remote access is back up.")
-
- plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extup', 'remote_access_info': server_response})
-
- ext_ping_count = 0
- ext_ping_error = None
-
- if ext_ping_count == plexpy.CONFIG.REMOTE_ACCESS_PING_THRESHOLD:
- logger.info("Tautulli Monitor: Plex remote access is down.")
- plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extdown', 'remote_access_info': server_response})
-
-
def check_server_updates():
with monitor_lock:
diff --git a/plexpy/common.py b/plexpy/common.py
index 883c83f9..c509e070 100644
--- a/plexpy/common.py
+++ b/plexpy/common.py
@@ -217,18 +217,19 @@ EXTRA_TYPES = {
}
SCHEDULER_LIST = [
- 'Check GitHub for updates',
- 'Check for server response',
- 'Check for active sessions',
- 'Check for recently added items',
- 'Check for Plex updates',
- 'Check for Plex remote access',
- 'Refresh users list',
- 'Refresh libraries list',
- 'Refresh Plex server URLs',
- 'Backup Tautulli database',
- 'Backup Tautulli config'
+ ('Check GitHub for updates', 'websocket'),
+ ('Check for server response', 'websocket'),
+ ('Check for active sessions', 'websocket'),
+ ('Check for recently added items', 'websocket'),
+ ('Check for server remote access', 'websocket'),
+ ('Check for Plex updates', 'scheduled'),
+ ('Refresh users list', 'scheduled'),
+ ('Refresh libraries list', 'scheduled'),
+ ('Refresh Plex server URLs', 'scheduled'),
+ ('Backup Tautulli database', 'scheduled'),
+ ('Backup Tautulli config', 'scheduled')
]
+SCHEDULER_LIST = OrderedDict(SCHEDULER_LIST)
DATE_TIME_FORMATS = [
{
diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py
index 2b2f679b..015b06f8 100644
--- a/plexpy/pmsconnect.py
+++ b/plexpy/pmsconnect.py
@@ -2971,8 +2971,6 @@ class PmsConnect(object):
return key_list
def get_server_response(self):
- # Refresh Plex remote access port mapping first
- self.put_refresh_reachability()
account_data = self.get_account(output_format='xml')
try:
diff --git a/plexpy/web_socket.py b/plexpy/web_socket.py
index 8a8ee39b..6ff5e4fc 100644
--- a/plexpy/web_socket.py
+++ b/plexpy/web_socket.py
@@ -255,42 +255,55 @@ def process(opcode, data):
try:
data = data.decode('utf-8')
logger.websocket_debug(data)
- info = json.loads(data)
+ event = json.loads(data)
except Exception as e:
logger.warn("Tautulli WebSocket :: Error decoding message from websocket: %s" % e)
logger.websocket_error(data)
return False
- info = info.get('NotificationContainer', info)
- info_type = info.get('type')
+ event = event.get('NotificationContainer', event)
+ event_type = event.get('type')
- if not info_type:
+ if not event_type:
return False
- if info_type == 'playing':
- time_line = info.get('PlaySessionStateNotification', info.get('_children', {}))
+ if event_type == 'playing':
+ event_data = event.get('PlaySessionStateNotification', event.get('_children', {}))
- if not time_line:
- logger.debug("Tautulli WebSocket :: Session found but unable to get timeline data.")
+ if not event_data:
+ logger.debug("Tautulli WebSocket :: Session event found but unable to get websocket data.")
return False
try:
- activity = activity_handler.ActivityHandler(timeline=time_line[0])
+ activity = activity_handler.ActivityHandler(timeline=event_data[0])
activity.process()
except Exception as e:
logger.exception("Tautulli WebSocket :: Failed to process session data: %s." % e)
- if info_type == 'timeline':
- time_line = info.get('TimelineEntry', info.get('_children', {}))
+ if event_type == 'timeline':
+ event_data = event.get('TimelineEntry', event.get('_children', {}))
- if not time_line:
- logger.debug("Tautulli WebSocket :: Timeline event found but unable to get timeline data.")
+ if not event_data:
+ logger.debug("Tautulli WebSocket :: Timeline event found but unable to get websocket data.")
return False
try:
- activity = activity_handler.TimelineHandler(timeline=time_line[0])
+ activity = activity_handler.TimelineHandler(timeline=event_data[0])
activity.process()
except Exception as e:
logger.exception("Tautulli WebSocket :: Failed to process timeline data: %s." % e)
+ if event_type == 'reachability':
+ event_data = event.get('ReachabilityNotification', event.get('_children', {}))
+
+ if not event_data:
+ logger.debug("Tautulli WebSocket :: Reachability event found but unable to get websocket data.")
+ return False
+
+ try:
+ activity = activity_handler.ReachabilityHandler(data=event_data[0])
+ activity.process()
+ except Exception as e:
+ logger.exception("Tautulli WebSocket :: Failed to process reachability data: %s." % e)
+
return True
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index d01af716..375db16b 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -2997,9 +2997,6 @@ class WebInterface(object):
"grouping_user_history": checked(plexpy.CONFIG.GROUPING_USER_HISTORY),
"grouping_charts": checked(plexpy.CONFIG.GROUPING_CHARTS),
"monitor_pms_updates": checked(plexpy.CONFIG.MONITOR_PMS_UPDATES),
- "monitor_remote_access": checked(plexpy.CONFIG.MONITOR_REMOTE_ACCESS),
- "remote_access_ping_interval": plexpy.CONFIG.REMOTE_ACCESS_PING_INTERVAL,
- "remote_access_ping_threshold": plexpy.CONFIG.REMOTE_ACCESS_PING_THRESHOLD,
"refresh_libraries_interval": plexpy.CONFIG.REFRESH_LIBRARIES_INTERVAL,
"refresh_libraries_on_startup": checked(plexpy.CONFIG.REFRESH_LIBRARIES_ON_STARTUP),
"refresh_users_interval": plexpy.CONFIG.REFRESH_USERS_INTERVAL,
@@ -3077,7 +3074,7 @@ class WebInterface(object):
"refresh_libraries_on_startup", "refresh_users_on_startup",
"notify_consecutive", "notify_recently_added_upgrade",
"notify_group_recently_added_grandparent", "notify_group_recently_added_parent",
- "monitor_pms_updates", "monitor_remote_access", "get_file_sizes", "log_blacklist", "http_hash_password",
+ "monitor_pms_updates", "get_file_sizes", "log_blacklist", "http_hash_password",
"allow_guest_access", "cache_images", "http_proxy", "http_basic_auth", "notify_concurrent_by_ip",
"history_table_activity", "plexpy_auto_update",
"themoviedb_lookup", "tvmaze_lookup", "musicbrainz_lookup", "http_plex_admin",
@@ -3130,8 +3127,6 @@ class WebInterface(object):
kwargs.get('refresh_users_interval') != str(plexpy.CONFIG.REFRESH_USERS_INTERVAL) or \
kwargs.get('pms_update_check_interval') != str(plexpy.CONFIG.PMS_UPDATE_CHECK_INTERVAL) or \
kwargs.get('monitor_pms_updates') != plexpy.CONFIG.MONITOR_PMS_UPDATES or \
- kwargs.get('monitor_remote_access') != plexpy.CONFIG.MONITOR_REMOTE_ACCESS or \
- kwargs.get('remote_access_ping_interval') != str(plexpy.CONFIG.REMOTE_ACCESS_PING_INTERVAL) or \
kwargs.get('pms_url_manual') != plexpy.CONFIG.PMS_URL_MANUAL:
reschedule = True