diff --git a/data/interfaces/default/css/plexpy.css b/data/interfaces/default/css/plexpy.css
index 1a0d5658..7d715a3c 100644
--- a/data/interfaces/default/css/plexpy.css
+++ b/data/interfaces/default/css/plexpy.css
@@ -1646,6 +1646,30 @@ input[type="color"],
width: 250px;
z-index: 9999;
}
+.tooltip.top .tooltip-arrow {
+ border-top-color: #fff;
+}
+.tooltip.right .tooltip-arrow {
+ border-right-color: #fff;
+}
+.tooltip.bottom .tooltip-arrow {
+ border-bottom-color: #fff;
+}
+.tooltip.left .tooltip-arrow {
+ border-left-color: #fff;
+}
+.tooltip-inner {
+ color: #000;
+ background: #fff;
+ border: 0;
+ font-weight: bold;
+}
+.history-title .popover.right {
+ margin-left: 12px;
+}
+.history-title .popover.right .popover-content {
+ padding: 5px 8px;
+}
#updatebar {
background-color: #444;
color: #999999;
diff --git a/data/interfaces/default/history.html b/data/interfaces/default/history.html
index 9546b94b..9e1ec5f6 100644
--- a/data/interfaces/default/history.html
+++ b/data/interfaces/default/history.html
@@ -79,7 +79,6 @@
});
}
});
-
});
diff --git a/data/interfaces/default/info.html b/data/interfaces/default/info.html
index a1c313b2..b2ba2b98 100644
--- a/data/interfaces/default/info.html
+++ b/data/interfaces/default/info.html
@@ -174,7 +174,9 @@ DOCUMENTATION :: END
-
@@ -184,8 +186,8 @@ DOCUMENTATION :: END
Delete |
Time |
User |
-
Platform |
IP Address |
+
Platform |
Title |
Started |
Paused |
@@ -236,7 +238,6 @@ DOCUMENTATION :: END
<%def name="javascriptIncludes()">
-
@@ -269,6 +270,18 @@ DOCUMENTATION :: END
$(colvis.button()).appendTo('div.colvis-button-bar');
clearSearchButton('history_table', history_table);
+
+ $('#row-edit-mode').click(function() {
+ if ($(this).hasClass('active')) {
+ $('.delete-control').each(function() {
+ $(this).addClass('hidden');
+ });
+ } else {
+ $('.delete-control').each(function() {
+ $(this).removeClass('hidden');
+ });
+ }
+ });
});
% elif data['type'] == 'show':
@@ -289,6 +302,18 @@ DOCUMENTATION :: END
$(colvis.button()).appendTo('div.colvis-button-bar');
clearSearchButton('history_table', history_table);
+
+ $('#row-edit-mode').click(function() {
+ if ($(this).hasClass('active')) {
+ $('.delete-control').each(function() {
+ $(this).addClass('hidden');
+ });
+ } else {
+ $('.delete-control').each(function() {
+ $(this).removeClass('hidden');
+ });
+ }
+ });
});
% endif
diff --git a/data/interfaces/default/js/tables/history_table.js b/data/interfaces/default/js/tables/history_table.js
index 65edc7c8..9898cc1b 100644
--- a/data/interfaces/default/js/tables/history_table.js
+++ b/data/interfaces/default/js/tables/history_table.js
@@ -34,6 +34,7 @@ history_table_options = {
"createdCell": function (td, cellData, rowData, row, col) {
$(td).html('
');
},
+ "width": "5%",
"className": "delete-control no-wrap hidden",
"searchable": false,
"orderable": false
@@ -49,6 +50,7 @@ history_table_options = {
}
},
"searchable": false,
+ "width": "8%",
"className": "no-wrap"
},
{
@@ -65,6 +67,7 @@ history_table_options = {
$(td).html(cellData);
}
},
+ "width": "8%",
"className": "no-wrap hidden-xs"
},
{
@@ -85,6 +88,7 @@ history_table_options = {
$(td).html('n/a');
}
},
+ "width": "8%",
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control-ip"
},
{
@@ -92,9 +96,18 @@ history_table_options = {
"data":"player",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
- $(td).html('
 ' + cellData + '');
+ var transcode_dec = '';
+ if (rowData['video_decision'] === 'transcode') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'copy') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'direct play' || rowData['video_decision'] === '') {
+ transcode_dec = '
 ';
+ }
+ $(td).html('
');
}
},
+ "width": "15%",
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control"
},
{
@@ -102,19 +115,27 @@ history_table_options = {
"data":"full_title",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
- if (rowData['media_type'] === 'movie' || rowData['media_type'] === 'episode') {
- var transcode_dec = '';
- if (rowData['video_decision'] === 'transcode') {
- transcode_dec = '
 ';
- }
- $(td).html('
');
+ var media_type = '';
+ var thumb_popover = '';
+ if (rowData['media_type'] === 'movie') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ' (' + rowData['year'] + ')'
+ $(td).html('
');
+ } else if (rowData['media_type'] === 'episode') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ' \
+ (S' + ('00' + rowData['parent_media_index']).slice(-2) + 'E' + ('00' + rowData['media_index']).slice(-2) + ')'
+ $(td).html('
');
} else if (rowData['media_type'] === 'track') {
- $(td).html('
');
+ media_type = '
';
+ thumb_popover = '
' + cellData + ' (' + rowData['parent_title'] + ')'
+ $(td).html('
' + media_type + ' ' + thumb_popover + '
');
} else {
$(td).html('
' + cellData + '');
}
}
- }
+ },
+ "width": "35%"
},
{
"targets": [6],
@@ -127,6 +148,7 @@ history_table_options = {
}
},
"searchable": false,
+ "width": "5%",
"className": "no-wrap hidden-sm hidden-xs"
},
{
@@ -140,6 +162,7 @@ history_table_options = {
}
},
"searchable": false,
+ "width": "5%",
"className": "no-wrap hidden-md hidden-sm hidden-xs"
},
{
@@ -153,6 +176,7 @@ history_table_options = {
}
},
"searchable": false,
+ "width": "5%",
"className": "no-wrap hidden-sm hidden-xs"
},
{
@@ -166,6 +190,7 @@ history_table_options = {
}
},
"searchable": false,
+ "width": "5%",
"className": "no-wrap hidden-xs"
},
{
@@ -173,27 +198,37 @@ history_table_options = {
"data":"percent_complete",
"render": function ( data, type, full ) {
if (data > 80) {
- return '
'
+ return '
'
} else if (data > 40) {
- return '
'
+ return '
'
} else {
- return '
'
+ return '
'
}
},
"searchable": false,
"orderable": false,
"className": "no-wrap hidden-md hidden-sm hidden-xs",
- "width": "10px"
+ "width": "1%"
},
],
"drawCallback": function (settings) {
// Jump to top of page
// $('html,body').scrollTop(0);
$('#ajaxMsg').fadeOut();
+
// Create the tooltips.
- $('.info-modal').each(function() {
- $(this).tooltip();
+ $('.transcode-tooltip').tooltip();
+ $('.media-type-tooltip').tooltip();
+ $('.watched-tooltip').tooltip();
+ $('.thumb-tooltip').popover({
+ html: true,
+ trigger: 'hover',
+ placement: 'right',
+ content: function () {
+ return '
';
+ }
});
+
if ($('#row-edit-mode').hasClass('active')) {
$('.delete-control').each(function() {
$(this).removeClass('hidden');
diff --git a/data/interfaces/default/js/tables/user_ips.js b/data/interfaces/default/js/tables/user_ips.js
index 9c8cc411..5968b67a 100644
--- a/data/interfaces/default/js/tables/user_ips.js
+++ b/data/interfaces/default/js/tables/user_ips.js
@@ -52,7 +52,15 @@ user_ip_table_options = {
"data":"platform",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData) {
- $(td).html('
 ' + cellData + '');
+ var transcode_dec = '';
+ if (rowData['video_decision'] === 'transcode') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'copy') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'direct play' || rowData['video_decision'] === '') {
+ transcode_dec = '
 ';
+ }
+ $(td).html('
');
} else {
$(td).html('n/a');
}
@@ -65,14 +73,20 @@ user_ip_table_options = {
"data":"last_watched",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
- if (rowData['media_type'] === 'movie' || rowData['media_type'] === 'episode') {
- var transcode_dec = '';
- if (rowData['video_decision'] === 'transcode') {
- transcode_dec = '
 ';
- }
- $(td).html('
');
+ var media_type = '';
+ var thumb_popover = ''
+ if (rowData['media_type'] === 'movie') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
');
+ } else if (rowData['media_type'] === 'episode') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
');
} else if (rowData['media_type'] === 'track') {
- $(td).html('
');
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
' + media_type + ' ' + thumb_popover + '
');
} else if (rowData['media_type']) {
$(td).html('
' + cellData + '');
} else {
@@ -93,10 +107,20 @@ user_ip_table_options = {
// Jump to top of page
// $('html,body').scrollTop(0);
$('#ajaxMsg').fadeOut();
+
// Create the tooltips.
- $('.info-modal').each(function () {
- $(this).tooltip();
+ $('.transcode-tooltip').tooltip();
+ $('.media-type-tooltip').tooltip();
+ $('.watched-tooltip').tooltip();
+ $('.thumb-tooltip').popover({
+ html: true,
+ trigger: 'hover',
+ placement: 'right',
+ content: function () {
+ return '
';
+ }
});
+
},
"preDrawCallback": function(settings) {
var msg = "
 Fetching rows...
";
diff --git a/data/interfaces/default/js/tables/users.js b/data/interfaces/default/js/tables/users.js
index c3e022e3..c3d1ae1e 100644
--- a/data/interfaces/default/js/tables/users.js
+++ b/data/interfaces/default/js/tables/users.js
@@ -18,7 +18,7 @@ users_list_table_options = {
"columnDefs": [
{
"targets": [0],
- "data": "thumb",
+ "data": "user_thumb",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData === '') {
$(td).html('

');
@@ -28,8 +28,8 @@ users_list_table_options = {
},
"orderable": false,
"searchable": false,
- "className": "users-poster-face",
- "width": "40px"
+ "width": "5%",
+ "className": "users-poster-face"
},
{
"targets": [1],
@@ -87,7 +87,15 @@ users_list_table_options = {
"data":"platform",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData) {
- $(td).html('
 ' + cellData + '');
+ var transcode_dec = '';
+ if (rowData['video_decision'] === 'transcode') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'copy') {
+ transcode_dec = '
 ';
+ } else if (rowData['video_decision'] === 'direct play' || rowData['video_decision'] === '') {
+ transcode_dec = '
 ';
+ }
+ $(td).html('
');
} else {
$(td).html('n/a');
}
@@ -100,14 +108,20 @@ users_list_table_options = {
"data":"last_watched",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') {
- if (rowData['media_type'] === 'movie' || rowData['media_type'] === 'episode') {
- var transcode_dec = '';
- if (rowData['video_decision'] === 'transcode') {
- transcode_dec = '
 ';
- }
- $(td).html('
');
+ var media_type = '';
+ var thumb_popover = ''
+ if (rowData['media_type'] === 'movie') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
');
+ } else if (rowData['media_type'] === 'episode') {
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
');
} else if (rowData['media_type'] === 'track') {
- $(td).html('
');
+ media_type = '
';
+ thumb_popover = '
' + cellData + ''
+ $(td).html('
' + media_type + ' ' + thumb_popover + '
');
} else if (rowData['media_type']) {
$(td).html('
' + cellData + '');
} else {
@@ -129,10 +143,20 @@ users_list_table_options = {
// Jump to top of page
//$('html,body').scrollTop(0);
$('#ajaxMsg').fadeOut();
+
// Create the tooltips.
- $('.info-modal').each(function () {
- $(this).tooltip();
+ $('.transcode-tooltip').tooltip();
+ $('.media-type-tooltip').tooltip();
+ $('.watched-tooltip').tooltip();
+ $('.thumb-tooltip').popover({
+ html: true,
+ trigger: 'hover',
+ placement: 'right',
+ content: function () {
+ return '
';
+ }
});
+
},
"preDrawCallback": function(settings) {
var msg = "
 Fetching rows...
";
diff --git a/plexpy/datafactory.py b/plexpy/datafactory.py
index cecee027..b60c654b 100644
--- a/plexpy/datafactory.py
+++ b/plexpy/datafactory.py
@@ -1,4 +1,4 @@
-# This file is part of PlexPy.
+# This file is part of PlexPy.
#
# PlexPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -36,6 +36,13 @@ class DataFactory(object):
'session_history.player',
'session_history.ip_address',
'session_history_metadata.full_title as full_title',
+ 'session_history_metadata.thumb',
+ 'session_history_metadata.parent_thumb',
+ 'session_history_metadata.grandparent_thumb',
+ 'session_history_metadata.media_index',
+ 'session_history_metadata.parent_media_index',
+ 'session_history_metadata.parent_title',
+ 'session_history_metadata.year',
'session_history.started',
'session_history.paused_counter',
'session_history.stopped',
@@ -81,12 +88,24 @@ class DataFactory(object):
rows = []
for item in history:
+ if item["media_type"] == 'episode' and item["parent_thumb"]:
+ thumb = item["parent_thumb"]
+ elif item["media_type"] == 'episode':
+ thumb = item["grandparent_thumb"]
+ else:
+ thumb = item["thumb"]
+
row = {"id": item['id'],
"date": item['date'],
"friendly_name": item['friendly_name'],
"player": item["player"],
"ip_address": item["ip_address"],
"full_title": item["full_title"],
+ "thumb": thumb,
+ "media_index": item["media_index"],
+ "parent_media_index": item["parent_media_index"],
+ "parent_title": item["parent_title"],
+ "year": item["year"],
"started": item["started"],
"paused_counter": item["paused_counter"],
"stopped": item["stopped"],
@@ -411,7 +430,6 @@ class DataFactory(object):
else:
return None
- print result
stream_output = {}
for item in result:
@@ -512,13 +530,15 @@ class DataFactory(object):
metadata = {}
for item in result:
- directors = item['directors'].split(';')
- writers = item['writers'].split(';')
- actors = item['actors'].split(';')
- genres = item['genres'].split(';')
+ directors = item['directors'].split(';') if item['directors'] else []
+ writers = item['writers'].split(';') if item['writers'] else []
+ actors = item['actors'].split(';') if item['actors'] else []
+ genres = item['genres'].split(';') if item['genres'] else []
metadata = {'type': item['media_type'],
'rating_key': item['rating_key'],
+ 'parent_rating_key': item['parent_rating_key'],
+ 'grandparent_rating_key': item['grandparent_rating_key'],
'grandparent_title': item['grandparent_title'],
'parent_index': item['parent_media_index'],
'parent_title': item['parent_title'],
diff --git a/plexpy/users.py b/plexpy/users.py
index fb31916c..8a24b38b 100644
--- a/plexpy/users.py
+++ b/plexpy/users.py
@@ -1,4 +1,4 @@
-# This file is part of PlexPy.
+# This file is part of PlexPy.
#
# PlexPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ class Users(object):
columns = ['session_history.id',
'users.user_id as user_id',
- 'users.custom_avatar_url as thumb',
+ 'users.custom_avatar_url as user_thumb',
'(case when users.friendly_name is null then users.username else \
users.friendly_name end) as friendly_name',
'MAX(session_history.started) as last_seen',
@@ -34,6 +34,9 @@ class Users(object):
'COUNT(session_history.id) as plays',
'session_history.player as platform',
'session_history_metadata.full_title as last_watched',
+ 'session_history_metadata.thumb',
+ 'session_history_metadata.parent_thumb',
+ 'session_history_metadata.grandparent_thumb',
'session_history_metadata.media_type',
'session_history.rating_key as rating_key',
'session_history_media_info.video_decision',
@@ -66,10 +69,17 @@ class Users(object):
rows = []
for item in users:
- if not item['thumb'] or item['thumb'] == '':
+ if item["media_type"] == 'episode' and item["parent_thumb"]:
+ thumb = item["parent_thumb"]
+ elif item["media_type"] == 'episode':
+ thumb = item["grandparent_thumb"]
+ else:
+ thumb = item["thumb"]
+
+ if not item['user_thumb'] or item['user_thumb'] == '':
user_thumb = common.DEFAULT_USER_THUMB
else:
- user_thumb = item['thumb']
+ user_thumb = item['user_thumb']
row = {"id": item['id'],
"plays": item['plays'],
@@ -78,10 +88,11 @@ class Users(object):
"ip_address": item['ip_address'],
"platform": item['platform'],
"last_watched": item['last_watched'],
+ "thumb": thumb,
"media_type": item['media_type'],
"rating_key": item['rating_key'],
"video_decision": item['video_decision'],
- "thumb": user_thumb,
+ "user_thumb": user_thumb,
"user": item["user"],
"user_id": item['user_id']
}
@@ -108,6 +119,9 @@ class Users(object):
'COUNT(session_history.id) as play_count',
'session_history.player as platform',
'session_history_metadata.full_title as last_watched',
+ 'session_history_metadata.thumb',
+ 'session_history_metadata.parent_thumb',
+ 'session_history_metadata.grandparent_thumb',
'session_history_metadata.media_type',
'session_history.rating_key as rating_key',
'session_history_media_info.video_decision',
@@ -144,12 +158,20 @@ class Users(object):
rows = []
for item in results:
+ if item["media_type"] == 'episode' and item["parent_thumb"]:
+ thumb = item["parent_thumb"]
+ elif item["media_type"] == 'episode':
+ thumb = item["grandparent_thumb"]
+ else:
+ thumb = item["thumb"]
+
row = {"id": item['id'],
"last_seen": item['last_seen'],
"ip_address": item['ip_address'],
"play_count": item['play_count'],
"platform": item['platform'],
"last_watched": item['last_watched'],
+ "thumb": thumb,
"media_type": item['media_type'],
"rating_key": item['rating_key'],
"video_decision": item['video_decision'],