initial commit

This commit is contained in:
herby2212 2023-01-03 06:15:00 +01:00
commit f0e91b7538
19 changed files with 101 additions and 25 deletions

View file

@ -10,14 +10,15 @@ Variable names: data {dict}
data :: Usable parameters data :: Usable parameters
== Global keys == == Global keys ==
session_key Returns a unique session id for the active stream session_key Returns a unique session id for the active stream.
rating_key Returns the unique identifier for the media item. rating_key Returns the unique identifier for the media item.
media_index Returns the index of the media item. media_index Returns the index of the media item.
parent_media_index Returns the index of the media item's parent. parent_media_index Returns the index of the media item's parent.
media_type Returns the type of session. Either 'track', 'episode' or 'movie'. 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. 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. 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 art Returns the location of the item's artwork.
originally_available_at Returns the air date of the item.
progress_percent Returns the current progress of the item. 0 to 100. progress_percent Returns the current progress of the item. 0 to 100.
user Returns the name of the user owning the session. user Returns the name of the user owning the session.
user_id Returns the Plex user id if available. user_id Returns the Plex user id if available.
@ -62,7 +63,7 @@ DOCUMENTATION :: END
% if session is not None: % if session is not None:
<% <%
from collections import defaultdict from collections import defaultdict
from plexpy.helpers import cast_to_int, get_percent, page, short_season from plexpy.helpers import cast_to_int, get_percent, page, short_season, format_date_based_show
from plexpy.common import VIDEO_RESOLUTION_OVERRIDES, AUDIO_CODEC_OVERRIDES, EXTRA_TYPES from plexpy.common import VIDEO_RESOLUTION_OVERRIDES, AUDIO_CODEC_OVERRIDES, EXTRA_TYPES
import plexpy import plexpy
%> %>
@ -76,6 +77,12 @@ DOCUMENTATION :: END
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'])
%> %>
% if not data['media_index']:
<%
data['originally_available_at'] = format_date_based_show(data['originally_available_at'])
%>
% endif
<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-parent_rating_key="${data['parent_rating_key']}" data-grandparent_rating_key="${data['grandparent_rating_key']}"
data-guid="${data['guid']}"> data-guid="${data['guid']}">
@ -499,8 +506,12 @@ DOCUMENTATION :: END
% if data['media_type'] == 'movie': % if data['media_type'] == 'movie':
<span title="${data['year']}" class="sub-heading">${data['year']}</span> <span title="${data['year']}" class="sub-heading">${data['year']}</span>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
% if data['media_index']:
<a href="${parent_href}" title="${data['parent_title']}" class="sub-heading">${season}</a> <a href="${parent_href}" title="${data['parent_title']}" class="sub-heading">${season}</a>
&middot; <a href="${href}" title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</a> &middot; <a href="${href}" title="Episode ${data['media_index']}" class="sub-heading">E${data['media_index']}</a>
% else:
<a href="${href}" title="Episode ${data['originally_available_at']}" class="sub-heading">E${data['originally_available_at']}</a>
% endif
% elif data['media_type'] == 'track': % 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> <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': % elif data['media_type'] == 'photo':

View file

@ -41,7 +41,7 @@ DOCUMENTATION :: END
from plexpy import notifiers from plexpy import notifiers
from plexpy.common import MEDIA_TYPE_HEADERS, MEDIA_FLAGS_AUDIO, MEDIA_FLAGS_VIDEO from plexpy.common import MEDIA_TYPE_HEADERS, MEDIA_FLAGS_AUDIO, MEDIA_FLAGS_VIDEO
from plexpy.helpers import page, get_percent, cast_to_int, short_season from plexpy.helpers import page, get_percent, cast_to_int, short_season, format_date_based_show
# Get audio codec file # Get audio codec file
def af(codec): def af(codec):
@ -81,9 +81,14 @@ DOCUMENTATION :: END
<% <%
data = defaultdict(lambda: None, **metadata) data = defaultdict(lambda: None, **metadata)
media_info = defaultdict(lambda: None, **(data['media_info'][0] if data['media_info'] else {})) media_info = defaultdict(lambda: None, **(data['media_info'][0] if data['media_info'] else {}))
episode = ''
season = '' season = ''
if data['media_type'] == 'episode': if data['media_type'] == 'episode':
season = short_season(data['parent_title']) season = short_season(data['parent_title'])
if data['media_index']:
episode = data['media_index']
else:
episode = format_date_based_show(data['originally_available_at'])
elif data['media_type'] == 'season': elif data['media_type'] == 'season':
season = short_season(data['title']) season = short_season(data['title'])
%> %>
@ -138,7 +143,7 @@ DOCUMENTATION :: END
<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'])}">${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 ${episode} - ${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'])}">${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>
@ -250,7 +255,10 @@ DOCUMENTATION :: END
<h1>${data['grandparent_title']}</h1> <h1>${data['grandparent_title']}</h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
% if data['media_index']: % if data['media_index']:
<h3 class="hidden-xs">${season} &middot; E${data['media_index']}</h3> <h3 class="hidden-xs">${season} &middot; E${episode}</h3>
% else:
<h3 class="hidden-xs">E${episode}</h3>
% endif
% endif % endif
% endif % endif
% elif data['media_type'] in ('movie', 'show', 'artist', 'collection', 'playlist', 'photo_album'): % elif data['media_type'] in ('movie', 'show', 'artist', 'collection', 'playlist', 'photo_album'):
@ -261,7 +269,11 @@ DOCUMENTATION :: END
% 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'])}">${data['grandparent_title']}</a></h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
<h3 class="hidden-xs">${season} &middot; E${data['media_index']}</h3> % if data['media_index']:
<h3 class="hidden-xs">${season} &middot; E${episode}</h3>
% else:
<h3 class="hidden-xs">E${episode}</h3>
% endif
% 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'])}">${data['parent_title']}</a></h1>
<h2>${data['title']}</h2> <h2>${data['title']}</h2>
@ -754,9 +766,14 @@ DOCUMENTATION :: END
% if metadata: % if metadata:
<% <%
data = defaultdict(None, **metadata) data = defaultdict(None, **metadata)
episode = ''
season = '' season = ''
if data['media_type'] == 'episode': if data['media_type'] == 'episode':
season = short_season(data['parent_title']) season = short_season(data['parent_title'])
if data['media_index']:
episode = data['media_index']
else:
episode = format_date_based_show(data['originally_available_at'])
elif data['media_type'] == 'season': elif data['media_type'] == 'season':
season = short_season(data['title']) season = short_season(data['title'])
%> %>
@ -800,7 +817,7 @@ DOCUMENTATION :: END
% elif data['media_type'] == 'season': % elif data['media_type'] == 'season':
${data['parent_title']}<br />${data['title']} ${data['parent_title']}<br />${data['title']}
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
${data['grandparent_title']}<br />${data['title']}<br />${season} &middot; E${data['media_index']} ${data['grandparent_title']}<br />${data['title']}<br />${season} &middot; E${episode}
% elif data['media_type'] == 'artist': % elif data['media_type'] == 'artist':
${data['title']} ${data['title']}
% elif data['media_type'] == 'album': % elif data['media_type'] == 'album':

View file

@ -19,6 +19,7 @@ data['children_list'] :: Usable paramaters
== Global keys == == Global keys ==
rating_key Returns the unique identifier for the media item. rating_key Returns the unique identifier for the media item.
media_index Returns the episode number. media_index Returns the episode number.
originally_available_at Returns the air date of the item.
title Returns the name of the episode. title Returns the name of the episode.
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
parent_thumb Returns the location of the item's parent thumbnail. Use with pms_image_proxy. parent_thumb Returns the location of the item's parent thumbnail. Use with pms_image_proxy.
@ -28,7 +29,7 @@ DOCUMENTATION :: END
% if data != None: % if data != None:
<% <%
from plexpy.helpers import cast_to_int, page, short_season from plexpy.helpers import cast_to_int, page, short_season, format_date_based_show
%> %>
% if data['children_count'] > 0: % if data['children_count'] > 0:
<div class="item-children-wrapper"> <div class="item-children-wrapper">
@ -166,7 +167,7 @@ DOCUMENTATION :: END
<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')});">
<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 format_date_based_show(child['originally_available_at'])}
</div> </div>
</div> </div>
</div> </div>

View file

@ -853,6 +853,10 @@ function short_season(title) {
return title return title
} }
function format_date_based_show(date) {
return String(date).replaceAll('-', '\u00B7')
}
function loadAllBlurHash() { function loadAllBlurHash() {
$('[data-blurhash]').each(function() { $('[data-blurhash]').each(function() {
const elem = $(this); const elem = $(this);

View file

@ -179,9 +179,11 @@ history_table_options = {
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) + '" 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'], history, 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'], history, rowData['live']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'episode') { } else if (rowData['media_type'] === 'episode') {
rowData['originally_available_at'] = format_date_based_show(rowData['originally_available_at']);
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 (isNaN(parseInt(rowData['media_index'])) && rowData['originally_available_at']) { parent_info = ' (' + rowData['originally_available_at'] + ')'; }
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) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>';

View file

@ -112,9 +112,11 @@ history_table_modal_options = {
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) + '" 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']) + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'episode') { } else if (rowData['media_type'] === 'episode') {
rowData['originally_available_at'] = format_date_based_show(rowData['originally_available_at']);
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 (isNaN(parseInt(rowData['media_index'])) && rowData['originally_available_at']) { parent_info = ' (' + rowData['originally_available_at'] + ')'; }
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) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>';

View file

@ -94,7 +94,9 @@ media_info_table_options = {
$(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key']) + '"><div style="float: left; padding-left: 15px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key']) + '"><div style="float: left; padding-left: 15px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'episode') { } else if (rowData['media_type'] === 'episode') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span>'; media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 500, 280, null, null, null, 'art') + '" data-height="80" data-width="140">E' + rowData['media_index'] + ' - ' + rowData['title'] + '</span>'; thumb_popover = (rowData['media_index']) ?
'<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 500, 280, null, null, null, 'art') + '" data-height="80" data-width="140">E' + rowData['media_index'] + ' - ' + rowData['title'] + '</span>'
: '<span class="thumb-tooltip" data-toggle="popover" data-img="' + page('pms_image_proxy', rowData['thumb'], rowData['rating_key'], 500, 280, null, null, null, 'art') + '" data-height="80" data-width="140">E' + format_date_based_show(rowData['originally_available_at']) + ' - ' + rowData['title'] + '</span>';
$(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key']) + '"><div style="float: left; padding-left: 30px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="' + page('info', rowData['rating_key']) + '"><div style="float: left; padding-left: 30px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'artist') { } else if (rowData['media_type'] === 'artist') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Artist"><i class="fa fa-music fa-fw"></i></span>'; media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Artist"><i class="fa fa-music fa-fw"></i></span>';

View file

@ -211,7 +211,9 @@ users_list_table_options = {
} 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';
rowData['originally_available_at'] = format_date_based_show(rowData['originally_available_at']);
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 (isNaN(parseInt(rowData['media_index'])) && rowData['originally_available_at']) { parent_info = ' (' + rowData['originally_available_at'] + ')'; }
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) + '" data-height="120" data-width="80">' + cellData + parent_info + '</span>';

View file

@ -19,6 +19,7 @@ parent_title Returns the name of the artist.
grandparent_title Returns the name of the show. grandparent_title Returns the name of the show.
media_index Returns the index number of the episode. media_index Returns the index number of the episode.
parent_media_index Returns the index number of the season. parent_media_index Returns the index number of the season.
originally_available_at Returns the air date of the media item.
section_id Returns the library section number of the media item. section_id Returns the library section number of the media item.
library_name Returns the library section name of the media item. library_name Returns the library section name of the media item.
year Returns the release year of the movie, episode, or album. year Returns the release year of the movie, episode, or album.
@ -32,7 +33,7 @@ DOCUMENTATION :: END
% if data: % if data:
<% <%
from plexpy.helpers import page, short_season from plexpy.helpers import page, short_season, format_date_based_show
%> %>
<div class="dashboard-recent-media-row"> <div class="dashboard-recent-media-row">
@ -78,8 +79,12 @@ DOCUMENTATION :: END
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
% if item['media_index']:
<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'])}" 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'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
% else:
<a href="${page('info', item['rating_key'])}" title="Episode ${format_date_based_show(item['originally_available_at'])}">E${format_date_based_show(item['originally_available_at'])}</a>
% endif
</h3> </h3>
% elif item['media_type'] == 'movie': % elif item['media_type'] == 'movie':
<h3> <h3>

View file

@ -19,6 +19,7 @@ parent_title Returns the name of the artist.
grandparent_title Returns the name of the show. grandparent_title Returns the name of the show.
media_index Returns the index number of the episode. media_index Returns the index number of the episode.
parent_media_index Returns the index number of the season. parent_media_index Returns the index number of the season.
originally_available_at Returns the air date of the media item.
section_id Returns the library section number of the media item. section_id Returns the library section number of the media item.
library_name Returns the library section name of the media item. library_name Returns the library section name of the media item.
year Returns the release year of the movie, episode, or album. year Returns the release year of the movie, episode, or album.
@ -32,7 +33,7 @@ DOCUMENTATION :: END
% if data != None: % if data != None:
<% <%
from plexpy.helpers import cast_to_int, page, short_season from plexpy.helpers import cast_to_int, page, short_season, format_date_based_show
%> %>
% if data: % if data:
<div class="dashboard-recent-media-row"> <div class="dashboard-recent-media-row">
@ -146,9 +147,14 @@ DOCUMENTATION :: END
<a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a> <a href="${page('info', item['rating_key'])}" title="${item['title']}">${item['title']}</a>
</h3> </h3>
<h3 class="text-muted"> <h3 class="text-muted">
% if item['media_index']:
<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'])}" 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'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
% else:
<a href="${page('info', item['rating_key'])}" title="Episode ${format_date_based_show(item['originally_available_at'])}">
E${format_date_based_show(item['originally_available_at'])}</a>
% endif
</h3> </h3>
</div> </div>
% elif item['media_type'] == 'album': % elif item['media_type'] == 'album':

View file

@ -21,6 +21,7 @@ parent_title Returns the name of the artist.
grandparent_title Returns the name of the show. grandparent_title Returns the name of the show.
media_index Returns the index number of the episode. media_index Returns the index number of the episode.
parent_media_index Returns the index number of the season. parent_media_index Returns the index number of the season.
originally_available_at Returns the air date of the media item.
year Returns the release year of the movie, episode, or album. year Returns the release year of the movie, episode, or album.
DOCUMENTATION :: END DOCUMENTATION :: END
@ -28,7 +29,7 @@ DOCUMENTATION :: END
% if data: % if data:
<% <%
from plexpy.helpers import page, short_season from plexpy.helpers import page, short_season, format_date_based_show
%> %>
<div class="dashboard-recent-media-row"> <div class="dashboard-recent-media-row">
<div id="recently-watched-row-scroller" style="left: 0;"> <div id="recently-watched-row-scroller" style="left: 0;">
@ -59,6 +60,9 @@ DOCUMENTATION :: END
</a> </a>
<div class="dashboard-recent-media-metacontainer"> <div class="dashboard-recent-media-metacontainer">
% if item['media_type'] == 'episode': % if item['media_type'] == 'episode':
% if not item['media_index']:
item['originally_available_at'] = format_date_based_show(item['originally_available_at'])
% endif
% 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'])}" title="${item['grandparent_title']}">${item['grandparent_title']}</a>
@ -68,8 +72,12 @@ DOCUMENTATION :: END
</h3> </h3>
% if item['media_index']: % if item['media_index']:
<h3 class="text-muted"> <h3 class="text-muted">
% if item['media_index']:
<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'])}" 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'])}" title="Episode ${item['media_index']}">E${item['media_index']}</a>
% else:
<a href="${page('info', item['rating_key'], history=True, live=item['live'])}" title="Episode ${item['originally_available_at']}">E${item['originally_available_at']}</a>
% endif
</h3> </h3>
% else: % else:
<h3 class="text-muted"> <h3 class="text-muted">

View file

@ -1,7 +1,7 @@
% if data: % if data:
<% <%
import plexpy import plexpy
from plexpy.helpers import grouper, get_img_service from plexpy.helpers import grouper, get_img_service, format_date_based_show
recently_added = data['recently_added'] recently_added = data['recently_added']
if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.HTTP_BASE_URL: if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.HTTP_BASE_URL:
@ -755,8 +755,11 @@
<p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;color: #ffffff;"> <p class="nowrap mb5" style="font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-weight: 400;margin: 0;margin-bottom: 5px;white-space: nowrap;text-overflow: ellipsis;overflow: hidden;max-width: 325px;color: #ffffff;">
% for i, season in enumerate(show['season'][:8]): % for i, season in enumerate(show['season'][:8]):
% if season['episode_count'] == 1: % if season['episode_count'] == 1:
% if season['episode'][0]['media_index']:
${season['title']} &middot; Episode ${season['episode'][0]['media_index']} - ${season['episode'][0]['title']} ${season['title']} &middot; Episode ${season['episode'][0]['media_index']} - ${season['episode'][0]['title']}
% else: % else:
${season['title']} &middot; Episode ${format_date_based_show(season['episode'][0]['originally_available_at'])}
- ${season['episode'][0]['title']}
${season['title']} &middot; Episodes ${season['episode_range']} ${season['title']} &middot; Episodes ${season['episode_range']}
% endif % endif
% if i < min(show['season_count'], 7): % if i < min(show['season_count'], 7):

View file

@ -508,6 +508,7 @@ NOTIFICATION_PARAMETERS = [
{'name': 'Season Number', 'type': 'int', 'value': 'season_num', 'description': 'The season number.', 'example': 'e.g. 1, or 1-3'}, {'name': 'Season Number', 'type': 'int', 'value': 'season_num', 'description': 'The season number.', 'example': 'e.g. 1, or 1-3'},
{'name': 'Season Number 00', 'type': 'int', 'value': 'season_num00', 'description': 'The two digit season number.', 'example': 'e.g. 01, or 01-03'}, {'name': 'Season Number 00', 'type': 'int', 'value': 'season_num00', 'description': 'The two digit season number.', 'example': 'e.g. 01, or 01-03'},
{'name': 'Episode Number', 'type': 'int', 'value': 'episode_num', 'description': 'The episode number.', 'example': 'e.g. 6, or 6-10'}, {'name': 'Episode Number', 'type': 'int', 'value': 'episode_num', 'description': 'The episode number.', 'example': 'e.g. 6, or 6-10'},
{'name': 'Episode Number', 'type': 'str', 'value': 'episode_date', 'description': 'The episode number of date based tv shows (in date format).'},
{'name': 'Episode Number 00', 'type': 'int', 'value': 'episode_num00', 'description': 'The two digit episode number.', 'example': 'e.g. 06, or 06-10'}, {'name': 'Episode Number 00', 'type': 'int', 'value': 'episode_num00', 'description': 'The two digit episode number.', 'example': 'e.g. 06, or 06-10'},
{'name': 'Disc Number', 'type': 'int', 'value': 'disc_num', 'description': 'The disc number.', 'example': 'e.g. 2'}, {'name': 'Disc Number', 'type': 'int', 'value': 'disc_num', 'description': 'The disc number.', 'example': 'e.g. 2'},
{'name': 'Disc Number 00', 'type': 'int', 'value': 'disc_num00', 'description': 'The two digit disc number.', 'example': 'e.g. 02'}, {'name': 'Disc Number 00', 'type': 'int', 'value': 'disc_num00', 'description': 'The two digit disc number.', 'example': 'e.g. 02'},

View file

@ -31,6 +31,7 @@ from collections import OrderedDict
import datetime import datetime
from functools import reduce, wraps from functools import reduce, wraps
import hashlib import hashlib
import html
import imghdr import imghdr
from future.moves.itertools import islice, zip_longest from future.moves.itertools import islice, zip_longest
import ipwhois import ipwhois
@ -418,6 +419,8 @@ def clean_filename(filename, replace='_'):
cleaned_filename = ''.join(c if c in whitelist else replace for c in cleaned_filename) cleaned_filename = ''.join(c if c in whitelist else replace for c in cleaned_filename)
return cleaned_filename return cleaned_filename
def format_date_based_show(date):
return str(date).replace('-', html.unescape('&middot;'))
def split_strip(s, delimiter=','): def split_strip(s, delimiter=','):
return [x.strip() for x in str(s).split(delimiter) if x.strip()] return [x.strip() for x in str(s).split(delimiter) if x.strip()]

View file

@ -539,6 +539,7 @@ 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 {}
# TODO: Auto trigger for update - needs to be triggered to get date based episode support
if refresh or not rows: if refresh or not rows:
pms_connect = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
@ -577,6 +578,7 @@ class Libraries(object):
'year': item['year'], 'year': item['year'],
'media_index': item['media_index'], 'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'], 'parent_media_index': item['parent_media_index'],
'originally_available_at': item['originally_available_at'],
'thumb': item['thumb'], 'thumb': item['thumb'],
'container': item.get('container', ''), 'container': item.get('container', ''),
'bitrate': item.get('bitrate', ''), 'bitrate': item.get('bitrate', ''),

View file

@ -766,6 +766,8 @@ class RecentlyAdded(Newsletter):
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)
#TODO How do we want to display the episode range in the newsletter
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,

View file

@ -912,8 +912,11 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
track_name = notify_params['title'] track_name = notify_params['title']
season_num = str(notify_params['parent_media_index']).zfill(1) season_num = str(notify_params['parent_media_index']).zfill(1)
season_num00 = str(notify_params['parent_media_index']).zfill(2) season_num00 = str(notify_params['parent_media_index']).zfill(2)
if notify_params['media_index']:
episode_num = str(notify_params['media_index']).zfill(1) episode_num = str(notify_params['media_index']).zfill(1)
episode_num00 = str(notify_params['media_index']).zfill(2) episode_num00 = str(notify_params['media_index']).zfill(2)
else:
episode_num = episode_num00 = helpers.format_date_based_show(notify_params['originally_available_at'])
disc_num = str(notify_params['parent_media_index']).zfill(1) disc_num = str(notify_params['parent_media_index']).zfill(1)
disc_num00 = str(notify_params['parent_media_index']).zfill(2) disc_num00 = str(notify_params['parent_media_index']).zfill(2)
track_num = str(notify_params['media_index']).zfill(1) track_num = str(notify_params['media_index']).zfill(1)

View file

@ -2821,6 +2821,7 @@ class PmsConnect(object):
'sort_title': helpers.get_xml_attr(item, 'titleSort'), 'sort_title': helpers.get_xml_attr(item, 'titleSort'),
'media_index': helpers.get_xml_attr(item, 'index'), 'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'originally_available_at': helpers.get_xml_attr(item, 'originallyAvailableAt'),
'year': helpers.get_xml_attr(item, 'year'), 'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'), 'thumb': helpers.get_xml_attr(item, 'thumb'),
'parent_thumb': helpers.get_xml_attr(item, 'thumb'), 'parent_thumb': helpers.get_xml_attr(item, 'thumb'),

View file

@ -792,6 +792,7 @@ class WebInterface(object):
"media_type": "show", "media_type": "show",
"parent_media_index": "", "parent_media_index": "",
"parent_rating_key": "", "parent_rating_key": "",
"originally_available_at": "2011-08-21",
"play_count": 15, "play_count": 15,
"rating_key": "1219", "rating_key": "1219",
"section_id": 2, "section_id": 2,