diff --git a/data/interfaces/default/index.html b/data/interfaces/default/index.html
index ee200dcb..af53ca3a 100644
--- a/data/interfaces/default/index.html
+++ b/data/interfaces/default/index.html
@@ -427,7 +427,6 @@
if (s.media_type === 'track') {
// Update if artist changed
if (s.grandparent_rating_key !== instance.data('grandparent_rating_key').toString()) {
- debugger;
$('#background-' + key).css('background-image', 'url(' + page('pms_image_proxy', s.art, s.rating_key, 500, 280, 40, '282828', 3, 'art', true, server_id=s.server_id) + ')');
$('#metadata-grandparent_title-' + key)
.attr('href', page('info', s.grandparent_rating_key, server_id=s.server_id))
@@ -436,7 +435,6 @@
}
// Update cover if album changed
if (s.parent_rating_key !== instance.data('parent_rating_key').toString()) {
- debugger;
$('#poster-' + key).css('background-image', 'url(' + page('pms_image_proxy', s.parent_thumb, s.parent_rating_key, 300, 300, null, null, null, 'poster', true, server_id=s.server_id) + ')');
$('#poster-' + key + '-bg').css('background-image', 'url(' + page('pms_image_proxy', s.parent_thumb, s.parent_rating_key, 300, 300, 60, '282828', 3, 'poster', true, server_id=s.server_id) + ')');
$('#poster-url-' + key)
@@ -809,7 +807,6 @@
[height, fallback_poster, fallback_art] = [450, 'poster-live', 'art-live'];
}
var href = '#';
- debugger;
if (stat_id === 'most_concurrent') {
return
} else if (stat_id === 'top_libraries') {
diff --git a/plexpy/__init__.py b/plexpy/__init__.py
index c5681b6f..a2062c43 100644
--- a/plexpy/__init__.py
+++ b/plexpy/__init__.py
@@ -144,6 +144,8 @@ DEV = False
TRACKER = None
+PLEX_REMOTE_ACCESS_UP = False
+
WIN_SYS_TRAY_ICON = None
MAC_SYS_TRAY_ICON = None
diff --git a/plexpy/activity_handler.py b/plexpy/activity_handler.py
index f5d4a3c3..0dd6e5e5 100644
--- a/plexpy/activity_handler.py
+++ b/plexpy/activity_handler.py
@@ -639,40 +639,40 @@ def schedule_callback(id, func=None, remove_job=False, args=None, **kwargs):
def force_stop_stream(session_key, title, user):
ap = activity_processor.ActivityProcessor()
session = ap.get_session_by_key(session_key=session_key)
+ if session:
+ row_id = ap.write_session_history(session=session)
- row_id = ap.write_session_history(session=session)
+ if row_id:
+ plexpy.NOTIFY_QUEUE.put({'stream_data': session.copy(), 'notify_action': 'on_stop'})
- if row_id:
- plexpy.NOTIFY_QUEUE.put({'stream_data': session.copy(), 'notify_action': 'on_stop'})
-
- # If session is written to the database successfully, remove the session from the session table
- logger.info("Tautulli ActivityHandler :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
- % (session['session_key'], session['rating_key']))
- ap.delete_session(row_id=row_id)
- delete_metadata_cache(session_key)
-
- else:
- session['write_attempts'] += 1
-
- if session['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
- logger.warn("Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
- "Will try again in 30 seconds. Write attempt %s."
- % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
- ap.increment_write_attempts(session_key=session_key)
-
- # Reschedule for 30 seconds later
- schedule_callback('session_key-{}'.format(session_key), func=force_stop_stream,
- args=[session_key, session['full_title'], session['user']], seconds=30)
-
- else:
- logger.warn("Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
- "Removing session from the database. Write attempt %s."
- % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
+ # If session is written to the database successfully, remove the session from the session table
logger.info("Tautulli ActivityHandler :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
% (session['session_key'], session['rating_key']))
- ap.delete_session(session_key=session_key)
+ ap.delete_session(row_id=row_id)
delete_metadata_cache(session_key)
+ else:
+ session['write_attempts'] += 1
+
+ if session['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
+ logger.warn("Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
+ "Will try again in 30 seconds. Write attempt %s."
+ % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
+ ap.increment_write_attempts(session_key=session_key)
+
+ # Reschedule for 30 seconds later
+ schedule_callback('session_key-{}'.format(session_key), func=force_stop_stream,
+ args=[session_key, session['full_title'], session['user']], seconds=30)
+
+ else:
+ logger.warn("Tautulli ActivityHandler :: Failed to write stream with sessionKey %s ratingKey %s to the database. " \
+ "Removing session from the database. Write attempt %s."
+ % (session['session_key'], session['rating_key'], str(session['write_attempts'])))
+ logger.info("Tautulli ActivityHandler :: Removing stale stream with sessionKey %s ratingKey %s from session queue"
+ % (session['session_key'], session['rating_key']))
+ ap.delete_session(session_key=session_key)
+ delete_metadata_cache(session_key)
+
def clear_recently_added_queue(rating_key, title):
logger.debug("Tautulli TimelineHandler :: Starting callback for library item '%s' (%s) after delay.",
diff --git a/plexpy/activity_processor.py b/plexpy/activity_processor.py
index 69f05132..b422904a 100644
--- a/plexpy/activity_processor.py
+++ b/plexpy/activity_processor.py
@@ -231,7 +231,7 @@ class ActivityProcessor(object):
self.write_continued_session(user_id=session['user_id'],
machine_id=session['machine_id'],
media_type=session['media_type'],
- stopped=stopped)
+ stopped=stopped, server_id=session['server_id'])
if str(session['rating_key']).isdigit() and session['media_type'] in ('movie', 'episode', 'track'):
logging_enabled = True
@@ -278,19 +278,19 @@ class ActivityProcessor(object):
if not is_import:
logger.debug("Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key'])
- for pms_connect in server_manager.ServerManger().get_server_list():
- if session['live']:
- metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']),
- cache_key=session['session_key'],
- return_cache=True)
- else:
- metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
- if not metadata:
- return False
- else:
- media_info = {}
- if 'media_info' in metadata and len(metadata['media_info']) > 0:
- media_info = metadata['media_info'][0]
+ pms_connect = server_manager.ServerManger().get_server(server_id=session['server_id'])
+ if session['live']:
+ metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']),
+ cache_key=session['session_key'],
+ return_cache=True)
+ else:
+ metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
+ if not metadata:
+ return False
+ else:
+ media_info = {}
+ if 'media_info' in metadata and len(metadata['media_info']) > 0:
+ media_info = metadata['media_info'][0]
else:
metadata = import_metadata
## TODO: Fix media info from imports. Temporary media info from import session.
@@ -701,8 +701,8 @@ class ActivityProcessor(object):
"WHERE session_key = ?",
[1, session_key])
- def write_continued_session(self, user_id=None, machine_id=None, media_type=None, stopped=None):
- keys = {'user_id': user_id, 'machine_id': machine_id, 'media_type': media_type}
+ def write_continued_session(self, user_id=None, machine_id=None, media_type=None, stopped=None, server_id=None):
+ keys = {'user_id': user_id, 'machine_id': machine_id, 'media_type': media_type, 'server_id': server_id}
values = {'stopped': stopped}
self.db.upsert(table_name='sessions_continued', key_dict=keys, value_dict=values)
diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py
index af98be46..9acdfe50 100644
--- a/plexpy/datafactory.py
+++ b/plexpy/datafactory.py
@@ -731,8 +731,8 @@ class DataFactory(object):
" GROUP BY %s) AS sh " \
"JOIN session_history_metadata AS shm ON shm.id = sh.id " \
"LEFT OUTER JOIN (SELECT * FROM library_sections WHERE deleted_section = 0) " \
- " AS ls ON sh.section_id = ls.section_id " \
- "GROUP BY sh.section_id " \
+ " AS ls ON sh.section_id = ls.section_id AND sh.server_id = ls.server_id " \
+ "GROUP BY sh.server_id " \
"ORDER BY %s DESC, sh.started DESC " \
"LIMIT %s OFFSET %s " % (timestamp, where_id, group_by, sort_type, stats_count, stats_start)
result = monitor_db.select(query)
diff --git a/plexpy/pmsconnect.py b/plexpy/pmsconnect.py
index d440a4e7..41d0b8dd 100644
--- a/plexpy/pmsconnect.py
+++ b/plexpy/pmsconnect.py
@@ -86,6 +86,8 @@ class PmsConnect(object):
self.timeout = plexpy.CONFIG.PMS_TIMEOUT
self.server_id = server_id
+
+ self.server_info = None
if not self.token:
# Check if we should use the admin token, or the guest server token
@@ -118,7 +120,7 @@ class PmsConnect(object):
return request
- def get_sessions_terminate(self, session_id='', reason='', server_id=None):
+ def get_sessions_terminate(self, session_id='', reason=''):
"""
Return current sessions.
@@ -649,7 +651,7 @@ class PmsConnect(object):
'guids': guids,
'full_title': helpers.get_xml_attr(m, 'title'),
'child_count': helpers.get_xml_attr(m, 'childCount'),
- 'server_id': server_info['machine_identifier']
+ 'server_id': self.server_id
}
recents_list.append(recent_item)
@@ -2309,7 +2311,7 @@ class PmsConnect(object):
'optimized_version_profile': optimized_version_profile,
'user': user_details['username'], # Keep for backwards compatibility
'channel_stream': channel_stream,
- 'server_id': server_info['machine_identifier'],
+ 'server_id': self.server_id,
'server_name': server_info['name'],
'server_ip': server_info['host'],
'server_port': server_info['port'],
@@ -2332,7 +2334,7 @@ class PmsConnect(object):
return session_output
- def terminate_session(self, session_key='', session_id='', message='', server_id=None):
+ def terminate_session(self, session_key='', session_id='', message=''):
"""
Terminates a streaming session.
"""
@@ -2347,7 +2349,7 @@ class PmsConnect(object):
ap = activity_processor.ActivityProcessor()
if session_key:
- session = ap.get_session_by_key(session_key=session_key, server_id=server_id)
+ session = ap.get_session_by_key(session_key=session_key, server_id=self.server_id)
if session and not session_id:
session_id = session['session_id']
@@ -2359,7 +2361,7 @@ class PmsConnect(object):
if session_id:
logger.info("Tautulli Pmsconnect :: Terminating session %s (session_id %s)." % (session_key, session_id))
- response = self.get_sessions_terminate(session_id=session_id, reason=message, server_id=server_id)
+ response = self.get_sessions_terminate(session_id=session_id, reason=message, server_id=self.server_id)
return response.ok
else:
msg = 'Missing session_id'
@@ -2495,7 +2497,7 @@ class PmsConnect(object):
'labels': labels,
'collections': collections,
'full_title': helpers.get_xml_attr(m, 'title'),
- 'server_id': self.get_server_info()['machine_identifier']
+ 'server_id': self.server_id
}
children_list.append(children_output)
@@ -2602,17 +2604,21 @@ class PmsConnect(object):
def get_server_info(self):
"""
- Return the base info of the current pms connection.
+ Return the base info of the current pms connection (cache it).
Output: dict
"""
- server_info = {}
- servers = self.get_servers_info()
- current = self.get_server_identity()
- for server in servers:
- if server['machine_identifier'] == current['machine_identifier']:
- server_info = server
- return server_info
+ if self.server_info is None:
+ servers = self.get_servers_info()
+ current = ""
+ if self.server_id is not None:
+ current = self.server_id
+ else:
+ current = self.get_server_identity()['machine_identifier']
+ for server in servers:
+ if server['machine_identifier'] == current:
+ self.server_info = server
+ return self.server_info
def get_server_identity(self):
"""
@@ -2633,7 +2639,8 @@ class PmsConnect(object):
server_identity = {"machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'),
"version": helpers.get_xml_attr(a, 'version'),
}
-
+ if self.server_id is None:
+ self.server_id = server_identity['machine_identifier']
return server_identity
def get_server_pref(self, pref=None):
diff --git a/plexpy/server_manager.py b/plexpy/server_manager.py
index d39448d7..2099a4f4 100644
--- a/plexpy/server_manager.py
+++ b/plexpy/server_manager.py
@@ -21,24 +21,43 @@ if plexpy.PYTHON2:
else:
from plexpy import pmsconnect
+pmsServers = []
+totalServers = 0
+
class ServerManger(object):
"""
- Return processed and validated library statistics.
+ Return list of cached servers
- Output: array
+ Output: array of servers
"""
def get_server_list(self):
- pmsServers = []
+ global totalServers
+ global pmsServers
+ if totalServers != 0 :
+ return pmsServers
for server in pmsconnect.PmsConnect().get_servers_info():
url = 'http://{hostname}:{port}'.format(hostname=server["host"], port=server["port"])
pmsServers.append(pmsconnect.PmsConnect(server['machine_identifier'], url=url))
+ totalServers = len(pmsServers)
return pmsServers
+ """
+ Return server by id or None
+
+ Output: PmsConnect
+
+ """
def get_server(self, server_id):
if server_id is not None:
+ global pmsServers
+ for server in pmsServers:
+ if server_id == server.server_id:
+ return server
for server in pmsconnect.PmsConnect().get_servers_info():
if server['machine_identifier'] == server_id:
url = 'http://{hostname}:{port}'.format(hostname=server["host"], port=server["port"])
- return pmsconnect.PmsConnect(server_id, url=url)
+ new = pmsconnect.PmsConnect(server_id, url=url)
+ pmsServers.append(new)
+ return new
return None
\ No newline at end of file
diff --git a/plexpy/web_socket.py b/plexpy/web_socket.py
index 0a609e98..48d94280 100644
--- a/plexpy/web_socket.py
+++ b/plexpy/web_socket.py
@@ -92,7 +92,6 @@ class WebSocketServer(object):
self.WEBSOCKET = None
self.WS_CONNECTED = False
self.PLEX_SERVER_UP = None
- self.PLEX_REMOTE_ACCESS_UP = None
self.server_id = server_id
def on_connect(self):
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index b80807ae..be711629 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -393,7 +393,7 @@ class WebInterface(object):
```
"""
pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
- result = pms_connect.terminate_session(session_key=session_key, session_id=session_id, message=message, server_id=server_id)
+ result = pms_connect.terminate_session(session_key=session_key, session_id=session_id, message=message)
if isinstance(result, str):
return {'result': 'error', 'message': 'Failed to terminate session: {}.'.format(result)}
@@ -4845,29 +4845,28 @@ class WebInterface(object):
# the image does not exist, download it from pms
try:
pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
- if pms_connect is not None:
- pms_connect.request_handler._silent = True
- result = pms_connect.get_image(img=img,
- width=width,
- height=height,
- opacity=opacity,
- background=background,
- blur=blur,
- img_format=img_format,
- clip=clip,
- refresh=refresh)
+ if pms_connect is None:
+ pms_connect = server_manager.ServerManger().get_server_list()[0]
+ pms_connect.request_handler._silent = True
+ result = pms_connect.get_image(img=img,
+ width=width,
+ height=height,
+ opacity=opacity,
+ background=background,
+ blur=blur,
+ img_format=img_format,
+ clip=clip,
+ refresh=refresh)
- if result and result[0]:
- cherrypy.response.headers['Content-type'] = result[1]
- if plexpy.CONFIG.CACHE_IMAGES and 'indexes' not in img:
- with open(ffp, 'wb') as f:
- f.write(result[0])
+ if result and result[0]:
+ cherrypy.response.headers['Content-type'] = result[1]
+ if plexpy.CONFIG.CACHE_IMAGES and 'indexes' not in img:
+ with open(ffp, 'wb') as f:
+ f.write(result[0])
- return result[0]
- else:
- raise Exception('PMS image request failed')
+ return result[0]
else:
- raise Exception('PMS server not found')
+ raise Exception('PMS image request failed')
except Exception as e:
logger.warn("Failed to get image %s, falling back to %s." % (img, fallback))