mostly working server manager and multi server support

This commit is contained in:
tyler breese 2023-10-15 01:59:53 -04:00
commit 09faeaa985
25 changed files with 996 additions and 830 deletions

View file

@ -69,67 +69,66 @@ DOCUMENTATION :: END
<% <%
data = defaultdict(lambda: 'Unknown', **session) data = defaultdict(lambda: 'Unknown', **session)
sk = data['session_key'] sk = data['session_key']
href = page('info', data['rating_key'], server_id=data['server_id'])
href = page('info', data['rating_key']) parent_href = page('info', data['parent_rating_key'], server_id=data['server_id'])
parent_href = page('info', data['parent_rating_key']) grandparent_href = page('info', data['grandparent_rating_key'], server_id=data['server_id'])
grandparent_href = page('info', data['grandparent_rating_key'])
user_href = page('user', data['user_id']) if data['user_id'] else '#' user_href = page('user', data['user_id']) if data['user_id'] else '#'
season = short_season(data['parent_title']) season = short_season(data['parent_title'])
%> %>
<div class="dashboard-activity-instance" id="activity-instance-${sk}" data-key="${sk}" data-id="${data['session_id']}" <div class="dashboard-activity-instance" id="activity-instance-${sk}" data-key="${sk}" data-id="${data['session_id']}"
data-rating_key="${data['rating_key']}" data-parent_rating_key="${data['parent_rating_key']}" data-grandparent_rating_key="${data['grandparent_rating_key']}" data-rating_key="${data['rating_key']}" data-server_id="${data['server_id']}" data-parent_rating_key="${data['parent_rating_key']}" data-grandparent_rating_key="${data['grandparent_rating_key']}"
data-guid="${data['guid']}"> data-guid="${data['guid']}">
<div class="dashboard-activity-container"> <div class="dashboard-activity-container">
<% <%
if data['live']: if data['live']:
background_url = page('pms_image_proxy', data['art'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art-live', refresh=True) background_url = page('pms_image_proxy', data['art'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art-live', refresh=True, server_id=data['server_id'])
elif data['channel_stream'] == 0: elif data['channel_stream'] == 0:
background_url = page('pms_image_proxy', data['art'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art', refresh=True) background_url = page('pms_image_proxy', data['art'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art', refresh=True, server_id=data['server_id'])
else: else:
background_url = page('pms_image_proxy', data['art'] or data['thumb'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art', refresh=True, clip=True) background_url = page('pms_image_proxy', data['art'] or data['thumb'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art', refresh=True, clip=True, server_id=data['server_id'])
%> %>
<div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(${background_url});"> <div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(${background_url});">
<div class="dashboard-activity-poster-container hidden-xs"> <div class="dashboard-activity-poster-container hidden-xs">
% if data['media_type'] == 'track': % if data['media_type'] == 'track':
<div id="poster-${sk}-bg" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 300, 60, '282828', 3, fallback='cover', refresh=True)});"></div> <div id="poster-${sk}-bg" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 300, 60, '282828', 3, fallback='cover', refresh=True, server_id=data['server_id'])});"></div>
% endif % endif
% if data['live']: % if data['live']:
% if data['media_type'] == 'movie': % if data['media_type'] == 'movie':
<a id="poster-url-${sk}" href="${href}" title="${data['title']}"> <a id="poster-url-${sk}" href="${href}" title="${data['title']}">
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True, server_id=data['server_id'])});"></div>
</a> </a>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
<a id="poster-url-${sk}" href="${href}" title="${data['grandparent_title']}"> <a id="poster-url-${sk}" href="${href}" title="${data['grandparent_title']}">
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True, server_id=data['server_id'])});"></div>
</a> </a>
% else: % else:
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'] or data['thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'] or data['thumb'], data['rating_key'], 300, 450, fallback='poster-live', refresh=True, server_id=data['server_id'])});"></div>
% endif % endif
% elif data['channel_stream'] == 0: % elif data['channel_stream'] == 0:
% if data['media_type'] == 'movie': % if data['media_type'] == 'movie':
<a id="poster-url-${sk}" href="${href}" title="${data['title']}"> <a id="poster-url-${sk}" href="${href}" title="${data['title']}">
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster', refresh=True, server_id=data['server_id'])});"></div>
</a> </a>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
<a id="poster-url-${sk}" href="${grandparent_href}" title="${data['grandparent_title']}"> <a id="poster-url-${sk}" href="${grandparent_href}" title="${data['grandparent_title']}">
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'], data['grandparent_rating_key'], 300, 450, fallback='poster', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'], data['grandparent_rating_key'], 300, 450, fallback='poster', refresh=True, server_id=data['server_id'])});"></div>
</a> </a>
% elif data['media_type'] == 'track': % elif data['media_type'] == 'track':
<a id="poster-url-${sk}" href="${parent_href}" title="${data['parent_title']}"> <a id="poster-url-${sk}" href="${parent_href}" title="${data['parent_title']}">
<div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 300, fallback='cover', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 300, fallback='cover', refresh=True, server_id=data['server_id'])});"></div>
</a> </a>
% elif data['media_type'] in ('photo', 'clip'): % elif data['media_type'] in ('photo', 'clip'):
% if data['parent_thumb']: % if data['parent_thumb']:
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 450, fallback='poster', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['parent_thumb'], data['parent_rating_key'], 300, 450, fallback='poster', refresh=True, server_id=data['server_id'])});"></div>
% else: % else:
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster', refresh=True, server_id=data['server_id'])});"></div>
% endif % endif
% else: % else:
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(images/poster.png);"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(images/poster.png);"></div>
% endif % endif
% else: % else:
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['channel_icon'], data['rating_key'], 300, 300, 60, '282828', 3, fallback='cover', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(${page('pms_image_proxy', data['channel_icon'], data['rating_key'], 300, 300, 60, '282828', 3, fallback='cover', refresh=True, server_id=data['server_id'])});"></div>
<div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(${page('pms_image_proxy', data['channel_icon'], data['rating_key'], 300, 300, fallback='cover', refresh=True)});"></div> <div id="poster-${sk}" class="dashboard-activity-cover" style="background-image: url(${page('pms_image_proxy', data['channel_icon'], data['rating_key'], 300, 300, fallback='cover', refresh=True, server_id=data['server_id'])});"></div>
% endif % endif
</div> </div>
<div class="dashboard-activity-info-icon"> <div class="dashboard-activity-info-icon">
@ -141,7 +140,7 @@ DOCUMENTATION :: END
%> %>
<div id="platform-${sk}" class="dashboard-activity-info-platform${no_terminate} svg-icon platform-${data['platform_name']}" title="${data['platform']}"></div> <div id="platform-${sk}" class="dashboard-activity-info-platform${no_terminate} svg-icon platform-${data['platform_name']}" title="${data['platform']}"></div>
% if _session['user_group'] == 'admin' and plexpy.CONFIG.PMS_PLEXPASS and data['session_id']: % if _session['user_group'] == 'admin' and plexpy.CONFIG.PMS_PLEXPASS and data['session_id']:
<div class="dashboard-activity-terminate-session" id="terminate-button-${sk}" data-key="${sk}" data-id="${data['session_id']}" data-toggle="tooltip" title="Terminate Stream"> <div class="dashboard-activity-terminate-session" id="terminate-button-${sk}" data-key="${sk}" data-id="${data['session_id']}" data-toggle="tooltip" data-server_id="${data['server_id']}" title="Terminate Stream">
<i class="fa fa-times" style="padding-top: 10px;"></i> <i class="fa fa-times" style="padding-top: 10px;"></i>
</div> </div>
% endif % endif
@ -179,6 +178,10 @@ DOCUMENTATION :: END
<span data-toggle="tooltip" title="Quality profile is only an estimate based on bitrate and may be incorrect"><i class="fa fa-exclamation-circle"></i></span> <span data-toggle="tooltip" title="Quality profile is only an estimate based on bitrate and may be incorrect"><i class="fa fa-exclamation-circle"></i></span>
</div> </div>
</li> </li>
<li class="dashboard-activity-info-item">
<div class="sub-heading">Server</div>
<div class="sub-value platform-right">${data['server_name']}(${data['server_ip']}:${data['server_port']})</div>
</li>
% if data['optimized_version'] == 1: % if data['optimized_version'] == 1:
<li class="dashboard-activity-info-item"> <li class="dashboard-activity-info-item">
<div class="sub-heading">Optimized</div> <div class="sub-heading">Optimized</div>

View file

@ -70,17 +70,18 @@ DOCUMENTATION :: END
<% <%
stat_id = top_stat['stat_id'] stat_id = top_stat['stat_id']
row0 = top_stat['rows'][0] row0 = top_stat['rows'][0]
row0['server_id']="test"
%> %>
<div class="dashboard-stats-instance" id="stats-instance-${stat_id}" data-stat_id="${stat_id}"> <div class="dashboard-stats-instance" id="stats-instance-${stat_id}" data-stat_id="${stat_id}">
<div class="dashboard-stats-container"> <div class="dashboard-stats-container">
% if stat_id in ('top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', 'popular_music', 'last_watched'): % if stat_id in ('top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', 'popular_music', 'last_watched'):
<% fallback = 'art-live' if row0['live'] else 'art' %> <% fallback = 'art-live' if row0['live'] else 'art' %>
<div id="stats-background-${stat_id}" class="dashboard-stats-background" style="background-image: url(${page('pms_image_proxy', row0['art'], row0['rating_key'], 500, 280, 40, '282828', 3, fallback=fallback)});"> <div id="stats-background-${stat_id}" class="dashboard-stats-background" style="background-image: url(${page('pms_image_proxy', row0['art'], row0['rating_key'], 500, 280, 40, '282828', 3, fallback=fallback, server_id=row0['server_id'])});">
% elif stat_id == 'top_libraries': % elif stat_id == 'top_libraries':
<% fallback = 'art-live' if row0['live'] else row0['library_art'] %> <% fallback = 'art-live' if row0['live'] else row0['library_art'] %>
<div id="stats-background-${stat_id}" class="dashboard-stats-background" style="background-image: url(${page('pms_image_proxy', row0['art'] or row0['library_art'], None, 500, 280, 40, '282828', 3, fallback=fallback)});" data-library_art="${row0['library_art']}"> <div id="stats-background-${stat_id}" class="dashboard-stats-background" style="background-image: url(${page('pms_image_proxy', row0['art'] or row0['library_art'], None, 500, 280, 40, '282828', 3, fallback=fallback, server_id=row0['server_id'])});" data-library_art="${row0['library_art']}">
% elif stat_id == 'top_users': % elif stat_id == 'top_users':
<div id="stats-background-${stat_id}" class="dashboard-stats-background" data-blurhash="${page('pms_image_proxy', row0['user_thumb'] or 'interfaces/default/images/gravatar-default.png', None, 100, 100, 40, '282828', 0, fallback='user')}"> <div id="stats-background-${stat_id}" class="dashboard-stats-background" data-blurhash="${page('pms_image_proxy', row0['user_thumb'] or 'interfaces/default/images/gravatar-default.png', None, 100, 100, 40, '282828', 0, fallback='user', server_id=row0['server_id'])}">
% elif stat_id == 'top_platforms': % elif stat_id == 'top_platforms':
<div id="stats-background-${stat_id}" class="dashboard-stats-background platform-${row0['platform_name']}-rgba no-image"> <div id="stats-background-${stat_id}" class="dashboard-stats-background platform-${row0['platform_name']}-rgba no-image">
% else: % else:
@ -89,7 +90,7 @@ DOCUMENTATION :: END
% if stat_id in ('top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', 'popular_music', 'last_watched'): % if stat_id in ('top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', 'popular_music', 'last_watched'):
<div class="dashboard-stats-poster-container hidden-xs"> <div class="dashboard-stats-poster-container hidden-xs">
% if stat_id in ('top_music', 'popular_music'): % if stat_id in ('top_music', 'popular_music'):
<div id="stats-thumb-${stat_id}-bg" class="dashboard-stats-poster" style="background-image: url(${page('pms_image_proxy', row0['thumb'], row0['rating_key'], 300, 300, 60, '282828', 3, fallback='cover')});"></div> <div id="stats-thumb-${stat_id}-bg" class="dashboard-stats-poster" style="background-image: url(${page('pms_image_proxy', row0['thumb'], row0['rating_key'], 300, 300, 60, '282828', 3, fallback='cover', server_id=row0['server_id'])});"></div>
% endif % endif
<% <%
height, fallback = ('450', 'poster') height, fallback = ('450', 'poster')
@ -101,24 +102,24 @@ DOCUMENTATION :: END
href = '#' href = '#'
if row0['rating_key']: if row0['rating_key']:
if row0['live']: if row0['live']:
href = page('info', row0['rating_key'], row0['guid'], history=True, live=row0['live']) href = page('info', row0['rating_key'], row0['guid'], history=True, live=row0['live'], server_id=row0['server_id'])
else: else:
href = page('info', row0['rating_key'], history=True) href = page('info', row0['rating_key'], history=True, server_id=row0['server_id'])
%> %>
<a id="stats-thumb-url-${stat_id}" href="${href}" title="${row0['title']}"> <a id="stats-thumb-url-${stat_id}" href="${href}" title="${row0['title']}">
<div id="stats-thumb-${stat_id}" class="dashboard-stats-${fallback.split('-')[0]}" style="background-image: url(${page('pms_image_proxy', row0['thumb'], row0['grandparent_rating_key'] or row0['rating_key'], 300, height, fallback=fallback)});"></div> <div id="stats-thumb-${stat_id}" class="dashboard-stats-${fallback.split('-')[0]}" style="background-image: url(${page('pms_image_proxy', row0['thumb'], row0['grandparent_rating_key'] or row0['rating_key'], 300, height, fallback=fallback, server_id=row0['server_id'])});"></div>
</a> </a>
</div> </div>
% elif stat_id == 'top_libraries': % elif stat_id == 'top_libraries':
% if row0['library_thumb'].startswith('http'): % if row0['library_thumb'].startswith('http'):
<div id="stats-thumb-${stat_id}" class="dashboard-stats-flat hidden-xs" style="background-image: url(${page('pms_image_proxy', row0['library_thumb'], None, 100, 100, fallback='cover')});"></div> <div id="stats-thumb-${stat_id}" class="dashboard-stats-flat hidden-xs" style="background-image: url(${page('pms_image_proxy', row0['library_thumb'], None, 100, 100, fallback='cover', server_id=row0['server_id'])});"></div>
% else: % else:
<div id="stats-thumb-${stat_id}" class="dashboard-stats-flat svg-icon library-${row0['section_type']} hidden-xs"></div> <div id="stats-thumb-${stat_id}" class="dashboard-stats-flat svg-icon library-${row0['section_type']} hidden-xs"></div>
% endif % endif
% elif stat_id == 'top_users': % elif stat_id == 'top_users':
<% user_href = page('user', row0['user_id']) if row0['user_id'] else '#' %> <% user_href = page('user', row0['user_id']) if row0['user_id'] else '#' %>
<a id="stats-thumb-url-${stat_id}" href="${user_href}" title="${row0['user']}" class="hidden-xs"> <a id="stats-thumb-url-${stat_id}" href="${user_href}" title="${row0['user']}" class="hidden-xs">
<div id="stats-thumb-${stat_id}" class="dashboard-stats-circle" style="background-image: url(${page('pms_image_proxy', row0['user_thumb'] or 'interfaces/default/images/gravatar-default.png', None, 100, 100, fallback='user')})"></div> <div id="stats-thumb-${stat_id}" class="dashboard-stats-circle" style="background-image: url(${page('pms_image_proxy', row0['user_thumb'] or 'interfaces/default/images/gravatar-default.png', None, 100, 100, fallback='user', server_id=row0['server_id'])})"></div>
</a> </a>
% elif stat_id == 'top_platforms': % elif stat_id == 'top_platforms':
<div id="stats-thumb-${stat_id}" class="dashboard-stats-flat svg-icon platform-${row0['platform_name']} transparent hidden-xs"></div> <div id="stats-thumb-${stat_id}" class="dashboard-stats-flat svg-icon platform-${row0['platform_name']} transparent hidden-xs"></div>
@ -157,15 +158,15 @@ DOCUMENTATION :: END
href = '#' href = '#'
if row['rating_key']: if row['rating_key']:
if row['live']: if row['live']:
href = page('info', row['rating_key'], row['guid'], history=True, live=row['live']) href = page('info', row['rating_key'], row['guid'], history=True, live=row['live'], server_id=row['server_id'])
else: else:
href = page('info', row['rating_key'], history=True) href = page('info', row['rating_key'], history=True, server_id=row['server_id'])
%> %>
<a href="${href}" title="${row['title']}"> <a href="${href}" title="${row['title']}">
${row['title']} ${row['title']}
</a> </a>
% elif stat_id == 'top_libraries': % elif stat_id == 'top_libraries':
<% library_href = page('library', row['section_id']) %> <% library_href = page('library', row['section_id'], server_id=row['server_id']) %>
<a href="${library_href}" title="${row['section_name']}"> <a href="${library_href}" title="${row['section_name']}">
${row['section_name']} ${row['section_name']}
</a> </a>

View file

@ -71,9 +71,6 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="home-padded-header padded-header" id="library-statistics-header"> <div class="home-padded-header padded-header" id="library-statistics-header">
<h3 class="pull-left">Library Statistics</h3> <h3 class="pull-left">Library Statistics</h3>
<div class="button-bar">
<span class="btn btn-dark active" style="cursor: default">${config['pms_name']}</span>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -757,7 +754,8 @@
data: { data: {
session_key: key, session_key: key,
session_id: session_id, session_id: session_id,
message: message message: message,
server_id: "test1"
}, },
async: true, async: true,
success: function (data) { success: function (data) {

View file

@ -93,7 +93,7 @@ DOCUMENTATION :: END
<div class="row"> <div class="row">
% if data['media_type'] not in ('photo_album', 'photo', 'playlist'): % if data['media_type'] not in ('photo_album', 'photo', 'playlist'):
<% fallback = 'art-live-full' if data['live'] else None %> <% fallback = 'art-live-full' if data['live'] else None %>
<div class="art-face" style="background-image:url(${page('pms_image_proxy', data['art'], data['rating_key'], 1920, 1080, fallback=fallback)})"></div> <div class="art-face" style="background-image:url(${page('pms_image_proxy', data['art'], data['rating_key'], 1920, 1080, fallback=fallback, server_id=data['server_id'])})"></div>
% endif % endif
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
<span class="overlay-refresh-image info-art" title="Refresh background image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image info-art" title="Refresh background image"><i class="fa fa-refresh refresh_pms_image"></i></span>
@ -104,7 +104,7 @@ DOCUMENTATION :: END
<div class="summary-navbar-list"> <div class="summary-navbar-list">
<ul class="list-unstyled breadcrumb"> <ul class="list-unstyled breadcrumb">
% if data['live']: % if data['live']:
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
% if data['media_type'] == 'movie': % if data['media_type'] == 'movie':
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
@ -120,57 +120,57 @@ DOCUMENTATION :: END
% endif % endif
% endif % endif
% elif data['media_type'] in ('movie', 'collection'): % elif data['media_type'] in ('movie', 'collection'):
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'show': % elif data['media_type'] == 'show':
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'season': % elif data['media_type'] == 'season':
<li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
<li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="hidden-xs hidden-sm"><a href="${page('info', data['grandparent_rating_key'])}">${data['grandparent_title']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('info', data['grandparent_rating_key'], server_id=data['server_id'])}">${data['grandparent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">Episode ${data['media_index']} - ${data['title']}</li> <li class="active metadata-xml">Episode ${data['media_index']} - ${data['title']}</li>
% elif data['media_type'] == 'artist': % elif data['media_type'] == 'artist':
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'album': % elif data['media_type'] == 'album':
<li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'track': % elif data['media_type'] == 'track':
<li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="hidden-xs hidden-sm"><a href="${page('info', data['grandparent_rating_key'])}">${data['grandparent_title']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('info', data['grandparent_rating_key'], server_id=data['server_id'])}">${data['grandparent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">Track ${data['media_index']} - ${data['title']}</li> <li class="active metadata-xml">Track ${data['media_index']} - ${data['title']}</li>
% elif data['media_type'] == 'photo_album': % elif data['media_type'] == 'photo_album':
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
% if data['parent_title']: % if data['parent_title']:
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
% endif % endif
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] in ('photo', 'clip'): % elif data['media_type'] in ('photo', 'clip'):
<li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li class="hidden-xs hidden-sm"><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></li> <li><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
% elif data['media_type'] == 'playlist': % elif data['media_type'] == 'playlist':
@ -178,7 +178,7 @@ DOCUMENTATION :: END
<li><a href="${page('user', user_info.get('user_id'))}">${user_info.get('friendly_name')}</a></li> <li><a href="${page('user', user_info.get('user_id'))}">${user_info.get('friendly_name')}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
% elif data['section_id']: % elif data['section_id']:
<li><a href="${page('library', data['section_id'])}">${data['library_name']}</a></li> <li><a href="${page('library', data['section_id'], server_id=data['server_id'])}">${data['library_name']}</a></li>
<span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span> <span class="breadcrumb-arrow"><i class="fa fa-chevron-right"></i></span>
% endif % endif
<li class="active metadata-xml">${data['title']}</li> <li class="active metadata-xml">${data['title']}</li>
@ -192,21 +192,21 @@ DOCUMENTATION :: END
<div class="summary-content-poster hidden-xs hidden-sm"> <div class="summary-content-poster hidden-xs hidden-sm">
<% legacy = '&legacy=1' if data['media_type'] in ('photo_album', 'photo', 'clip') else '' %> <% legacy = '&legacy=1' if data['media_type'] in ('photo_album', 'photo', 'clip') else '' %>
% if data['media_type'] in ('track', 'photo'): % if data['media_type'] in ('track', 'photo'):
<a href="${config['pms_web_url']}#!/server/${config['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${data['parent_rating_key']}${legacy}" target="_blank" rel="noreferrer" title="View on Plex Web"> <a href="${config['pms_web_url']}#!/server/${data['server_id']}/details?key=%2Flibrary%2Fmetadata%2F${data['parent_rating_key']}${legacy}" target="_blank" rel="noreferrer" title="View on Plex Web">
% elif data['media_type'] == 'playlist': % elif data['media_type'] == 'playlist':
<a href="${config['pms_web_url']}#!/server/${config['pms_identifier']}/playlist?key=%2Fplaylists%2F${data['rating_key']}" target="_blank" rel="noreferrer" title="View on Plex Web"> <a href="${config['pms_web_url']}#!/server/${data['server_id']}/playlist?key=%2Fplaylists%2F${data['rating_key']}" target="_blank" rel="noreferrer" title="View on Plex Web">
% elif not data['live']: % elif not data['live']:
<a href="${config['pms_web_url']}#!/server/${config['pms_identifier']}/details?key=%2Flibrary%2Fmetadata%2F${data['rating_key']}${legacy}" target="_blank" rel="noreferrer" title="View on Plex Web"> <a href="${config['pms_web_url']}#!/server/${data['server_id']}/details?key=%2Flibrary%2Fmetadata%2F${data['rating_key']}${legacy}" target="_blank" rel="noreferrer" title="View on Plex Web">
% endif % endif
% if data['live']: % if data['live']:
<div class="summary-poster-face" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'] or data['thumb'], data['rating_key'], 300, 450, fallback='poster-live')});"> <div class="summary-poster-face" style="background-image: url(${page('pms_image_proxy', data['grandparent_thumb'] or data['thumb'], data['rating_key'], 300, 450, fallback='poster-live', server_id=data['server_id'])});">
<div class="summary-poster-face-overlay"> <div class="summary-poster-face-overlay">
<span></span> <span></span>
</div> </div>
</div> </div>
% else: % else:
% if data['media_type'] == 'episode': % if data['media_type'] == 'episode':
<div class="summary-poster-face-episode" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 500, 280, fallback='art')});"> <div class="summary-poster-face-episode" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 500, 280, fallback='art', server_id=data['server_id'])});">
<div class="summary-poster-face-overlay"> <div class="summary-poster-face-overlay">
<span></span> <span></span>
</div> </div>
@ -215,7 +215,7 @@ DOCUMENTATION :: END
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
% elif data['media_type'] in ('artist', 'album', 'track', 'playlist', 'photo_album', 'photo', 'clip') or data['sub_media_type'] in ('artist', 'album', 'track'): % elif data['media_type'] in ('artist', 'album', 'track', 'playlist', 'photo_album', 'photo', 'clip') or data['sub_media_type'] in ('artist', 'album', 'track'):
<div class="summary-poster-face-track" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 300, fallback='cover')});"> <div class="summary-poster-face-track" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 300, fallback='cover', server_id=data['server_id'])});">
<div class="summary-poster-face-overlay"> <div class="summary-poster-face-overlay">
<span></span> <span></span>
</div> </div>
@ -227,7 +227,7 @@ DOCUMENTATION :: END
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
% else: % else:
<div class="summary-poster-face" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster')});"> <div class="summary-poster-face" style="background-image: url(${page('pms_image_proxy', data['thumb'], data['rating_key'], 300, 450, fallback='poster', server_id=data['server_id'])});">
<div class="summary-poster-face-overlay"> <div class="summary-poster-face-overlay">
<span></span> <span></span>
</div> </div>
@ -258,21 +258,21 @@ DOCUMENTATION :: END
% elif data['media_type'] in ('movie', 'show', 'artist', 'collection', 'playlist', 'photo_album'): % elif data['media_type'] in ('movie', 'show', 'artist', 'collection', 'playlist', 'photo_album'):
<h1>&nbsp;</h1><h1>${data['title']}</h1> <h1>&nbsp;</h1><h1>${data['title']}</h1>
% elif data['media_type'] == 'season': % elif data['media_type'] == 'season':
<h1>&nbsp;</h1><h1><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></h1> <h1>&nbsp;</h1><h1><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></h1>
<h3 class="hidden-xs">${season}</h3> <h3 class="hidden-xs">${season}</h3>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
<h1><a href="${page('info', data['grandparent_rating_key'])}">${data['grandparent_title']}</a></h1> <h1><a href="${page('info', data['grandparent_rating_key'], server_id=data['server_id'])}">${data['grandparent_title']}</a></h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
<h3 class="hidden-xs">${season} &middot; E${data['media_index']}</h3> <h3 class="hidden-xs">${season} &middot; E${data['media_index']}</h3>
% elif data['media_type'] == 'album': % elif data['media_type'] == 'album':
<h1><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></h1> <h1><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
% elif data['media_type'] == 'track': % elif data['media_type'] == 'track':
<h1><a href="${page('info', data['grandparent_rating_key'])}">${data['grandparent_title']}</a></h1> <h1><a href="${page('info', data['grandparent_rating_key'], server_id=data['server_id'])}">${data['grandparent_title']}</a></h1>
<h2><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a> - ${data['title']}</h2> <h2><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a> - ${data['title']}</h2>
<h3 class="hidden-xs">T${data['media_index']}</h3> <h3 class="hidden-xs">T${data['media_index']}</h3>
% elif data['media_type'] in ('photo', 'clip'): % elif data['media_type'] in ('photo', 'clip'):
<h1><a href="${page('info', data['parent_rating_key'])}">${data['parent_title']}</a></h1> <h1><a href="${page('info', data['parent_rating_key'], server_id=data['server_id'])}">${data['parent_title']}</a></h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
% endif % endif
</div> </div>
@ -878,17 +878,18 @@ DOCUMENTATION :: END
transcode_decision: transcode_decision, transcode_decision: transcode_decision,
user_id: "${history_user_id}", user_id: "${history_user_id}",
% if data['live']: % if data['live']:
guid: "${data['guid']} guid: "${data['guid']}",
% elif data['media_type'] in ('show', 'artist'): % elif data['media_type'] in ('show', 'artist'):
grandparent_rating_key: "${data['rating_key']}" grandparent_rating_key: "${data['rating_key']}",
% elif data['media_type'] in ('season', 'album'): % elif data['media_type'] in ('season', 'album'):
parent_rating_key: "${data['rating_key']}" parent_rating_key: "${data['rating_key']}",
% elif data['media_type'] in ('movie', 'episode', 'track'): % elif data['media_type'] in ('movie', 'episode', 'track'):
rating_key: "${data['rating_key']}" rating_key: "${data['rating_key']}",
% elif data['media_type'] in ('collection', 'playlist'): % elif data['media_type'] in ('collection', 'playlist'):
media_type: "${data['media_type']}", media_type: "${data['media_type']}",
rating_key: "${data['rating_key']}" rating_key: "${data['rating_key']}",
% endif % endif
server_id: "${data['server_id']}"
}; };
} }
} }
@ -932,7 +933,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
rating_key: "${data['rating_key']}", rating_key: "${data['rating_key']}",
media_type: "${data['media_type']}" media_type: "${data['media_type']}",
server_id: "${data['server_id']}"
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#children-list").html(xhr.responseText); $("#children-list").html(xhr.responseText);
@ -948,7 +950,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
rating_key: "${data['rating_key']}", rating_key: "${data['rating_key']}",
media_type: "${data['media_type']}" media_type: "${data['media_type']}",
server_id: "${data['server_id']}"
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#watch-time-stats").html(xhr.responseText); $("#watch-time-stats").html(xhr.responseText);
@ -960,7 +963,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
rating_key: "${data['rating_key']}", rating_key: "${data['rating_key']}",
media_type: "${data['media_type']}" media_type: "${data['media_type']}",
server_id: "${data['server_id']}"
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#user-stats").html(xhr.responseText); $("#user-stats").html(xhr.responseText);
@ -976,7 +980,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
rating_key: "${data['rating_key']}", rating_key: "${data['rating_key']}",
title: "${data['title']}" title: "${data['title']}",
server_id: "${data['server_id']}"
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#collection-related-list-container").html(xhr.responseText).show(); $("#collection-related-list-container").html(xhr.responseText).show();
@ -1064,7 +1069,7 @@ DOCUMENTATION :: END
data: function ( d ) { data: function ( d ) {
return { return {
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
rating_key: "${data['rating_key']}" rating_key: "${data['rating_key']}",
}; };
} }
}; };

View file

@ -48,61 +48,61 @@ DOCUMENTATION :: END
<span class="item-children-list-item-title"> <span class="item-children-list-item-title">
% if child['media_type'] == 'movie': % if child['media_type'] == 'movie':
<span class="media-type-tooltip" data-toggle="tooltip" title="Movie"><i class="fa fa-film fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Movie"><i class="fa fa-film fa-fw"></i></span>
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster')}" data-height="120" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])}" data-height="120" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>
<span class="text-muted"> (${child['year']})</span> <span class="text-muted"> (${child['year']})</span>
% elif child['media_type'] == 'episode': % elif child['media_type'] == 'episode':
<span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span>
<a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}"> <a href="${page('info', child['grandparent_rating_key'], server_id=child['server_id'])}" title="${child['grandparent_title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 450, fallback='poster')}" data-height="120" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])}" data-height="120" data-width="80">
${child['grandparent_title']} ${child['grandparent_title']}
</span> </span>
</a> - </a> -
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 450, fallback='poster')}" data-height="120" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])}" data-height="120" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>
<span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${short_season(child['parent_title'])}</a> &middot; <a class="no-highlight" href="${page('info', child['rating_key'])}" title="${child['title']}">E${child['media_index']}</a>)</span> <span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${short_season(child['parent_title'])}</a> &middot; <a class="no-highlight" href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">E${child['media_index']}</a>)</span>
% elif child['media_type'] == 'track': % elif child['media_type'] == 'track':
<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> - </a> -
<a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}"> <a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['grandparent_title']} ${child['grandparent_title']}
</span> </span>
</a> </a>
<span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span> <span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span>
% elif child['media_type'] == 'photo': % elif child['media_type'] == 'photo':
<span class="media-type-tooltip" data-toggle="tooltip" title="Photo"><i class="fa fa-picture-o fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Photo"><i class="fa fa-picture-o fa-fw"></i></span>
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>
% if child['grandparent_title']: % if child['grandparent_title']:
- <a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}"> - <a href="${page('info', child['grandparent_rating_key'], server_id=child['server_id'])}" title="${child['grandparent_title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['grandparent_title']} ${child['grandparent_title']}
</span> </span>
</a> </a>
% endif % endif
<span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span> <span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span>
% elif child['media_type'] == 'clip': % elif child['media_type'] == 'clip':
<span class="media-type-tooltip" data-toggle="tooltip" title="Video"><i class="fa fa-video-camera fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Video"><i class="fa fa-video-camera fa-fw"></i></span>
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>
<span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span> <span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span>
% endif % endif
</span> </span>
% if child['duration']: % if child['duration']:
@ -113,9 +113,9 @@ DOCUMENTATION :: END
% endif % endif
</div> </div>
% elif child['media_type'] == 'movie': % elif child['media_type'] == 'movie':
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<div class="item-children-poster"> <div class="item-children-poster">
<div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster')});"></div> <div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])});"></div>
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
@ -123,14 +123,14 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper poster-item"> <div class="item-children-instance-text-wrapper poster-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
<h3 class="text-muted">${child['year']}</h3> <h3 class="text-muted">${child['year']}</h3>
</div> </div>
% elif child['media_type'] == 'show': % elif child['media_type'] == 'show':
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<div class="item-children-poster"> <div class="item-children-poster">
<div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster')});"></div> <div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])});"></div>
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
@ -138,16 +138,16 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper poster-item"> <div class="item-children-instance-text-wrapper poster-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
</div> </div>
% elif child['media_type'] == 'season': % elif child['media_type'] == 'season':
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<div class="item-children-poster"> <div class="item-children-poster">
% if child['thumb']: % if child['thumb']:
<div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster')});"> <div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])});">
% else: % else:
<div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 450, fallback='poster')});"> <div class="item-children-poster-face poster-item" style="background-image: url(${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 450, fallback='poster', server_id=child['server_id'])});">
% endif % endif
<div class="item-children-card-overlay"> <div class="item-children-card-overlay">
<div class="item-children-overlay-text"> <div class="item-children-overlay-text">
@ -162,18 +162,18 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper poster-item"> <div class="item-children-instance-text-wrapper poster-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
% if media_type == 'collection': % if media_type == 'collection':
<h3 class="text-muted"> <h3 class="text-muted">
<a class="text-muted" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a> <a class="text-muted" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${child['parent_title']}</a>
</h3> </h3>
% endif % endif
</div> </div>
% elif child['media_type'] == 'episode': % elif child['media_type'] == 'episode':
<a href="${page('info', child['rating_key'])}" title="Episode ${child['media_index']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="Episode ${child['media_index']}">
<div class="item-children-poster"> <div class="item-children-poster">
<div class="item-children-poster-face episode-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 500, 280, fallback='art')});"> <div class="item-children-poster-face episode-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 500, 280, fallback='art', server_id=child['server_id'])});">
<div class="item-children-card-overlay"> <div class="item-children-card-overlay">
<div class="item-children-overlay-text"> <div class="item-children-overlay-text">
Episode ${child['media_index'] or child['originally_available_at']} Episode ${child['media_index'] or child['originally_available_at']}
@ -187,22 +187,22 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper episode-item"> <div class="item-children-instance-text-wrapper episode-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
% if media_type == 'collection': % if media_type == 'collection':
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}">${child['grandparent_title']}</a> <a href="${page('info', child['grandparent_rating_key'], server_id=child['server_id'])}" title="${child['grandparent_title']}">${child['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${short_season(child['parent_title'])}</a> <a href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${short_season(child['parent_title'])}</a>
&middot; <a href="${page('info', child['rating_key'])}" title="Episode ${child['media_index']}">E${child['media_index']}</a> &middot; <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="Episode ${child['media_index']}">E${child['media_index']}</a>
</h3> </h3>
% endif % endif
</div> </div>
% elif child['media_type'] == 'artist': % elif child['media_type'] == 'artist':
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<div class="item-children-poster"> <div class="item-children-poster">
<div class="item-children-poster-face cover-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover')});"></div> <div class="item-children-poster-face cover-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])});"></div>
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
@ -210,13 +210,13 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper cover-item"> <div class="item-children-instance-text-wrapper cover-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
</div> </div>
% elif child['media_type'] == 'album': % elif child['media_type'] == 'album':
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<div class="item-children-poster"> <div class="item-children-poster">
<div class="item-children-poster-face cover-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover')});"></div> <div class="item-children-poster-face cover-item" style="background-image: url(${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])});"></div>
% if _session['user_group'] == 'admin': % if _session['user_group'] == 'admin':
<span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span> <span class="overlay-refresh-image" title="Refresh image"><i class="fa fa-refresh refresh_pms_image"></i></span>
% endif % endif
@ -224,11 +224,11 @@ DOCUMENTATION :: END
</a> </a>
<div class="item-children-instance-text-wrapper cover-item"> <div class="item-children-instance-text-wrapper cover-item">
<h3> <h3>
<a href="${page('info', child['rating_key'])}" title="${child['title']}">${child['title']}</a> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">${child['title']}</a>
</h3> </h3>
% if media_type == 'collection': % if media_type == 'collection':
<h3 class="text-muted"> <h3 class="text-muted">
<a class="text-muted" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a> <a class="text-muted" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title'], server_id=child['server_id']}">${child['parent_title']}</a>
</h3> </h3>
% endif % endif
</div> </div>
@ -238,19 +238,19 @@ DOCUMENTATION :: END
<span class="item-children-list-item-index">${child['media_index']}</span> <span class="item-children-list-item-index">${child['media_index']}</span>
<span class="item-children-list-item-title"> <span class="item-children-list-item-title">
<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['parent_thumb'], child['parent_rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>
% if media_type == 'collection': % if media_type == 'collection':
- -
<a href="${page('info', child['grandparent_rating_key'])}" title="${child['grandparent_title']}"> <a href="${page('info', child['grandparent_rating_key'], server_id=child['server_id'])}" title="${child['grandparent_title'], server_id=child['server_id']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['grandparent_thumb'], child['grandparent_rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80">
${child['grandparent_title']} ${child['grandparent_title']}
</span> </span>
</a> </a>
<span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span> <span class="text-muted"> (<a class="no-highlight" href="${page('info', child['parent_rating_key'], server_id=child['server_id'])}" title="${child['parent_title']}">${child['parent_title']}</a>)</span>
% elif child['original_title']: % elif child['original_title']:
<span class="text-muted"> - ${child['original_title']}</span> <span class="text-muted"> - ${child['original_title']}</span>
% endif % endif
@ -272,8 +272,8 @@ DOCUMENTATION :: END
% else: % else:
<span class="media-type-tooltip" data-toggle="tooltip" title="Photo"><i class="fa fa-picture-o fa-fw"></i></span> <span class="media-type-tooltip" data-toggle="tooltip" title="Photo"><i class="fa fa-picture-o fa-fw"></i></span>
% endif % endif
<a href="${page('info', child['rating_key'])}" title="${child['title']}"> <a href="${page('info', child['rating_key'], server_id=child['server_id'])}" title="${child['title']}">
<span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover')}" data-height="80" data-width="80"> <span class="thumb-tooltip" data-toggle="popover" data-img="${page('pms_image_proxy', child['thumb'], child['rating_key'], 300, 300, fallback='cover', server_id=child['server_id'])}" data-height="80" data-width="80">
${child['title']} ${child['title']}
</span> </span>
</a> </a>

View file

@ -784,7 +784,7 @@ function page(endpoint, ...args) {
return endpoint + '?' + $.param(params).replace(/'/g, '%27'); return endpoint + '?' + $.param(params).replace(/'/g, '%27');
} }
function pms_image_proxy(img, rating_key, width, height, opacity, background, blur, fallback, refresh, clip, img_format) { function pms_image_proxy(img, rating_key, width, height, opacity, background, blur, fallback, refresh, clip, img_format, server_id) {
var params = {}; var params = {};
if (img != null) { params.img = img; } if (img != null) { params.img = img; }
@ -798,11 +798,12 @@ function pms_image_proxy(img, rating_key, width, height, opacity, background, bl
if (refresh != null) { params.refresh = true; } if (refresh != null) { params.refresh = true; }
if (clip != null) { params.clip = true; } if (clip != null) { params.clip = true; }
if (img_format != null) { params.img_format = img_format; } if (img_format != null) { params.img_format = img_format; }
if (server_id != null) { params.server_id = server_id; }
return params; return params;
} }
function info_page(rating_key, guid, history, live) { function info_page(rating_key, guid, history, live, server_id) {
var params = {}; var params = {};
if (live && history) { if (live && history) {
@ -813,13 +814,16 @@ function info_page(rating_key, guid, history, live) {
if (history) { params.source = 'history'; } if (history) { params.source = 'history'; }
if (server_id != null) { params.server_id = server_id; }
return params; return params;
} }
function library_page(section_id) { function library_page(section_id, server_id) {
var params = {}; var params = {};
if (section_id != null) { params.section_id = section_id; } if (section_id != null) { params.section_id = section_id; }
if (server_id != null) { params.server_id = server_id; }
return params; return params;
} }

View file

@ -49,12 +49,12 @@ libraries_list_table_options = {
if (!rowData['is_active']) { inactive = '<span class="inactive-library-tooltip" data-toggle="tooltip" title="Library not on Plex server"><i class="fa fa-exclamation-triangle"></i></span>'; } if (!rowData['is_active']) { inactive = '<span class="inactive-library-tooltip" data-toggle="tooltip" title="Library not on Plex server"><i class="fa fa-exclamation-triangle"></i></span>'; }
if (cellData !== null && cellData !== '') { if (cellData !== null && cellData !== '') {
if (rowData['library_thumb'].substring(0, 4) == "http") { if (rowData['library_thumb'].substring(0, 4) == "http") {
$(td).html('<a href="' + page('library', rowData['section_id']) + '"><div class="libraries-poster-face" style="background-image: url(' + rowData['library_thumb'] + ');">' + inactive + '</div></a>'); $(td).html('<a href="' + page('library', rowData['section_id'], rowData['server_id']) + '"><div class="libraries-poster-face" style="background-image: url(' + rowData['library_thumb'] + ');">' + inactive + '</div></a>');
} else { } else {
$(td).html('<a href="' + page('library', rowData['section_id']) + '"><div class="libraries-poster-face svg-icon library-' + rowData['section_type'] + '">' + inactive + '</div></a>'); $(td).html('<a href="' + page('library', rowData['section_id'], rowData['server_id']) + '"><div class="libraries-poster-face svg-icon library-' + rowData['section_type'] + '">' + inactive + '</div></a>');
} }
} else { } else {
$(td).html('<a href="' + page('library', rowData['section_id']) + '"><div class="libraries-poster-face" style="background-image: url(../../images/cover.png);">' + inactive + '</div></a>'); $(td).html('<a href="' + page('library', rowData['section_id'], rowData['server_id']) + '"><div class="libraries-poster-face" style="background-image: url(../../images/cover.png);">' + inactive + '</div></a>');
} }
}, },
"orderable": false, "orderable": false,
@ -68,7 +68,7 @@ libraries_list_table_options = {
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html('<div data-id="' + rowData['row_id'] + '">' + $(td).html('<div data-id="' + rowData['row_id'] + '">' +
'<a href="' + page('library', rowData['section_id']) + '">' + cellData + '</a>' + '<a href="' + page('library', rowData['section_id'], rowData['server_id']) + '">' + cellData + '</a>' +
'</div>'); '</div>');
} else { } else {
$(td).html('n/a'); $(td).html('n/a');
@ -154,23 +154,23 @@ libraries_list_table_options = {
icon_title = (rowData['live']) ? 'Live TV' : 'Movie'; icon_title = (rowData['live']) ? 'Live TV' : 'Movie';
if (rowData['year']) { parent_info = ' (' + rowData['year'] + ')'; } if (rowData['year']) { parent_info = ' (' + rowData['year'] + ')'; }
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="' + icon_title + '"><i class="fa ' + icon + ' fa-fw"></i></span>'; media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="' + icon_title + '"><i class="fa ' + icon + ' fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 450, null, null, null, fallback) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>'; thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 450, null, null, null, fallback, rowData['server_id']) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>';
$(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live'], rowData['server_id']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'episode') { } else if (rowData['media_type'] === 'episode') {
icon = (rowData['live']) ? 'fa-broadcast-tower' : 'fa-television'; icon = (rowData['live']) ? 'fa-broadcast-tower' : 'fa-television';
icon_title = (rowData['live']) ? 'Live TV' : 'Episode'; icon_title = (rowData['live']) ? 'Live TV' : 'Episode';
if (!isNaN(parseInt(rowData['parent_media_index'])) && !isNaN(parseInt(rowData['media_index']))) { parent_info = ' (' + short_season(rowData['parent_title']) + ' &middot; E' + rowData['media_index'] + ')'; } if (!isNaN(parseInt(rowData['parent_media_index'])) && !isNaN(parseInt(rowData['media_index']))) { parent_info = ' (' + short_season(rowData['parent_title']) + ' &middot; E' + rowData['media_index'] + ')'; }
else if (rowData['live'] && rowData['originally_available_at']) { parent_info = ' (' + rowData['originally_available_at'] + ')'; } else if (rowData['live'] && rowData['originally_available_at']) { parent_info = ' (' + rowData['originally_available_at'] + ')'; }
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="' + icon_title + '"><i class="fa ' + icon + ' fa-fw"></i></span>'; media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="' + icon_title + '"><i class="fa ' + icon + ' fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 450, null, null, null, fallback) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>'; thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 450, null, null, null, fallback, rowData['server_id']) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>';
$(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live']) + '"><div style="float: left;" >' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live'], rowData['server_id']) + '"><div style="float: left;" >' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'track') { } else if (rowData['media_type'] === 'track') {
if (rowData['parent_title']) { parent_info = ' (' + rowData['parent_title'] + ')'; } if (rowData['parent_title']) { parent_info = ' (' + rowData['parent_title'] + ')'; }
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>'; media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 300, null, null, null, 'cover') + '" data-height="80" data-width="80">' + cellData + parent_info + '</span>'; thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 300, 300, null, null, null, 'cover', rowData['server_id']) + '" data-height="80" data-width="80">' + cellData + parent_info + '</span>';
$(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key'], rowData['guid'], true, rowData['live'], rowData['server_id']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type']) { } else if (rowData['media_type']) {
$(td).html('<a href="' + page('info', rowData['rating_key']) + '">' + cellData + '</a>'); $(td).html('<a href="' + page('info', rowData['rating_key'], rowData['server_id']) + '">' + cellData + '</a>');
} }
} else { } else {
$(td).html('n/a'); $(td).html('n/a');

View file

@ -548,6 +548,7 @@ DOCUMENTATION :: END
% endif % endif
var section_name = '${data['section_name'].replace("'", "\\'")}'; var section_name = '${data['section_name'].replace("'", "\\'")}';
var refresh_table = false; var refresh_table = false;
var server_id = "${data['server_id']}";
% if config['get_file_sizes']: % if config['get_file_sizes']:
var get_file_sizes = false; var get_file_sizes = false;
@ -577,7 +578,8 @@ DOCUMENTATION :: END
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
section_id: section_id, section_id: section_id,
user_id: "${history_user_id}", user_id: "${history_user_id}",
transcode_decision: transcode_decision transcode_decision: transcode_decision,
server_id: server_id
}; };
} }
}; };
@ -625,7 +627,8 @@ DOCUMENTATION :: END
data: function ( d ) { data: function ( d ) {
return { return {
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
section_id: section_id section_id: section_id,
server_id: server_id
}; };
} }
}; };
@ -657,7 +660,8 @@ DOCUMENTATION :: END
data: function ( d ) { data: function ( d ) {
return { return {
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
section_id: section_id section_id: section_id,
server_id: server_id
}; };
} }
}; };
@ -686,7 +690,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
section_id: section_id, section_id: section_id,
limit: 50 limit: 50,
server_id: server_id
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-recently-watched").html(xhr.responseText); $("#library-recently-watched").html(xhr.responseText);
@ -702,7 +707,8 @@ DOCUMENTATION :: END
async: true, async: true,
data: { data: {
section_id: section_id, section_id: section_id,
limit: 50 limit: 50,
server_id: server_id
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-recently-added").html(xhr.responseText); $("#library-recently-added").html(xhr.responseText);
@ -811,7 +817,10 @@ DOCUMENTATION :: END
$.ajax({ $.ajax({
url: 'library_watch_time_stats', url: 'library_watch_time_stats',
async: true, async: true,
data: { section_id: section_id }, data: {
section_id: section_id,
server_id: server_id
},
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-time-stats").html(xhr.responseText); $("#library-time-stats").html(xhr.responseText);
} }
@ -821,7 +830,10 @@ DOCUMENTATION :: END
$.ajax({ $.ajax({
url: 'library_user_stats', url: 'library_user_stats',
async: true, async: true,
data: { section_id: section_id }, data: {
section_id: section_id,
server_id: server_id
},
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-user-stats").html(xhr.responseText); $("#library-user-stats").html(xhr.responseText);
} }
@ -840,7 +852,8 @@ DOCUMENTATION :: END
return { return {
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
section_id: section_id, section_id: section_id,
refresh: refresh_table refresh: refresh_table,
server_id: server_id
}; };
} }
}; };
@ -874,7 +887,8 @@ DOCUMENTATION :: END
data: function ( d ) { data: function ( d ) {
return { return {
json_data: JSON.stringify( d ), json_data: JSON.stringify( d ),
section_id: section_id section_id: section_id,
server_id: server_id
}; };
} }
}; };
@ -904,7 +918,10 @@ DOCUMENTATION :: END
$("#edit-library-tooltip").tooltip('hide'); $("#edit-library-tooltip").tooltip('hide');
$.ajax({ $.ajax({
url: 'edit_library_dialog', url: 'edit_library_dialog',
data: { section_id: section_id }, data: {
section_id: section_id,
server_id: server_id
},
cache: false, cache: false,
async: true, async: true,
complete: function(xhr, status) { complete: function(xhr, status) {
@ -920,7 +937,8 @@ DOCUMENTATION :: END
section_id: $(this).data('section_id'), section_id: $(this).data('section_id'),
media_type: $(this).data('media_type'), media_type: $(this).data('media_type'),
sub_media_type: $(this).data('sub_media_type'), sub_media_type: $(this).data('sub_media_type'),
export_type: $(this).data('export_type') export_type: $(this).data('export_type'),
server_id: server_id
}, },
cache: false, cache: false,
async: true, async: true,
@ -941,7 +959,10 @@ DOCUMENTATION :: END
$.ajax({ $.ajax({
url: 'delete_history_rows', url: 'delete_history_rows',
type: 'POST', type: 'POST',
data: { row_ids: history_to_delete.join(',') }, data: {
row_ids: history_to_delete.join(','),
server_id: server_id
},
async: true, async: true,
success: function (data) { success: function (data) {
var msg = "History deleted"; var msg = "History deleted";

View file

@ -42,19 +42,19 @@ DOCUMENTATION :: END
<li> <li>
% if item['media_type'] == 'episode' or item['media_type'] == 'movie': % if item['media_type'] == 'episode' or item['media_type'] == 'movie':
% if item['media_type'] == 'movie': % if item['media_type'] == 'movie':
<a href="${page('info', item['rating_key'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">
% elif item['media_type'] == 'episode': % elif item['media_type'] == 'episode':
<a href="${page('info', item['rating_key'])}" title="${item['grandparent_title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['grandparent_title']}">
% endif % endif
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
% if item['media_type'] == 'episode': % if item['media_type'] == 'episode':
% if item['parent_thumb']: % if item['parent_thumb']:
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['parent_thumb'], item['parent_rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['parent_thumb'], item['parent_rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
% else: % else:
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['grandparent_thumb'], item['grandparent_rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['grandparent_thumb'], item['grandparent_rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
% endif % endif
% elif item['media_type'] == 'movie': % elif item['media_type'] == 'movie':
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
% endif % endif
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
@ -72,27 +72,27 @@ DOCUMENTATION :: END
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
% if item['media_type'] == 'episode': % if item['media_type'] == 'episode':
<h3> <h3>
<a href="${page('info', item['grandparent_rating_key'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a> <a href="${page('info', item['grandparent_rating_key'], server_id=item['server_id'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a>
&middot; <a href="${page('info', item['rating_key'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a> &middot; <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
</h3> </h3>
% elif item['media_type'] == 'movie': % elif item['media_type'] == 'movie':
<h3> <h3>
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">${item['year']}</h3> <h3 class="text-muted">${item['year']}</h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
% endif % endif
</div> </div>
% elif item['media_type'] == 'album': % elif item['media_type'] == 'album':
<a href="${page('info', item['rating_key'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">
<div class="dashboard-recent-media-cover"> <div class="dashboard-recent-media-cover">
<div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover')});"> <div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
<script> <script>
@ -104,10 +104,10 @@ DOCUMENTATION :: END
</div> </div>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${item['parent_title']}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${item['parent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a class="text-muted" href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a class="text-muted" href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
</div> </div>

View file

@ -42,9 +42,9 @@ DOCUMENTATION :: END
<div class="dashboard-recent-media-instance"> <div class="dashboard-recent-media-instance">
<li data-type="${item['media_type']}"> <li data-type="${item['media_type']}">
% if item['media_type'] == 'movie': % if item['media_type'] == 'movie':
<a href="${page('info', item['rating_key'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
<script> <script>
@ -60,15 +60,15 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">${item['year']}</h3> <h3 class="text-muted">${item['year']}</h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
</div> </div>
% elif item['media_type'] == 'show': % elif item['media_type'] == 'show':
<a href="${page('info', item['rating_key'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
<script> <script>
@ -84,7 +84,7 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
${item['child_count']} Season${'s' if cast_to_int(item['child_count']) > 1 else ''} ${item['child_count']} Season${'s' if cast_to_int(item['child_count']) > 1 else ''}
@ -92,12 +92,12 @@ DOCUMENTATION :: END
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
</div> </div>
% elif item['media_type'] == 'season': % elif item['media_type'] == 'season':
<a href="${page('info', item['rating_key'])}" title="${item['parent_title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
% if item['thumb']: % if item['thumb']:
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
% else: % else:
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['parent_thumb'], item['parent_rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['parent_thumb'], item['parent_rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
% endif % endif
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
@ -114,17 +114,17 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${item['parent_title']}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${item['parent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a class="text-muted" href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a class="text-muted" href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
</div> </div>
% elif item['media_type'] == 'episode': % elif item['media_type'] == 'episode':
<a href="${page('info', item['rating_key'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['grandparent_thumb'], item['grandparent_rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['grandparent_thumb'], item['grandparent_rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
<script> <script>
@ -140,21 +140,21 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['grandparent_rating_key'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a> <a href="${page('info', item['grandparent_rating_key'], server_id=item['server_id'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a>
&middot; &middot;
<a href="${page('info', item['rating_key'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
</h3> </h3>
</div> </div>
% elif item['media_type'] == 'album': % elif item['media_type'] == 'album':
<a href="${page('info', item['rating_key'])}" title="${item['parent_title']}"> <a href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">
<div class="dashboard-recent-media-cover"> <div class="dashboard-recent-media-cover">
<div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover')});"> <div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}"> <div class="dashboard-recent-media-overlay-text" id="added_at-${item['rating_key']}">
<script> <script>
@ -170,10 +170,10 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3> <h3>
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${item['parent_title']}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${item['parent_title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a class="text-muted" href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a class="text-muted" href="${page('info', item['rating_key'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
</div> </div>

View file

@ -38,12 +38,12 @@ DOCUMENTATION :: END
% if item['media_type'] == 'episode' or item['media_type'] == 'movie': % if item['media_type'] == 'episode' or item['media_type'] == 'movie':
% if item['rating_key']: % if item['rating_key']:
% if item['media_type'] == 'movie': % if item['media_type'] == 'movie':
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['title']}"> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['title']}">
% elif item['media_type'] == 'episode': % elif item['media_type'] == 'episode':
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['grandparent_title']}"> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['grandparent_title']}">
% endif % endif
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
<div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster')});"> <div class="dashboard-recent-media-poster-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 450, fallback='poster', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="time-${item['time']}"> <div class="dashboard-recent-media-overlay-text" id="time-${item['time']}">
<script> <script>
@ -61,36 +61,36 @@ DOCUMENTATION :: END
% if item['media_type'] == 'episode': % if item['media_type'] == 'episode':
% if item['live']: % if item['live']:
<h3> <h3>
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted" title="${item['title']}"> <h3 class="text-muted" title="${item['title']}">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
% if item['media_index']: % if item['media_index']:
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a>
&middot; <a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a> &middot; <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
</h3> </h3>
% else: % else:
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['originally_available_at']}">${item['originally_available_at']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['originally_available_at']}">${item['originally_available_at']}</a>
</h3> </h3>
% endif % endif
% else: % else:
<h3> <h3>
<a href="${page('info', item['grandparent_rating_key'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a> <a href="${page('info', item['grandparent_rating_key'], server_id=item['server_id'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted" title="${item['title']}"> <h3 class="text-muted" title="${item['title']}">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${short_season(item['parent_title'])}</a>
&middot; <a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a> &middot; <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
</h3> </h3>
% endif % endif
% elif item['media_type'] == 'movie': % elif item['media_type'] == 'movie':
<h3 title="${item['title']}"> <h3 title="${item['title']}">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted">${item['year']}</h3> <h3 class="text-muted">${item['year']}</h3>
<h3 class="text-muted">&nbsp;</h3> <h3 class="text-muted">&nbsp;</h3>
@ -116,9 +116,9 @@ DOCUMENTATION :: END
% endif % endif
% elif item['media_type'] == 'track': % elif item['media_type'] == 'track':
% if item['rating_key']: % if item['rating_key']:
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['parent_title']}"> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['parent_title']}">
<div class="dashboard-recent-media-cover"> <div class="dashboard-recent-media-cover">
<div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover')});"> <div class="dashboard-recent-media-cover-face" style="background-image: url(${page('pms_image_proxy', item['thumb'], item['rating_key'], 300, 300, fallback='cover', server_id=item['server_id'])});">
<div class="dashboard-recent-media-overlay"> <div class="dashboard-recent-media-overlay">
<div class="dashboard-recent-media-overlay-text" id="time-${item['time']}"> <div class="dashboard-recent-media-overlay-text" id="time-${item['time']}">
<script> <script>
@ -131,13 +131,13 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
<h3 title="${item['original_title'] or item['grandparent_title']}"> <h3 title="${item['original_title'] or item['grandparent_title']}">
<a href="${page('info', item['grandparent_rating_key'])}" title="${item['original_title'] or item['grandparent_title']}">${item['original_title'] or item['grandparent_title']}</a> <a href="${page('info', item['grandparent_rating_key'], server_id=item['server_id'])}" title="${item['original_title'] or item['grandparent_title']}">${item['original_title'] or item['grandparent_title']}</a>
</h3> </h3>
<h3 class="text-muted" title="${item['title']}"> <h3 class="text-muted" title="${item['title']}">
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'], history=True, live=item['live'], server_id=item['server_id'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
<a href="${page('info', item['parent_rating_key'])}" title="${item['parent_title']}">${item['parent_title']}</a> <a href="${page('info', item['parent_rating_key'], server_id=item['server_id'])}" title="${item['parent_title']}">${item['parent_title']}</a>
</h3> </h3>
</div> </div>
% else: % else:

View file

@ -662,13 +662,14 @@ def dbcheck():
"buffer_count INTEGER DEFAULT 0, buffer_last_triggered INTEGER, last_paused INTEGER, watched INTEGER DEFAULT 0, " "buffer_count INTEGER DEFAULT 0, buffer_last_triggered INTEGER, last_paused INTEGER, watched INTEGER DEFAULT 0, "
"intro INTEGER DEFAULT 0, credits INTEGER DEFAULT 0, commercial INTEGER DEFAULT 0, marker INTEGER DEFAULT 0, " "intro INTEGER DEFAULT 0, credits INTEGER DEFAULT 0, commercial INTEGER DEFAULT 0, marker INTEGER DEFAULT 0, "
"initial_stream INTEGER DEFAULT 1, write_attempts INTEGER DEFAULT 0, raw_stream_info TEXT, " "initial_stream INTEGER DEFAULT 1, write_attempts INTEGER DEFAULT 0, raw_stream_info TEXT, "
"rating_key_websocket TEXT)" "rating_key_websocket TEXT, "
"server_id TEXT)"
) )
# sessions_continued table :: This is a temp table that keeps track of continued streaming sessions # sessions_continued table :: This is a temp table that keeps track of continued streaming sessions
c_db.execute( c_db.execute(
"CREATE TABLE IF NOT EXISTS sessions_continued (id INTEGER PRIMARY KEY AUTOINCREMENT, " "CREATE TABLE IF NOT EXISTS sessions_continued (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"user_id INTEGER, machine_id TEXT, media_type TEXT, stopped INTEGER)" "user_id INTEGER, machine_id TEXT, media_type TEXT, stopped INTEGER, server_id TEXT)"
) )
# session_history table :: This is a history table which logs essential stream details # session_history table :: This is a history table which logs essential stream details
@ -679,7 +680,7 @@ def dbcheck():
"platform TEXT, platform_version TEXT, profile TEXT, machine_id TEXT, " "platform TEXT, platform_version TEXT, profile TEXT, machine_id TEXT, "
"bandwidth INTEGER, location TEXT, quality_profile TEXT, secure INTEGER, relayed INTEGER, " "bandwidth INTEGER, location TEXT, quality_profile TEXT, secure INTEGER, relayed INTEGER, "
"parent_rating_key INTEGER, grandparent_rating_key INTEGER, media_type TEXT, section_id INTEGER, " "parent_rating_key INTEGER, grandparent_rating_key INTEGER, media_type TEXT, section_id INTEGER, "
"view_offset INTEGER DEFAULT 0)" "view_offset INTEGER DEFAULT 0, server_id TEXT)"
) )
# session_history_media_info table :: This is a table which logs each session"s media info # session_history_media_info table :: This is a table which logs each session"s media info
@ -705,7 +706,7 @@ def dbcheck():
"stream_subtitle_decision TEXT, stream_subtitle_codec TEXT, " "stream_subtitle_decision TEXT, stream_subtitle_codec TEXT, "
"stream_subtitle_container TEXT, stream_subtitle_forced INTEGER, stream_subtitle_language TEXT, " "stream_subtitle_container TEXT, stream_subtitle_forced INTEGER, stream_subtitle_language TEXT, "
"synced_version INTEGER, synced_version_profile TEXT, " "synced_version INTEGER, synced_version_profile TEXT, "
"optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT)" "optimized_version INTEGER, optimized_version_profile TEXT, optimized_version_title TEXT, server_id TEXT)"
) )
# session_history_metadata table :: This is a table which logs each session"s media metadata # session_history_metadata table :: This is a table which logs each session"s media metadata
@ -719,7 +720,7 @@ def dbcheck():
"last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, " "last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, "
"duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT, " "duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT, "
"labels TEXT, live INTEGER DEFAULT 0, channel_call_sign TEXT, channel_identifier TEXT, channel_thumb TEXT, " "labels TEXT, live INTEGER DEFAULT 0, channel_call_sign TEXT, channel_identifier TEXT, channel_thumb TEXT, "
"marker_credits_first INTEGER DEFAULT NULL, marker_credits_final INTEGER DEFAULT NULL)" "marker_credits_first INTEGER DEFAULT NULL, marker_credits_final INTEGER DEFAULT NULL, server_id TEXT)"
) )
# users table :: This table keeps record of the friends list # users table :: This table keeps record of the friends list
@ -731,7 +732,8 @@ def dbcheck():
"is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL, " "is_allow_sync INTEGER DEFAULT NULL, is_restricted INTEGER DEFAULT NULL, "
"do_notify INTEGER DEFAULT 1, keep_history INTEGER DEFAULT 1, deleted_user INTEGER DEFAULT 0, " "do_notify INTEGER DEFAULT 1, keep_history INTEGER DEFAULT 1, deleted_user INTEGER DEFAULT 0, "
"allow_guest INTEGER DEFAULT 0, user_token TEXT, server_token TEXT, shared_libraries TEXT, " "allow_guest INTEGER DEFAULT 0, user_token TEXT, server_token TEXT, shared_libraries TEXT, "
"filter_all TEXT, filter_movies TEXT, filter_tv TEXT, filter_music TEXT, filter_photos TEXT)" "filter_all TEXT, filter_movies TEXT, filter_tv TEXT, filter_music TEXT, filter_photos TEXT, "
"server_id TEXT )"
) )
# library_sections table :: This table keeps record of the servers library sections # library_sections table :: This table keeps record of the servers library sections
@ -813,7 +815,7 @@ def dbcheck():
"CREATE TABLE IF NOT EXISTS recently_added (id INTEGER PRIMARY KEY AUTOINCREMENT, " "CREATE TABLE IF NOT EXISTS recently_added (id INTEGER PRIMARY KEY AUTOINCREMENT, "
"added_at INTEGER, pms_identifier TEXT, section_id INTEGER, " "added_at INTEGER, pms_identifier TEXT, section_id INTEGER, "
"rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, media_type TEXT, " "rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, media_type TEXT, "
"media_info TEXT)" "media_info TEXT, server_id TEXT)"
) )
# mobile_devices table :: This table keeps record of devices linked with the mobile app # mobile_devices table :: This table keeps record of devices linked with the mobile app

View file

@ -32,7 +32,7 @@ if plexpy.PYTHON2:
import helpers import helpers
import logger import logger
import notification_handler import notification_handler
import pmsconnect import server_manager
else: else:
from plexpy import activity_processor from plexpy import activity_processor
from plexpy import common from plexpy import common
@ -40,7 +40,7 @@ else:
from plexpy import helpers from plexpy import helpers
from plexpy import logger from plexpy import logger
from plexpy import notification_handler from plexpy import notification_handler
from plexpy import pmsconnect from plexpy import server_manager
ACTIVITY_SCHED = None ACTIVITY_SCHED = None
@ -78,26 +78,26 @@ class ActivityHandler(object):
def get_metadata(self, skip_cache=False): def get_metadata(self, skip_cache=False):
if self.metadata is None: if self.metadata is None:
cache_key = None if skip_cache else self.session_key cache_key = None if skip_cache else self.session_key
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
metadata = pms_connect.get_metadata_details(rating_key=self.rating_key, cache_key=cache_key) metadata = pms_connect.get_metadata_details(rating_key=self.rating_key, cache_key=cache_key)
if metadata: if metadata:
self.metadata = metadata self.metadata = metadata
def get_live_session(self, skip_cache=False): def get_live_session(self, skip_cache=False):
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
session_list = pms_connect.get_current_activity(skip_cache=skip_cache) session_list = pms_connect.get_current_activity(skip_cache=skip_cache)
if session_list: if session_list:
for session in session_list['sessions']: for session in session_list['sessions']:
if int(session['session_key']) == self.session_key: if int(session['session_key']) == self.session_key:
# Live sessions don't have rating keys in sessions # Live sessions don't have rating keys in sessions
# Get it from the websocket data # Get it from the websocket data
if not session['rating_key']: if not session['rating_key']:
session['rating_key'] = self.rating_key session['rating_key'] = self.rating_key
session['rating_key_websocket'] = self.rating_key session['rating_key_websocket'] = self.rating_key
self.session = session self.session = session
return session return session
def update_db_session(self, notify=False): def update_db_session(self, notify=False):
if self.session is None: if self.session is None:
@ -552,9 +552,9 @@ class ReachabilityHandler(object):
self.is_reachable = self.data.get('reachable', False) self.is_reachable = self.data.get('reachable', False)
def remote_access_enabled(self): def remote_access_enabled(self):
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
pref = pms_connect.get_server_pref(pref='PublishServerOnPlexOnlineKey') pref = pms_connect.get_server_pref(pref='PublishServerOnPlexOnlineKey')
return helpers.bool_true(pref) return helpers.bool_true(pref)
def on_extdown(self, server_response): def on_extdown(self, server_response):
plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extdown', 'remote_access_info': server_response}) plexpy.NOTIFY_QUEUE.put({'notify_action': 'on_extdown', 'remote_access_info': server_response})
@ -571,8 +571,8 @@ class ReachabilityHandler(object):
if self.is_reachable and plexpy.PLEX_REMOTE_ACCESS_UP: if self.is_reachable and plexpy.PLEX_REMOTE_ACCESS_UP:
return return
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
server_response = pms_connect.get_server_response() server_response = pms_connect.get_server_response()
if not server_response: if not server_response:
return return
@ -702,8 +702,8 @@ def clear_recently_added_queue(rating_key, title):
def on_created(rating_key, **kwargs): def on_created(rating_key, **kwargs):
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
metadata = pms_connect.get_metadata_details(rating_key) metadata = pms_connect.get_metadata_details(rating_key)
logger.debug("Tautulli TimelineHandler :: Library item '%s' (%s) added to Plex.", logger.debug("Tautulli TimelineHandler :: Library item '%s' (%s) added to Plex.",
metadata['full_title'], str(rating_key)) metadata['full_title'], str(rating_key))

View file

@ -28,8 +28,8 @@ if plexpy.PYTHON2:
import logger import logger
import notification_handler import notification_handler
import plextv import plextv
import pmsconnect
import web_socket import web_socket
import server_manager
else: else:
from plexpy import activity_handler from plexpy import activity_handler
from plexpy import activity_processor from plexpy import activity_processor
@ -39,8 +39,9 @@ else:
from plexpy import logger from plexpy import logger
from plexpy import notification_handler from plexpy import notification_handler
from plexpy import plextv from plexpy import plextv
from plexpy import pmsconnect
from plexpy import web_socket from plexpy import web_socket
from plexpy import server_manager
monitor_lock = threading.Lock() monitor_lock = threading.Lock()
@ -60,166 +61,167 @@ def check_active_sessions(ws_request=False):
for stream in db_streams: for stream in db_streams:
activity_handler.delete_metadata_cache(stream['session_key']) activity_handler.delete_metadata_cache(stream['session_key'])
pms_connect = pmsconnect.PmsConnect() session_list = []
session_list = pms_connect.get_current_activity() for pms_connect in server_manager.ServerManger().get_server_list():
session_list = pms_connect.get_current_activity()
logger.debug("Tautulli Monitor :: Checking for active streams.") logger.debug("Tautulli Monitor :: Checking for active streams.")
if session_list: if session_list:
media_container = session_list['sessions'] media_container = session_list['sessions']
# Check our temp table for what we must do with the new streams # Check our temp table for what we must do with the new streams
for stream in db_streams: for stream in db_streams:
if any(d['session_key'] == str(stream['session_key']) and d['rating_key'] == str(stream['rating_key']) if any(d['session_key'] == str(stream['session_key']) and d['rating_key'] == str(stream['rating_key'])
for d in media_container): for d in media_container):
# The user's session is still active # The user's session is still active
for session in media_container: for session in media_container:
if session['session_key'] == str(stream['session_key']) and \ if session['session_key'] == str(stream['session_key']) and \
session['rating_key'] == str(stream['rating_key']): session['rating_key'] == str(stream['rating_key']):
# The user is still playing the same media item # The user is still playing the same media item
# Here we can check the play states # Here we can check the play states
if session['state'] != stream['state']: if session['state'] != stream['state']:
if session['state'] == 'paused': if session['state'] == 'paused':
logger.debug("Tautulli Monitor :: Session %s paused." % stream['session_key']) logger.debug("Tautulli Monitor :: Session %s paused." % stream['session_key'])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_pause'}) plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_pause'})
if session['state'] == 'playing' and stream['state'] == 'paused': if session['state'] == 'playing' and stream['state'] == 'paused':
logger.debug("Tautulli Monitor :: Session %s resumed." % stream['session_key']) logger.debug("Tautulli Monitor :: Session %s resumed." % stream['session_key'])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_resume'}) plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_resume'})
if session['state'] == 'error': if session['state'] == 'error':
logger.debug("Tautulli Monitor :: Session %s encountered an error." % stream['session_key']) logger.debug("Tautulli Monitor :: Session %s encountered an error." % stream['session_key'])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_error'}) plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_error'})
if stream['state'] == 'paused' and not ws_request: if stream['state'] == 'paused' and not ws_request:
# The stream is still paused so we need to increment the paused_counter # The stream is still paused so we need to increment the paused_counter
# Using the set config parameter as the interval, probably not the most accurate but # Using the set config parameter as the interval, probably not the most accurate but
# it will have to do for now. If it's a websocket request don't use this method. # it will have to do for now. If it's a websocket request don't use this method.
paused_counter = int(stream['paused_counter']) + plexpy.CONFIG.MONITORING_INTERVAL paused_counter = int(stream['paused_counter']) + plexpy.CONFIG.MONITORING_INTERVAL
monitor_db.action("UPDATE sessions SET paused_counter = ? " monitor_db.action("UPDATE sessions SET paused_counter = ? "
"WHERE session_key = ? AND rating_key = ?", "WHERE session_key = ? AND rating_key = ?",
[paused_counter, stream['session_key'], stream['rating_key']]) [paused_counter, stream['session_key'], stream['rating_key']])
if session['state'] == 'buffering' and plexpy.CONFIG.BUFFER_THRESHOLD > 0: if session['state'] == 'buffering' and plexpy.CONFIG.BUFFER_THRESHOLD > 0:
# The stream is buffering so we need to increment the buffer_count # The stream is buffering so we need to increment the buffer_count
# We're going just increment on every monitor ping, # We're going just increment on every monitor ping,
# would be difficult to keep track otherwise # would be difficult to keep track otherwise
monitor_db.action("UPDATE sessions SET buffer_count = buffer_count + 1 " monitor_db.action("UPDATE sessions SET buffer_count = buffer_count + 1 "
"WHERE session_key = ? AND rating_key = ?", "WHERE session_key = ? AND rating_key = ?",
[stream['session_key'], stream['rating_key']]) [stream['session_key'], stream['rating_key']])
# Check the current buffer count and last buffer to determine if we should notify # Check the current buffer count and last buffer to determine if we should notify
buffer_values = monitor_db.select("SELECT buffer_count, buffer_last_triggered " buffer_values = monitor_db.select("SELECT buffer_count, buffer_last_triggered "
"FROM sessions " "FROM sessions "
"WHERE session_key = ? AND rating_key = ?", "WHERE session_key = ? AND rating_key = ?",
[stream['session_key'], stream['rating_key']]) [stream['session_key'], stream['rating_key']])
if buffer_values[0]['buffer_count'] >= plexpy.CONFIG.BUFFER_THRESHOLD: if buffer_values[0]['buffer_count'] >= plexpy.CONFIG.BUFFER_THRESHOLD:
# Push any notifications - # Push any notifications -
# Push it on it's own thread so we don't hold up our db actions # Push it on it's own thread so we don't hold up our db actions
# Our first buffer notification # Our first buffer notification
if buffer_values[0]['buffer_count'] == plexpy.CONFIG.BUFFER_THRESHOLD: if buffer_values[0]['buffer_count'] == plexpy.CONFIG.BUFFER_THRESHOLD:
logger.info("Tautulli Monitor :: User '%s' has triggered a buffer warning." logger.info("Tautulli Monitor :: User '%s' has triggered a buffer warning."
% stream['user']) % stream['user'])
# Set the buffer trigger time
monitor_db.action("UPDATE sessions "
"SET buffer_last_triggered = strftime('%s', 'now') "
"WHERE session_key = ? AND rating_key = ?",
[stream['session_key'], stream['rating_key']])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_buffer'})
else:
# Subsequent buffer notifications after wait time
if helpers.timestamp() > buffer_values[0]['buffer_last_triggered'] + \
plexpy.CONFIG.BUFFER_WAIT:
logger.info("Tautulli Monitor :: User '%s' has triggered multiple buffer warnings."
% stream['user'])
# Set the buffer trigger time # Set the buffer trigger time
monitor_db.action("UPDATE sessions " monitor_db.action("UPDATE sessions "
"SET buffer_last_triggered = strftime('%s', 'now') " "SET buffer_last_triggered = strftime('%s', 'now') "
"WHERE session_key = ? AND rating_key = ?", "WHERE session_key = ? AND rating_key = ?",
[stream['session_key'], stream['rating_key']]) [stream['session_key'], stream['rating_key']])
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_buffer'}) plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_buffer'})
logger.debug("Tautulli Monitor :: Session %s is buffering. Count is now %s. Last triggered %s." else:
% (stream['session_key'], # Subsequent buffer notifications after wait time
buffer_values[0]['buffer_count'], if helpers.timestamp() > buffer_values[0]['buffer_last_triggered'] + \
buffer_values[0]['buffer_last_triggered'])) plexpy.CONFIG.BUFFER_WAIT:
logger.info("Tautulli Monitor :: User '%s' has triggered multiple buffer warnings."
% stream['user'])
# Set the buffer trigger time
monitor_db.action("UPDATE sessions "
"SET buffer_last_triggered = strftime('%s', 'now') "
"WHERE session_key = ? AND rating_key = ?",
[stream['session_key'], stream['rating_key']])
# Check if the user has reached the offset in the media we defined as the "watched" percent plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_buffer'})
# Don't trigger if state is buffer as some clients push the progress to the end when
# buffering on start.
if session['state'] != 'buffering':
progress_percent = helpers.get_percent(session['view_offset'], session['duration'])
notify_states = notification_handler.get_notify_state(session=session)
if (session['media_type'] == 'movie' and progress_percent >= plexpy.CONFIG.MOVIE_WATCHED_PERCENT or
session['media_type'] == 'episode' and progress_percent >= plexpy.CONFIG.TV_WATCHED_PERCENT or
session['media_type'] == 'track' and progress_percent >= plexpy.CONFIG.MUSIC_WATCHED_PERCENT) \
and not any(d['notify_action'] == 'on_watched' for d in notify_states):
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_watched'})
else: logger.debug("Tautulli Monitor :: Session %s is buffering. Count is now %s. Last triggered %s."
# The user has stopped playing a stream % (stream['session_key'],
if stream['state'] != 'stopped': buffer_values[0]['buffer_count'],
logger.debug("Tautulli Monitor :: Session %s stopped." % stream['session_key']) buffer_values[0]['buffer_last_triggered']))
if not stream['stopped']: # Check if the user has reached the offset in the media we defined as the "watched" percent
# Set the stream stop time # Don't trigger if state is buffer as some clients push the progress to the end when
stream['stopped'] = helpers.timestamp() # buffering on start.
monitor_db.action("UPDATE sessions SET stopped = ?, state = ? " if session['state'] != 'buffering':
"WHERE session_key = ? AND rating_key = ?", progress_percent = helpers.get_percent(session['view_offset'], session['duration'])
[stream['stopped'], 'stopped', stream['session_key'], stream['rating_key']]) notify_states = notification_handler.get_notify_state(session=session)
if (session['media_type'] == 'movie' and progress_percent >= plexpy.CONFIG.MOVIE_WATCHED_PERCENT or
session['media_type'] == 'episode' and progress_percent >= plexpy.CONFIG.TV_WATCHED_PERCENT or
session['media_type'] == 'track' and progress_percent >= plexpy.CONFIG.MUSIC_WATCHED_PERCENT) \
and not any(d['notify_action'] == 'on_watched' for d in notify_states):
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_watched'})
progress_percent = helpers.get_percent(stream['view_offset'], stream['duration'])
notify_states = notification_handler.get_notify_state(session=stream)
if (stream['media_type'] == 'movie' and progress_percent >= plexpy.CONFIG.MOVIE_WATCHED_PERCENT or
stream['media_type'] == 'episode' and progress_percent >= plexpy.CONFIG.TV_WATCHED_PERCENT or
stream['media_type'] == 'track' and progress_percent >= plexpy.CONFIG.MUSIC_WATCHED_PERCENT) \
and not any(d['notify_action'] == 'on_watched' for d in notify_states):
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_watched'})
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_stop'})
# Write the item history on playback stop
row_id = monitor_process.write_session_history(session=stream)
if row_id:
# If session is written to the databaase successfully, remove the session from the session table
logger.debug("Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue"
% (stream['session_key'], stream['rating_key']))
monitor_process.delete_session(row_id=row_id)
else: else:
stream['write_attempts'] += 1 # The user has stopped playing a stream
if stream['state'] != 'stopped':
logger.debug("Tautulli Monitor :: Session %s stopped." % stream['session_key'])
if stream['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS: if not stream['stopped']:
logger.warn("Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \ # Set the stream stop time
"Will try again on the next pass. Write attempt %s." stream['stopped'] = helpers.timestamp()
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts']))) monitor_db.action("UPDATE sessions SET stopped = ?, state = ? "
monitor_process.increment_write_attempts(session_key=stream['session_key']) "WHERE session_key = ? AND rating_key = ?",
else: [stream['stopped'], 'stopped', stream['session_key'], stream['rating_key']])
logger.warn("Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
"Removing session from the database. Write attempt %s." progress_percent = helpers.get_percent(stream['view_offset'], stream['duration'])
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts']))) notify_states = notification_handler.get_notify_state(session=stream)
if (stream['media_type'] == 'movie' and progress_percent >= plexpy.CONFIG.MOVIE_WATCHED_PERCENT or
stream['media_type'] == 'episode' and progress_percent >= plexpy.CONFIG.TV_WATCHED_PERCENT or
stream['media_type'] == 'track' and progress_percent >= plexpy.CONFIG.MUSIC_WATCHED_PERCENT) \
and not any(d['notify_action'] == 'on_watched' for d in notify_states):
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_watched'})
plexpy.NOTIFY_QUEUE.put({'stream_data': stream.copy(), 'notify_action': 'on_stop'})
# Write the item history on playback stop
row_id = monitor_process.write_session_history(session=stream)
if row_id:
# If session is written to the databaase successfully, remove the session from the session table
logger.debug("Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue" logger.debug("Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue"
% (stream['session_key'], stream['rating_key'])) % (stream['session_key'], stream['rating_key']))
monitor_process.delete_session(session_key=stream['session_key']) monitor_process.delete_session(row_id=row_id)
else:
stream['write_attempts'] += 1
# Process the newly received session data if stream['write_attempts'] < plexpy.CONFIG.SESSION_DB_WRITE_ATTEMPTS:
for session in media_container: logger.warn("Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
new_session = monitor_process.write_session(session) "Will try again on the next pass. Write attempt %s."
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts'])))
monitor_process.increment_write_attempts(session_key=stream['session_key'])
else:
logger.warn("Tautulli Monitor :: Failed to write sessionKey %s ratingKey %s to the database. " \
"Removing session from the database. Write attempt %s."
% (stream['session_key'], stream['rating_key'], str(stream['write_attempts'])))
logger.debug("Tautulli Monitor :: Removing sessionKey %s ratingKey %s from session queue"
% (stream['session_key'], stream['rating_key']))
monitor_process.delete_session(session_key=stream['session_key'])
if new_session: # Process the newly received session data
logger.debug("Tautulli Monitor :: Session %s started by user %s (%s) with ratingKey %s (%s)%s." for session in media_container:
% (str(session['session_key']), str(session['user_id']), session['username'], new_session = monitor_process.write_session(session)
str(session['rating_key']), session['full_title'], '[Live TV]' if session['live'] else ''))
else: if new_session:
logger.debug("Tautulli Monitor :: Unable to read session list.") logger.debug("Tautulli Monitor :: Session %s started by user %s (%s) with ratingKey %s (%s)%s."
% (str(session['session_key']), str(session['user_id']), session['username'],
str(session['rating_key']), session['full_title'], '[Live TV]' if session['live'] else ''))
else:
logger.debug("Tautulli Monitor :: Unable to read session list.")
def connect_server(log=True, startup=False): def connect_server(log=True, startup=False):

View file

@ -26,15 +26,15 @@ if plexpy.PYTHON2:
import helpers import helpers
import libraries import libraries
import logger import logger
import pmsconnect
import users import users
import server_manager
else: else:
from plexpy import database from plexpy import database
from plexpy import helpers from plexpy import helpers
from plexpy import libraries from plexpy import libraries
from plexpy import logger from plexpy import logger
from plexpy import pmsconnect
from plexpy import users from plexpy import users
from plexpy import server_manager
class ActivityProcessor(object): class ActivityProcessor(object):
@ -273,19 +273,20 @@ class ActivityProcessor(object):
# Fetch metadata first so we can return false if it fails # Fetch metadata first so we can return false if it fails
if not is_import: if not is_import:
logger.debug("Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key']) logger.debug("Tautulli ActivityProcessor :: Fetching metadata for item ratingKey %s" % session['rating_key'])
pms_connect = pmsconnect.PmsConnect()
if session['live']: for pms_connect in server_manager.ServerManger().get_server_list():
metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']), if session['live']:
cache_key=session['session_key'], metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']),
return_cache=True) cache_key=session['session_key'],
else: return_cache=True)
metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key'])) else:
if not metadata: metadata = pms_connect.get_metadata_details(rating_key=str(session['rating_key']))
return False if not metadata:
else: return False
media_info = {} else:
if 'media_info' in metadata and len(metadata['media_info']) > 0: media_info = {}
media_info = metadata['media_info'][0] if 'media_info' in metadata and len(metadata['media_info']) > 0:
media_info = metadata['media_info'][0]
else: else:
metadata = import_metadata metadata = import_metadata
## TODO: Fix media info from imports. Temporary media info from import session. ## TODO: Fix media info from imports. Temporary media info from import session.

View file

@ -32,7 +32,7 @@ if plexpy.PYTHON2:
import libraries import libraries
import helpers import helpers
import logger import logger
import pmsconnect import server_manager
import session import session
import users import users
else: else:
@ -42,7 +42,7 @@ else:
from plexpy import datatables from plexpy import datatables
from plexpy import helpers from plexpy import helpers
from plexpy import logger from plexpy import logger
from plexpy import pmsconnect from plexpy import server_manager
from plexpy import session from plexpy import session
from plexpy import users from plexpy import users
@ -1214,9 +1214,9 @@ class DataFactory(object):
group_by = 'session_history.reference_id' if grouping else 'session_history.id' group_by = 'session_history.reference_id' if grouping else 'session_history.id'
if media_type in ('collection', 'playlist'): if media_type in ('collection', 'playlist'):
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type) result += pms_connect.get_item_children(rating_key=rating_key, media_type=media_type)
rating_keys = [child['rating_key'] for child in result['children_list']] rating_keys += [child['rating_key'] for child in result['children_list']]
else: else:
rating_keys = [rating_key] rating_keys = [rating_key]
@ -1298,9 +1298,9 @@ class DataFactory(object):
group_by = 'session_history.reference_id' if grouping else 'session_history.id' group_by = 'session_history.reference_id' if grouping else 'session_history.id'
if media_type in ('collection', 'playlist'): if media_type in ('collection', 'playlist'):
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type) result += pms_connect.get_item_children(rating_key=rating_key, media_type=media_type)
rating_keys = [child['rating_key'] for child in result['children_list']] rating_keys += [child['rating_key'] for child in result['children_list']]
else: else:
rating_keys = [rating_key] rating_keys = [rating_key]
@ -2029,8 +2029,8 @@ class DataFactory(object):
return key_list return key_list
def update_metadata(self, old_key_list='', new_key_list='', media_type='', single_update=False): def update_metadata(self, old_key_list='', new_key_list='', media_type='', single_update=False, server_id=None):
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
# function to map rating keys pairs # function to map rating keys pairs
@ -2400,10 +2400,10 @@ class DataFactory(object):
return result return result
def set_recently_added_item(self, rating_key=''): def set_recently_added_item(self, rating_key='', server_id=None):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
metadata = pms_connect.get_metadata_details(rating_key) metadata = pms_connect.get_metadata_details(rating_key)
keys = {'rating_key': metadata['rating_key']} keys = {'rating_key': metadata['rating_key']}

View file

@ -1578,7 +1578,7 @@ def page(endpoint, *args, **kwargs):
def pms_image_proxy(img=None, rating_key=None, width=None, height=None, def pms_image_proxy(img=None, rating_key=None, width=None, height=None,
opacity=None, background=None, blur=None, img_format=None, opacity=None, background=None, blur=None, img_format=None,
fallback=None, refresh=None, clip=None): fallback=None, refresh=None, clip=None, server_id=None):
params = {} params = {}
if img is not None: if img is not None:
@ -1603,11 +1603,13 @@ def pms_image_proxy(img=None, rating_key=None, width=None, height=None,
params['refresh'] = 'true' params['refresh'] = 'true'
if clip is not None: if clip is not None:
params['clip'] = 'true' params['clip'] = 'true'
if server_id is not None:
params['server_id'] = server_id
return params return params
def info_page(rating_key=None, guid=None, history=None, live=None): def info_page(rating_key=None, guid=None, history=None, live=None, server_id=None):
params = {} params = {}
if live and history: if live and history:
@ -1618,15 +1620,21 @@ def info_page(rating_key=None, guid=None, history=None, live=None):
if history: if history:
params['source'] = 'history' params['source'] = 'history'
if server_id is not None:
params['server_id'] = server_id
return params return params
def library_page(section_id=None): def library_page(section_id=None, server_id=None):
params = {} params = {}
if section_id is not None: if section_id is not None:
params['section_id'] = section_id params['section_id'] = section_id
if server_id is not None:
params['server_id'] = server_id
return params return params

View file

@ -32,9 +32,9 @@ if plexpy.PYTHON2:
import helpers import helpers
import logger import logger
import plextv import plextv
import pmsconnect
import session import session
import users import users
import server_manager
from plex import Plex from plex import Plex
else: else:
from plexpy import common from plexpy import common
@ -43,71 +43,75 @@ else:
from plexpy import helpers from plexpy import helpers
from plexpy import logger from plexpy import logger
from plexpy import plextv from plexpy import plextv
from plexpy import pmsconnect
from plexpy import session from plexpy import session
from plexpy import users from plexpy import users
from plexpy import server_manager
from plexpy.plex import Plex from plexpy.plex import Plex
def refresh_libraries(): def refresh_libraries():
logger.info("Tautulli Libraries :: Requesting libraries list refresh...") logger.info("Tautulli Libraries :: Requesting libraries list refresh...")
server_id = plexpy.CONFIG.PMS_IDENTIFIER passed = True
if not server_id:
logger.error("Tautulli Libraries :: No PMS identifier, cannot refresh libraries. Verify server in settings.")
return
library_sections = pmsconnect.PmsConnect().get_library_details() for server in server_manager.ServerManger().get_server_list():
library_sections = server.get_library_details()
if library_sections: server_id = server.get_server_identity()["machine_identifier"]
monitor_db = database.MonitorDatabase() if not server_id:
logger.error("Tautulli Libraries :: No PMS identifier, cannot refresh libraries. Verify server in settings.")
continue
library_keys = [] if library_sections:
new_keys = [] monitor_db = database.MonitorDatabase()
# Keep track of section_id to update is_active status library_keys = []
section_ids = [common.LIVE_TV_SECTION_ID] # Live TV library always considered active new_keys = []
for section in library_sections: # Keep track of section_id to update is_active status
section_ids.append(helpers.cast_to_int(section['section_id'])) section_ids = [common.LIVE_TV_SECTION_ID] # Live TV library always considered active
section_keys = {'server_id': server_id, for section in library_sections:
'section_id': section['section_id']} section_ids.append(helpers.cast_to_int(section['section_id']))
section_values = {'server_id': server_id,
'section_id': section['section_id'],
'section_name': section['section_name'],
'section_type': section['section_type'],
'agent': section['agent'],
'thumb': section['thumb'],
'art': section['art'],
'count': section['count'],
'parent_count': section.get('parent_count', None),
'child_count': section.get('child_count', None),
'is_active': section['is_active']
}
result = monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values) section_keys = {'server_id': server_id,
'section_id': section['section_id']}
section_values = {'server_id': server_id,
'section_id': section['section_id'],
'section_name': section['section_name'],
'section_type': section['section_type'],
'agent': section['agent'],
'thumb': section['thumb'],
'art': section['art'],
'count': section['count'],
'parent_count': section.get('parent_count', None),
'child_count': section.get('child_count', None),
'is_active': section['is_active']
}
library_keys.append(section['section_id']) result = monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values)
if result == 'insert': library_keys.append(section['section_id'])
new_keys.append(section['section_id'])
add_live_tv_library(refresh=True) if result == 'insert':
new_keys.append(section['section_id'])
query = "UPDATE library_sections SET is_active = 0 WHERE server_id != ? OR " \ add_live_tv_library(refresh=True)
"section_id NOT IN ({})".format(", ".join(["?"] * len(section_ids)))
monitor_db.action(query=query, args=[plexpy.CONFIG.PMS_IDENTIFIER] + section_ids)
new_keys = plexpy.CONFIG.HOME_LIBRARY_CARDS + new_keys # query = "UPDATE library_sections SET is_active = 0 WHERE server_id != ? OR " \
plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', new_keys) # "section_id NOT IN ({})".format(", ".join(["?"] * len(section_ids)))
plexpy.CONFIG.write() # monitor_db.action(query=query, args=[plexpy.CONFIG.PMS_IDENTIFIER] + section_ids)
logger.info("Tautulli Libraries :: Libraries list refreshed.") new_keys = plexpy.CONFIG.HOME_LIBRARY_CARDS + new_keys
return True plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', new_keys)
else: plexpy.CONFIG.write()
logger.warn("Tautulli Libraries :: Unable to refresh libraries list.")
return False logger.info("Tautulli Libraries :: Libraries list refreshed.")
else:
logger.warn("Tautulli Libraries :: Unable to refresh libraries list.")
passed = False
return passed
def add_live_tv_library(refresh=False): def add_live_tv_library(refresh=False):
@ -439,7 +443,8 @@ class Libraries(object):
'do_notify': item['do_notify'], 'do_notify': item['do_notify'],
'do_notify_created': item['do_notify_created'], 'do_notify_created': item['do_notify_created'],
'keep_history': item['keep_history'], 'keep_history': item['keep_history'],
'is_active': item['is_active'] 'is_active': item['is_active'],
'server_id': item['server_id']
} }
rows.append(row) rows.append(row)
@ -519,63 +524,62 @@ class Libraries(object):
# If no cache was imported, get all library children items # If no cache was imported, get all library children items
cached_items = {d['rating_key']: d['file_size'] for d in rows} if not refresh else {} cached_items = {d['rating_key']: d['file_size'] for d in rows} if not refresh else {}
for pms_connect in server_manager.ServerManger().get_server_list():
if refresh or not rows:
if refresh or not rows: if rating_key:
pms_connect = pmsconnect.PmsConnect() library_children = pms_connect.get_library_children_details(rating_key=rating_key,
section_id=section_id,
section_type=section_type,
get_media_info=True)
elif section_id:
library_children = pms_connect.get_library_children_details(section_id=section_id,
section_type=section_type,
get_media_info=True)
if library_children:
library_count = library_children['library_count']
children_list = library_children['children_list']
else:
logger.warn("Tautulli Libraries :: Unable to get a list of library items.")
return default_return
if rating_key: new_rows = []
library_children = pms_connect.get_library_children_details(rating_key=rating_key, for item in children_list:
section_id=section_id, ## TODO: Check list of media info items, currently only grabs first item
section_type=section_type,
get_media_info=True)
elif section_id:
library_children = pms_connect.get_library_children_details(section_id=section_id,
section_type=section_type,
get_media_info=True)
if library_children:
library_count = library_children['library_count']
children_list = library_children['children_list']
else:
logger.warn("Tautulli Libraries :: Unable to get a list of library items.")
return default_return
new_rows = [] cached_file_size = cached_items.get(item['rating_key'], None)
for item in children_list: file_size = cached_file_size if cached_file_size else item.get('file_size', '')
## TODO: Check list of media info items, currently only grabs first item
cached_file_size = cached_items.get(item['rating_key'], None) row = {'section_id': library_details['section_id'],
file_size = cached_file_size if cached_file_size else item.get('file_size', '') 'section_type': library_details['section_type'],
'added_at': item['added_at'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'title': item['title'],
'sort_title': item['sort_title'] or item['title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': item['thumb'],
'container': item.get('container', ''),
'bitrate': item.get('bitrate', ''),
'video_codec': item.get('video_codec', ''),
'video_resolution': item.get('video_resolution', ''),
'video_framerate': item.get('video_framerate', ''),
'audio_codec': item.get('audio_codec', ''),
'audio_channels': item.get('audio_channels', ''),
'file_size': file_size
}
new_rows.append(row)
row = {'section_id': library_details['section_id'], rows = new_rows
'section_type': library_details['section_type'], if not rows:
'added_at': item['added_at'], return default_return
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'title': item['title'],
'sort_title': item['sort_title'] or item['title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': item['thumb'],
'container': item.get('container', ''),
'bitrate': item.get('bitrate', ''),
'video_codec': item.get('video_codec', ''),
'video_resolution': item.get('video_resolution', ''),
'video_framerate': item.get('video_framerate', ''),
'audio_codec': item.get('audio_codec', ''),
'audio_channels': item.get('audio_channels', ''),
'file_size': file_size
}
new_rows.append(row)
rows = new_rows # Cache the media info to a json file
if not rows: self._save_media_info_cache(section_id=section_id, rating_key=rating_key, rows=rows)
return default_return
# Cache the media info to a json file
self._save_media_info_cache(section_id=section_id, rating_key=rating_key, rows=rows)
# Update the last_played and play_count # Update the last_played and play_count
for item in rows: for item in rows:
@ -670,29 +674,28 @@ class Libraries(object):
elif section_id: elif section_id:
logger.debug("Tautulli Libraries :: Fetting file sizes for section_id %s." % section_id) logger.debug("Tautulli Libraries :: Fetting file sizes for section_id %s." % section_id)
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
for item in rows:
if item['rating_key'] and not item['file_size']:
file_size = 0
for item in rows: metadata = pms_connect.get_metadata_children_details(rating_key=item['rating_key'],
if item['rating_key'] and not item['file_size']: get_children=True,
file_size = 0 media_type=item['media_type'],
section_id=section_id)
metadata = pms_connect.get_metadata_children_details(rating_key=item['rating_key'], for child_metadata in metadata:
get_children=True, ## TODO: Check list of media info items, currently only grabs first item
media_type=item['media_type'], media_info = media_part_info = {}
section_id=section_id) if 'media_info' in child_metadata and len(child_metadata['media_info']) > 0:
media_info = child_metadata['media_info'][0]
if 'parts' in media_info and len (media_info['parts']) > 0:
media_part_info = next((p for p in media_info['parts'] if p['selected']),
media_info['parts'][0])
for child_metadata in metadata: file_size += helpers.cast_to_int(media_part_info.get('file_size', 0))
## TODO: Check list of media info items, currently only grabs first item
media_info = media_part_info = {}
if 'media_info' in child_metadata and len(child_metadata['media_info']) > 0:
media_info = child_metadata['media_info'][0]
if 'parts' in media_info and len (media_info['parts']) > 0:
media_part_info = next((p for p in media_info['parts'] if p['selected']),
media_info['parts'][0])
file_size += helpers.cast_to_int(media_part_info.get('file_size', 0)) item['file_size'] = file_size
item['file_size'] = file_size
# Cache the media info to a json file # Cache the media info to a json file
self._save_media_info_cache(section_id=section_id, rating_key=rating_key, rows=rows) self._save_media_info_cache(section_id=section_id, rating_key=rating_key, rows=rows)
@ -1018,7 +1021,7 @@ class Libraries(object):
return session.mask_session_info(user_stats, mask_metadata=False) return session.mask_session_info(user_stats, mask_metadata=False)
def get_recently_watched(self, section_id=None, limit='10'): def get_recently_watched(self, section_id=None, limit='10', server_id=None):
if not session.allow_session_library(section_id): if not session.allow_session_library(section_id):
return [] return []
@ -1037,7 +1040,7 @@ class Libraries(object):
"year, originally_available_at, added_at, live, started, user, content_rating, labels, section_id " \ "year, originally_available_at, added_at, live, started, user, content_rating, labels, section_id " \
"FROM session_history_metadata " \ "FROM session_history_metadata " \
"JOIN session_history ON session_history_metadata.id = session_history.id " \ "JOIN session_history ON session_history_metadata.id = session_history.id " \
"WHERE section_id = ? " \ "WHERE section_id = ? and server_id = '" + server_id + "' " \
"GROUP BY session_history.rating_key " \ "GROUP BY session_history.rating_key " \
"ORDER BY MAX(started) DESC LIMIT ?" "ORDER BY MAX(started) DESC LIMIT ?"
result = monitor_db.select(query, args=[section_id, limit]) result = monitor_db.select(query, args=[section_id, limit])
@ -1075,6 +1078,7 @@ class Libraries(object):
'user': row['user'], 'user': row['user'],
'section_id': row['section_id'], 'section_id': row['section_id'],
'content_rating': row['content_rating'], 'content_rating': row['content_rating'],
'server_id': row['server_id'],
'labels': row['labels'].split(';') if row['labels'] else (), 'labels': row['labels'].split(';') if row['labels'] else (),
} }
recently_watched.append(recent_output) recently_watched.append(recent_output)

View file

@ -37,7 +37,7 @@ if plexpy.PYTHON2:
import libraries import libraries
import logger import logger
import newsletter_handler import newsletter_handler
import pmsconnect import server_manager
from notifiers import send_notification, EMAIL from notifiers import send_notification, EMAIL
else: else:
from plexpy import common from plexpy import common
@ -46,7 +46,7 @@ else:
from plexpy import libraries from plexpy import libraries
from plexpy import logger from plexpy import logger
from plexpy import newsletter_handler from plexpy import newsletter_handler
from plexpy import pmsconnect from plexpy import server_manager
from plexpy.notifiers import send_notification, EMAIL from plexpy.notifiers import send_notification, EMAIL
@ -706,125 +706,125 @@ class RecentlyAdded(Newsletter):
def _get_recently_added(self, media_type=None): def _get_recently_added(self, media_type=None):
from plexpy.notification_handler import format_group_index from plexpy.notification_handler import format_group_index
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
recently_added = [] recently_added = []
done = False done = False
start = 0 start = 0
while not done: while not done:
recent_items = pms_connect.get_recently_added_details(start=str(start), count='10', media_type=media_type) recent_items = pms_connect.get_recently_added_details(start=str(start), count='10', media_type=media_type)
filtered_items = [i for i in recent_items['recently_added'] filtered_items = [i for i in recent_items['recently_added']
if self.start_time < helpers.cast_to_int(i['added_at'])] if self.start_time < helpers.cast_to_int(i['added_at'])]
if len(filtered_items) < 10: if len(filtered_items) < 10:
done = True done = True
else: else:
start += 10 start += 10
recently_added.extend(filtered_items) recently_added.extend(filtered_items)
if media_type in ('movie', 'other_video'): if media_type in ('movie', 'other_video'):
movie_list = [] movie_list = []
for item in recently_added: for item in recently_added:
# Filter included libraries # Filter included libraries
if item['section_id'] not in self.config['incl_libraries']: if item['section_id'] not in self.config['incl_libraries']:
continue continue
if self.start_time < helpers.cast_to_int(item['added_at']) < self.end_time: if self.start_time < helpers.cast_to_int(item['added_at']) < self.end_time:
movie_list.append(item) movie_list.append(item)
recently_added = movie_list recently_added += movie_list
if media_type == 'show': if media_type == 'show':
shows_list = [] shows_list = []
show_rating_keys = [] show_rating_keys = []
for item in recently_added: for item in recently_added:
# Filter included libraries # Filter included libraries
if item['section_id'] not in self.config['incl_libraries']: if item['section_id'] not in self.config['incl_libraries']:
continue continue
if item['media_type'] == 'show': if item['media_type'] == 'show':
show_rating_key = item['rating_key'] show_rating_key = item['rating_key']
elif item['media_type'] == 'season': elif item['media_type'] == 'season':
show_rating_key = item['parent_rating_key'] show_rating_key = item['parent_rating_key']
elif item['media_type'] == 'episode': elif item['media_type'] == 'episode':
show_rating_key = item['grandparent_rating_key'] show_rating_key = item['grandparent_rating_key']
if show_rating_key in show_rating_keys: if show_rating_key in show_rating_keys:
continue continue
show_metadata = pms_connect.get_metadata_details(show_rating_key, media_info=False) show_metadata = pms_connect.get_metadata_details(show_rating_key, media_info=False)
children = pms_connect.get_item_children(show_rating_key, media_type=media_type, get_grandchildren=True) children = pms_connect.get_item_children(show_rating_key, media_type=media_type, get_grandchildren=True)
filtered_children = [i for i in children['children_list'] filtered_children = [i for i in children['children_list']
if self.start_time < helpers.cast_to_int(i['added_at']) < self.end_time] if self.start_time < helpers.cast_to_int(i['added_at']) < self.end_time]
filtered_children.sort(key=lambda x: helpers.cast_to_int(x['parent_media_index'])) filtered_children.sort(key=lambda x: helpers.cast_to_int(x['parent_media_index']))
if not filtered_children: if not filtered_children:
continue continue
seasons = [] seasons = []
for (index, title), children in groupby(filtered_children, for (index, title), children in groupby(filtered_children,
key=lambda x: (x['parent_media_index'], x['parent_title'])): key=lambda x: (x['parent_media_index'], x['parent_title'])):
episodes = list(children) episodes = list(children)
num, num00 = format_group_index([helpers.cast_to_int(d['media_index']) for d in episodes]) num, num00 = format_group_index([helpers.cast_to_int(d['media_index']) for d in episodes])
seasons.append({'media_index': index, seasons.append({'media_index': index,
'title': title, 'title': title,
'episode_range': num00, 'episode_range': num00,
'episode_count': len(episodes), 'episode_count': len(episodes),
'episode': episodes}) 'episode': episodes})
num, num00 = format_group_index([helpers.cast_to_int(d['media_index']) for d in seasons]) num, num00 = format_group_index([helpers.cast_to_int(d['media_index']) for d in seasons])
show_metadata['season_range'] = num00 show_metadata['season_range'] = num00
show_metadata['season_count'] = len(seasons) show_metadata['season_count'] = len(seasons)
show_metadata['season'] = seasons show_metadata['season'] = seasons
shows_list.append(show_metadata) shows_list.append(show_metadata)
show_rating_keys.append(show_rating_key) show_rating_keys.append(show_rating_key)
recently_added = shows_list recently_added += shows_list
if media_type == 'artist': if media_type == 'artist':
artists_list = [] artists_list = []
artist_rating_keys = [] artist_rating_keys = []
for item in recently_added: for item in recently_added:
# Filter included libraries # Filter included libraries
if item['section_id'] not in self.config['incl_libraries']: if item['section_id'] not in self.config['incl_libraries']:
continue continue
if item['media_type'] == 'artist': if item['media_type'] == 'artist':
artist_rating_key = item['rating_key'] artist_rating_key = item['rating_key']
elif item['media_type'] == 'album': elif item['media_type'] == 'album':
artist_rating_key = item['parent_rating_key'] artist_rating_key = item['parent_rating_key']
elif item['media_type'] == 'track': elif item['media_type'] == 'track':
artist_rating_key = item['grandparent_rating_key'] artist_rating_key = item['grandparent_rating_key']
if artist_rating_key in artist_rating_keys: if artist_rating_key in artist_rating_keys:
continue continue
artist_metadata = pms_connect.get_metadata_details(artist_rating_key, media_info=False) artist_metadata = pms_connect.get_metadata_details(artist_rating_key, media_info=False)
children = pms_connect.get_item_children(artist_rating_key, media_type=media_type) children = pms_connect.get_item_children(artist_rating_key, media_type=media_type)
filtered_children = [i for i in children['children_list'] filtered_children = [i for i in children['children_list']
if self.start_time < helpers.cast_to_int(i['added_at']) < self.end_time] if self.start_time < helpers.cast_to_int(i['added_at']) < self.end_time]
filtered_children.sort(key=lambda x: x['added_at']) filtered_children.sort(key=lambda x: x['added_at'])
if not filtered_children: if not filtered_children:
continue continue
albums = [] albums = []
for a in filtered_children: for a in filtered_children:
album_metadata = pms_connect.get_metadata_details(a['rating_key'], media_info=False) album_metadata = pms_connect.get_metadata_details(a['rating_key'], media_info=False)
album_metadata['track_count'] = helpers.cast_to_int(album_metadata['children_count']) album_metadata['track_count'] = helpers.cast_to_int(album_metadata['children_count'])
albums.append(album_metadata) albums.append(album_metadata)
artist_metadata['album_count'] = len(albums) artist_metadata['album_count'] = len(albums)
artist_metadata['album'] = albums artist_metadata['album'] = albums
artists_list.append(artist_metadata) artists_list.append(artist_metadata)
artist_rating_keys.append(artist_rating_key) artist_rating_keys.append(artist_rating_key)
recently_added = artists_list recently_added += artists_list
return recently_added return recently_added

View file

@ -47,8 +47,8 @@ if plexpy.PYTHON2:
import logger import logger
import helpers import helpers
import notifiers import notifiers
import pmsconnect
import request import request
import server_manager
from newsletter_handler import notify as notify_newsletter from newsletter_handler import notify as notify_newsletter
else: else:
from plexpy import activity_processor from plexpy import activity_processor
@ -58,8 +58,8 @@ else:
from plexpy import logger from plexpy import logger
from plexpy import helpers from plexpy import helpers
from plexpy import notifiers from plexpy import notifiers
from plexpy import pmsconnect
from plexpy import request from plexpy import request
from plexpy import server_manager
from plexpy.newsletter_handler import notify as notify_newsletter from plexpy.newsletter_handler import notify as notify_newsletter
@ -180,23 +180,23 @@ def notify_conditions(notify_action=None, stream_data=None, timeline_data=None,
# return False # return False
if notify_action == 'on_concurrent': if notify_action == 'on_concurrent':
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_current_activity() result = pms_connect.get_current_activity()
user_sessions = [] user_sessions = []
if result: if result:
user_sessions = [s for s in result['sessions'] if s['user_id'] == stream_data['user_id']] user_sessions = [s for s in result['sessions'] if s['user_id'] == stream_data['user_id']]
if plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP: if plexpy.CONFIG.NOTIFY_CONCURRENT_BY_IP:
ip_addresses = set() ip_addresses = set()
for s in user_sessions: for s in user_sessions:
if helpers.ip_type(s['ip_address']) == 'IPv6': if helpers.ip_type(s['ip_address']) == 'IPv6':
ip_addresses.add(helpers.get_ipv6_network_address(s['ip_address'])) ip_addresses.add(helpers.get_ipv6_network_address(s['ip_address']))
elif helpers.ip_type(s['ip_address']) == 'IPv4': elif helpers.ip_type(s['ip_address']) == 'IPv4':
ip_addresses.add(s['ip_address']) ip_addresses.add(s['ip_address'])
evaluated = len(ip_addresses) >= plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD evaluated = len(ip_addresses) >= plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
else: else:
evaluated = len(user_sessions) >= plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD evaluated = len(user_sessions) >= plexpy.CONFIG.NOTIFY_CONCURRENT_THRESHOLD
elif notify_action == 'on_newdevice': elif notify_action == 'on_newdevice':
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
@ -595,18 +595,18 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
notify_params.update(media_info) notify_params.update(media_info)
notify_params.update(media_part_info) notify_params.update(media_part_info)
for pmsconnect in server_manager.ServerManger().get_server_list():
metadata = pmsconnect.get_metadata_details(rating_key=rating_key)
metadata = pmsconnect.PmsConnect().get_metadata_details(rating_key=rating_key) child_metadata = grandchild_metadata = []
for key in kwargs.pop('child_keys', []):
child_metadata = grandchild_metadata = [] child = pmsconnect.get_metadata_details(rating_key=key)
for key in kwargs.pop('child_keys', []): if child:
child = pmsconnect.PmsConnect().get_metadata_details(rating_key=key) child_metadata.append(child)
if child: for key in kwargs.pop('grandchild_keys', []):
child_metadata.append(child) grandchild = pmsconnect.get_metadata_details(rating_key=key)
for key in kwargs.pop('grandchild_keys', []): if grandchild:
grandchild = pmsconnect.PmsConnect().get_metadata_details(rating_key=key) grandchild_metadata.append(grandchild)
if grandchild:
grandchild_metadata.append(grandchild)
# Session values # Session values
session = session or {} session = session or {}
@ -1235,83 +1235,84 @@ def build_server_notify_params(notify_action=None, **kwargs):
date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','') date_format = plexpy.CONFIG.DATE_FORMAT.replace('Do','')
time_format = plexpy.CONFIG.TIME_FORMAT.replace('Do','') time_format = plexpy.CONFIG.TIME_FORMAT.replace('Do','')
update_channel = pmsconnect.PmsConnect().get_server_update_channel() for pmsconnect in server_manager.ServerManger().get_server_list():
update_channel = pmsconnect.get_server_update_channel()
pms_download_info = defaultdict(str, kwargs.pop('pms_download_info', {})) pms_download_info = defaultdict(str, kwargs.pop('pms_download_info', {}))
plexpy_download_info = defaultdict(str, kwargs.pop('plexpy_download_info', {})) plexpy_download_info = defaultdict(str, kwargs.pop('plexpy_download_info', {}))
remote_access_info = defaultdict(str, kwargs.pop('remote_access_info', {})) remote_access_info = defaultdict(str, kwargs.pop('remote_access_info', {}))
windows_exe = macos_pkg = '' windows_exe = macos_pkg = ''
if plexpy_download_info: if plexpy_download_info:
release_assets = plexpy_download_info.get('assets', []) release_assets = plexpy_download_info.get('assets', [])
for asset in release_assets: for asset in release_assets:
if asset['content_type'] == 'application/vnd.microsoft.portable-executable': if asset['content_type'] == 'application/vnd.microsoft.portable-executable':
windows_exe = asset['browser_download_url'] windows_exe = asset['browser_download_url']
elif asset['content_type'] == 'application/vnd.apple.installer+xml': elif asset['content_type'] == 'application/vnd.apple.installer+xml':
macos_pkg = asset['browser_download_url'] macos_pkg = asset['browser_download_url']
now = arrow.now() now = arrow.now()
now_iso = now.isocalendar() now_iso = now.isocalendar()
available_params = { available_params = {
# Global paramaters # Global paramaters
'tautulli_version': common.RELEASE, 'tautulli_version': common.RELEASE,
'tautulli_remote': plexpy.CONFIG.GIT_REMOTE, 'tautulli_remote': plexpy.CONFIG.GIT_REMOTE,
'tautulli_branch': plexpy.CONFIG.GIT_BRANCH, 'tautulli_branch': plexpy.CONFIG.GIT_BRANCH,
'tautulli_commit': plexpy.CURRENT_VERSION, 'tautulli_commit': plexpy.CURRENT_VERSION,
'server_name': helpers.pms_name(), 'server_name': helpers.pms_name(),
'server_ip': plexpy.CONFIG.PMS_IP, 'server_ip': plexpy.CONFIG.PMS_IP,
'server_port': plexpy.CONFIG.PMS_PORT, 'server_port': plexpy.CONFIG.PMS_PORT,
'server_url': plexpy.CONFIG.PMS_URL, 'server_url': plexpy.CONFIG.PMS_URL,
'server_platform': plexpy.CONFIG.PMS_PLATFORM, 'server_platform': plexpy.CONFIG.PMS_PLATFORM,
'server_version': plexpy.CONFIG.PMS_VERSION, 'server_version': plexpy.CONFIG.PMS_VERSION,
'server_machine_id': plexpy.CONFIG.PMS_IDENTIFIER, 'server_machine_id': plexpy.CONFIG.PMS_IDENTIFIER,
'action': notify_action.split('on_')[-1], 'action': notify_action.split('on_')[-1],
'current_year': now.year, 'current_year': now.year,
'current_month': now.month, 'current_month': now.month,
'current_day': now.day, 'current_day': now.day,
'current_hour': now.hour, 'current_hour': now.hour,
'current_minute': now.minute, 'current_minute': now.minute,
'current_second': now.second, 'current_second': now.second,
'current_weekday': now_iso[2], 'current_weekday': now_iso[2],
'current_week': now_iso[1], 'current_week': now_iso[1],
'week_number': now_iso[1], # Keep for backwards compatibility 'week_number': now_iso[1], # Keep for backwards compatibility
'datestamp': now.format(date_format), 'datestamp': now.format(date_format),
'timestamp': now.format(time_format), 'timestamp': now.format(time_format),
'unixtime': helpers.timestamp(), 'unixtime': helpers.timestamp(),
'utctime': helpers.utc_now_iso(), 'utctime': helpers.utc_now_iso(),
# Plex remote access parameters # Plex remote access parameters
'remote_access_mapping_state': remote_access_info['mapping_state'], 'remote_access_mapping_state': remote_access_info['mapping_state'],
'remote_access_mapping_error': remote_access_info['mapping_error'], 'remote_access_mapping_error': remote_access_info['mapping_error'],
'remote_access_public_address': remote_access_info['public_address'], 'remote_access_public_address': remote_access_info['public_address'],
'remote_access_public_port': remote_access_info['public_port'], 'remote_access_public_port': remote_access_info['public_port'],
'remote_access_private_address': remote_access_info['private_address'], 'remote_access_private_address': remote_access_info['private_address'],
'remote_access_private_port': remote_access_info['private_port'], 'remote_access_private_port': remote_access_info['private_port'],
'remote_access_reason': remote_access_info['reason'], 'remote_access_reason': remote_access_info['reason'],
# Plex Media Server update parameters # Plex Media Server update parameters
'update_version': pms_download_info['version'], 'update_version': pms_download_info['version'],
'update_url': pms_download_info['download_url'], 'update_url': pms_download_info['download_url'],
'update_release_date': arrow.get(pms_download_info['release_date']).format(date_format) 'update_release_date': arrow.get(pms_download_info['release_date']).format(date_format)
if pms_download_info['release_date'] else '', if pms_download_info['release_date'] else '',
'update_channel': 'Beta' if update_channel == 'beta' else 'Public', 'update_channel': 'Beta' if update_channel == 'beta' else 'Public',
'update_platform': pms_download_info['platform'], 'update_platform': pms_download_info['platform'],
'update_distro': pms_download_info['distro'], 'update_distro': pms_download_info['distro'],
'update_distro_build': pms_download_info['build'], 'update_distro_build': pms_download_info['build'],
'update_requirements': pms_download_info['requirements'], 'update_requirements': pms_download_info['requirements'],
'update_extra_info': pms_download_info['extra_info'], 'update_extra_info': pms_download_info['extra_info'],
'update_changelog_added': pms_download_info['changelog_added'], 'update_changelog_added': pms_download_info['changelog_added'],
'update_changelog_fixed': pms_download_info['changelog_fixed'], 'update_changelog_fixed': pms_download_info['changelog_fixed'],
# Tautulli update parameters # Tautulli update parameters
'tautulli_update_version': plexpy_download_info['tag_name'], 'tautulli_update_version': plexpy_download_info['tag_name'],
'tautulli_update_release_url': plexpy_download_info['html_url'], 'tautulli_update_release_url': plexpy_download_info['html_url'],
'tautulli_update_exe': windows_exe, 'tautulli_update_exe': windows_exe,
'tautulli_update_pkg': macos_pkg, 'tautulli_update_pkg': macos_pkg,
'tautulli_update_tar': plexpy_download_info['tarball_url'], 'tautulli_update_tar': plexpy_download_info['tarball_url'],
'tautulli_update_zip': plexpy_download_info['zipball_url'], 'tautulli_update_zip': plexpy_download_info['zipball_url'],
'tautulli_update_commit': kwargs.pop('plexpy_update_commit', ''), 'tautulli_update_commit': kwargs.pop('plexpy_update_commit', ''),
'tautulli_update_behind': kwargs.pop('plexpy_update_behind', ''), 'tautulli_update_behind': kwargs.pop('plexpy_update_behind', ''),
'tautulli_update_changelog': plexpy_download_info['body'] 'tautulli_update_changelog': plexpy_download_info['body']
} }
return available_params return available_params
@ -1551,47 +1552,47 @@ def get_img_info(img=None, rating_key=None, title='', width=1000, height=1500,
img_info = database_img_info[0] img_info = database_img_info[0]
elif not database_img_info and img: elif not database_img_info and img:
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_image(refresh=True, **image_info) result = pms_connect.get_image(refresh=True, **image_info)
if result and result[0]: if result and result[0]:
img_url = delete_hash = '' img_url = delete_hash = ''
if service == 'imgur': if service == 'imgur':
img_url, delete_hash = helpers.upload_to_imgur(img_data=result[0], img_url, delete_hash = helpers.upload_to_imgur(img_data=result[0],
img_title=title, img_title=title,
rating_key=rating_key, rating_key=rating_key,
fallback=fallback) fallback=fallback)
elif service == 'cloudinary': elif service == 'cloudinary':
img_url = helpers.upload_to_cloudinary(img_data=result[0], img_url = helpers.upload_to_cloudinary(img_data=result[0],
img_title=title, img_title=title,
rating_key=rating_key, rating_key=rating_key,
fallback=fallback) fallback=fallback)
if img_url: if img_url:
img_hash = set_hash_image_info(**image_info) img_hash = set_hash_image_info(**image_info)
data_factory.set_img_info(img_hash=img_hash, data_factory.set_img_info(img_hash=img_hash,
img_title=title, img_title=title,
img_url=img_url, img_url=img_url,
delete_hash=delete_hash, delete_hash=delete_hash,
service=service) service=service)
img_info = {'img_title': title, 'img_url': img_url} img_info = {'img_title': title, 'img_url': img_url}
if img_info['img_url'] and service == 'cloudinary': if img_info['img_url'] and service == 'cloudinary':
# Transform image using Cloudinary # Transform image using Cloudinary
image_info = {'rating_key': rating_key, image_info = {'rating_key': rating_key,
'width': width, 'width': width,
'height': height, 'height': height,
'opacity': opacity, 'opacity': opacity,
'background': background, 'background': background,
'blur': blur, 'blur': blur,
'fallback': fallback, 'fallback': fallback,
'img_title': title} 'img_title': title}
transformed_url = helpers.cloudinary_transform(**image_info) transformed_url = helpers.cloudinary_transform(**image_info)
if transformed_url: if transformed_url:
img_info['img_url'] = transformed_url img_info['img_url'] = transformed_url
return img_info return img_info

View file

@ -67,7 +67,7 @@ if plexpy.PYTHON2:
import helpers import helpers
import logger import logger
import mobile_app import mobile_app
import pmsconnect import server_manager
import request import request
import users import users
else: else:
@ -76,7 +76,7 @@ else:
from plexpy import helpers from plexpy import helpers
from plexpy import logger from plexpy import logger
from plexpy import mobile_app from plexpy import mobile_app
from plexpy import pmsconnect from plexpy import server_manager
from plexpy import request from plexpy import request
from plexpy import users from plexpy import users

View file

@ -603,6 +603,7 @@ class PmsConnect(object):
for guid in m.getElementsByTagName('Guid'): for guid in m.getElementsByTagName('Guid'):
guids.append(helpers.get_xml_attr(guid, 'id')) guids.append(helpers.get_xml_attr(guid, 'id'))
server_info = self.get_server_info()
recent_item = {'media_type': helpers.get_xml_attr(m, 'type'), recent_item = {'media_type': helpers.get_xml_attr(m, 'type'),
'section_id': helpers.get_xml_attr(m, 'librarySectionID'), 'section_id': helpers.get_xml_attr(m, 'librarySectionID'),
'library_name': helpers.get_xml_attr(m, 'librarySectionTitle'), 'library_name': helpers.get_xml_attr(m, 'librarySectionTitle'),
@ -645,7 +646,8 @@ class PmsConnect(object):
'collections': collections, 'collections': collections,
'guids': guids, 'guids': guids,
'full_title': helpers.get_xml_attr(m, 'title'), 'full_title': helpers.get_xml_attr(m, 'title'),
'child_count': helpers.get_xml_attr(m, 'childCount') 'child_count': helpers.get_xml_attr(m, 'childCount'),
'server_id': server_info['machine_identifier']
} }
recents_list.append(recent_item) recents_list.append(recent_item)
@ -2294,6 +2296,7 @@ class PmsConnect(object):
synced_version_profile = '' synced_version_profile = ''
optimized_version_profile = '' optimized_version_profile = ''
server_info = self.get_server_info()
# Entire session output (single dict for backwards compatibility) # Entire session output (single dict for backwards compatibility)
session_output = {'session_key': session_key, session_output = {'session_key': session_key,
'media_type': media_type, 'media_type': media_type,
@ -2303,7 +2306,11 @@ class PmsConnect(object):
'synced_version_profile': synced_version_profile, 'synced_version_profile': synced_version_profile,
'optimized_version_profile': optimized_version_profile, 'optimized_version_profile': optimized_version_profile,
'user': user_details['username'], # Keep for backwards compatibility 'user': user_details['username'], # Keep for backwards compatibility
'channel_stream': channel_stream 'channel_stream': channel_stream,
'server_id': server_info['machine_identifier'],
'server_name': server_info['name'],
'server_ip': server_info['host'],
'server_port': server_info['port'],
} }
session_output.update(metadata_details) session_output.update(metadata_details)
@ -2492,7 +2499,8 @@ class PmsConnect(object):
'genres': genres, 'genres': genres,
'labels': labels, 'labels': labels,
'collections': collections, 'collections': collections,
'full_title': helpers.get_xml_attr(m, 'title') 'full_title': helpers.get_xml_attr(m, 'title'),
'server_id': self.get_server_info()['machine_identifier']
} }
children_list.append(children_output) children_list.append(children_output)
@ -2597,6 +2605,20 @@ class PmsConnect(object):
return server_info return server_info
def get_server_info(self):
"""
Return the base info of the current pms connection.
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
def get_server_identity(self): def get_server_identity(self):
""" """
Return the local machine identity. Return the local machine identity.
@ -2614,7 +2636,7 @@ class PmsConnect(object):
server_identity = {} server_identity = {}
for a in xml_head: for a in xml_head:
server_identity = {"machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'), server_identity = {"machine_identifier": helpers.get_xml_attr(a, 'machineIdentifier'),
"version": helpers.get_xml_attr(a, 'version') "version": helpers.get_xml_attr(a, 'version'),
} }
return server_identity return server_identity

44
plexpy/server_manager.py Normal file
View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# This file is part of Tautulli.
#
# Tautulli is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Tautulli is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Tautulli. If not, see <http://www.gnu.org/licenses/>.
import plexpy
if plexpy.PYTHON2:
import pmsconnect
else:
from plexpy import pmsconnect
class ServerManger(object):
"""
Return processed and validated library statistics.
Output: array
"""
def get_server_list(self):
pmsServers = []
for server in pmsconnect.PmsConnect().get_servers_info():
url = 'http://{hostname}:{port}'.format(hostname=server["host"], port=server["port"])
pmsServers.append(pmsconnect.PmsConnect(url=url))
return pmsServers
def get_server(self, server_id):
if server_id is not None:
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(url=url)
return None

View file

@ -35,12 +35,14 @@ if plexpy.PYTHON2:
import activity_processor import activity_processor
import database import database
import logger import logger
import server_manager
else: else:
from plexpy import activity_handler from plexpy import activity_handler
from plexpy import activity_pinger from plexpy import activity_pinger
from plexpy import activity_processor from plexpy import activity_processor
from plexpy import database from plexpy import database
from plexpy import logger from plexpy import logger
from plexpy import server_manager
name = 'websocket' name = 'websocket'

View file

@ -76,6 +76,7 @@ if plexpy.PYTHON2:
import versioncheck import versioncheck
import web_socket import web_socket
import webstart import webstart
import server_manager
from api2 import API2 from api2 import API2
from helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out from helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out
from session import get_session_info, get_session_user_id, allow_session_user, allow_session_library from session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
@ -111,6 +112,7 @@ else:
from plexpy import versioncheck from plexpy import versioncheck
from plexpy import web_socket from plexpy import web_socket
from plexpy import webstart from plexpy import webstart
from plexpy import server_manager
from plexpy.api2 import API2 from plexpy.api2 import API2
from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out from plexpy.helpers import checked, addtoapi, get_ip, create_https_certificates, build_datatables_json, sanitize_out
from plexpy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library from plexpy.session import get_session_info, get_session_user_id, allow_session_user, allow_session_library
@ -141,7 +143,7 @@ def serve_template(template_name, **kwargs):
try: try:
template = TEMPLATE_LOOKUP.get_template(template_name) template = TEMPLATE_LOOKUP.get_template(template_name)
return template.render(http_root=http_root, server_name=server_name, cache_param=cache_param, return template.render(http_root=http_root, server_name=server_name, cache_param=cache_param,
_session=_session, **kwargs) _session=_session, server_id="test2", **kwargs)
except Exception as e: except Exception as e:
logger.exception("WebUI :: Mako template render error: %s" % e) logger.exception("WebUI :: Mako template render error: %s" % e)
return mako.exceptions.html_error_template().render() return mako.exceptions.html_error_template().render()
@ -333,10 +335,17 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_current_activity(self, **kwargs): def get_current_activity(self, **kwargs):
result = {
'stream_count':0,
'sessions': []
}
pms_connect = pmsconnect.PmsConnect(token=plexpy.CONFIG.PMS_TOKEN) for server in server_manager.ServerManger().get_server_list():
result = pms_connect.get_current_activity() res = server.get_current_activity()
if len(res['sessions']) > 0:
result['sessions'] += res['sessions']
result['stream_count'] = len(result['sessions'])
if result: if result:
return serve_template(template_name="current_activity.html", data=result) return serve_template(template_name="current_activity.html", data=result)
else: else:
@ -347,9 +356,17 @@ class WebInterface(object):
@requireAuth() @requireAuth()
def get_current_activity_instance(self, session_key=None, **kwargs): def get_current_activity_instance(self, session_key=None, **kwargs):
pms_connect = pmsconnect.PmsConnect(token=plexpy.CONFIG.PMS_TOKEN) result = {
result = pms_connect.get_current_activity() 'stream_count':0,
'sessions': []
}
for server in server_manager.ServerManger().get_server_list():
res = server.get_current_activity()
if len(res['sessions']) > 0:
result['sessions'] += res['sessions']
result['stream_count'] = len(result['sessions'])
if result: if result:
session = next((s for s in result['sessions'] if s['session_key'] == session_key), None) session = next((s for s in result['sessions'] if s['session_key'] == session_key), None)
return serve_template(template_name="current_activity_instance.html", session=session) return serve_template(template_name="current_activity_instance.html", session=session)
@ -360,7 +377,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def terminate_session(self, session_key='', session_id='', message='', **kwargs): def terminate_session(self, session_key='', session_id='', message='', server_id=None, **kwargs):
""" Stop a streaming session. """ Stop a streaming session.
``` ```
@ -375,7 +392,7 @@ class WebInterface(object):
None None
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() 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) result = pms_connect.terminate_session(session_key=session_key, session_id=session_id, message=message)
if isinstance(result, str): if isinstance(result, str):
@ -422,14 +439,18 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_recently_added(self, count='0', media_type='', **kwargs): def get_recently_added(self, count='0', media_type='', server_id=None, **kwargs):
results =[]
try: try:
pms_connect = pmsconnect.PmsConnect() for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_recently_added_details(count=count, media_type=media_type) results += pms_connect.get_recently_added_details(count=count, media_type=media_type)['recently_added']
except IOError as e: except IOError as e:
return serve_template(template_name="recently_added.html", data=None) return serve_template(template_name="recently_added.html", data=None)
result = {'recently_added': results}
if result and 'recently_added' in result: if result and 'recently_added' in result:
return serve_template(template_name="recently_added.html", data=result['recently_added']) return serve_template(template_name="recently_added.html", data=result['recently_added'])
else: else:
@ -619,7 +640,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def library(self, section_id=None, **kwargs): def library(self, section_id=None, server_id=None, **kwargs):
if not allow_session_library(section_id): if not allow_session_library(section_id):
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT) raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
@ -631,7 +652,7 @@ class WebInterface(object):
if section_id: if section_id:
try: try:
library_data = libraries.Libraries() library_data = libraries.Libraries()
library_details = library_data.get_details(section_id=section_id) library_details = library_data.get_details(section_id=section_id, server_id=server_id)
except: except:
logger.warn("Unable to retrieve library details for section_id %s " % section_id) logger.warn("Unable to retrieve library details for section_id %s " % section_id)
return serve_template(template_name="library.html", title="Library", data=None, config=config) return serve_template(template_name="library.html", title="Library", data=None, config=config)
@ -733,13 +754,13 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def library_recently_watched(self, section_id=None, limit='10', **kwargs): def library_recently_watched(self, section_id=None, limit='10', server_id=None, **kwargs):
if not allow_session_library(section_id): if not allow_session_library(section_id):
return serve_template(template_name="user_recently_watched.html", data=None, title="Recently Watched") return serve_template(template_name="user_recently_watched.html", data=None, title="Recently Watched")
if section_id: if section_id:
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_recently_watched(section_id=section_id, limit=limit) result = library_data.get_recently_watched(section_id=section_id, limit=limit, server_id=server_id)
else: else:
result = None result = None
@ -751,12 +772,13 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def library_recently_added(self, section_id=None, limit='10', **kwargs): def library_recently_added(self, section_id=None, limit='10', server_id=None, **kwargs):
if not allow_session_library(section_id): if not allow_session_library(section_id):
return serve_template(template_name="library_recently_added.html", data=None, title="Recently Added") return serve_template(template_name="library_recently_added.html", data=None, title="Recently Added")
result = []
if section_id: if section_id:
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
result = pms_connect.get_recently_added_details(section_id=section_id, count=limit) result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
else: else:
result = None result = None
@ -1900,7 +1922,7 @@ class WebInterface(object):
@requireAuth() @requireAuth()
@sanitize_out() @sanitize_out()
@addtoapi() @addtoapi()
def get_history(self, user=None, user_id=None, grouping=None, include_activity=None, **kwargs): def get_history(self, user=None, user_id=None, grouping=None, include_activity=None, server_id=None, **kwargs):
""" Get the Tautulli history. """ Get the Tautulli history.
``` ```
@ -2017,7 +2039,7 @@ class WebInterface(object):
custom_where.append(['session_history.user', user]) custom_where.append(['session_history.user', user])
if 'rating_key' in kwargs: if 'rating_key' in kwargs:
if kwargs.get('media_type') in ('collection', 'playlist') and kwargs.get('rating_key'): if kwargs.get('media_type') in ('collection', 'playlist') and kwargs.get('rating_key'):
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
result = pms_connect.get_item_children(rating_key=kwargs.pop('rating_key'), media_type=kwargs.pop('media_type')) result = pms_connect.get_item_children(rating_key=kwargs.pop('rating_key'), media_type=kwargs.pop('media_type'))
rating_keys = [child['rating_key'] for child in result['children_list']] rating_keys = [child['rating_key'] for child in result['children_list']]
custom_where.append(['session_history_metadata.rating_key OR', rating_keys]) custom_where.append(['session_history_metadata.rating_key OR', rating_keys])
@ -4385,7 +4407,7 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def info(self, rating_key=None, guid=None, source=None, section_id=None, user_id=None, **kwargs): def info(self, rating_key=None, guid=None, source=None, section_id=None, user_id=None, server_id=None, **kwargs):
if rating_key and not str(rating_key).isdigit(): if rating_key and not str(rating_key).isdigit():
raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT) raise cherrypy.HTTPRedirect(plexpy.HTTP_ROOT)
@ -4404,8 +4426,9 @@ class WebInterface(object):
# Try to get metadata from the Plex server first # Try to get metadata from the Plex server first
if rating_key: if rating_key:
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
metadata = pms_connect.get_metadata_details(rating_key=rating_key, section_id=section_id) metadata = pms_connect.get_metadata_details(rating_key=rating_key, section_id=section_id)
metadata['server_id'] = pms_connect.get_server_info()['machine_identifier']
# If the item is not found on the Plex server, get the metadata from history # If the item is not found on the Plex server, get the metadata from history
if not metadata and source == 'history': if not metadata and source == 'history':
@ -4433,10 +4456,12 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_item_children(self, rating_key='', media_type=None, **kwargs): def get_item_children(self, rating_key='', media_type=None, server_id=None, **kwargs):
pms_connect = pmsconnect.PmsConnect() result = None
result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type) pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
if pms_connect is not None:
result = pms_connect.get_item_children(rating_key=rating_key, media_type=media_type)
if result: if result:
return serve_template(template_name="info_children_list.html", data=result, return serve_template(template_name="info_children_list.html", data=result,
@ -4447,9 +4472,9 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
@requireAuth() @requireAuth()
def get_item_children_related(self, rating_key='', title='', **kwargs): def get_item_children_related(self, rating_key='', title='', server_id=None, **kwargs):
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
result = pms_connect.get_item_children_related(rating_key=rating_key) result = pms_connect.get_item_children_related(rating_key=rating_key)
if result: if result:
@ -4601,7 +4626,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi("get_children_metadata") @addtoapi("get_children_metadata")
def get_children_metadata_details(self, rating_key='', media_type=None, **kwargs): def get_children_metadata_details(self, rating_key='', media_type=None, server_id=None, **kwargs):
""" Get the metadata for the children of a media item. """ Get the metadata for the children of a media item.
``` ```
@ -4667,7 +4692,7 @@ class WebInterface(object):
} }
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
metadata = pms_connect.get_item_children(rating_key=rating_key, metadata = pms_connect.get_item_children(rating_key=rating_key,
media_type=media_type) media_type=media_type)
@ -4681,7 +4706,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi('notify_recently_added') @addtoapi('notify_recently_added')
def send_manual_on_created(self, notifier_id='', rating_key='', **kwargs): def send_manual_on_created(self, notifier_id='', rating_key='', server_id=None, **kwargs):
""" Send a recently added notification using Tautulli. """ Send a recently added notification using Tautulli.
``` ```
@ -4700,7 +4725,7 @@ class WebInterface(object):
``` ```
""" """
if rating_key: if rating_key:
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
metadata = pms_connect.get_metadata_details(rating_key=rating_key) metadata = pms_connect.get_metadata_details(rating_key=rating_key)
data = {'timeline_data': metadata, 'notify_action': 'on_created', 'manual_trigger': True} data = {'timeline_data': metadata, 'notify_action': 'on_created', 'manual_trigger': True}
@ -4733,7 +4758,7 @@ class WebInterface(object):
@addtoapi('pms_image_proxy') @addtoapi('pms_image_proxy')
def real_pms_image_proxy(self, img=None, rating_key=None, width=750, height=1000, def real_pms_image_proxy(self, img=None, rating_key=None, width=750, height=1000,
opacity=100, background='000000', blur=0, img_format='png', opacity=100, background='000000', blur=0, img_format='png',
fallback=None, refresh=False, clip=False, **kwargs): fallback=None, refresh=False, clip=False, server_id=None, **kwargs):
""" Gets an image from the PMS and saves it to the image cache directory. """ Gets an image from the PMS and saves it to the image cache directory.
``` ```
@ -4817,27 +4842,30 @@ class WebInterface(object):
except NotFound: except NotFound:
# the image does not exist, download it from pms # the image does not exist, download it from pms
try: try:
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
pms_connect.request_handler._silent = True if pms_connect is not None:
result = pms_connect.get_image(img=img, pms_connect.request_handler._silent = True
width=width, result = pms_connect.get_image(img=img,
height=height, width=width,
opacity=opacity, height=height,
background=background, opacity=opacity,
blur=blur, background=background,
img_format=img_format, blur=blur,
clip=clip, img_format=img_format,
refresh=refresh) clip=clip,
refresh=refresh)
if result and result[0]: if result and result[0]:
cherrypy.response.headers['Content-type'] = result[1] cherrypy.response.headers['Content-type'] = result[1]
if plexpy.CONFIG.CACHE_IMAGES and 'indexes' not in img: if plexpy.CONFIG.CACHE_IMAGES and 'indexes' not in img:
with open(ffp, 'wb') as f: with open(ffp, 'wb') as f:
f.write(result[0]) f.write(result[0])
return result[0] return result[0]
else:
raise Exception('PMS image request failed')
else: else:
raise Exception('PMS image request failed') raise Exception('PMS server not found')
except Exception as e: except Exception as e:
logger.warn("Failed to get image %s, falling back to %s." % (img, fallback)) logger.warn("Failed to get image %s, falling back to %s." % (img, fallback))
@ -5141,8 +5169,9 @@ class WebInterface(object):
} }
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() result = []
result = pms_connect.get_search_results(query=query, limit=limit) for pms_connect in server_manager.ServerManger().get_server_list():
result += pms_connect.get_search_results(query=query, limit=limit)
if result: if result:
return result return result
@ -5154,8 +5183,9 @@ class WebInterface(object):
@requireAuth() @requireAuth()
def get_search_results_children(self, query='', limit='', media_type=None, season_index=None, **kwargs): def get_search_results_children(self, query='', limit='', media_type=None, season_index=None, **kwargs):
pms_connect = pmsconnect.PmsConnect() result = []
result = pms_connect.get_search_results(query=query, limit=limit) for pms_connect in server_manager.ServerManger().get_server_list():
result += pms_connect.get_search_results(query=query, limit=limit)
if media_type: if media_type:
result['results_list'] = {media_type: result['results_list'][media_type]} result['results_list'] = {media_type: result['results_list'][media_type]}
@ -5193,7 +5223,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def update_metadata_details(self, old_rating_key, new_rating_key, media_type, single_update=False, **kwargs): def update_metadata_details(self, old_rating_key, new_rating_key, media_type, single_update=False, server_id=None, **kwargs):
""" Update the metadata in the Tautulli database by matching rating keys. """ Update the metadata in the Tautulli database by matching rating keys.
Also updates all parents or children of the media item if it is a show/season/episode Also updates all parents or children of the media item if it is a show/season/episode
or artist/album/track. or artist/album/track.
@ -5215,7 +5245,7 @@ class WebInterface(object):
if new_rating_key: if new_rating_key:
data_factory = datafactory.DataFactory() data_factory = datafactory.DataFactory()
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
old_key_list = data_factory.get_rating_keys_list(rating_key=old_rating_key, media_type=media_type) old_key_list = data_factory.get_rating_keys_list(rating_key=old_rating_key, media_type=media_type)
new_key_list = pms_connect.get_rating_keys_list(rating_key=new_rating_key, media_type=media_type) new_key_list = pms_connect.get_rating_keys_list(rating_key=new_rating_key, media_type=media_type)
@ -5235,7 +5265,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi() @addtoapi()
def get_new_rating_keys(self, rating_key='', media_type='', **kwargs): def get_new_rating_keys(self, rating_key='', media_type='', server_id=None, **kwargs):
""" Get a list of new rating keys for the PMS of all of the item's parent/children. """ Get a list of new rating keys for the PMS of all of the item's parent/children.
``` ```
@ -5252,7 +5282,7 @@ class WebInterface(object):
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
result = pms_connect.get_rating_keys_list(rating_key=rating_key, media_type=media_type) result = pms_connect.get_rating_keys_list(rating_key=rating_key, media_type=media_type)
if result: if result:
@ -5296,8 +5326,9 @@ class WebInterface(object):
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
def get_pms_sessions_json(self, **kwargs): def get_pms_sessions_json(self, **kwargs):
""" Get all the current sessions. """ """ Get all the current sessions. """
pms_connect = pmsconnect.PmsConnect() result = []
result = pms_connect.get_sessions('json') for pms_connect in server_manager.ServerManger().get_server_list():
result += pms_connect.get_sessions('json')
if result: if result:
return result return result
@ -5309,7 +5340,7 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
@addtoapi("get_metadata") @addtoapi("get_metadata")
def get_metadata_details(self, rating_key='', sync_id='', **kwargs): def get_metadata_details(self, rating_key='', sync_id='', server_id=None, **kwargs):
""" Get the metadata for a media item. """ Get the metadata for a media item.
``` ```
@ -5505,7 +5536,7 @@ class WebInterface(object):
} }
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server(server_id=server_id)
metadata = pms_connect.get_metadata_details(rating_key=rating_key, metadata = pms_connect.get_metadata_details(rating_key=rating_key,
sync_id=sync_id) sync_id=sync_id)
@ -5600,8 +5631,11 @@ class WebInterface(object):
if 'type' in kwargs: if 'type' in kwargs:
media_type = kwargs['type'] media_type = kwargs['type']
pms_connect = pmsconnect.PmsConnect() result =[]
result = pms_connect.get_recently_added_details(start=start, count=count, media_type=media_type, section_id=section_id)
for pms_connect in server_manager.ServerManger().get_server_list():
result = pms_connect.get_recently_added_details(start=start, count=count, media_type=media_type, section_id=section_id)
if result: if result:
return result return result
@ -5668,7 +5702,8 @@ class WebInterface(object):
@cherrypy.tools.json_out() @cherrypy.tools.json_out()
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
def get_servers(self, **kwargs): def get_servers(self, **kwargs):
pms_connect = pmsconnect.PmsConnect() # just grab first one
pms_connect = server_manager.ServerManger().get_server_list()[0]
result = pms_connect.get_server_list(output_format='json') result = pms_connect.get_server_list(output_format='json')
if result: if result:
@ -5701,7 +5736,7 @@ class WebInterface(object):
] ]
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() pms_connect = server_manager.ServerManger().get_server_list()[0]
result = pms_connect.get_servers_info() result = pms_connect.get_servers_info()
if result: if result:
@ -5890,6 +5925,7 @@ class WebInterface(object):
"relay": 0, "relay": 0,
"section_id": "2", "section_id": "2",
"secure": 1, "secure": 1,
"server_id": XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
"session_id": "helf15l3rxgw01xxe0jf3l3d", "session_id": "helf15l3rxgw01xxe0jf3l3d",
"session_key": "27", "session_key": "27",
"shared_libraries": [ "shared_libraries": [
@ -6033,8 +6069,18 @@ class WebInterface(object):
``` ```
""" """
try: try:
pms_connect = pmsconnect.PmsConnect(token=plexpy.CONFIG.PMS_TOKEN)
result = pms_connect.get_current_activity() result = {
'stream_count':0,
'sessions': []
}
for server in server_manager.ServerManger().get_server_list():
res = server.get_current_activity()
if len(res['sessions']) > 0:
result['sessions'] += res['sessions']
result['stream_count'] = len(result['sessions'])
if result: if result:
if session_key: if session_key:
@ -6103,8 +6149,9 @@ class WebInterface(object):
] ]
``` ```
""" """
pms_connect = pmsconnect.PmsConnect() result=[]
result = pms_connect.get_library_details() for pms_connect in server_manager.ServerManger().get_server_list():
result += pms_connect.get_library_details()
if result: if result:
return result return result
@ -6224,8 +6271,9 @@ class WebInterface(object):
@requireAuth(member_of("admin")) @requireAuth(member_of("admin"))
def get_sync_transcode_queue(self, **kwargs): def get_sync_transcode_queue(self, **kwargs):
""" Return details for currently syncing items. """ """ Return details for currently syncing items. """
pms_connect = pmsconnect.PmsConnect() result =[]
result = pms_connect.get_sync_transcode_queue(output_format='json') for pms_connect in server_manager.ServerManger().get_server_list():
result += pms_connect.get_sync_transcode_queue(output_format='json')
if result: if result:
return result return result