mirror of
https://github.com/Tautulli/Tautulli.git
synced 2024-11-23 22:10:17 -08:00
544 lines
38 KiB
HTML
544 lines
38 KiB
HTML
<%doc>
|
|
USAGE DOCUMENTATION :: PLEASE LEAVE THIS AT THE TOP OF THIS FILE
|
|
|
|
For Mako templating syntax documentation please visit: http://docs.makotemplates.org/en/latest/
|
|
|
|
Filename: current_activity_instance.html
|
|
Version: 0.1
|
|
Variable names: data {dict}
|
|
|
|
data :: Usable parameters
|
|
|
|
== Global keys ==
|
|
session_key Returns a unique session id for the active stream
|
|
rating_key Returns the unique identifier for the media item.
|
|
media_index Returns the index of the media item.
|
|
parent_media_index Returns the index of the media item's parent.
|
|
media_type Returns the type of session. Either 'track', 'episode' or 'movie'.
|
|
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
|
|
bif_thumb Returns the location of the item's bif thumbnail. Use with pms_image_proxy.
|
|
art Returns the location of the item's artwork
|
|
progress_percent Returns the current progress of the item. 0 to 100.
|
|
user Returns the name of the user owning the session.
|
|
user_id Returns the Plex user id if available.
|
|
machine_id Returns the machine id of the players being used.
|
|
friendly_name Returns the friendlly name of the user owning the session.
|
|
user_thumb Returns the profile picture of the user owning the session.
|
|
state Returns the state of the current session. Either 'playing', 'paused' or 'buffering'.
|
|
title Returns the name of the episode, movie or music track.
|
|
year Returns the year of the episode, movie, or clip.
|
|
ip_address Returns the ip address of the stream.
|
|
player Returns the name of the platform used to play the stream.
|
|
platform Returns the type of platform used to play the stream.
|
|
transcode_throttled Returns true if the transcode session is throttled.
|
|
transcode_progress Returns the current transcode progress of the item. 0 to 100.
|
|
transcode_speed Returns the current transcode speed of the item.
|
|
audio_decision Returns the audio transcode decision. Either 'transcode', 'copy' or 'direct play'.
|
|
audio_codec Returns the name of the audio codec.
|
|
audio_channels Returns the number of audio channels.
|
|
grandparent_title Returns the title of the item's grandparent.
|
|
parent_title Returns the title of the item's parent.
|
|
video_decision Returns the video transcode decision. Either 'transcode', 'copy' or 'direct play'.
|
|
video_codec Returns the name of the video codec.
|
|
height Returns the value of the video height.
|
|
width Returns the value of the video width.
|
|
container Returns the value of the media container.
|
|
bitrate Returns the value of the media bitrate.
|
|
video_resolution Returns the value of the video resolution.
|
|
video_framerate Returns the value of the video framerate.
|
|
video_aspect_ratio Returns the value of the video aspect ratio.
|
|
transcode_audio_channels Returns the amount of audio channels if there is a transcode session.
|
|
transcode_audio_codec Returns the name of the audio codec if there is a transcode session.
|
|
transcode_video_codec Returns the name of the video codec if there is a transcode session.
|
|
transcode_width Returns the video width if there is a transcode session.
|
|
transcode_height Returns the video height if there is a transcode session.
|
|
transcode_container Returns the value of media container if there is a transcode session.
|
|
transcode_protocol Returns the value of media protocol if there is a transcode session.
|
|
indexes Returns true if the media has media indexes and are enabled
|
|
|
|
DOCUMENTATION :: END
|
|
</%doc>
|
|
|
|
% if session is not None:
|
|
<%
|
|
from collections import defaultdict
|
|
from plexpy.helpers import cast_to_int, get_percent, page, short_season
|
|
from plexpy.common import VIDEO_RESOLUTION_OVERRIDES, AUDIO_CODEC_OVERRIDES, EXTRA_TYPES
|
|
import plexpy
|
|
%>
|
|
<%
|
|
data = defaultdict(lambda: 'Unknown', **session)
|
|
sk = data['session_key']
|
|
|
|
href = page('info', data['rating_key'])
|
|
parent_href = page('info', data['parent_rating_key'])
|
|
grandparent_href = page('info', data['grandparent_rating_key'])
|
|
user_href = page('user', data['user_id']) if data['user_id'] else '#'
|
|
season = short_season(data['parent_title'])
|
|
%>
|
|
<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-guid="${data['guid']}">
|
|
<div class="dashboard-activity-container">
|
|
<%
|
|
if data['live']:
|
|
background_url = page('pms_image_proxy', data['art'], data['rating_key'], 500, 280, 40, '282828', 3, fallback='art-live', refresh=True)
|
|
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)
|
|
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)
|
|
%>
|
|
<div id="background-${sk}" class="dashboard-activity-background" style="background-image: url(${background_url});">
|
|
<div class="dashboard-activity-poster-container hidden-xs">
|
|
% 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>
|
|
% endif
|
|
% if data['live']:
|
|
% if data['media_type'] == 'movie':
|
|
<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>
|
|
</a>
|
|
% elif data['media_type'] == 'episode':
|
|
<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>
|
|
</a>
|
|
% 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>
|
|
% endif
|
|
% elif data['channel_stream'] == 0:
|
|
% if data['media_type'] == 'movie':
|
|
<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>
|
|
</a>
|
|
% elif data['media_type'] == 'episode':
|
|
<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>
|
|
</a>
|
|
% elif data['media_type'] == 'track':
|
|
<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>
|
|
</a>
|
|
% elif data['media_type'] in ('photo', 'clip'):
|
|
% 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>
|
|
% 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>
|
|
% endif
|
|
% else:
|
|
<div id="poster-${sk}" class="dashboard-activity-poster" style="background-image: url(images/poster.png);"></div>
|
|
% endif
|
|
% 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-cover" style="background-image: url(${page('pms_image_proxy', data['channel_icon'], data['rating_key'], 300, 300, fallback='cover', refresh=True)});"></div>
|
|
% endif
|
|
</div>
|
|
<div class="dashboard-activity-info-icon">
|
|
<%
|
|
if not _session['user_group'] == 'admin' or not data['session_id']:
|
|
no_terminate = '-no-terminate'
|
|
else:
|
|
no_terminate = ''
|
|
%>
|
|
<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']:
|
|
<div class="dashboard-activity-terminate-session" id="terminate-button-${sk}" data-key="${sk}" data-id="${data['session_id']}" data-toggle="tooltip" title="Terminate Stream">
|
|
<i class="fa fa-times" style="padding-top: 10px;"></i>
|
|
</div>
|
|
% endif
|
|
</div>
|
|
<div class="dashboard-activity-info-container">
|
|
<div class="dashboard-activity-info-scroller scrollbar-macosx">
|
|
<div class="dashboard-activity-info scoller-content">
|
|
<ul class="list-unstyled dashboard-activity-info-list">
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Product</div>
|
|
<div class="sub-value platform-right">${data['product']}</div>
|
|
</li>
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Player</div>
|
|
<div class="sub-value platform-right">${data['player']}</div>
|
|
</li>
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Quality</div>
|
|
<div class="sub-value platform-right">
|
|
<span id="stream_quality-${sk}">
|
|
% if data['media_type'] != 'photo' and data['quality_profile'] != 'Unknown':
|
|
<%
|
|
br = cast_to_int(data['stream_bitrate']) or ''
|
|
if br:
|
|
if br > 1000:
|
|
br = '(' + str(round(br / 1000.0, 1)) + ' Mbps)'
|
|
else:
|
|
br = '(' + str(br) + ' kbps)'
|
|
%>
|
|
${data['quality_profile']} ${br}
|
|
% else:
|
|
${data['quality_profile']}
|
|
% endif
|
|
</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>
|
|
</li>
|
|
% if data['optimized_version'] == 1:
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Optimized</div>
|
|
<div class="sub-value" id="optimized_version-${sk}">
|
|
${data['optimized_version_profile']} (${data['optimized_version_title']})
|
|
</div>
|
|
</li>
|
|
% endif
|
|
% if data['synced_version'] == 1:
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Synced</div>
|
|
<div class="sub-value" id="synced_version-${sk}">
|
|
${data['synced_version_profile']}
|
|
</div>
|
|
</li>
|
|
% endif
|
|
</ul>
|
|
<ul class="list-unstyled dashboard-activity-info-list">
|
|
<li class="dashboard-activity-info-item">
|
|
% if _session['user_group'] == 'admin':
|
|
<div class="sub-heading"><span class="raw-stream-info-modal" data-toggle="modal" data-target="#raw-stream-info-modal" data-key="${sk}">Stream</span></div>
|
|
% else:
|
|
<div class="sub-heading">Stream</div>
|
|
% endif
|
|
<div class="sub-value" id="transcode_decision-${sk}">
|
|
% if data['transcode_decision'] == 'transcode':
|
|
Transcode
|
|
% if data['transcode_throttled'] == 1:
|
|
(Throttled)
|
|
% else:
|
|
(Speed: ${data['transcode_speed']})
|
|
% endif
|
|
% elif data['transcode_decision'] == 'copy':
|
|
Direct Stream
|
|
% else:
|
|
Direct Play
|
|
% endif
|
|
</div>
|
|
</li>
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Container</div>
|
|
<div class="sub-value" id="transcode_container-${sk}">
|
|
% if data['stream_container_decision'] == 'transcode':
|
|
Converting (${data['container'].upper()} <i class="fa fa-long-arrow-right"></i> ${data['stream_container'].upper()})
|
|
% else:
|
|
Direct Play (${data['stream_container'].upper()})
|
|
% endif
|
|
</div>
|
|
</li>
|
|
% if data['media_type'] in ('movie', 'episode', 'clip', 'photo'):
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Video</div>
|
|
<div class="sub-value" id="video_decision-${sk}">
|
|
% if data['media_type'] in ('movie', 'episode', 'clip') and data['stream_video_decision']:
|
|
<%
|
|
if data['video_dynamic_range'] != 'SDR':
|
|
video_dynamic_range = ' ' + data['video_dynamic_range']
|
|
else:
|
|
video_dynamic_range = ''
|
|
if data['stream_video_dynamic_range'] != 'SDR' or video_dynamic_range:
|
|
stream_video_dynamic_range = ' ' + data['stream_video_dynamic_range']
|
|
else:
|
|
stream_video_dynamic_range = ''
|
|
%>
|
|
% if data['stream_video_decision'] == 'transcode':
|
|
<%
|
|
hw_d = ' (HW)' if data['transcode_hw_decoding'] else ''
|
|
hw_e = ' (HW)' if data['transcode_hw_encoding'] else ''
|
|
%>
|
|
Transcode (${data['video_codec'].upper()}${hw_d} ${data['video_full_resolution']}${video_dynamic_range} <i class="fa fa-long-arrow-right"></i> ${data['stream_video_codec'].upper()}${hw_e} ${data['stream_video_full_resolution']}${stream_video_dynamic_range})
|
|
% elif data['stream_video_decision'] == 'copy':
|
|
Direct Stream (${data['stream_video_codec'].upper()} ${data['stream_video_full_resolution']}${stream_video_dynamic_range})
|
|
% else:
|
|
Direct Play (${data['stream_video_codec'].upper()} ${data['stream_video_full_resolution']}${stream_video_dynamic_range})
|
|
% endif
|
|
% elif data['media_type'] == 'photo':
|
|
Direct Play (${data['width']}x${data['height']})
|
|
% endif
|
|
</div>
|
|
</li>
|
|
% endif
|
|
% if data['media_type'] in ('movie', 'episode', 'clip', 'track'):
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Audio</div>
|
|
<div class="sub-value" id="audio_decision-${sk}">
|
|
% if data['stream_audio_decision']:
|
|
<%
|
|
audio_language = (data['audio_language'] or 'Unknown') + ' - ' if data['media_type'] != 'track' else ''
|
|
%>
|
|
% if data['stream_audio_decision'] == 'transcode':
|
|
Transcode (${audio_language}${AUDIO_CODEC_OVERRIDES.get(data['audio_codec'], data['audio_codec'].upper())} ${data['audio_channel_layout'].split('(')[0].capitalize()} <i class="fa fa-long-arrow-right"></i> ${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
|
% elif data['stream_audio_decision'] == 'copy':
|
|
Direct Stream (${audio_language}${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
|
% else:
|
|
Direct Play (${audio_language}${AUDIO_CODEC_OVERRIDES.get(data['stream_audio_codec'], data['stream_audio_codec'].upper())} ${data['stream_audio_channel_layout'].split('(')[0].capitalize()})
|
|
% endif
|
|
% endif
|
|
</div>
|
|
</li>
|
|
% endif
|
|
% if data['media_type'] in ('movie', 'episode', 'clip'):
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Subtitle</div>
|
|
<div class="sub-value" id="subtitle_decision-${sk}">
|
|
% if data['subtitles'] == 1:
|
|
<%
|
|
subtitle_codec = 'None' if data['stream_subtitle_codec'] and data['stream_subtitle_transient'] else data['subtitle_codec'].upper()
|
|
%>
|
|
% if data['stream_subtitle_decision'] == 'transcode':
|
|
Transcode (${data['subtitle_language'] or 'Unknown'} - ${subtitle_codec} <i class="fa fa-long-arrow-right"></i> ${data['stream_subtitle_codec'].upper()})
|
|
% elif data['stream_subtitle_decision'] == 'copy':
|
|
Direct Stream (${data['subtitle_language'] or 'Unknown'} - ${subtitle_codec})
|
|
% elif data['stream_subtitle_decision'] == 'burn':
|
|
Burn (${data['subtitle_language'] or 'Unknown'} - ${subtitle_codec})
|
|
% else:
|
|
Direct Play (${data['subtitle_language'] or 'Unknown'} - ${subtitle_codec if data['synced_version'] else data['stream_subtitle_codec'].upper()})
|
|
% endif
|
|
% else:
|
|
None
|
|
% endif
|
|
</div>
|
|
</li>
|
|
% endif
|
|
</ul>
|
|
<ul class="list-unstyled dashboard-activity-info-list">
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Location</div>
|
|
<div class="sub-value time-right">
|
|
% if data['secure'] is not None:
|
|
% if data['secure']:
|
|
<span data-toggle="tooltip" title="Secure Connection"><i class="fa fa-lock"></i></span>
|
|
% else:
|
|
<span data-toggle="tooltip" title="Insecure Connection"><i class="fa fa-unlock"></i></span>
|
|
% endif
|
|
% endif
|
|
<span id="location-${sk}">${data['location'].upper()}</span>:
|
|
% if data['ip_address'] != 'N/A':
|
|
% if len(data['ip_address']) > 20:
|
|
<span class="ip-container"><span class="ip-address" data-toggle="tooltip" title="${data['ip_address']}">${data['ip_address']}</span></span>
|
|
% else:
|
|
<span class="ip-container"><span class="ip-address">${data['ip_address']}</span></span>
|
|
% endif
|
|
% if data['relayed']:
|
|
<span data-toggle="tooltip" title="Plex Relay"><i class="fa fa-exclamation-circle"></i></span>
|
|
% else:
|
|
<a href="#" class="external_ip-modal" data-toggle="modal" data-target="#ip-info-modal"
|
|
data-ip="${data['ip_address']}" data-location="${data['location']}" data-secure="${data['secure']}" data-relayed="${data['relayed']}">
|
|
<span id="external_ip-${sk}" class="external-ip-tooltip" data-toggle="tooltip" title="Lookup External IP" style="display: none;"><i class="fa fa-map-marker"></i></span>
|
|
</a>
|
|
<script>
|
|
isPrivateIP("${data['ip_address']}").then(function () {
|
|
$("#external_ip-${sk}").hide();
|
|
}, function () {
|
|
$("#external_ip-${sk}").show();
|
|
});
|
|
</script>
|
|
% endif
|
|
% else:
|
|
N/A
|
|
% endif
|
|
</div>
|
|
</li>
|
|
<li class="dashboard-activity-info-item">
|
|
<div class="sub-heading">Bandwidth</div>
|
|
<div class="sub-value time-right">
|
|
% if data['media_type'] != 'photo' and data['bandwidth'] != 'Unknown':
|
|
<%
|
|
bw = cast_to_int(data['bandwidth'])
|
|
if bw > 1000000:
|
|
bw = str(round(bw / 1000000.0, 1)) + ' Gbps'
|
|
elif bw > 1000:
|
|
bw = str(round(bw / 1000.0, 1)) + ' Mbps'
|
|
else:
|
|
bw = str(bw) + ' kbps'
|
|
%>
|
|
<span id="stream-bandwidth-${sk}">${bw}</span>
|
|
<span id="streaming-brain-${sk}" data-toggle="tooltip" title="Streaming Brain Estimate (Reserved Bandwidth)"><i class="fa fa-info-circle"></i></span>
|
|
% elif data['synced_version'] == 1 or data['channel_stream'] == 1:
|
|
<span id="stream-bandwidth-${sk}">None</span>
|
|
% else:
|
|
<span id="stream-bandwidth-${sk}">Unknown</span>
|
|
% endif
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
% if data['media_type'] != 'photo':
|
|
<div class="dashboard-activity-info-time">
|
|
% if data['live']:
|
|
<br /><span class="thumb-tooltip dashboard-activity-info-channel" data-toggle="popover" data-img="${data['channel_thumb']}" data-height="40" data-width="40">${data['channel_title'] or (data['channel_vcn'] + ' ' + data['channel_call_sign'])}</span>
|
|
% elif data['view_offset']:
|
|
ETA:
|
|
<span id="stream-eta-${sk}">
|
|
<script>
|
|
$("#stream-eta-${sk}").html(moment().add(parseInt("${data['stream_duration']}") - parseInt("${data['view_offset']}"), 'milliseconds').format(time_format));
|
|
</script>
|
|
</span><br /><span class="progress_time_offset" id="stream-view-offset-${sk}" data-last_view_offset="${data['view_offset']}" data-view_offset="${data['view_offset']}" data-stream_duration="${data['stream_duration']}" data-state="${data['state']}">
|
|
<script>
|
|
$("#stream-view-offset-${sk}").html(millisecondsToMinutes(parseInt("${data['view_offset']}"), false));
|
|
</script>
|
|
</span> / <span class="progress_time_total" id="stream-duration-${sk}">
|
|
<script>
|
|
$("#stream-duration-${sk}").html(millisecondsToMinutes(parseInt("${data['stream_duration']}"), false));
|
|
</script>
|
|
</span>
|
|
% else:
|
|
ETA: Unknown<br />0:00 / <span class="progress_time_total" id="stream-duration-${sk}">
|
|
<script>
|
|
$("#stream-duration-${sk}").html(millisecondsToMinutes(parseInt("${data['stream_duration']}"), false));
|
|
</script>
|
|
</span>
|
|
% endif
|
|
</div>
|
|
% endif
|
|
</div>
|
|
</div>
|
|
<div class="dashboard-activity-progress">
|
|
<div class="dashboard-activity-progress-bar">
|
|
% if data['live']:
|
|
<div id="progress-bar-${sk}" class="progress-bar" style="width: 100%" data-state="live" data-toggle="tooltip" title="Stream Progress Live">Live</div>
|
|
% else:
|
|
<% transcode_progress = get_percent(data['transcode_max_offset_available'] * 1000, data['duration']) or data['transcode_progress'] %>
|
|
<div id="buffer-bar-${sk}" class="buffer-bar" style="width: ${transcode_progress}%" data-toggle="tooltip" title="Transcoder Progress ${transcode_progress}%">${transcode_progress}%</div>
|
|
<div id="progress-bar-${sk}" class="progress-bar" style="width: ${data['progress_percent']}%" data-last_view_offset="${data['view_offset']}" data-view_offset="${data['view_offset']}" data-stream_duration="${data['stream_duration']}" data-state="${data['state']}" data-toggle="tooltip" title="Stream Progress ${data['progress_percent']}%">${data['progress_percent']}%</div>
|
|
% endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="dashboard-activity-metadata-wrapper">
|
|
<a href="${user_href}" title="${data['username']}">
|
|
<div class="dashboard-activity-metadata-user-thumb" style="background-image: url(${page('pms_image_proxy', data['user_thumb'], None, 80, 80, fallback='user')});"></div>
|
|
</a>
|
|
<div class="dashboard-activity-metadata-title-container">
|
|
<div id="play-state-${sk}" class="dashboard-activity-metadata-play_state-icon" title="${data['state'].capitalize()}">
|
|
% if data['state'] == 'playing':
|
|
<i class="fa fa-fw fa-play"></i>
|
|
% elif data['state'] == 'paused':
|
|
<i class="fa fa-fw fa-pause"></i>
|
|
% elif data['state'] == 'buffering':
|
|
<i class="fa fa-fw fa-spinner"></i>
|
|
% elif data['state'] == 'error':
|
|
<i class="fa fa-fw fa-exclamation-triangle"></i>
|
|
% else:
|
|
<i class="fa fa-fw fa-question-circle"></i>
|
|
% endif
|
|
</div>
|
|
<div class="dashboard-activity-metadata-title">
|
|
% if data['live']:
|
|
% if data['media_type'] == 'movie':
|
|
<a href="${href}" title="${data['title']}">${data['title']}</a>
|
|
% elif data['media_type'] == 'episode':
|
|
<a href="${href}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
|
- <a href="${href}" title="${data['title']}">${data['title']}</a>
|
|
% else:
|
|
<span title="${data['title']}">${data['title']}</span>
|
|
% endif
|
|
% elif data['channel_stream'] == 0:
|
|
% if data['media_type'] == 'movie':
|
|
<a href="${href}" title="${data['title']}">${data['title']}</a>
|
|
% elif data['media_type'] == 'episode':
|
|
<a href="${grandparent_href}" title="${data['grandparent_title']}">${data['grandparent_title']}</a>
|
|
- <a href="${href}" title="${data['title']}">${data['title']}</a>
|
|
% elif data['media_type'] == 'track':
|
|
<a id="metadata-title-${sk}" href="${href}" title="${data['title']}">${data['title']}</a>
|
|
- <a id="metadata-grandparent_title-${sk}" href="${grandparent_href}" title="${data['original_title'] or data['grandparent_title']}">${data['original_title'] or data['grandparent_title']}</a>
|
|
% elif data['media_type'] == 'photo':
|
|
<span title="${data['parent_title']}">${data['parent_title']}</span>
|
|
% elif data['media_type'] == 'clip':
|
|
<span title="${data['title']}">${data['title']}</span>
|
|
% else:
|
|
<span title="${data['title']}">${data['title']}</span>
|
|
% endif
|
|
% elif data['media_type'] == 'episode' and data['grandparent_title']:
|
|
<span title="${data['grandparent_title']}">${data['grandparent_title']}</span>
|
|
- <span title="${data['title']}">${data['title']}</span>
|
|
% else:
|
|
<span title="${data['title']}">${data['title']}</span>
|
|
% endif
|
|
</div>
|
|
</div>
|
|
<div class="dashboard-activity-metadata-subtitle-container">
|
|
% if data['live']:
|
|
<div id="media-type-${sk}" class="dashboard-activity-metadata-media_type-icon" title="Live TV">
|
|
<i class="fa fa-fw fa-broadcast-tower"></i>
|
|
</div>
|
|
% elif data['channel_stream'] == 0:
|
|
<div id="media-type-${sk}" class="dashboard-activity-metadata-media_type-icon" title="${data['media_type'].capitalize()}">
|
|
% if data['media_type'] == 'movie':
|
|
<i class="fa fa-fw fa-film"></i>
|
|
% elif data['media_type'] == 'episode':
|
|
<i class="fa fa-fw fa-television"></i>
|
|
% elif data['media_type'] == 'track':
|
|
<i class="fa fa-fw fa-music"></i>
|
|
% elif data['media_type'] == 'photo':
|
|
<i class="fa fa-fw fa-picture-o"></i>
|
|
% elif data['media_type'] == 'clip':
|
|
<i class="fa fa-fw fa-video-camera"></i>
|
|
% endif
|
|
</div>
|
|
% else:
|
|
<div id="media-type-${sk}" class="dashboard-activity-metadata-media_type-icon" title="Channel">
|
|
<i class="fa fa-fw fa-cloud"></i>
|
|
</div>
|
|
% endif
|
|
<div class="dashboard-activity-metadata-subtitle">
|
|
% if data['live']:
|
|
% if data['media_type'] == 'movie':
|
|
<span title="${data['year']}" class="sub-heading">${data['year']}</span>
|
|
% elif data['media_type'] == 'episode':
|
|
% if data['media_index']:
|
|
<a href="${href}" title="${data['parent_title']}" class="sub-heading">${season}</a>
|
|
· <a href="${href}" title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</a>
|
|
% else:
|
|
<a href="${href}" title="${data['originally_available_at']}" class="sub-heading">${data['originally_available_at']}</a>
|
|
% endif
|
|
% else:
|
|
<span title="Live TV" class="sub-heading">Live TV</span>
|
|
% endif
|
|
% elif data['channel_stream'] == 0:
|
|
% if data['media_type'] == 'movie':
|
|
<span title="${data['year']}" class="sub-heading">${data['year']}</span>
|
|
% elif data['media_type'] == 'episode':
|
|
<a href="${parent_href}" title="${data['parent_title']}" class="sub-heading">${season}</a>
|
|
· <a href="${href}" title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</a>
|
|
% elif data['media_type'] == 'track':
|
|
<a id="metadata-parent_title-${sk}" href="${parent_href}" title="${data['parent_title']}" class="sub-heading">${data['parent_title']}</a>
|
|
% elif data['media_type'] == 'photo':
|
|
<span title="${data['title']}" class="sub-heading">${data['title']}</span>
|
|
% else:
|
|
% if data['extra_type']:
|
|
<% extra_type = EXTRA_TYPES.get(data['extra_type'], data['sub_type'].capitalize()) %>
|
|
<span title="${data['year']} (${extra_type})" class="sub-heading">${data['year']} (${extra_type})</span>
|
|
% else:
|
|
<span title="${data['year']}" class="sub-heading">${data['year']}</span>
|
|
% endif
|
|
% endif
|
|
% elif data['channel_title']:
|
|
<span title="${data['channel_title']}" class="sub-heading">${data['channel_title']}</span>
|
|
% if data['media_type'] == 'episode' and data['parent_media_index'] and data['media_index']:
|
|
(<span title="${data['parent_title']}" class="sub-heading">${season}</span>
|
|
· <span title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</span>)
|
|
% elif data['media_type'] == 'episode' and data['originally_available_at']:
|
|
(<span title="${data['originally_available_at']}" class="sub-heading">${data['originally_available_at']}</span>)
|
|
% endif
|
|
% else:
|
|
<span title="Channel" class="sub-heading">Channel</span>
|
|
% if data['media_type'] == 'episode' and data['parent_media_index'] and data['media_index']:
|
|
(<span title="${data['parent_title']}" class="sub-heading">${season}</span>
|
|
· <span title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</span>)
|
|
% elif data['media_type'] == 'episode' and data['originally_available_at']:
|
|
(<span title="${data['originally_available_at']}" class="sub-heading">${data['originally_available_at']}</span>)
|
|
% endif
|
|
% endif
|
|
</div>
|
|
<div class="dashboard-activity-metadata-user">
|
|
<a href="${user_href}" title="${data['username']}">${data['friendly_name']}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
% endif
|