mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-16 02:02:58 -07:00
Add individual library page
This commit is contained in:
parent
979d68957e
commit
5fedac691d
13 changed files with 836 additions and 393 deletions
|
@ -504,9 +504,9 @@ textarea.form-control:focus {
|
|||
background-size: contain;
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
/*-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);*/
|
||||
}
|
||||
a .poster-face:hover,
|
||||
a .cover-face:hover,
|
||||
|
@ -1664,7 +1664,6 @@ a:hover .item-children-poster {
|
|||
}
|
||||
.user-player-instance-box {
|
||||
float: left;
|
||||
width: 75px;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
|
@ -1686,6 +1685,7 @@ a:hover .item-children-poster {
|
|||
font-weight: normal;
|
||||
width: 140px;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.user-player-instance-playcount h3 {
|
||||
font-size: 30px;
|
||||
|
@ -1705,6 +1705,35 @@ a:hover .item-children-poster {
|
|||
top: 15px;
|
||||
left: 0px;
|
||||
}
|
||||
.library-info-poster-face {
|
||||
float: left;
|
||||
margin-top: 15px;
|
||||
margin-right: 15px;
|
||||
background-size: contain;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
/*-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);*/
|
||||
}
|
||||
.library-user-instance-box {
|
||||
float: left;
|
||||
-webkit-border-radius: 50%;
|
||||
-moz-border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
-webkit-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
-moz-box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.3),inset 0 0 0 1px rgba(255,255,255,.1);
|
||||
background-size: contain;
|
||||
position: relative;
|
||||
height: 80px;
|
||||
width: 80px;
|
||||
}
|
||||
.library-user-instance-box:hover {
|
||||
-webkit-box-shadow: inset 0 0 0 2px #e9a049;
|
||||
-moz-box-shadow: inset 0 0 0 2px #e9a049;
|
||||
box-shadow: inset 0 0 0 2px #e9a049;
|
||||
}
|
||||
.home-platforms {
|
||||
}
|
||||
.home-platforms ul {
|
||||
|
|
171
data/interfaces/default/edit_library.html
Normal file
171
data/interfaces/default/edit_library.html
Normal file
|
@ -0,0 +1,171 @@
|
|||
<%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: edit_library.html
|
||||
Version: 0.1
|
||||
Variable names: data [list]
|
||||
|
||||
data :: Usable parameters
|
||||
|
||||
== Global keys ==
|
||||
section_id Returns the library id of the library.
|
||||
section_name Returns the name of the library.
|
||||
section_type Returns the type of the library.
|
||||
library_thumb Returns the thumbnail for the library.
|
||||
count Returns the item count for the library.
|
||||
parent_count Returns the parent item count for the library.
|
||||
child_count Returns the child item count for the library.
|
||||
do_notify Returns bool value for whether to send notifications for the library.
|
||||
keep_history Returns bool value for whether to keep history for the library.
|
||||
|
||||
DOCUMENTATION :: END
|
||||
</%doc>
|
||||
|
||||
<%!
|
||||
from plexpy import helpers
|
||||
%>
|
||||
|
||||
% if data != None:
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title">Edit library <strong>${data['section_name']}</strong></h4>
|
||||
</div>
|
||||
<div class="modal-body" id="modal-text">
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label for="profile_url">Library Picture URL</label>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
% if data['custom_thumb']:
|
||||
<input type="text" class="form-control" id="custom_thumb_url" name="custom_thumb_url" value="${data['custom_thumb']}">
|
||||
% else:
|
||||
<input type="text" class="form-control" id="custom_thumb_url" name="custom_thumb_url" value="${data['library_thumb']}">
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block">Change the library's picture in PlexPy. To reset to default, leave this field empty and save.</p>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="do_notify" name="do_notify" value="1" ${helpers.checked(data['do_notify'])}> Enable notifications
|
||||
</label>
|
||||
<p class="help-block">Uncheck this if you do not want to receive notifications for this library's activity.</p>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" id="keep_history" name="keep_history" value="1" ${helpers.checked(data['keep_history'])}> Keep history
|
||||
</label>
|
||||
<p class="help-block">Uncheck this if you do not want this keep any history on this library's activity.</p>
|
||||
</div>
|
||||
% if data['section_id']:
|
||||
<div class="form-group">
|
||||
<button class="btn btn-danger" id="delete-all-history">Purge</button>
|
||||
<p class="help-block">DANGER ZONE! Click the purge button to remove all history logged for this library. This is permanent!</p>
|
||||
</div>
|
||||
% endif
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div>
|
||||
<span id="edit-library-status-message"></span>
|
||||
<input type="button" id="save_library" class="btn btn-bright" value="Save">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="confirm-modal-purge" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="confirm-modal-purge">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Purge</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to purge all history for this library?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-purge">Purge</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Set new friendly name
|
||||
$("#save_library").click(function () {
|
||||
var custom_thumb = $("#custom_thumb_url").val();
|
||||
var do_notify = 0;
|
||||
var keep_history = 0;
|
||||
if ($("#do_notify").is(":checked")) {
|
||||
do_notify = 1;
|
||||
}
|
||||
if ($("#keep_history").is(":checked")) {
|
||||
keep_history = 1;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: 'edit_library',
|
||||
data: {
|
||||
section_id: '${data["section_id"]}',
|
||||
do_notify: do_notify,
|
||||
keep_history: keep_history,
|
||||
custom_thumb: custom_thumb
|
||||
},
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#delete-all-history").on('click', function() {
|
||||
$('#confirm-modal-purge').modal();
|
||||
$('#confirm-modal-purge').one('click', '#confirm-purge', function () {
|
||||
$.ajax({
|
||||
url: 'delete_all_library_history',
|
||||
data: { section_id: '${data["section_id"]}' },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function(data) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
// Move #confirm-modal to parent container
|
||||
if (!($('#edit-library-modal').next().is('#confirm-modal-purge'))) {
|
||||
$('#confirm-modal-purge').appendTo($('#edit-library-modal').parent());
|
||||
}
|
||||
$('#edit-library-modal > #confirm-modal-purge').remove();
|
||||
|
||||
$('#edit-library-modal').css('z-index', '1050');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1049');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
|
||||
$('#confirm-modal-purge').on('show.bs.modal', function () {
|
||||
// Fix position to match parent modal
|
||||
var currentPadding = parseInt($('body').css('padding-right'));
|
||||
$(this).children('.modal-dialog').css('left', -currentPadding/2);
|
||||
$('#edit-library-modal').css('overflow-y', 'hidden');
|
||||
});
|
||||
$('#confirm-modal-purge').on('shown.bs.modal', function () {
|
||||
$(this).css('z-index', '1060');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').css('z-index', '1059');
|
||||
$('.modal-backdrop').not('.modal-backdrop-stack').addClass('modal-backdrop-stack');
|
||||
});
|
||||
$('#confirm-modal-purge').on('hidden.bs.modal', function () {
|
||||
$('body').addClass('modal-open');
|
||||
$('#edit-library-modal').css('overflow-y', 'auto');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
% endif
|
|
@ -53,32 +53,30 @@ DOCUMENTATION :: END
|
|||
<div class="col-md-12">
|
||||
<div class="summary-navbar-list">
|
||||
<ul class="list-unstyled breadcrumb">
|
||||
% if data['media_type'] == 'library':
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'movie':
|
||||
<li><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
% if data['media_type'] == 'movie':
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'show':
|
||||
<li><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'season':
|
||||
<li class="hidden-xs hidden-sm"><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||
<li class="active">Season ${data['media_index']}</li>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<li class="hidden-xs hidden-sm"><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
||||
<li><a href="info?rating_key=${data['parent_rating_key']}">Season ${data['parent_media_index']}</a></li>
|
||||
<li class="active">Episode ${data['media_index']} - ${data['title']}</li>
|
||||
% elif data['media_type'] == 'artist':
|
||||
<li><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'album':
|
||||
<li class="hidden-xs hidden-sm"><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'track':
|
||||
<li class="hidden-xs hidden-sm"><a href="info?library_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
|
||||
<li class="hidden-xs hidden-sm"><a href="info?rating_key=${data['grandparent_rating_key']}">${data['grandparent_title']}</a></li>
|
||||
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||
<li class="active">Track ${data['media_index']} - ${data['title']}</li>
|
||||
|
@ -87,13 +85,12 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% if data['media_type'] != 'library':
|
||||
<div class="summary-content-title-wrapper">
|
||||
<div class="col-md-9">
|
||||
<div class="summary-content-poster hidden-xs hidden-sm">
|
||||
% if data['media_type'] == 'track':
|
||||
<a href="http://app.plex.tv/web/app#!/server/${config['pms_identifier']}/details/%2Flibrary%2Fmetadata%2F${data['parent_rating_key']}" target="Plex/Web" title="View in Plex/Web">
|
||||
% elif data['media_type'] != 'library':
|
||||
% else:
|
||||
<a href="http://app.plex.tv/web/app#!/server/${config['pms_identifier']}/details/%2Flibrary%2Fmetadata%2F${data['rating_key']}" target="Plex/Web" title="View in Plex/Web">
|
||||
% endif
|
||||
% if data['media_type'] == 'episode':
|
||||
|
@ -108,7 +105,7 @@ DOCUMENTATION :: END
|
|||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
% elif data['media_type'] != 'library':
|
||||
% else:
|
||||
<div class="summary-poster-face" style="background-image: url(pms_image_proxy?img=${data['thumb']}&width=300&height=450&fallback=poster);">
|
||||
<div class="summary-poster-face-overlay">
|
||||
<span></span>
|
||||
|
@ -138,9 +135,7 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
<div class="summary-content-wrapper">
|
||||
% if data['media_type'] != 'library':
|
||||
<div class="col-md-9">
|
||||
% if data['media_type'] == 'movie' or data['media_type'] == 'show' or data['media_type'] == 'season':
|
||||
<div class="summary-content-padding hidden-xs hidden-sm" style="height: 275px;"></div>
|
||||
|
@ -292,8 +287,8 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
</div>
|
||||
% endif
|
||||
% endif
|
||||
<div class='col-md-12'>
|
||||
<!-- Need to find a place to put this -->
|
||||
% if data['media_type'] == 'library' and config['update_library_ids'] == 1:
|
||||
<div id="update_library_ids_mssage" style="text-align: center; margin-top: 20px;">
|
||||
<i class="fa fa-refresh fa-spin"></i> Updating library ids in the database. This could take a few minutes depending on the size of your database.
|
||||
|
@ -374,6 +369,7 @@ DOCUMENTATION :: END
|
|||
|
||||
% if data:
|
||||
<script src="interfaces/default/js/tables/history_table.js"></script>
|
||||
<!-- Need to find a place to put this -->
|
||||
% if data['media_type'] == 'library':
|
||||
<script>
|
||||
function get_history() {
|
||||
|
@ -499,13 +495,7 @@ DOCUMENTATION :: END
|
|||
});
|
||||
</script>
|
||||
% endif
|
||||
% if data['media_type'] != 'library':
|
||||
<script>
|
||||
$('#row-edit-mode').after('<a href="update_metadata?rating_key=${data['rating_key']}" class="btn btn-danger btn-edit" id="fix-metadata"> \
|
||||
<i class="fa fa-wrench"></i> Fix Metadata</a>');
|
||||
</script>
|
||||
% endif
|
||||
% if data['media_type'] != 'library' and data['rating']:
|
||||
% if data['rating']:
|
||||
<script>
|
||||
// Convert rating to 5 star rating type
|
||||
var starRating = Math.round(${data['rating']} / 2);
|
||||
|
@ -513,6 +503,8 @@ DOCUMENTATION :: END
|
|||
</script>
|
||||
% endif
|
||||
<script>
|
||||
$('#row-edit-mode').after('<a href="update_metadata?rating_key=${data['rating_key']}" class="btn btn-danger btn-edit" id="fix-metadata"> \
|
||||
<i class="fa fa-wrench"></i> Fix Metadata</a>');
|
||||
$("#airdate").html(moment($("#airdate").text()).format('MMM DD, YYYY'));
|
||||
$("#runtime").html(millisecondsToMinutes($("#runtime").text(), true));
|
||||
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
|
||||
|
|
|
@ -37,9 +37,13 @@ libraries_list_table_options = {
|
|||
"data": "library_thumb",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData === '') {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(interfaces/default/images/gravatar-default-80x80.png);"></div></a>');
|
||||
} else {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(pms_image_proxy?img=' + rowData['library_thumb'] + '&width=80&height=80&fallback=poster);"></div></a>');
|
||||
} else {
|
||||
if (rowData['custom_thumb']) {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(' + rowData['custom_thumb'] + ');"></div></a>');
|
||||
} else {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(pms_image_proxy?img=' + rowData['library_thumb'] + '&width=80&height=80&fallback=poster);"></div></a>');
|
||||
}
|
||||
}
|
||||
},
|
||||
"orderable": false,
|
||||
|
@ -213,6 +217,11 @@ $('#libraries_list_table').on('change', 'td.edit-control > .edit-library-toggles
|
|||
if ($('#keep_history-' + rowData['section_id']).is(':checked')) {
|
||||
keep_history = 1;
|
||||
}
|
||||
if (rowData['custom_thumb']) {
|
||||
custom_thumb = rowData['custom_thumb']
|
||||
} else {
|
||||
custom_thumb = rowData['library_thumb']
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: 'edit_library',
|
||||
|
@ -220,7 +229,7 @@ $('#libraries_list_table').on('change', 'td.edit-control > .edit-library-toggles
|
|||
section_id: rowData['section_id'],
|
||||
do_notify: do_notify,
|
||||
keep_history: keep_history,
|
||||
custom_thumb: rowData['library_thumb']
|
||||
custom_thumb: custom_thumb
|
||||
},
|
||||
cache: false,
|
||||
async: true,
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
for (var i = 0; i < libraries_to_purge.length; i++) {
|
||||
$.ajax({
|
||||
url: 'delete_all_library_history',
|
||||
data: { library_id: libraries_to_purge[i] },
|
||||
data: { section_id: libraries_to_purge[i] },
|
||||
cache: false,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
|
|
365
data/interfaces/default/library.html
Normal file
365
data/interfaces/default/library.html
Normal file
|
@ -0,0 +1,365 @@
|
|||
<%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: library.html
|
||||
Version: 0.1
|
||||
Variable names: data [list]
|
||||
|
||||
data :: Usable parameters
|
||||
|
||||
section_id Returns the library id of the library.
|
||||
section_name Returns the name of the library.
|
||||
section_type Returns the type of the library.
|
||||
library_thumb Returns the thumbnail for the library.
|
||||
count Returns the item count for the library.
|
||||
parent_count Returns the parent item count for the library.
|
||||
child_count Returns the child item count for the library.
|
||||
do_notify Returns bool value for whether to send notifications for the library.
|
||||
keep_history Returns bool value for whether to keep history for the library.
|
||||
|
||||
DOCUMENTATION :: END
|
||||
|
||||
</%doc>
|
||||
|
||||
<%inherit file="base.html"/>
|
||||
|
||||
<%def name="headIncludes()">
|
||||
<link rel="stylesheet" href="interfaces/default/css/dataTables.bootstrap.css">
|
||||
<link rel="stylesheet" href="interfaces/default/css/dataTables.colVis.css">
|
||||
<link rel="stylesheet" href="interfaces/default/css/plexpy-dataTables.css">
|
||||
</%def>
|
||||
|
||||
% if data != None:
|
||||
<%def name="body()">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="art-face" style="background-image:url(pms_image_proxy?img=${data['library_art']}&width=1920&height=1080)"></div>
|
||||
<div class="summary-container">
|
||||
<div class="summary-navbar">
|
||||
<div class="col-md-12">
|
||||
<div class="summary-navbar-list">
|
||||
<ul class="list-unstyled breadcrumb">
|
||||
<li class="active">${data['section_name']}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="summary-content-wrapper">
|
||||
<div class="col-md-12">
|
||||
<div class="table-card-back">
|
||||
<div class="user-info-wrapper">
|
||||
% if data['custom_thumb']:
|
||||
<div class="library-info-poster-face" id="user-gravatar" style="background-image: url(${data['custom_thumb']});">
|
||||
% else:
|
||||
<div class="library-info-poster-face" id="user-gravatar" style="background-image: url(pms_image_proxy?img=${data['library_thumb']}&width=80&height=80&fallback=poster);">
|
||||
% endif
|
||||
</div>
|
||||
<div class="user-info-username">
|
||||
<span class="set-username">${data['section_name']}</span>
|
||||
<span id="edit-library-tooltip" data-target="tooltip" title="Edit library details">
|
||||
<a href="#" data-toggle="modal" data-target="#edit-library-modal" id="toggle-edit-library-modal"><i class="fa fa-pencil"></i></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="user-info-nav">
|
||||
<ul class="user-info-nav">
|
||||
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
|
||||
<li><a id="history-tab-btn" href="#libraryHistory" data-toggle="tab">History</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="edit-library-modal" class="modal fade" tabindex="-1" role="dialog"
|
||||
aria-labelledby="edit-library-modal">
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="profile">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="table-card-header">
|
||||
<div class="header-bar">
|
||||
<span><i class="fa fa-line-chart"></i> Global Stats</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card-back">
|
||||
<div id="library-time-stats" class="user-overview-stats-wrapper">
|
||||
<div class='muted'><i class="fa fa-refresh fa-spin"></i> Loading data...</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="table-card-header">
|
||||
<div class="header-bar">
|
||||
<span><i class="fa fa-group"></i> User Stats</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card-back">
|
||||
<div id="library-user-stats" class="user-player">
|
||||
<div class='muted'><i class="fa fa-refresh fa-spin"></i> Loading data...</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="table-card-header">
|
||||
<div class="header-bar">
|
||||
<span><i class="fa fa-history"></i> Recently Watched</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card-back">
|
||||
<div id="library-recently-watched">
|
||||
<div class='muted'><i class="fa fa-refresh fa-spin"></i> Loading data...</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="libraryHistory">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class='table-card-header'>
|
||||
<div class="header-bar">
|
||||
<span>
|
||||
<i class="fa fa-history"></i> Watch History for <strong>
|
||||
<span class="set-username">${data['section_name']}</span>
|
||||
</strong>
|
||||
</span>
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<div class="colvis-button-bar hidden-xs" id="button-bar-history"></div>
|
||||
<button class="btn btn-danger btn-edit" data-toggle="button" aria-pressed="false" autocomplete="off" id="row-edit-mode">
|
||||
<i class="fa fa-trash-o"></i> Delete mode
|
||||
</button>
|
||||
<div class="alert alert-danger alert-edit" role="alert" id="row-edit-mode-alert"><i class="fa fa-exclamation-triangle"></i> Select rows to delete. Data is deleted upon exiting delete mode.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-card-back">
|
||||
<table class="display" id="history_table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align='left' id="delete">Delete</th>
|
||||
<th align='left' id="time">Time</th>
|
||||
<th align='left' id="friendly_name">User</th>
|
||||
<th align='left' id="ip_address">IP Address</th>
|
||||
<th align='left' id="platform">Platform</th>
|
||||
<th align='left' id="player">Player</th>
|
||||
<th align='left' id="title">Title</th>
|
||||
<th align='left' id="started">Started</th>
|
||||
<th align='left' id="paused_counter">Paused</th>
|
||||
<th align='left' id="stopped">Stopped</th>
|
||||
<th align='left' id="duration">Duration</th>
|
||||
<th align='left' id="percent_complete"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="ip-info-modal" tabindex="-1" role="dialog" aria-labelledby="ip-info-modal">
|
||||
</div>
|
||||
<div class="modal fade" id="confirm-modal" tabindex="-1" role="dialog" aria-labelledby="confirm-modal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||
<h4 class="modal-title" id="myModalLabel">Confirm Delete</h4>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align: center;">
|
||||
<p>Are you REALLY sure you want to delete <strong><span id="deleteCount"></span></strong> history item(s)?</p>
|
||||
<p>This is permanent and cannot be undone!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark" data-dismiss="modal">Cancel</button>
|
||||
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer></footer>
|
||||
</%def>
|
||||
|
||||
<%def name="javascriptIncludes()">
|
||||
<script src="interfaces/default/js/jquery.dataTables.min.js"></script>
|
||||
<script src="interfaces/default/js/dataTables.colVis.js"></script>
|
||||
<script src="interfaces/default/js/dataTables.bootstrap.min.js"></script>
|
||||
<script src="interfaces/default/js/dataTables.bootstrap.pagination.js"></script>
|
||||
<script src="interfaces/default/js/moment-with-locale.js"></script>
|
||||
<script src="interfaces/default/js/tables/history_table.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
% if data['section_id']:
|
||||
var section_id = ${data['section_id']};
|
||||
% else:
|
||||
var section_id = null;
|
||||
% endif
|
||||
|
||||
var section_name = '${data['section_name'].replace("'", "\\'")}';
|
||||
|
||||
$("#edit-library-tooltip").tooltip();
|
||||
|
||||
// Populate watch time stats
|
||||
$.ajax({
|
||||
url: 'get_library_watch_time_stats',
|
||||
async: true,
|
||||
data: { library_id: section_id },
|
||||
complete: function(xhr, status) {
|
||||
$("#library-time-stats").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
// Populate user stats
|
||||
$.ajax({
|
||||
url: 'get_library_user_stats',
|
||||
async: true,
|
||||
data: { library_id: section_id },
|
||||
complete: function(xhr, status) {
|
||||
$("#library-user-stats").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
|
||||
function loadHistoryTable() {
|
||||
// Build watch history table
|
||||
history_table_options.ajax = {
|
||||
url: 'get_history',
|
||||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return {
|
||||
'json_data': JSON.stringify( d ),
|
||||
'section_id': section_id
|
||||
};
|
||||
}
|
||||
}
|
||||
history_table = $('#history_table').DataTable(history_table_options);
|
||||
//history_table.column(2).visible(false);
|
||||
|
||||
var colvis = new $.fn.dataTable.ColVis(history_table, { buttonText: '<i class="fa fa-columns"></i> Select columns', buttonClass: 'btn btn-dark', exclude: [0, 11] });
|
||||
$(colvis.button()).appendTo('#button-bar-history');
|
||||
|
||||
clearSearchButton('history_table', history_table);
|
||||
}
|
||||
|
||||
$( "#history-tab-btn" ).one( "click", function() {
|
||||
loadHistoryTable();
|
||||
});
|
||||
|
||||
// Load edit library modal
|
||||
$("#toggle-edit-library-modal").click(function() {
|
||||
$("#edit-library-tooltip").tooltip('hide');
|
||||
$.ajax({
|
||||
url: 'edit_library_dialog',
|
||||
data: { section_id: section_id },
|
||||
cache: false,
|
||||
async: true,
|
||||
complete: function(xhr, status) {
|
||||
$("#edit-library-modal").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#row-edit-mode').on('click', function() {
|
||||
$('#row-edit-mode-alert').fadeIn(200);
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
if (history_to_delete.length > 0) {
|
||||
$('#deleteCount').text(history_to_delete.length);
|
||||
$('#confirm-modal').modal();
|
||||
$('#confirm-modal').one('click', '#confirm-delete', function () {
|
||||
for (var i = 0; i < history_to_delete.length; i++) {
|
||||
$.ajax({
|
||||
url: 'delete_history_rows',
|
||||
data: { row_id: history_to_delete[i] },
|
||||
async: true,
|
||||
success: function (data) {
|
||||
var msg = "History deleted";
|
||||
showMsg(msg, false, true, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
history_table.draw();
|
||||
});
|
||||
}
|
||||
|
||||
$('.delete-control').each(function () {
|
||||
$(this).addClass('hidden');
|
||||
$('#row-edit-mode-alert').fadeOut(200);
|
||||
});
|
||||
|
||||
} else {
|
||||
history_to_delete = [];
|
||||
$('.delete-control').each(function() {
|
||||
$(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger');
|
||||
$(this).removeClass('hidden');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function recentlyWatched() {
|
||||
var widthVal = $('body').find("#library-recently-watched").width();
|
||||
var tmp = (widthVal-32) / 180;
|
||||
|
||||
if (tmp > 0) {
|
||||
containerSize = parseInt(tmp);
|
||||
} else {
|
||||
containerSize = 1;
|
||||
}
|
||||
|
||||
// Populate recently watched
|
||||
$.ajax({
|
||||
url: 'get_library_recently_watched',
|
||||
async: true,
|
||||
data: {
|
||||
library_id: section_id,
|
||||
limit: containerSize
|
||||
},
|
||||
complete: function(xhr, status) {
|
||||
$("#library-recently-watched").html(xhr.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
recentlyWatched();
|
||||
$(window).resize(function() {
|
||||
recentlyWatched();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
|
||||
</script>
|
||||
</%def>
|
||||
% else:
|
||||
<div class="clear"></div>
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span10 offset1">
|
||||
<h3>Error retrieving library information. Please see the logs for more details.</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
|
@ -30,13 +30,9 @@ DOCUMENTATION :: END
|
|||
<li>
|
||||
<div class="home-platforms-instance-info">
|
||||
<div class="home-platforms-instance-name">
|
||||
% if library['section_type'] != 'photo':
|
||||
<h4>
|
||||
<a href="info?library_id=${library['section_id']}" title="${library['section_name']}">${library['section_name']}</a>
|
||||
<a href="library?section_id=${library['section_id']}" title="${library['section_name']}">${library['section_name']}</a>
|
||||
</h4>
|
||||
% else:
|
||||
<h4>${library['section_name']}</h4>
|
||||
% endif
|
||||
</div>
|
||||
% if library['section_type'] == 'movie':
|
||||
<div class="home-platforms-instance-playcount">
|
||||
|
|
43
data/interfaces/default/library_user_stats.html
Normal file
43
data/interfaces/default/library_user_stats.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<%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: library_user_stats.html
|
||||
Version: 0.1
|
||||
Variable names: data [array]
|
||||
|
||||
data[array_index] :: Usable parameters
|
||||
|
||||
== Global keys ==
|
||||
user Returns the name of the user.
|
||||
user_id Returns the user id of the user.
|
||||
thumb Returns the avatar of the user.
|
||||
total_plays Returns the play count for the user.
|
||||
|
||||
DOCUMENTATION :: END
|
||||
</%doc>
|
||||
|
||||
% if data != None:
|
||||
% for a in data:
|
||||
<ul class="list-unstyled">
|
||||
<div class="user-player-instance">
|
||||
<li>
|
||||
<a href="user?user_id=${a['user_id']}" title="${a['user']}">
|
||||
<div class="library-user-instance-box" style="background-image: url(${a['thumb']});"></div>
|
||||
</a>
|
||||
<div class=" user-player-instance-name">
|
||||
<a href="user?user_id=${a['user_id']}" title="${a['user']}">${a['user']}</a>
|
||||
</div>
|
||||
<div class="user-player-instance-playcount">
|
||||
<h3>${a['total_plays']}</h3>
|
||||
<p> plays</p>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
% endfor
|
||||
% else:
|
||||
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
|
||||
</div><br>
|
||||
% endif
|
Loading…
Add table
Add a link
Reference in a new issue