Massive code cleanup

* Finish up library pages (toggles and notifications)
* Update user pages to match library pages
* Fix no current activity bif thumbnail at the start of a stream
* Improved logging throughout PlexPy
This commit is contained in:
Jonathan Wong 2016-01-05 20:46:27 -08:00
parent 5fedac691d
commit 636f898da8
31 changed files with 2873 additions and 2715 deletions

View file

@ -174,42 +174,42 @@ from plexpy import version
</div>
</form>
</li>
% if title=="Home":
% if title == "Home":
<li class="active"><a href="home"><i class="fa fa-lg fa-home"></i></a></li>
% else:
<li><a href="home"><i class="fa fa-lg fa-home"></i></a></li>
% endif
% if title=="Libraries" or title=="Library":
% if title == "Libraries" or title == "Library" or title == "Info":
<li class="active"><a href="libraries">Libraries</a></li>
% else:
<li><a href="libraries">Libraries</a></li>
% endif
% if title=="Users" or title=="User":
% if title == "Users" or title == "User":
<li class="active"><a href="users">Users</a></li>
% else:
<li><a href="users">Users</a></li>
% endif
% if title=="History":
% if title == "History":
<li class="active"><a href="history">History</a></li>
% else:
<li><a href="history">History</a></li>
% endif
% if title=="Graphs":
% if title == "Graphs":
<li class="active"><a href="graphs">Graphs</a></li>
% else:
<li><a href="graphs">Graphs</a></li>
% endif
% if title=="Synced Items":
% if title == "Synced Items":
<li class="active"><a href="sync">Synced Items</a></li>
% else:
<li><a href="sync">Synced Items</a></li>
% endif
% if title=="Log":
% if title == "Log":
<li class="active"><a href="logs">Logs</a></li>
% else:
<li><a href="logs">Logs</a></li>
% endif
% if title=="Settings":
% if title == "Settings":
<li class="active"><a href="settings">Settings</a></li>
% else:
<li><a href="settings">Settings</a></li>

View file

@ -2463,6 +2463,7 @@ a .home-platforms-instance-list-oval:hover,
}
#users-to-delete > li,
#users-to-purge > li,
#libraries-to-delete > li,
#libraries-to-purge > li {
color: #e9a049;
}

View file

@ -72,9 +72,9 @@ DOCUMENTATION :: END
<a href="info?rating_key=${a['rating_key']}">
% endif
<div class="dashboard-activity-poster">
% if a['media_type'] == 'movie' and not a['indexes']:
% if (a['media_type'] == 'movie' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280);"></div>
% elif a['media_type'] == 'episode' and not a['indexes']:
% elif (a['media_type'] == 'episode' and not a['indexes']) or (a['indexes'] and not a['view_offset']):
<div class="dashboard-activity-poster-face" style="background-image: url(pms_image_proxy?img=${a['art']}&width=500&height=280);"></div>
% elif a['indexes']:
<div class="dashboard-activity-poster-face bif" style="background-image: url(pms_image_proxy?img=${a['bif_thumb']}&width=500&height=280); display: none;"></div>

View file

@ -14,6 +14,8 @@ 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.
custom_thumb Returns the custom thumbnail for the library.
library_art Returns the artwork 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.
@ -40,11 +42,7 @@ DOCUMENTATION :: END
<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>
@ -61,6 +59,12 @@ DOCUMENTATION :: END
</label>
<p class="help-block">Uncheck this if you do not want this keep any history on this library's activity.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="do_notify_created" name="do_notify_created" value="1" ${helpers.checked(data['do_notify_created'])}> Enable recently added notifications
</label>
<p class="help-block">Uncheck this if you do not want to receive recently added notifications for this library.</p>
</div>
% if data['section_id']:
<div class="form-group">
<button class="btn btn-danger" id="delete-all-history">Purge</button>
@ -96,14 +100,18 @@ DOCUMENTATION :: END
</div>
</div>
<script>
// Set new friendly name
$("#save_library").click(function () {
// Save library options
$("#save_library").on('click', function () {
var custom_thumb = $("#custom_thumb_url").val();
var do_notify = 0;
var do_notify_created = 0;
var keep_history = 0;
if ($("#do_notify").is(":checked")) {
do_notify = 1;
}
if ($("#do_notify_created").is(":checked")) {
do_notify_created = 1;
}
if ($("#keep_history").is(":checked")) {
keep_history = 1;
}
@ -112,9 +120,10 @@ DOCUMENTATION :: END
url: 'edit_library',
data: {
section_id: '${data["section_id"]}',
custom_thumb: custom_thumb,
do_notify: do_notify,
keep_history: keep_history,
custom_thumb: custom_thumb
do_notify_created: do_notify_created,
keep_history: keep_history
},
cache: false,
async: true,
@ -167,5 +176,4 @@ DOCUMENTATION :: END
});
});
</script>
% endif

View file

@ -10,21 +10,30 @@ Variable names: data [list]
data :: Usable parameters
== Global keys ==
user Return the real Plex username
user_id Return the Plex user_id
friendly_name Returns the friendly edited Plex username
do_notify Returns bool value for whether the user should trigger notifications
keep_history Returns bool value for whether the user's activity should be logged
user_id Returns the user id of the user.
username Returns the user's username.
friendly_name Returns the friendly name of the user.
email Returns the user's email address.
user_thumb Returns the thumbnail for the user.
is_home_user Returns bool value for whether the user is part of a Plex Home.
is_allow_sync Returns bool value for whether the user has sync rights.
is_restricted Returns bool value for whether the user account is restricted.
do_notify Returns bool value for whether to send notifications for the user.
keep_history Returns bool value for whether to keep history for the user.
DOCUMENTATION :: END
</%doc>
% if data is not None:
<%!
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 user <strong>${data['user']}</strong></h4>
<h4 class="modal-title">Edit user <strong>${data['username']}</strong></h4>
</div>
<div class="modal-body" id="modal-text">
<fieldset>
@ -41,20 +50,20 @@ DOCUMENTATION :: END
<label for="profile_url">Profile Picture URL</label>
<div class="row">
<div class="col-md-8">
<input type="text" class="form-control" id="profile_url" name="profile_url" value="${data['thumb']}">
<input type="text" class="form-control" id="custom_avatar_url" name="custom_avatar_url" value="${data['user_thumb']}">
</div>
</div>
<p class="help-block">Change the users profile picture in PlexPy. To reset to default, leave this field empty and save then perform a user refresh.</p>
<p class="help-block">Change the users profile 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" ${data['do_notify']}> Enable notifications
<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 user's activity.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="keep_history" name="keep_history" value="1" ${data['keep_history']}> Keep history
<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 user's activity.</p>
</div>
@ -69,7 +78,7 @@ DOCUMENTATION :: END
<div class="modal-footer">
<div>
<span id="edit-user-status-message"></span>
<input type="button" id="save_user_name" class="btn btn-bright" value="Save">
<input type="button" id="save_user" class="btn btn-bright" value="Save">
</div>
</div>
</div>
@ -93,10 +102,10 @@ DOCUMENTATION :: END
</div>
</div>
<script>
// Set new friendly name
$("#save_user_name").click(function() {
// Set user options
$("#save_user").on('click', function () {
var friendly_name = $("#friendly_name").val();
var thumb = $("#profile_url").val();
var custom_thumb = $("#custom_avatar_url").val();
var do_notify = 0;
var keep_history = 0;
if ($("#do_notify").is(":checked")) {
@ -106,35 +115,21 @@ DOCUMENTATION :: END
keep_history = 1;
}
% if data['user_id']:
$.ajax({
url: 'edit_user',
data: {user_id: '${data['user_id']}', friendly_name: friendly_name, do_notify: do_notify, keep_history: keep_history, thumb: thumb},
cache: false,
async: true,
success: function(data) {
$("#edit-user-status-message").html(data);
if ($.trim(friendly_name) !== '') {
$('.set-username').html(document.createTextNode(friendly_name));
}
$("#user-profile-thumb").attr('src', thumb);
}
});
% else:
$.ajax({
url: 'edit_user',
data: {user: '${data['user']}', friendly_name: friendly_name, do_notify: do_notify, keep_history: keep_history, thumb: thumb},
cache: false,
async: true,
success: function(data) {
$("#edit-user-status-message").html(data);
if ($.trim(friendly_name) !== '') {
$(".set-username").html(friendly_name);
}
$("#user-profile-thumb").attr('src', thumb);
}
});
% endif
$.ajax({
url: 'edit_user',
data: {
user_id: '${data["user_id"]}',
friendly_name: friendly_name,
custom_thumb: custom_thumb,
do_notify: do_notify,
keep_history: keep_history
},
cache: false,
async: true,
success: function(data) {
location.reload();
}
});
});
$("#delete-all-history").on('click', function() {
@ -142,7 +137,7 @@ DOCUMENTATION :: END
$('#confirm-modal').one('click', '#confirm-purge', function () {
$.ajax({
url: 'delete_all_user_history',
data: {user_id: '${data['user_id']}'},
data: { user_id: '${data["user_id"]}' },
cache: false,
async: true,
success: function(data) {
@ -155,7 +150,8 @@ DOCUMENTATION :: END
$(document).ready(function() {
// Move #confirm-modal to parent container
if(!($('#edit-user-modal').next().is('#confirm-modal'))) {
$('#confirm-modal').appendTo($('#edit-user-modal').parent()); }
$('#confirm-modal').appendTo($('#edit-user-modal').parent());
}
$('#edit-user-modal > #confirm-modal').remove();
$('#edit-user-modal').css('z-index', '1050');
@ -179,5 +175,4 @@ DOCUMENTATION :: END
});
});
</script>
% endif

View file

@ -11,15 +11,15 @@ data :: Usable parameters (if not applicable for media type, blank value will be
== Global keys ==
rating_key Returns the unique identifier for the media item.
media_type Returns the type of media. Either 'movie', 'show', 'season', 'episode', 'artist', 'album', or 'track'.
media_type Returns the type of media. Either 'movie', 'show', 'season', 'episode', 'artist', 'album', or 'track'.
art Returns the location of the item's artwork
title Returns the name of the movie, show, episode, artist, album, or track.
duration Returns the standard runtime of the media.
content_rating Returns the age rating for the media.
summary Returns a brief description of the media plot.
grandparent_title Returns the name of the show, or artist.
parent_index Returns the index number of the season.
index Returns the index number of the episode, or track.
parent_media_index Returns the index number of the season.
media_index Returns the index number of the episode, or track.
parent_thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
writers Returns an array of writers.
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
@ -54,29 +54,29 @@ DOCUMENTATION :: END
<div class="summary-navbar-list">
<ul class="list-unstyled breadcrumb">
% if data['media_type'] == 'movie':
<li><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li>
% elif data['media_type'] == 'show':
<li><a href="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li>
% elif data['media_type'] == 'season':
<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="library?section_id=${data['library_id']}">${data['library_name']}</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="library?section_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_name']}</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="library?section_id=${data['library_id']}">${data['library_title']}</a></li>
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li>
% elif data['media_type'] == 'album':
<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="library?section_id=${data['library_id']}">${data['library_name']}</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="library?section_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_name']}</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>

View file

@ -1,3 +1,4 @@
var libraries_to_delete = [];
var libraries_to_purge = [];
libraries_list_table_options = {
@ -23,9 +24,12 @@ libraries_list_table_options = {
"data": null,
"createdCell": function (td, cellData, rowData, row, col) {
$(td).html('<div class="edit-library-toggles">' +
'<button class="btn btn-xs btn-warning delete-library" data-id="' + rowData['section_id'] + '" data-toggle="button"><i class="fa fa-trash-o fa-fw"></i> Delete</button>&nbsp' +
'<button class="btn btn-xs btn-warning purge-library" data-id="' + rowData['section_id'] + '" data-toggle="button"><i class="fa fa-eraser fa-fw"></i> Purge</button>&nbsp&nbsp&nbsp' +
'<input type="checkbox" id="do_notify-' + rowData['section_id'] + '" name="do_notify" value="1" ' + rowData['do_notify'] + '><label class="edit-tooltip" for="do_notify-' + rowData['section_id'] + '" data-toggle="tooltip" title="Toggle Notifications"><i class="fa fa-bell fa-lg fa-fw"></i></label>&nbsp' +
'<input type="checkbox" id="keep_history-' + rowData['section_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['section_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp');
'<input type="checkbox" id="keep_history-' + rowData['section_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['section_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp' +
'<input type="checkbox" id="do_notify_created-' + rowData['section_id'] + '" name="do_notify_created" value="1" ' + rowData['do_notify_created'] + '><label class="edit-tooltip" for="do_notify_created-' + rowData['section_id'] + '" data-toggle="tooltip" title="Toggle Recently Added"><i class="fa fa-download fa-lg fa-fw"></i></label>&nbsp' +
'</div>');
},
"width": "7%",
"className": "edit-control no-wrap hidden",
@ -37,10 +41,10 @@ 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(pms_image_proxy?img=' + rowData['library_thumb'] + '&width=80&height=80&fallback=poster);"></div></a>');
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(interfaces/default/images/cover.png);"></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>');
if (rowData['library_thumb'].substring(0, 4) == "http") {
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(' + rowData['library_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>');
}
@ -56,7 +60,9 @@ libraries_list_table_options = {
"data": "section_name",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
$(td).html('<div data-id="' + rowData['section_id'] + '"><a href="library?section_id=' + rowData['section_id'] + '">' + cellData + '</a></div>');
$(td).html('<div data-id="' + rowData['section_id'] + '">' +
'<a href="library?section_id=' + rowData['section_id'] + '">' + cellData + '</a>' +
'</div>');
} else {
$(td).html(cellData);
}
@ -198,8 +204,11 @@ libraries_list_table_options = {
showMsg(msg, false, false, 0)
},
"rowCallback": function (row, rowData) {
if ($.inArray(rowData['section_id'], libraries_to_delete) !== -1) {
$(row).find('button.delete-library[data-id="' + rowData['section_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
}
if ($.inArray(rowData['section_id'], libraries_to_purge) !== -1) {
$(row).find('button[data-id="' + rowData['section_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
$(row).find('button.purge-library[data-id="' + rowData['section_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
}
}
}
@ -210,10 +219,14 @@ $('#libraries_list_table').on('change', 'td.edit-control > .edit-library-toggles
var rowData = row.data();
var do_notify = 0;
var do_notify_created = 0;
var keep_history = 0;
if ($('#do_notify-' + rowData['section_id']).is(':checked')) {
do_notify = 1;
}
if ($('#do_notify_created-' + rowData['section_id']).is(':checked')) {
do_notify_created = 1;
}
if ($('#keep_history-' + rowData['section_id']).is(':checked')) {
keep_history = 1;
}
@ -228,6 +241,7 @@ $('#libraries_list_table').on('change', 'td.edit-control > .edit-library-toggles
data: {
section_id: rowData['section_id'],
do_notify: do_notify,
do_notify_created: do_notify_created,
keep_history: keep_history,
custom_thumb: custom_thumb
},
@ -240,17 +254,44 @@ $('#libraries_list_table').on('change', 'td.edit-control > .edit-library-toggles
});
});
$('#libraries_list_table').on('click', 'td.edit-control > .edit-library-toggles > button.delete-library', function () {
var tr = $(this).parents('tr');
var row = libraries_list_table.row(tr);
var rowData = row.data();
var index_delete = $.inArray(rowData['section_id'], libraries_to_delete);
var index_purge = $.inArray(rowData['section_id'], libraries_to_purge);
if (index_delete === -1) {
libraries_to_delete.push(rowData['section_id']);
if (index_purge === -1) {
tr.find('button.purge-library').click();
}
} else {
libraries_to_delete.splice(index_delete, 1);
if (index_purge != -1) {
tr.find('button.purge-library').click();
}
}
$(this).toggleClass('btn-warning').toggleClass('btn-danger');
});
$('#libraries_list_table').on('click', 'td.edit-control > .edit-library-toggles > button.purge-library', function () {
var tr = $(this).parents('tr');
var row = libraries_list_table.row(tr);
var rowData = row.data();
var index_delete = $.inArray(rowData['section_id'], libraries_to_delete);
var index_purge = $.inArray(rowData['section_id'], libraries_to_purge);
if (index_purge === -1) {
libraries_to_purge.push(rowData['section_id']);
} else {
libraries_to_purge.splice(index_purge, 1);
if (index_delete != -1) {
tr.find('button.delete-library').click();
}
}
$(this).toggleClass('btn-warning').toggleClass('btn-danger');
});

View file

@ -23,12 +23,12 @@ users_list_table_options = {
"targets": [0],
"data": null,
"createdCell": function (td, cellData, rowData, row, col) {
$(td).html('<div class="edit-user-toggles"><button class="btn btn-xs btn-warning delete-user" data-id="' + rowData['user_id'] + '" data-toggle="button"><i class="fa fa-trash-o fa-fw"></i> Delete</button>&nbsp' +
$(td).html('<div class="edit-user-toggles">' +
'<button class="btn btn-xs btn-warning delete-user" data-id="' + rowData['user_id'] + '" data-toggle="button"><i class="fa fa-trash-o fa-fw"></i> Delete</button>&nbsp' +
'<button class="btn btn-xs btn-warning purge-user" data-id="' + rowData['user_id'] + '" data-toggle="button"><i class="fa fa-eraser fa-fw"></i> Purge</button>&nbsp&nbsp&nbsp' +
'<input type="checkbox" id="do_notify-' + rowData['user_id'] + '" name="do_notify" value="1" ' + rowData['do_notify'] + '><label class="edit-tooltip" for="do_notify-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle Notifications"><i class="fa fa-bell fa-lg fa-fw"></i></label>&nbsp' +
'<input type="checkbox" id="keep_history-' + rowData['user_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp');
// Show/hide user currently doesn't work
//'<input type="checkbox" id="show_hide-' + rowData['user_id'] + '" name="show_hide" value="1" checked><label class="edit-tooltip" for="show_hide-' + rowData['user_id'] + '" data-toggle="tooltip" title="Show/Hide User"><i class="fa fa-eye fa-lg fa-fw"></i></label>');
'<input type="checkbox" id="keep_history-' + rowData['user_id'] + '" name="keep_history" value="1" ' + rowData['keep_history'] + '><label class="edit-tooltip" for="keep_history-' + rowData['user_id'] + '" data-toggle="tooltip" title="Toggle History"><i class="fa fa-history fa-lg fa-fw"></i></label>&nbsp' +
'</div>');
},
"width": "7%",
"className": "edit-control no-wrap hidden",
@ -42,7 +42,7 @@ users_list_table_options = {
if (cellData === '') {
$(td).html('<a href="user?user_id=' + rowData['user_id'] + '"><div class="users-poster-face" style="background-image: url(interfaces/default/images/gravatar-default-80x80.png);"></div></a>');
} else {
$(td).html('<a href="user?user_id=' + rowData['user_id'] + '"><div class="users-poster-face" style="background-image: url(' + cellData + ');"></div></a>');
$(td).html('<a href="user?user_id=' + rowData['user_id'] + '"><div class="users-poster-face" style="background-image: url(' + rowData['user_thumb'] + ');"></div></a>');
}
},
"orderable": false,
@ -55,13 +55,10 @@ users_list_table_options = {
"data": "friendly_name",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
if (rowData['user_id'] > 0) {
$(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '"><a href="user?user_id=' + rowData['user_id'] + '">' + cellData + '</a>' +
'<input type="text" class="hidden" value="' + cellData + '"></div>');
} else {
$(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '"><a href="user?user=' + rowData['user'] + '">' + cellData + '</a>' +
'<input type="text" class="hidden" value="' + cellData + '"></div>');
}
$(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '">' +
'<a href="user?user_id=' + rowData['user_id'] + '">' + cellData + '</a>' +
'<input type="text" class="hidden" value="' + cellData + '">' +
'</div>');
} else {
$(td).html(cellData);
}
@ -206,8 +203,11 @@ users_list_table_options = {
showMsg(msg, false, false, 0)
},
"rowCallback": function (row, rowData) {
if ($.inArray(rowData['user_id'], users_to_delete) !== -1) {
$(row).find('button.delete-user[data-id="' + rowData['user_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
}
if ($.inArray(rowData['user_id'], users_to_purge) !== -1) {
$(row).find('button[data-id="' + rowData['user_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
$(row).find('button.purge-user[data-id="' + rowData['user_id'] + '"]').toggleClass('btn-warning').toggleClass('btn-danger');
}
}
}

View file

@ -43,15 +43,16 @@
<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>
<h4 class="modal-title" id="myModalLabel">Confirm Delete/Purge</h4>
</div>
<div class="modal-body" style="text-align: center;">
<ul id="libraries-to-delete" class="list-unstyled"></ul>
<ul id="libraries-to-purge" class="list-unstyled"></ul>
<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">Confirm</button>
<button type="button" class="btn btn-danger btn-ok" data-dismiss="modal" id="confirm-delete">Confirm</button>
</div>
</div>
</div>
@ -83,7 +84,8 @@
$('#row-edit-mode').on('click', function () {
$('#row-edit-mode-alert').fadeIn(200);
$('#libraries_to_purge').html('');
$('#libraries-to-delete').html('');
$('#libraries-to-purge').html('');
if ($(this).hasClass('active')) {
if (libraries_to_purge.length > 0) {
@ -91,6 +93,17 @@
$(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger');
});
libraries_to_purge = $.grep(libraries_to_purge, function (value) {
return $.inArray(value, libraries_to_delete) < 0;
});
if (libraries_to_delete.length > 0) {
$('#libraries-to-delete').prepend('<p>Are you REALLY sure you want to delete the following libraries:</p>')
for (var i = 0; i < libraries_to_delete.length; i++) {
$('#libraries-to-delete').append('<li>' + $('div[data-id=' + libraries_to_delete[i] + ']').text() + '</li>');
}
}
if (libraries_to_purge.length > 0) {
$('#libraries-to-purge').prepend('<p>Are you REALLY sure you want to purge all history for the following libraries:</p>')
for (var i = 0; i < libraries_to_purge.length; i++) {
@ -99,7 +112,19 @@
}
$('#confirm-modal').modal();
$('#confirm-modal').one('click', '#confirm-purge', function () {
$('#confirm-modal').one('click', '#confirm-delete', function () {
for (var i = 0; i < libraries_to_delete.length; i++) {
$.ajax({
url: 'delete_library',
data: { section_id: libraries_to_delete[i] },
cache: false,
async: true,
success: function (data) {
var msg = "Library deleted";
showMsg(msg, false, true, 2000);
}
});
}
for (var i = 0; i < libraries_to_purge.length; i++) {
$.ajax({
url: 'delete_all_library_history',
@ -122,6 +147,7 @@
});
} else {
libraries_to_delete = [];
libraries_to_purge = [];
$('.edit-control').each(function () {
$(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger');
@ -137,13 +163,13 @@
cache: false,
async: true,
success: function (data) {
showMsg('<i class="fa fa-refresh"></i>&nbspLibraries list refresh started...', false, true, 2000, false)
showMsg('<i class="fa fa-refresh"></i>&nbspLibraries list refresh started...', false, true, 2000, false);
},
complete: function (data) {
showMsg('<i class="fa fa-check"></i>&nbspLibraries list refreshed.', false, true, 2000, false)
showMsg('<i class="fa fa-check"></i>&nbspLibraries list refreshed.', false, true, 2000, false);
},
error: function (jqXHR, textStatus, errorThrown) {
showMsg('<i class="fa fa-exclamation-circle"></i>&nbspUnable to refresh libraries list.',false,true,2000,true)
showMsg('<i class="fa fa-exclamation-circle"></i>&nbspUnable to refresh libraries list.', false, true, 2000, true);
}
});
});

View file

@ -13,6 +13,8 @@ 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.
custom_thumb Returns the custom thumbnail for the library.
library_art Returns the artwork 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.
@ -31,8 +33,8 @@ DOCUMENTATION :: END
<link rel="stylesheet" href="interfaces/default/css/plexpy-dataTables.css">
</%def>
% if data != None:
<%def name="body()">
% if data:
<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>
@ -50,12 +52,11 @@ DOCUMENTATION :: END
<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']});">
% if data['library_thumb'][:4] == 'http':
<div class="library-info-poster-face" style="background-image: url(${data['library_thumb']});"></div>
% 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);">
<div class="library-info-poster-face" style="background-image: url(pms_image_proxy?img=${data['library_thumb']}&width=80&height=80&fallback=cover);"></div>
% 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">
@ -201,6 +202,27 @@ DOCUMENTATION :: END
</div>
</div>
<footer></footer>
% else:
<div class="container-fluid">
<div class="row">
<div class="summary-container">
<div class="summary-navbar">
<div class="col-md-12">
<div class="summary-navbar-list">
</div>
</div>
</div>
<div class="summary-content-wrapper">
<div class='col-md-12'>
<div style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> Error retrieving library information. Please see the logs for more details.
</div>
</div>
</div>
</div>
</div>
</div>
% endif
</%def>
<%def name="javascriptIncludes()">
@ -208,12 +230,13 @@ DOCUMENTATION :: END
<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>
% if data:
<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']:
% if str(data['section_id']).isdigit():
var section_id = ${data['section_id']};
% else:
var section_id = null;
@ -348,18 +371,7 @@ DOCUMENTATION :: END
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
% endif
</%def>

View file

@ -18,7 +18,7 @@ total_plays Returns the play count for the user.
DOCUMENTATION :: END
</%doc>
% if data != None:
% if data:
% for a in data:
<ul class="list-unstyled">
<div class="user-player-instance">
@ -38,6 +38,6 @@ DOCUMENTATION :: END
</ul>
% endfor
% else:
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
<div class="text-muted">Unable to retrieve data from database.
</div><br>
% endif

View file

@ -800,7 +800,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
% for agent in available_notification_agents:
<li>
<span>
% if agent['on_play'] or agent['on_stop'] or agent['on_pause'] or agent['on_resume'] or agent['on_buffer'] or agent['on_watched'] or agent['on_created'] or agent['on_extdown'] or agent['on_intdown']:
% if any(k[:2] == 'on' and v == 1 for k, v in agent.iteritems()):
<a href="javascript:void(0)" data-target="#notification-triggers-modal" data-id="${agent['id']}" class="toggle-notification-triggers-modal toggle-left active" data-toggle="modal"><i class="fa fa-lg fa-bell"></i></a>
% else:
<a href="javascript:void(0)" data-target="#notification-triggers-modal" data-id="${agent['id']}" class="toggle-notification-triggers-modal toggle-left" data-toggle="modal"><i class="fa fa-lg fa-bell"></i></a>
@ -1167,6 +1167,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{title}</strong></td>
<td>The full title of the item being played.</td>
</tr>
<tr>
<td><strong>{library_name}</strong></td>
<td>The library title of the item being played.</td>
</tr>
<tr>
<td><strong>{show_name}</strong></td>
<td>The title of the TV series being played.</td>

View file

@ -13,10 +13,12 @@ user_id Returns the user id of the user.
username Returns the user's username.
friendly_name Returns the friendly name of the user.
email Returns the user's email address.
thumb Returns the thumbnail for the user.
user_thumb Returns the thumbnail for the user.
is_home_user Returns bool value for whether the user is part of a Plex Home.
is_allow_sync Returns bool value for whether the user has sync rights.
is_restricted Returns bool value for whether the user account is restricted.
do_notify Returns bool value for whether to send notifications for the user.
keep_history Returns bool value for whether to keep history for the user.
DOCUMENTATION :: END
@ -33,223 +35,261 @@ from plexpy import helpers
<link rel="stylesheet" href="interfaces/default/css/plexpy-dataTables.css">
</%def>
% if user != None:
<%def name="body()">
% if data:
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="table-card-back">
<div class="user-info-wrapper">
<div class="user-info-poster-face" id="user-gravatar" style="background-image: url(${data['thumb']});">
</div>
<div class="user-info-username">
<span class="set-username">${data['friendly_name']}</span> <span id="edit-user-tooltip" data-target="tooltip" title="Edit user details"><a href="#" data-toggle="modal" data-target="#edit-user-modal" id="toggle-edit-user-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="ip-tab-btn" href="#userAddresses" data-toggle="tab">IP Addresses</a></li>
<li><a id="history-tab-btn" href="#userHistory" data-toggle="tab">History</a></li>
<li><a id="sync-tab-btn" href="#userSyncItems" data-toggle="tab">Synced Items</a></li>
</ul>
<div class="summary-container">
<div class="summary-navbar">
<div class="col-md-12">
<div class="summary-navbar-list">
<ul class="list-unstyled breadcrumb"></ul>
</div>
</div>
</div>
</div>
</div>
<div id="edit-user-modal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="edit-user-modal">
</div>
</div>
<div class="tab-content">
<div class="tab-pane active" id="profile">
<div class="container-fluid">
<div class="row">
<div class="summary-content-wrapper">
<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="user-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-television"></i> Player Stats</span>
</div>
</div>
<div class="table-card-back">
<div id="user-player-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="user-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="userAddresses">
<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-map-marker"></i> IP Addresses for <strong>
<div class="user-info-wrapper">
<div class="user-info-poster-face" style="background-image: url(${data['user_thumb']});"></div>
<div class="user-info-username">
<span class="set-username">${data['friendly_name']}</span>
</strong></span>
<span id="edit-user-tooltip" data-target="tooltip" title="Edit user details">
<a href="#" data-toggle="modal" data-target="#edit-user-modal" id="toggle-edit-user-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="ip-tab-btn" href="#userAddresses" data-toggle="tab">IP Addresses</a></li>
<li><a id="history-tab-btn" href="#userHistory" data-toggle="tab">History</a></li>
<li><a id="sync-tab-btn" href="#userSyncItems" data-toggle="tab">Synced Items</a></li>
</ul>
</div>
</div>
</div>
<div class="table-card-back">
<table id="user_ip_table" class="display" width="100%">
<thead>
<tr>
<th align="left">Last Seen</th>
<th align="left">IP Address</th>
<th align="left">Last Platform</th>
<th align="left">Last Player</th>
<th align="left">Last Watched</th>
<th align="left">Play Count</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="userHistory">
<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['friendly_name']}</span>
</strong></span>
<div id="edit-user-modal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="edit-user-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="user-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="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>&nbspSelect rows to delete. Data is deleted upon exiting delete mode.</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-television"></i> Player Stats</span>
</div>
</div>
<div class="table-card-back">
<div id="user-player-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="user-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="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="tab-pane" id="userSyncItems">
<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-cloud-download"></i> Synced Items for <strong>
<span class="set-username">${data['friendly_name']}</span>
</strong></span>
</div>
<div class="colvis-button-bar hidden-xs" id="button-bar-sync">
<div class="tab-pane" id="userAddresses">
<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-map-marker"></i> IP Addresses for <strong>
<span class="set-username">${data['friendly_name']}</span>
</strong>
</span>
</div>
</div>
<div class="table-card-back">
<table id="user_ip_table" class="display" width="100%">
<thead>
<tr>
<th align="left">Last Seen</th>
<th align="left">IP Address</th>
<th align="left">Last Platform</th>
<th align="left">Last Player</th>
<th align="left">Last Watched</th>
<th align="left">Play Count</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="table-card-back">
<table class="display" id="sync_table" width="100%">
<thead>
<tr>
<th align='left' id="state">State</th>
<th align='left' id="username">Username</th>
<th align='left' id="sync_title">Title</th>
<th align='left' id="type">Type</th>
<th align='left' id="sync_platform">Platform</th>
<th align='left' id="device">Device</th>
<th align='left' id="size">Total Size</th>
<th align='left' id="items">Total Items</th>
<th align='left' id="converted">Converted</th>
<th align='left' id="downloaded">Downloaded</th>
<th align='left' id="sync_percent_complete">Complete</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="tab-pane" id="userHistory">
<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['friendly_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>&nbspSelect 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="tab-pane" id="userSyncItems">
<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-cloud-download"></i> Synced Items for <strong>
<span class="set-username">${data['friendly_name']}</span>
</strong>
</span>
</div>
<div class="colvis-button-bar hidden-xs" id="button-bar-sync">
</div>
</div>
<div class="table-card-back">
<table class="display" id="sync_table" width="100%">
<thead>
<tr>
<th align='left' id="state">State</th>
<th align='left' id="username">Username</th>
<th align='left' id="sync_title">Title</th>
<th align='left' id="type">Type</th>
<th align='left' id="sync_platform">Platform</th>
<th align='left' id="device">Device</th>
<th align='left' id="size">Total Size</th>
<th align='left' id="items">Total Items</th>
<th align='left' id="converted">Converted</th>
<th align='left' id="downloaded">Downloaded</th>
<th align='left' id="sync_percent_complete">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 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>
<footer></footer>
% else:
<div class="container-fluid">
<div class="row">
<div class="summary-container">
<div class="summary-navbar">
<div class="col-md-12">
<div class="summary-navbar-list">
</div>
</div>
</div>
<div class="summary-content-wrapper">
<div class='col-md-12'>
<div style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> Error retrieving user information. Please see the logs for more details.
</div>
</div>
</div>
</div>
</div>
</div>
% endif
</%def>
<%def name="javascriptIncludes()">
@ -257,6 +297,7 @@ from plexpy import helpers
<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>
% if data:
<script src="interfaces/default/js/moment-with-locale.js"></script>
<script src="interfaces/default/js/tables/history_table.js"></script>
<script src="interfaces/default/js/tables/user_ips.js"></script>
@ -264,10 +305,10 @@ from plexpy import helpers
<script>
$(document).ready(function () {
% if data['user_id']:
var user_id = ${data['user_id']};
% if str(data['user_id']).isdigit():
var user_id = ${data['user_id']};
% else:
var user_id = null;
var user_id = null;
% endif
var username = '${data['username'].replace("'", "\\'")}';
@ -303,7 +344,6 @@ from plexpy import helpers
return {
'json_data': JSON.stringify( d ),
'user_id': user_id,
'user': username,
'media_type': media_type
};
}
@ -313,7 +353,7 @@ from plexpy import helpers
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_table_filter').prepend('<div class="btn-group" data-toggle="buttons" id="media_type-selection" style="padding-right: 15px;"> \
@ -348,27 +388,25 @@ from plexpy import helpers
$( "#ip-tab-btn" ).one( "click", function() {
// Build user IP table
user_ip_table_options.ajax = {
"url": "get_user_ips",
url: 'get_user_ips',
type: 'post',
data: function ( d ) {
return { 'json_data': JSON.stringify( d ),
'user_id': user_id,
'user': username
'user_id': user_id
};
}
}
user_ip_table = $('#user_ip_table').DataTable(user_ip_table_options);
clearSearchButton('user_ip_table', user_ip_table);
});
$( "#sync-tab-btn" ).one( "click", function() {
// Build user sync table
sync_table_options.ajax = {
"url": "get_sync",
"data": function(d) {
d.user_id = user_id;
d.user = username;
url: 'get_sync',
data: function(d) {
d.user_id = user_id;
}
}
sync_table = $('#sync_table').DataTable(sync_table_options);
@ -376,7 +414,7 @@ from plexpy import helpers
var colvis_sync = new $.fn.dataTable.ColVis( sync_table, { buttonText: '<i class="fa fa-columns"></i> Select columns', buttonClass: 'btn btn-dark' } );
$( colvis_sync.button() ).appendTo('#button-bar-sync');
clearSearchButton('sync_table', sync_table);
});
@ -385,7 +423,7 @@ from plexpy import helpers
$("#edit-user-tooltip").tooltip('hide');
$.ajax({
url: 'edit_user_dialog',
data: { user_id: user_id, user: username },
data: { user_id: user_id },
cache: false,
async: true,
complete: function(xhr, status) {
@ -441,37 +479,25 @@ from plexpy import helpers
containerSize = 1;
}
% if data['user_id']:
var user_id = ${data['user_id']};
% else:
var user_id = null;
% endif
// Populate recently watched
$.ajax({
url: 'get_user_recently_watched',
async: true,
data: { user_id: user_id, user: username, limit: containerSize },
data: {
user_id: user_id,
limit: containerSize
},
complete: function(xhr, status) {
$("#user-recently-watched").html(xhr.responseText);
}
});
}
recentlyWatched();
$(window).resize(function() {
recentlyWatched();
});
});
</script>
</%def>
% else:
<div class="clear"></div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span10 offset1">
<h3>Error retrieving user information. Please see the logs for more details.</h3>
</div>
</div>
</div>
% endif
% endif
</%def>

View file

@ -18,7 +18,7 @@ total_plays Returns the play count for the player.
DOCUMENTATION :: END
</%doc>
% if data != None:
% if data:
% for a in data:
<ul class="list-unstyled">
<div class="user-player-instance">
@ -39,6 +39,6 @@ DOCUMENTATION :: END
</script>
% endfor
% else:
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
<div class="text-muted">Unable to retrieve data from database.
</div><br>
% endif

View file

@ -28,7 +28,7 @@ year Returns the movie release year.
DOCUMENTATION :: END
</%doc>
% if data != None:
% if data:
<div class="dashboard-recent-media-row">
<ul class="dashboard-recent-media list-unstyled">
% for item in data:
@ -84,6 +84,6 @@ DOCUMENTATION :: END
</ul>
</div>
% else:
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
<div class="text-muted">Unable to retrieve data from database.
</div><br>
% endif

View file

@ -16,7 +16,7 @@ total_plays Returns the play count for the watch stat period..
DOCUMENTATION :: END
</%doc>
% if data != None:
% if data:
<ul class="list-unstyled">
% for a in data:
<div class='user-overview-stats-instance'>
@ -43,6 +43,6 @@ DOCUMENTATION :: END
% endfor
</ul>
% else:
<div class="text-muted">Unable to retrieve data from database. Please check your <a href="settings">settings</a>.
<div class="text-muted">Unable to retrieve data from database.
</div><br>
% endif

View file

@ -177,13 +177,13 @@
cache: false,
async: true,
success: function(data) {
showMsg('<i class="fa fa-check"></i>&nbspUsers list refresh started...',false,true,2000,false)
showMsg('<i class="fa fa-check"></i>&nbspUsers list refresh started...', false, true, 2000, false);
},
complete: function (data) {
showMsg('<i class="fa fa-check"></i>&nbspUsers list refreshed.', false, true, 2000, false)
showMsg('<i class="fa fa-check"></i>&nbspUsers list refreshed.', false, true, 2000, false);
},
error: function (jqXHR, textStatus, errorThrown) {
showMsg('<i class="fa fa-exclamation-circle"></i>&nbspUnable to refresh users list.',false,true,2000,true)
showMsg('<i class="fa fa-exclamation-circle"></i>&nbspUnable to refresh users list.', false, true, 2000, true);
}
});
});