mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-22 06:13:25 -07:00
random optimizations
fixes to watch history fixes to library watch count
This commit is contained in:
parent
4989464420
commit
87eebeffe2
9 changed files with 114 additions and 91 deletions
|
@ -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') {
|
||||
|
|
|
@ -144,6 +144,8 @@ DEV = False
|
|||
|
||||
TRACKER = None
|
||||
|
||||
PLEX_REMOTE_ACCESS_UP = False
|
||||
|
||||
WIN_SYS_TRAY_ICON = None
|
||||
MAC_SYS_TRAY_ICON = None
|
||||
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
|
@ -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):
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue