Add media info table to library page

This commit is contained in:
Jonathan Wong 2016-01-10 13:35:20 -08:00
parent 10e4d562ab
commit 381c3da31c
28 changed files with 1415 additions and 462 deletions

View file

@ -71,9 +71,20 @@ img {
-moz-box-shadow: 0 0 0 3px rgba(0,0,0,.2); -moz-box-shadow: 0 0 0 3px rgba(0,0,0,.2);
box-shadow: 0 0 0 3px rgba(0,0,0,.2); box-shadow: 0 0 0 3px rgba(0,0,0,.2);
} }
.navbar-header {
position: absolute;
top: 0;
left: 15px;
width: 100%;
}
.navbar-brand { .navbar-brand {
padding: 5px 5px; padding: 5px 5px;
} }
.navbar-right {
position: absolute;
top: 0;
right: 15px;
}
.nav > li > a { .nav > li > a {
color: #999; color: #999;
-webkit-transition: all 0.3s ease; -webkit-transition: all 0.3s ease;
@ -2542,12 +2553,22 @@ a .home-platforms-instance-list-oval:hover,
width: 100%; width: 100%;
} }
} }
table.display,
table.display tr.shown + tr table[id^='history_child'],
table.display tr.shown + tr table[id^='media_info_child'],
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] {
table-layout: fixed;
}
table.display.no-fixed {
table-layout: auto;
}
table.display tr.shown + tr div.slider { table.display tr.shown + tr div.slider {
display: none; display: none;
} }
table.display tr.shown + tr > td { table.display tr.shown + tr > td {
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
padding-left: 0;
} }
table.display tr.shown + tr:hover { table.display tr.shown + tr:hover {
background-color: rgba(255,255,255,0); background-color: rgba(255,255,255,0);
@ -2558,7 +2579,9 @@ table.display tr.shown + tr .pagination > .active > a,
table.display tr.shown + tr .pagination > .active > a:hover { table.display tr.shown + tr .pagination > .active > a:hover {
color: #fff; color: #fff;
} }
table.display tr.shown + tr table[id^='history_child'] td:hover a { table.display tr.shown + tr table[id^='history_child'] td:hover a,
table.display tr.shown + tr table[id^='media_info_child'] > tr > td:hover a,
table.display tr.shown + tr table[id^='media_info_child'] tr.shown + tr table[id^='media_info_child'] td:hover a {
color: #F9AA03; color: #F9AA03;
} }
table.display tr.shown + tr .pagination > .disabled > a { table.display tr.shown + tr .pagination > .disabled > a {
@ -2569,14 +2592,22 @@ table.display tr.shown + tr .pagination > li > a:hover {
} }
table[id^='history_child'] { table[id^='history_child'] {
margin-top: 0; margin-top: 0;
margin-left: -4px;
opacity: .6; opacity: .6;
} }
table[id^='history_child'] thead th { table[id^='media_info_child'] {
margin-top: 0;
}
table[id^='history_child'] thead th,
table[id^='media_info_child'] thead th {
line-height: 0; line-height: 0;
height: 0 !important; height: 0 !important;
overflow: hidden; overflow: hidden;
} }
table[id^='media_info_child'] table[id^='media_info_child'] thead th {
line-height: 25px;
height: 35px !important;
overflow: hidden;
}
#search_form { #search_form {
width: 300px; width: 300px;
padding: 8px 15px; padding: 8px 15px;

View file

@ -25,18 +25,18 @@
<table class="display" id="history_table" width="100%"> <table class="display" id="history_table" width="100%">
<thead> <thead>
<tr> <tr>
<th align='left' id="delete_row">Delete</th> <th align="left" id="delete_row">Delete</th>
<th align='left' id="time">Time</th> <th align="left" id="time">Time</th>
<th align='left' id="friendly_name">User</th> <th align="left" id="friendly_name">User</th>
<th align='left' id="ip_address">IP Address</th> <th align="left" id="ip_address">IP Address</th>
<th align='left' id="platform">Platform</th> <th align="left" id="platform">Platform</th>
<th align='left' id="device">Player</th> <th align="left" id="device">Player</th>
<th align='left' id="title">Title</th> <th align="left" id="title">Title</th>
<th align='left' id="started">Started</th> <th align="left" id="started">Started</th>
<th align='left' id="paused_counter">Paused</th> <th align="left" id="paused_counter">Paused</th>
<th align='left' id="stopped">Stopped</th> <th align="left" id="stopped">Stopped</th>
<th align='left' id="duration">Duration</th> <th align="left" id="duration">Duration</th>
<th align='left' id="percent_complete"></th> <th align="left" id="percent_complete"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -83,8 +83,8 @@
type: 'post', type: 'post',
data: function (d) { data: function (d) {
return { return {
'json_data': JSON.stringify(d), json_data: JSON.stringify(d),
'media_type': media_type media_type: media_type
}; };
} }
} }

View file

@ -10,14 +10,14 @@
</h4> </h4>
</div> </div>
<div class="modal-body" id="modal-text"> <div class="modal-body" id="modal-text">
<table class="display" id="history_table" width="100%"> <table class="display no-fixed" id="history_table" width="100%">
<thead> <thead>
<tr> <tr>
<th align='left' id="started">Started</th> <th align="left" id="started">Started</th>
<th align='left' id="stopped">Stopped</th> <th align="left" id="stopped">Stopped</th>
<th align='left' id="friendly_name">User</th> <th align="left" id="friendly_name">User</th>
<th align='left' id="player">Player</th> <th align="left" id="player">Player</th>
<th align='left' id="title">Title</th> <th align="left" id="title">Title</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -34,12 +34,13 @@
$(document).ready(function() { $(document).ready(function() {
$('#date-header').html(moment('${data}','YYYY-MM-DD').format('ddd MMM Do YYYY')); $('#date-header').html(moment('${data}','YYYY-MM-DD').format('ddd MMM Do YYYY'));
history_table_modal_options.ajax = { history_table_modal_options.ajax = {
"url": "get_history", url: 'get_history',
type: "post", type: "post",
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ), return {
'grouping': false, json_data: JSON.stringify(d),
'start_date': '${data}' grouping: false,
start_date: '${data}'
}; };
} }
} }

View file

@ -54,29 +54,29 @@ DOCUMENTATION :: END
<div class="summary-navbar-list"> <div class="summary-navbar-list">
<ul class="list-unstyled breadcrumb"> <ul class="list-unstyled breadcrumb">
% if data['media_type'] == 'movie': % if data['media_type'] == 'movie':
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li> <li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li> <li class="active">${data['title']}</li>
% elif data['media_type'] == 'show': % elif data['media_type'] == 'show':
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li> <li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li> <li class="active">${data['title']}</li>
% elif data['media_type'] == 'season': % elif data['media_type'] == 'season':
<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="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_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> <li class="active">Season ${data['media_index']}</li>
% elif data['media_type'] == 'episode': % elif data['media_type'] == 'episode':
<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="library?section_id=${data['section_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 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><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> <li class="active">Episode ${data['media_index']} - ${data['title']}</li>
% elif data['media_type'] == 'artist': % elif data['media_type'] == 'artist':
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li> <li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
<li class="active">${data['title']}</li> <li class="active">${data['title']}</li>
% elif data['media_type'] == 'album': % elif data['media_type'] == 'album':
<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="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
<li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li> <li><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
<li class="active">${data['title']}</li> <li class="active">${data['title']}</li>
% elif data['media_type'] == 'track': % elif data['media_type'] == 'track':
<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="library?section_id=${data['section_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 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><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
<li class="active">Track ${data['media_index']} - ${data['title']}</li> <li class="active">Track ${data['media_index']} - ${data['title']}</li>
@ -288,14 +288,6 @@ DOCUMENTATION :: END
</div> </div>
% endif % endif
<div class='col-md-12'> <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.
<br />
The history table will refresh automatically when the update is complete. Please wait...
</div>
% endif
<div class='table-card-header'> <div class='table-card-header'>
<div class="header-bar"> <div class="header-bar">
<span>Watch History for <strong>${data['title']}</strong></span> <span>Watch History for <strong>${data['title']}</strong></span>
@ -370,41 +362,17 @@ DOCUMENTATION :: END
% if data: % if data:
<script src="interfaces/default/js/tables/history_table.js"></script> <script src="interfaces/default/js/tables/history_table.js"></script>
<!-- Need to find a place to put this --> <!-- Need to find a place to put this -->
% if data['media_type'] == 'library': % if data['media_type'] == 'show' or data['media_type'] == 'artist':
<script> <script>
function get_history() { function get_history() {
history_table_options.ajax = { history_table_options.ajax = {
url: 'get_history', url: 'get_history',
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ), return {
'library_id': "${data['library_id']}" }; json_data: JSON.stringify( d ),
} grandparent_rating_key: "${data['rating_key']}"
} };
}
if ("${config['update_library_ids']}" == "1") {
$.ajax({
url: 'update_library_ids',
type: 'post',
cache: false,
async: true,
data: { },
complete: function (xhr, status) {
$('#update_library_ids_mssage').remove();
history_table.draw();
}
});
}
</script>
% elif data['media_type'] == 'show' or data['media_type'] == 'artist':
<script>
function get_history() {
history_table_options.ajax = {
url: 'get_history',
type: 'post',
data: function ( d ) {
return { 'json_data': JSON.stringify( d ),
'grandparent_rating_key': "${data['rating_key']}" };
} }
} }
} }
@ -416,8 +384,10 @@ DOCUMENTATION :: END
url: 'get_history', url: 'get_history',
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ), return {
'parent_rating_key': "${data['rating_key']}" }; json_data: JSON.stringify( d ),
parent_rating_key: "${data['rating_key']}"
};
} }
} }
} }
@ -429,8 +399,10 @@ DOCUMENTATION :: END
url: 'get_history', url: 'get_history',
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ), return {
'rating_key': "${data['rating_key']}" }; json_data: JSON.stringify( d ),
rating_key: "${data['rating_key']}"
};
} }
} }
} }

View file

@ -56,7 +56,7 @@ history_table_options = {
} }
}, },
"searchable": false, "searchable": false,
"width": "8%", "width": "7%",
"className": "no-wrap expand-history" "className": "no-wrap expand-history"
}, },
{ {
@ -73,7 +73,7 @@ history_table_options = {
$(td).html(cellData); $(td).html(cellData);
} }
}, },
"width": "8%", "width": "7%",
"className": "no-wrap hidden-xs" "className": "no-wrap hidden-xs"
}, },
{ {
@ -95,7 +95,7 @@ history_table_options = {
$(td).html('n/a'); $(td).html('n/a');
} }
}, },
"width": "8%", "width": "7%",
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control-ip" "className": "no-wrap hidden-md hidden-sm hidden-xs modal-control-ip"
}, },
{ {
@ -106,7 +106,7 @@ history_table_options = {
$(td).html(cellData); $(td).html(cellData);
} }
}, },
"width": "8%", "width": "7%",
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control" "className": "no-wrap hidden-md hidden-sm hidden-xs modal-control"
}, },
{ {
@ -153,7 +153,7 @@ history_table_options = {
} }
} }
}, },
"width": "35%" "width": "33%"
}, },
{ {
"targets": [7], "targets": [7],
@ -226,7 +226,7 @@ history_table_options = {
"searchable": false, "searchable": false,
"orderable": false, "orderable": false,
"className": "no-wrap hidden-md hidden-sm hidden-xs", "className": "no-wrap hidden-md hidden-sm hidden-xs",
"width": "1%" "width": "2%"
}, },
], ],
"drawCallback": function (settings) { "drawCallback": function (settings) {
@ -260,7 +260,7 @@ history_table_options = {
var rowData = this.data(); var rowData = this.data();
if (rowData['group_count'] != 1 && rowData['reference_id'] in history_child_table) { if (rowData['group_count'] != 1 && rowData['reference_id'] in history_child_table) {
// if grouped row and a child table was already created // if grouped row and a child table was already created
$(this.node()).find('i.fa').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle'); $(this.node()).find('i.fa.fa-plus-circle').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle');
this.child(childTableFormat(rowData)).show(); this.child(childTableFormat(rowData)).show();
createChildTable(this, rowData) createChildTable(this, rowData)
} }
@ -426,13 +426,13 @@ function childTableOptions(rowData) {
history_child_options.pageLength = 10; history_child_options.pageLength = 10;
history_child_options.bStateSave = false; history_child_options.bStateSave = false;
history_child_options.ajax = { history_child_options.ajax = {
"url": "get_history", url: 'get_history',
type: "post", type: 'post',
data: function (d) { data: function (d) {
return { return {
'json_data': JSON.stringify(d), json_data: JSON.stringify(d),
'grouping': false, grouping: false,
'reference_id': rowData['reference_id'] reference_id: rowData['reference_id']
}; };
} }
} }
@ -469,7 +469,7 @@ function childTableOptions(rowData) {
// Format the detailed history child table // Format the detailed history child table
function childTableFormat(rowData) { function childTableFormat(rowData) {
return '<div class="slider">' + return '<div class="slider">' +
'<table id="history_child-' + rowData['reference_id'] + '">' + '<table id="history_child-' + rowData['reference_id'] + '" width="100%">' +
'<thead>' + '<thead>' +
'<tr>' + '<tr>' +
'<th align="left" id="delete_row">Delete</th>' + '<th align="left" id="delete_row">Delete</th>' +

View file

@ -39,7 +39,7 @@ history_table_modal_options = {
}, },
"searchable": false, "searchable": false,
"className": "no-wrap", "className": "no-wrap",
"width": "5%" "width": "10%"
}, },
{ {
"targets": [1], "targets": [1],
@ -53,7 +53,7 @@ history_table_modal_options = {
}, },
"searchable": false, "searchable": false,
"className": "no-wrap", "className": "no-wrap",
"width": "5%" "width": "10%"
}, },
{ {
"targets": [2], "targets": [2],
@ -69,7 +69,8 @@ history_table_modal_options = {
$(td).html(cellData); $(td).html(cellData);
} }
}, },
"className": "no-wrap hidden-xs" "className": "no-wrap hidden-xs",
"width": "15%"
}, },
{ {
"targets": [3], "targets": [3],
@ -87,7 +88,8 @@ history_table_modal_options = {
$(td).html('<div><a href="#" data-target="#info-modal" data-toggle="modal"><div style="float: left;">' + transcode_dec + '&nbsp' + cellData + '</div></a></div>'); $(td).html('<div><a href="#" data-target="#info-modal" data-toggle="modal"><div style="float: left;">' + transcode_dec + '&nbsp' + cellData + '</div></a></div>');
} }
}, },
"className": "no-wrap hidden-sm hidden-xs modal-control" "className": "no-wrap hidden-sm hidden-xs modal-control",
"width": "20%"
}, },
{ {
"targets": [4], "targets": [4],
@ -113,7 +115,8 @@ history_table_modal_options = {
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>'); $(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
} }
} }
} },
"width": "30%"
} }
], ],
"drawCallback": function (settings) { "drawCallback": function (settings) {

View file

@ -14,7 +14,7 @@ libraries_list_table_options = {
"processing": false, "processing": false,
"serverSide": true, "serverSide": true,
"pageLength": 10, "pageLength": 10,
"order": [ 1, 'asc'], "order": [ 2, 'asc'],
"autoWidth": true, "autoWidth": true,
"stateSave": true, "stateSave": true,
"pagingType": "bootstrap", "pagingType": "bootstrap",
@ -40,14 +40,14 @@ libraries_list_table_options = {
"targets": [1], "targets": [1],
"data": "library_thumb", "data": "library_thumb",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData === '') { if (cellData !== null && cellData !== '') {
$(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['library_thumb'].substring(0, 4) == "http") { 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>'); $(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 { } 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>'); $(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 {
$(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>');
} }
}, },
"orderable": false, "orderable": false,
@ -59,12 +59,12 @@ libraries_list_table_options = {
"targets": [2], "targets": [2],
"data": "section_name", "data": "section_name",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html('<div data-id="' + rowData['section_id'] + '">' + $(td).html('<div data-id="' + rowData['section_id'] + '">' +
'<a href="library?section_id=' + rowData['section_id'] + '">' + cellData + '</a>' + '<a href="library?section_id=' + rowData['section_id'] + '">' + cellData + '</a>' +
'</div>'); '</div>');
} else { } else {
$(td).html(cellData); $(td).html('n/a');
} }
}, },
"width": "10%", "width": "10%",
@ -74,7 +74,7 @@ libraries_list_table_options = {
"targets": [3], "targets": [3],
"data": "section_type", "data": "section_type",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html(cellData); $(td).html(cellData);
} }
}, },
@ -85,10 +85,8 @@ libraries_list_table_options = {
"targets": [4], "targets": [4],
"data": "count", "data": "count",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null) { if (cellData !== null && cellData !== '') {
$(td).html(cellData); $(td).html(cellData);
} else {
$(td).html('n/a');
} }
}, },
@ -99,10 +97,8 @@ libraries_list_table_options = {
"targets": [5], "targets": [5],
"data": "parent_count", "data": "parent_count",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null) { if (cellData !== null && cellData !== '') {
$(td).html(cellData); $(td).html(cellData);
} else {
$(td).html('n/a');
} }
}, },
@ -113,10 +109,8 @@ libraries_list_table_options = {
"targets": [6], "targets": [6],
"data": "child_count", "data": "child_count",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null) { if (cellData !== null && cellData !== '') {
$(td).html(cellData); $(td).html(cellData);
} else {
$(td).html('n/a');
} }
}, },
@ -126,11 +120,11 @@ libraries_list_table_options = {
{ {
"targets": [7], "targets": [7],
"data": "last_accessed", "data": "last_accessed",
"render": function (data, type, full) { "createdCell": function (td, cellData, rowData, row, col) {
if (data) { if (cellData !== null && cellData !== '') {
return moment(data, "X").fromNow(); $(td).html(moment(cellData, "X").fromNow());
} else { } else {
return "never"; $(td).html("never");
} }
}, },
"searchable": false, "searchable": false,
@ -141,7 +135,7 @@ libraries_list_table_options = {
"targets": [8], "targets": [8],
"data":"last_watched", "data":"last_watched",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
var media_type = ''; var media_type = '';
var thumb_popover = '' var thumb_popover = ''
if (rowData['media_type'] === 'movie') { if (rowData['media_type'] === 'movie') {
@ -158,10 +152,10 @@ libraries_list_table_options = {
$(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type']) { } else if (rowData['media_type']) {
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>'); $(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
}
} else { } else {
$(td).html('n/a'); $(td).html('n/a');
} }
}
}, },
"width": "25%", "width": "25%",
"className": "hidden-sm hidden-xs" "className": "hidden-sm hidden-xs"

View file

@ -0,0 +1,420 @@
var date_format = 'YYYY-MM-DD';
var time_format = 'hh:mm a';
$.ajax({
url: 'get_date_formats',
type: 'GET',
success: function(data) {
date_format = data.date_format;
time_format = data.time_format;
}
});
media_info_table_options = {
"destroy": true,
"language": {
"search": "Search: ",
"lengthMenu":"Show _MENU_ entries per page",
"info":"Showing _START_ to _END_ of _TOTAL_ library items",
"infoEmpty":"Showing 0 to 0 of 0 entries",
"infoFiltered":"<span class='hidden-md hidden-sm hidden-xs'>(filtered from _MAX_ total entries)</span>",
"emptyTable": "No data in table"
},
"pagingType": "bootstrap",
"stateSave": true,
"processing": false,
"serverSide": true,
"pageLength": 25,
"order": [ 1, 'asc'],
"autoWidth": false,
"columnDefs": [
{
"targets": [0],
"data": "added_at",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
var expand_details = '';
var date = moment(cellData, "X").format(date_format);
if (rowData['media_type'] === 'show') {
expand_details = '<span class="expand-media-info-tooltip" data-toggle="tooltip" title="Show Seasons"><i class="fa fa-plus-circle fa-fw"></i></span>';
$(td).html('<div><a href="#"><div style="float: left;">' + expand_details + '&nbsp;' + date + '</div></a></div>');
} else if (rowData['media_type'] === 'season') {
expand_details = '<span class="expand-media-info-tooltip" data-toggle="tooltip" title="Show Episodes"><i class="fa fa-plus-circle fa-fw"></i></span>';
$(td).html('<div><a href="#"><div style="float: left;">' + expand_details + '&nbsp;' + date + '</div></a></div>');
} else if (rowData['media_type'] === 'artist') {
expand_details = '<span class="expand-media-info-tooltip" data-toggle="tooltip" title="Show Albumns"><i class="fa fa-plus-circle fa-fw"></i></span>';
$(td).html('<div><a href="#"><div style="float: left;">' + expand_details + '&nbsp;' + date + '</div></a></div>');
} else if (rowData['media_type'] === 'album') {
expand_details = '<span class="expand-media-info-tooltip" data-toggle="tooltip" title="Show Tracks"><i class="fa fa-plus-circle fa-fw"></i></span>';
$(td).html('<div><a href="#"><div style="float: left;">' + expand_details + '&nbsp;' + date + '</div></a></div>');
} else {
$(td).html('<div style="float: left;"><i class="fa fa-fw"></i>&nbsp;' + date + '</div>');
}
}
},
"width": "7%",
"className": "no-wrap expand-media-info",
"searchable": false
},
{
"targets": [1],
"data": "title",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
var media_type = '';
var thumb_popover = '';
if (rowData['media_type'] === 'movie') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Movie"><i class="fa fa-film fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120">' + cellData + ' (' + rowData['year'] + ')</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'show') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="TV Show"><i class="fa fa-television fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120">' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'season') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Season"><i class="fa fa-television fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120">' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left; padding-left: 15px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'episode') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Episode"><i class="fa fa-television fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=450&fallback=poster" data-height="120">E' + rowData['media_index'] + ' - ' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left; padding-left: 30px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'artist') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Artist"><i class="fa fa-music fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=300&fallback=poster" data-height="80">' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'album') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Album"><i class="fa fa-music fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=300&fallback=poster" data-height="80">' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left; padding-left: 15px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type'] === 'track') {
media_type = '<span class="media-type-tooltip" data-toggle="tooltip" title="Track"><i class="fa fa-music fa-fw"></i></span>';
thumb_popover = '<span class="thumb-tooltip" data-toggle="popover" data-img="pms_image_proxy?img=' + rowData['thumb'] + '&width=300&height=300&fallback=poster" data-height="80">T' + rowData['media_index'] + ' - ' + cellData + '</span>'
$(td).html('<div class="history-title"><a href="info?rating_key=' + rowData['rating_key'] + '"><div style="float: left; padding-left: 30px;">' + media_type + '&nbsp;' + thumb_popover + '</div></a></div>');
} else {
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
}
}
},
"width": "26%"
},
{
"targets": [2],
"data": "container",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "5%",
"className": "no-wrap hidden-sm hidden-xs"
},
{
"targets": [3],
"data": "bitrate",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData + ' kbps');
}
},
"width": "5%",
"className": "no-wrap hidden-md hidden-sm hidden-xs",
"searchable": false
},
{
"targets": [4],
"data": "video_codec",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "8%",
"className": "no-wrap hidden-sm hidden-xs"
},
{
"targets": [5],
"data": "video_resolution",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "8%",
"className": "no-wrap hidden-md hidden-sm hidden-xs"
},
{
"targets": [6],
"data": "video_framerate",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "8%",
"className": "no-wrap hidden-md hidden-sm hidden-xs"
},
{
"targets": [7],
"data": "audio_codec",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "8%",
"className": "no-wrap hidden-sm hidden-xs"
},
{
"targets": [8],
"data": "audio_channels",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData + ' ch');
}
},
"width": "8%",
"className": "no-wrap hidden-md hidden-sm hidden-xs"
},
{
"targets": [9],
"data": "file_size",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(Math.round(cellData / 1024 / 1000).toString() + ' MB');
}
},
"width": "5%",
"className": "no-wrap hidden-md hidden-sm hidden-xs",
"searchable": false
},
{
"targets": [10],
"data": "last_watched",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
date = moment(cellData, "X").format(date_format);
$(td).html(date);
}
},
"width": "7%",
"className": "no-wrap hidden-xs",
"searchable": false
},
{
"targets": [11],
"data": "play_count",
"createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== null && cellData !== '') {
$(td).html(cellData);
}
},
"width": "5%",
"className": "no-wrap hidden-xs",
"searchable": false
}
],
"drawCallback": function (settings) {
// Jump to top of page
// $('html,body').scrollTop(0);
$('#ajaxMsg').fadeOut();
// Create the tooltips.
$('.expand-media-info-tooltip').tooltip({ container: 'body' });
$('.media-type-tooltip').tooltip({ container: 'body' });
$('.thumb-tooltip').popover({
html: true,
container: 'body',
trigger: 'hover',
placement: 'right',
content: function () {
return '<div class="history-thumbnail" style="background-image: url(' + $(this).data('img') + '); height: ' + $(this).data('height') + 'px;" />';
}
});
media_info_table.rows().every(function () {
var rowData = this.data();
if (rowData['rating_key'] in media_info_child_table) {
// if a child table was already created
$(this.node()).find('i.fa.fa-plus-circle').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle');
this.child(childTableFormatMedia(rowData)).show();
createChildTableMedia(this, rowData)
}
});
},
"preDrawCallback": function(settings) {
var msg = "<i class='fa fa-refresh fa-spin'></i>&nbspFetching rows...";
showMsg(msg, false, false, 0)
},
"rowCallback": function (row, rowData, rowIndex) {
if (rowData['rating_key'] in media_info_child_table) {
// if a child table was already created
$(row).addClass('shown')
media_info_table.row(row).child(childTableFormatMedia(rowData)).show();
}
}
}
// Parent table expand detailed media info
$('#media_info_table').on('click', '> tbody > tr > td.expand-media-info a', function () {
var tr = $(this).closest('tr');
var row = media_info_table.row(tr);
var rowData = row.data();
$(this).find('i.fa').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle');
if (row.child.isShown()) {
$('div.slider', row.child()).slideUp(function () {
row.child.hide();
tr.removeClass('shown');
delete media_info_child_table[rowData['rating_key']];
});
} else {
tr.addClass('shown');
row.child(childTableFormatMedia(rowData)).show();
createChildTableMedia(row, rowData);
}
});
// Initialize the detailed media info child table options using the parent table options
function childTableOptionsMedia(rowData) {
switch (rowData['section_type']) {
case 'show':
section_type = 'season';
break;
case 'season':
section_type = 'episode';
break;
case 'artist':
section_type = 'album';
break;
case 'album':
section_type = 'track';
break;
}
media_info_table_options = media_info_table_options;
// Remove settings that are not necessary
media_info_table_options.searching = false;
media_info_table_options.lengthChange = false;
media_info_table_options.info = false;
media_info_table_options.pageLength = 10;
media_info_table_options.bStateSave = false;
media_info_table_options.ajax = {
url: 'get_library_media_info2',
type: 'post',
data: function (d) {
return {
json_data: JSON.stringify(d),
section_id: rowData['section_id'],
section_type: section_type,
rating_key: rowData['rating_key']
};
}
}
media_info_table_options.fnDrawCallback = function (settings) {
$('#ajaxMsg').fadeOut();
// Create the tooltips.
$('.expand-media-info-tooltip').tooltip({ container: 'body' });
$('.media-type-tooltip').tooltip();
$('.thumb-tooltip').popover({
html: true,
trigger: 'hover',
placement: 'right',
content: function () {
return '<div class="history-thumbnail" style="background-image: url(' + $(this).data('img') + '); height: ' + $(this).data('height') + 'px;" />';
}
});
if (rowData['rating_key'] in media_info_child_table) {
media_info_child_table[rowData['rating_key']].rows().every(function () {
var childrowData = this.data();
if (childrowData['rating_key'] in media_info_child_table) {
// if a child table was already created
$(this.node()).find('i.fa.fa-plus-circle').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle');
this.child(childTableFormatMedia(childrowData)).show();
createChildTableMedia(this, childrowData)
}
});
}
$(this).closest('div.slider').slideDown();
}
media_info_table_options.fnRowCallback = function (row, rowData, rowIndex) {
if (rowData['rating_key'] in media_info_child_table) {
// if a child table was already created
$(row).addClass('shown')
media_info_table.row(row).child(childTableFormatMedia(rowData)).show();
}
}
return media_info_table_options;
}
// Format the detailed media info child table
function childTableFormatMedia(rowData) {
return '<div class="slider">' +
'<table id="media_info_child-' + rowData['rating_key'] + '" data-id="' + rowData['rating_key'] + '" width="100%">' +
'<thead>' +
'<tr>' +
'<th align="left" id="added_at">Added At</th>' +
'<th align="left" id="title">Title</th>' +
'<th align="left" id="container">Container</th>' +
'<th align="left" id="bitrate">Bitrate</th>' +
'<th align="left" id="video_codec">Video Codec</th>' +
'<th align="left" id="video_resolution">Video Resolution</th>' +
'<th align="left" id="video_resolution">Video Framerate</th>' +
'<th align="left" id="audio_codec">Audio Codec</th>' +
'<th align="left" id="audio_channels">Audio Channels</th>' +
'<th align="left" id="file_size">File Size</th>' +
'<th align="left" id="last_watched">Last Watched</th>' +
'<th align="left" id="total_plays">Total Plays</th>' +
'</tr>' +
'</thead>' +
'<tbody>' +
'</tbody>' +
'</table>' +
'</div>';
}
// Create the detailed media info child table
media_info_child_table = {};
function createChildTableMedia(row, rowData) {
media_info_table_options = childTableOptionsMedia(rowData);
// initialize the child table
media_info_child_table[rowData['rating_key']] = $('#media_info_child-' + rowData['rating_key']).DataTable(media_info_table_options);
// Set child table column visibility to match parent table
var visibility = media_info_table.columns().visible();
for (var i = 0; i < visibility.length; i++) {
if (!(visibility[i])) { media_info_child_table[rowData['rating_key']].column(i).visible(visibility[i]); }
}
media_info_table.on('column-visibility', function (e, settings, colIdx, visibility) {
if (row.child.isShown()) {
media_info_child_table[rowData['rating_key']].column(colIdx).visible(visibility);
}
});
// Child table expand detailed media info
$('table[id^=media_info_child]').on('click', '> tbody > tr > td.expand-media-info a', function () {
var table_id = $(this).closest('table').data('id');
var tr = $(this).closest('tr');
var row = media_info_child_table[table_id].row(tr);
var rowData = row.data();
$(this).find('i.fa').toggleClass('fa-plus-circle').toggleClass('fa-minus-circle');
if (row.child.isShown()) {
$('div.slider', row.child()).slideUp(function () {
row.child.hide();
tr.removeClass('shown');
delete media_info_child_table[rowData['rating_key']];
});
} else {
tr.addClass('shown');
row.child(childTableFormatMedia(rowData)).show();
createChildTableMedia(row, rowData);
}
});
}

View file

@ -4,7 +4,7 @@ var plex_log_table_options = {
"serverSide": false, "serverSide": false,
"pagingType": "bootstrap", "pagingType": "bootstrap",
"order": [ 0, 'desc'], "order": [ 0, 'desc'],
"pageLength": 10, "pageLength": 50,
"stateSave": true, "stateSave": true,
"language": { "language": {
"search":"Search: ", "search":"Search: ",

View file

@ -54,13 +54,13 @@ users_list_table_options = {
"targets": [2], "targets": [2],
"data": "friendly_name", "data": "friendly_name",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '">' + $(td).html('<div class="edit-user-name" data-id="' + rowData['user_id'] + '">' +
'<a href="user?user_id=' + rowData['user_id'] + '">' + cellData + '</a>' + '<a href="user?user_id=' + rowData['user_id'] + '">' + cellData + '</a>' +
'<input type="text" class="hidden" value="' + cellData + '">' + '<input type="text" class="hidden" value="' + cellData + '">' +
'</div>'); '</div>');
} else { } else {
$(td).html(cellData); $(td).html('n/a');
} }
}, },
"width": "10%", "width": "10%",
@ -69,11 +69,11 @@ users_list_table_options = {
{ {
"targets": [3], "targets": [3],
"data": "last_seen", "data": "last_seen",
"render": function ( data, type, full ) { "createdCell": function (td, cellData, rowData, row, col) {
if (data) { if (cellData !== null && cellData !== '') {
return moment(data, "X").fromNow(); $(td).html(moment(cellData, "X").fromNow());
} else { } else {
return "never"; $(td).html("never");
} }
}, },
"searchable": false, "searchable": false,
@ -105,7 +105,7 @@ users_list_table_options = {
"targets": [5], "targets": [5],
"data": "platform", "data": "platform",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
$(td).html(cellData); $(td).html(cellData);
} else { } else {
$(td).html('n/a'); $(td).html('n/a');
@ -118,7 +118,7 @@ users_list_table_options = {
"targets": [6], "targets": [6],
"data":"player", "data":"player",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData) { if (cellData !== null && cellData !== '') {
var transcode_dec = ''; var transcode_dec = '';
if (rowData['video_decision'] === 'transcode') { if (rowData['video_decision'] === 'transcode') {
transcode_dec = '<span class="transcode-tooltip" data-toggle="tooltip" title="Transcode"><i class="fa fa-server fa-fw"></i></span>'; transcode_dec = '<span class="transcode-tooltip" data-toggle="tooltip" title="Transcode"><i class="fa fa-server fa-fw"></i></span>';
@ -139,7 +139,7 @@ users_list_table_options = {
"targets": [7], "targets": [7],
"data":"last_watched", "data":"last_watched",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
if (cellData !== '') { if (cellData !== null && cellData !== '') {
var media_type = ''; var media_type = '';
var thumb_popover = '' var thumb_popover = ''
if (rowData['media_type'] === 'movie') { if (rowData['media_type'] === 'movie') {
@ -156,10 +156,10 @@ users_list_table_options = {
$(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp' + thumb_popover + '</div></a></div>'); $(td).html('<div class="history-title"><a href="info?source=history&rating_key=' + rowData['rating_key'] + '"><div style="float: left;">' + media_type + '&nbsp' + thumb_popover + '</div></a></div>');
} else if (rowData['media_type']) { } else if (rowData['media_type']) {
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>'); $(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
}
} else { } else {
$(td).html('n/a'); $(td).html('n/a');
} }
}
}, },
"width": "30%", "width": "30%",
"className": "hidden-sm hidden-xs" "className": "hidden-sm hidden-xs"

View file

@ -7,6 +7,17 @@
<%def name="body()"> <%def name="body()">
<div class='container-fluid'> <div class='container-fluid'>
% if config['update_section_ids'] == 1:
<div id="update_section_ids_mssage" style="text-align: center; margin-top: 20px;">
<i class="fa fa-exclamation-triangle"></i> PlexPy needs to update the Library IDs in your databse. Click the "<strong>Refresh libraries</strong>" button below to begin the update.
</div>
% elif config['update_section_ids'] == -1:
<div id="update_section_ids_mssage" style="text-align: center; margin-top: 20px;">
<i class="fa fa-refresh fa-spin"></i> PlexPy is updating library IDs in the database. This could take a few minutes depending on the size of your database.
<br />
You may leave this page and come back later.
</div>
% endif
<div class='table-card-header'> <div class='table-card-header'>
<div class="header-bar"> <div class="header-bar">
<span><i class="fa fa-book"></i> All Libraries</span> <span><i class="fa fa-book"></i> All Libraries</span>
@ -20,7 +31,7 @@
</div> </div>
</div> </div>
<div class='table-card-back'> <div class='table-card-back'>
<table id="libraries_list_table" class="display" width="100%"> <table id="libraries_list_table" class="display no-fixed" width="100%">
<thead> <thead>
<tr> <tr>
<th align="left" id="edit_row">Edit</th> <th align="left" id="edit_row">Edit</th>
@ -74,7 +85,9 @@
url: 'get_library_list', url: 'get_library_list',
type: 'POST', type: 'POST',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ) }; return {
json_data: JSON.stringify(d)
};
} }
} }
@ -157,7 +170,15 @@
}); });
}); });
$("#refresh-libraries-list").click(function() { $("#refresh-libraries-list").click(function () {
if ("${config['update_section_ids']}" == "1") {
$('#update_section_ids_mssage').html(
'<i class="fa fa-refresh fa-spin"></i> PlexPy is updating library IDs in the database. This could take a few minutes depending on the size of your database.' +
'<br />' +
'You may leave this page and come back later.');
$(this).prop('disabled', true);
}
$.ajax({ $.ajax({
url: 'refresh_libraries_list', url: 'refresh_libraries_list',
cache: false, cache: false,
@ -173,5 +194,9 @@
} }
}); });
}); });
if ("${config['update_section_ids']}" == "-1") {
$("#refresh-libraries-list").prop('disabled', true);
}
</script> </script>
</%def> </%def>

View file

@ -67,6 +67,7 @@ DOCUMENTATION :: END
<ul class="user-info-nav"> <ul class="user-info-nav">
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li> <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> <li><a id="history-tab-btn" href="#libraryHistory" data-toggle="tab">History</a></li>
<li><a id="media-info-tab-btn" href="#libraryMediaInfo" data-toggle="tab">Media Info</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -170,18 +171,62 @@ DOCUMENTATION :: END
<table class="display" id="history_table" width="100%"> <table class="display" id="history_table" width="100%">
<thead> <thead>
<tr> <tr>
<th align='left' id="delete">Delete</th> <th align="left" id="delete">Delete</th>
<th align='left' id="time">Time</th> <th align="left" id="time">Time</th>
<th align='left' id="friendly_name">User</th> <th align="left" id="friendly_name">User</th>
<th align='left' id="ip_address">IP Address</th> <th align="left" id="ip_address">IP Address</th>
<th align='left' id="platform">Platform</th> <th align="left" id="platform">Platform</th>
<th align='left' id="player">Player</th> <th align="left" id="player">Player</th>
<th align='left' id="title">Title</th> <th align="left" id="title">Title</th>
<th align='left' id="started">Started</th> <th align="left" id="started">Started</th>
<th align='left' id="paused_counter">Paused</th> <th align="left" id="paused_counter">Paused</th>
<th align='left' id="stopped">Stopped</th> <th align="left" id="stopped">Stopped</th>
<th align='left' id="duration">Duration</th> <th align="left" id="duration">Duration</th>
<th align='left' id="percent_complete"></th> <th align="left" id="percent_complete"></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane" id="libraryMediaInfo">
<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> All Media Info for <strong>
<span class="set-username">${data['section_name']}</span>
</strong>
</span>
</div>
<div class="button-bar">
<button class="btn btn-dark refresh-media-info-table-button" id="refresh-media-info-table" style="margin-right: 5px;">
<i class="fa fa-refresh"></i> Refresh media info
</button>
<div class="colvis-button-bar hidden-xs" id="button-bar-media-info"></div>
</div>
</div>
<div class="table-card-back">
<table class="display" id="media_info_table" width="100%">
<thead>
<tr>
<th align="left" id="added_at">Added At</th>
<th align="left" id="title">Title</th>
<th align="left" id="container">Container</th>
<th align="left" id="bitrate">Bitrate</th>
<th align="left" id="video_codec">Video Codec</th>
<th align="left" id="video_resolution">Video Resolution</th>
<th align="left" id="video_resolution">Video Framerate</th>
<th align="left" id="audio_codec">Audio Codec</th>
<th align="left" id="audio_channels">Audio Channels</th>
<th align="left" id="file_size">File Size</th>
<th align="left" id="last_watched">Last Watched</th>
<th align="left" id="total_plays">Total Plays</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
@ -250,6 +295,7 @@ DOCUMENTATION :: END
% if data: % if data:
<script src="interfaces/default/js/moment-with-locale.js"></script> <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/history_table.js"></script>
<script src="interfaces/default/js/tables/media_info_table.js"></script>
<script> <script>
$(document).ready(function () { $(document).ready(function () {
@ -267,7 +313,7 @@ DOCUMENTATION :: END
$.ajax({ $.ajax({
url: 'get_library_watch_time_stats', url: 'get_library_watch_time_stats',
async: true, async: true,
data: { library_id: section_id }, data: { section_id: section_id },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-time-stats").html(xhr.responseText); $("#library-time-stats").html(xhr.responseText);
} }
@ -277,7 +323,7 @@ DOCUMENTATION :: END
$.ajax({ $.ajax({
url: 'get_library_user_stats', url: 'get_library_user_stats',
async: true, async: true,
data: { library_id: section_id }, data: { section_id: section_id },
complete: function(xhr, status) { complete: function(xhr, status) {
$("#library-user-stats").html(xhr.responseText); $("#library-user-stats").html(xhr.responseText);
} }
@ -290,8 +336,8 @@ DOCUMENTATION :: END
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { return {
'json_data': JSON.stringify( d ), json_data: JSON.stringify( d ),
'section_id': section_id section_id: section_id
}; };
} }
} }
@ -304,9 +350,44 @@ DOCUMENTATION :: END
clearSearchButton('history_table', history_table); clearSearchButton('history_table', history_table);
} }
function loadMediaInfoTable() {
// Build media info table
media_info_table_options.ajax = {
url: 'get_library_media_info2',
type: 'post',
data: function ( d ) {
return {
json_data: JSON.stringify( d ),
section_id: section_id
};
}
}
media_info_table = $('#media_info_table').DataTable(media_info_table_options);
var colvis = new $.fn.dataTable.ColVis(media_info_table, { buttonText: '<i class="fa fa-columns"></i> Select columns', buttonClass: 'btn btn-dark' });
$(colvis.button()).appendTo('#button-bar-media-info');
clearSearchButton('media_info_table', media_info_table);
}
$( "#history-tab-btn" ).one( "click", function() { $( "#history-tab-btn" ).one( "click", function() {
loadHistoryTable(); loadHistoryTable();
}); });
$( "#media-info-tab-btn" ).one( "click", function() {
loadMediaInfoTable();
});
$("#refresh-media-info-table").click(function () {
$.ajax({
url: 'delete_datatable_media_info_cache',
cache: false,
async: true,
data: { section_id: section_id },
complete: function(xhr, status) {
media_info_table.draw()
}
});
});
// Load edit library modal // Load edit library modal
$("#toggle-edit-library-modal").click(function() { $("#toggle-edit-library-modal").click(function() {
@ -374,7 +455,7 @@ DOCUMENTATION :: END
url: 'get_library_recently_watched', url: 'get_library_recently_watched',
async: true, async: true,
data: { data: {
library_id: section_id, section_id: section_id,
limit: containerSize limit: containerSize
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
@ -398,7 +479,7 @@ DOCUMENTATION :: END
url: 'get_library_recently_added', url: 'get_library_recently_added',
async: true, async: true,
data: { data: {
library_id: section_id, section_id: section_id,
limit: containerSize limit: containerSize
}, },
complete: function(xhr, status) { complete: function(xhr, status) {
@ -413,8 +494,9 @@ DOCUMENTATION :: END
recentlyWatched(); recentlyWatched();
recentlyAdded(); recentlyAdded();
}); });
});
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 }); $('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
});
</script> </script>
% endif % endif
</%def> </%def>

View file

@ -19,7 +19,7 @@ parent_title Returns the name of the artist.
grandparent_title Returns the name of the show. grandparent_title Returns the name of the show.
media_index Returns the index number of the episode. media_index Returns the index number of the episode.
parent_media_index Returns the index number of the season. parent_media_index Returns the index number of the season.
library_id Returns the library section number of the media item. section_id Returns the library section number of the media item.
library_name Returns the library section name of the media item. library_name Returns the library section name of the media item.
year Returns the release year of the movie, episode, or album. year Returns the release year of the movie, episode, or album.
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.
@ -39,7 +39,11 @@ DOCUMENTATION :: END
<a href="info?rating_key=${item['rating_key']}"> <a href="info?rating_key=${item['rating_key']}">
<div class="dashboard-recent-media-poster"> <div class="dashboard-recent-media-poster">
% if item['media_type'] == 'episode': % if item['media_type'] == 'episode':
% if item['parent_thumb']:
<div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['parent_thumb']}&width=300&height=450&fallback=poster);"> <div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['parent_thumb']}&width=300&height=450&fallback=poster);">
% else:
<div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['grandparent_thumb']}&width=300&height=450&fallback=poster);">
% endif
% elif item['media_type'] == 'movie': % elif item['media_type'] == 'movie':
<div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['thumb']}&width=300&height=450&fallback=poster);"> <div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['thumb']}&width=300&height=450&fallback=poster);">
% endif % endif

View file

@ -19,7 +19,7 @@ parent_title Returns the name of the artist.
grandparent_title Returns the name of the show. grandparent_title Returns the name of the show.
media_index Returns the index number of the episode. media_index Returns the index number of the episode.
parent_media_index Returns the index number of the season. parent_media_index Returns the index number of the season.
library_id Returns the library section number of the media item. section_id Returns the library section number of the media item.
library_name Returns the library section name of the media item. library_name Returns the library section name of the media item.
year Returns the release year of the movie, episode, or album. year Returns the release year of the movie, episode, or album.
thumb Returns the location of the item's thumbnail. Use with pms_image_proxy. thumb Returns the location of the item's thumbnail. Use with pms_image_proxy.

View file

@ -181,18 +181,18 @@ from plexpy import helpers
<table class="display" id="history_table" width="100%"> <table class="display" id="history_table" width="100%">
<thead> <thead>
<tr> <tr>
<th align='left' id="delete">Delete</th> <th align="left" id="delete">Delete</th>
<th align='left' id="time">Time</th> <th align="left" id="time">Time</th>
<th align='left' id="friendly_name">User</th> <th align="left" id="friendly_name">User</th>
<th align='left' id="ip_address">IP Address</th> <th align="left" id="ip_address">IP Address</th>
<th align='left' id="platform">Platform</th> <th align="left" id="platform">Platform</th>
<th align='left' id="player">Player</th> <th align="left" id="player">Player</th>
<th align='left' id="title">Title</th> <th align="left" id="title">Title</th>
<th align='left' id="started">Started</th> <th align="left" id="started">Started</th>
<th align='left' id="paused_counter">Paused</th> <th align="left" id="paused_counter">Paused</th>
<th align='left' id="stopped">Stopped</th> <th align="left" id="stopped">Stopped</th>
<th align='left' id="duration">Duration</th> <th align="left" id="duration">Duration</th>
<th align='left' id="percent_complete"></th> <th align="left" id="percent_complete"></th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
@ -221,17 +221,17 @@ from plexpy import helpers
<table class="display" id="sync_table" width="100%"> <table class="display" id="sync_table" width="100%">
<thead> <thead>
<tr> <tr>
<th align='left' id="state">State</th> <th align="left" id="state">State</th>
<th align='left' id="username">Username</th> <th align="left" id="username">Username</th>
<th align='left' id="sync_title">Title</th> <th align="left" id="sync_title">Title</th>
<th align='left' id="type">Type</th> <th align="left" id="type">Type</th>
<th align='left' id="sync_platform">Platform</th> <th align="left" id="sync_platform">Platform</th>
<th align='left' id="device">Device</th> <th align="left" id="device">Device</th>
<th align='left' id="size">Total Size</th> <th align="left" id="size">Total Size</th>
<th align='left' id="items">Total Items</th> <th align="left" id="items">Total Items</th>
<th align='left' id="converted">Converted</th> <th align="left" id="converted">Converted</th>
<th align='left' id="downloaded">Downloaded</th> <th align="left" id="downloaded">Downloaded</th>
<th align='left' id="sync_percent_complete">Complete</th> <th align="left" id="sync_percent_complete">Complete</th>
</tr> </tr>
</thead> </thead>
<tbody></tbody> <tbody></tbody>
@ -342,9 +342,9 @@ from plexpy import helpers
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { return {
'json_data': JSON.stringify( d ), json_data: JSON.stringify( d ),
'user_id': user_id, user_id: user_id,
'media_type': media_type media_type: media_type
}; };
} }
} }
@ -391,8 +391,9 @@ from plexpy import helpers
url: 'get_user_ips', url: 'get_user_ips',
type: 'post', type: 'post',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ), return {
'user_id': user_id json_data: JSON.stringify( d ),
user_id: user_id
}; };
} }
} }

View file

@ -20,7 +20,7 @@
</div> </div>
</div> </div>
<div class='table-card-back'> <div class='table-card-back'>
<table id="users_list_table" class="display" width="100%"> <table id="users_list_table" class="display no-fixed" width="100%">
<thead> <thead>
<tr> <tr>
<th align="left" id="edit_row">Edit</th> <th align="left" id="edit_row">Edit</th>
@ -77,7 +77,9 @@
url: 'get_user_list', url: 'get_user_list',
type: 'POST', type: 'POST',
data: function ( d ) { data: function ( d ) {
return { 'json_data': JSON.stringify( d ) }; return {
json_data: JSON.stringify(d)
};
} }
} }

View file

@ -377,7 +377,7 @@ def dbcheck():
# sessions table :: This is a temp table that logs currently active sessions # sessions table :: This is a temp table that logs currently active sessions
c_db.execute( c_db.execute(
'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, ' 'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, '
'session_key INTEGER, rating_key INTEGER, library_id INTEGER, media_type TEXT, started INTEGER, ' 'session_key INTEGER, rating_key INTEGER, section_id INTEGER, media_type TEXT, started INTEGER, '
'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, ' 'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, '
'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, ' 'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, '
'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, ' 'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
@ -413,7 +413,7 @@ def dbcheck():
'CREATE TABLE IF NOT EXISTS session_history_metadata (id INTEGER PRIMARY KEY, ' 'CREATE TABLE IF NOT EXISTS session_history_metadata (id INTEGER PRIMARY KEY, '
'rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, ' 'rating_key INTEGER, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
'title TEXT, parent_title TEXT, grandparent_title TEXT, full_title TEXT, media_index INTEGER, ' 'title TEXT, parent_title TEXT, grandparent_title TEXT, full_title TEXT, media_index INTEGER, '
'parent_media_index INTEGER, library_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, ' 'parent_media_index INTEGER, section_id INTEGER, thumb TEXT, parent_thumb TEXT, grandparent_thumb TEXT, '
'art TEXT, media_type TEXT, year INTEGER, originally_available_at TEXT, added_at INTEGER, updated_at INTEGER, ' 'art TEXT, media_type TEXT, year INTEGER, originally_available_at TEXT, added_at INTEGER, updated_at INTEGER, '
'last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, ' 'last_viewed_at INTEGER, content_rating TEXT, summary TEXT, tagline TEXT, rating TEXT, '
'duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT)' 'duration INTEGER DEFAULT 0, guid TEXT, directors TEXT, writers TEXT, actors TEXT, genres TEXT, studio TEXT)'
@ -594,11 +594,11 @@ def dbcheck():
# Upgrade sessions table from earlier versions # Upgrade sessions table from earlier versions
try: try:
c_db.execute('SELECT library_id from sessions') c_db.execute('SELECT section_id from sessions')
except sqlite3.OperationalError: except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table sessions.") logger.debug(u"Altering database. Updating database table sessions.")
c_db.execute( c_db.execute(
'ALTER TABLE sessions ADD COLUMN library_id INTEGER' 'ALTER TABLE sessions ADD COLUMN section_id INTEGER'
) )
# Upgrade session_history table from earlier versions # Upgrade session_history table from earlier versions
@ -644,11 +644,11 @@ def dbcheck():
# Upgrade session_history_metadata table from earlier versions # Upgrade session_history_metadata table from earlier versions
try: try:
c_db.execute('SELECT library_id from session_history_metadata') c_db.execute('SELECT section_id from session_history_metadata')
except sqlite3.OperationalError: except sqlite3.OperationalError:
logger.debug(u"Altering database. Updating database table session_history_metadata.") logger.debug(u"Altering database. Updating database table session_history_metadata.")
c_db.execute( c_db.execute(
'ALTER TABLE session_history_metadata ADD COLUMN library_id INTEGER' 'ALTER TABLE session_history_metadata ADD COLUMN section_id INTEGER'
) )
# Upgrade users table from earlier versions # Upgrade users table from earlier versions

View file

@ -192,7 +192,7 @@ def check_recently_added():
recently_added = recently_added_list['recently_added'] recently_added = recently_added_list['recently_added']
for item in recently_added: for item in recently_added:
library_details = library_data.get_details(section_id=item['library_id']) library_details = library_data.get_details(section_id=item['section_id'])
if not library_details['do_notify_created']: if not library_details['do_notify_created']:
continue continue
@ -221,7 +221,7 @@ def check_recently_added():
if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT: if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
for item in metadata: for item in metadata:
library_details = library_data.get_details(section_id=item['library_id']) library_details = library_data.get_details(section_id=item['section_id'])
if 0 < time_threshold - int(item['added_at']) <= time_interval: if 0 < time_threshold - int(item['added_at']) <= time_interval:
logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key'])) logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key']))

View file

@ -29,7 +29,7 @@ class ActivityProcessor(object):
def write_session(self, session=None, notify=True): def write_session(self, session=None, notify=True):
if session: if session:
values = {'session_key': session['session_key'], values = {'session_key': session['session_key'],
'library_id': session['library_id'], 'section_id': session['section_id'],
'rating_key': session['rating_key'], 'rating_key': session['rating_key'],
'media_type': session['media_type'], 'media_type': session['media_type'],
'state': session['state'], 'state': session['state'],
@ -104,7 +104,7 @@ class ActivityProcessor(object):
user_details = user_data.get_details(user_id=session['user_id']) user_details = user_data.get_details(user_id=session['user_id'])
library_data = libraries.Libraries() library_data = libraries.Libraries()
library_details = library_data.get_details(section_id=session['library_id']) library_details = library_data.get_details(section_id=session['section_id'])
if session: if session:
logging_enabled = False logging_enabled = False
@ -257,7 +257,7 @@ class ActivityProcessor(object):
# logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...") # logger.debug(u"PlexPy ActivityProcessor :: Attempting to write to session_history_metadata table...")
query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \ query = 'INSERT INTO session_history_metadata (id, rating_key, parent_rating_key, ' \
'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \ 'grandparent_rating_key, title, parent_title, grandparent_title, full_title, media_index, ' \
'parent_media_index, library_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \ 'parent_media_index, section_id, thumb, parent_thumb, grandparent_thumb, art, media_type, ' \
'year, originally_available_at, added_at, updated_at, last_viewed_at, content_rating, ' \ 'year, originally_available_at, added_at, updated_at, last_viewed_at, content_rating, ' \
'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \ 'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \
'(last_insert_rowid(), ' \ '(last_insert_rowid(), ' \
@ -265,7 +265,7 @@ class ActivityProcessor(object):
args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'], args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'],
session['title'], session['parent_title'], session['grandparent_title'], full_title, session['title'], session['parent_title'], session['grandparent_title'], full_title,
metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'], metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'],
metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], session['media_type'], metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], session['media_type'],
metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'], metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'], metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],

View file

@ -372,7 +372,7 @@ _CONFIG_DEFINITIONS = {
'TWITTER_ON_EXTUP': (int, 'Twitter', 0), 'TWITTER_ON_EXTUP': (int, 'Twitter', 0),
'TWITTER_ON_INTUP': (int, 'Twitter', 0), 'TWITTER_ON_INTUP': (int, 'Twitter', 0),
'UPDATE_DB_INTERVAL': (int, 'General', 24), 'UPDATE_DB_INTERVAL': (int, 'General', 24),
'UPDATE_LIBRARY_IDS': (int, 'General', 1), 'UPDATE_SECTION_IDS': (int, 'General', 1),
'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1), 'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1),
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1), 'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
'XBMC_ENABLED': (int, 'XBMC', 0), 'XBMC_ENABLED': (int, 'XBMC', 0),

View file

@ -98,12 +98,12 @@ class DataFactory(object):
for item in history: for item in history:
filter_duration += int(item['duration']) filter_duration += int(item['duration'])
if item["media_type"] == 'episode' and item["parent_thumb"]: if item['media_type'] == 'episode' and item['parent_thumb']:
thumb = item["parent_thumb"] thumb = item['parent_thumb']
elif item["media_type"] == 'episode': elif item['media_type'] == 'episode':
thumb = item["grandparent_thumb"] thumb = item['grandparent_thumb']
else: else:
thumb = item["thumb"] thumb = item['thumb']
if item['percent_complete'] >= watched_percent: if item['percent_complete'] >= watched_percent:
watched_status = 1 watched_status = 1
@ -113,37 +113,37 @@ class DataFactory(object):
watched_status = 0 watched_status = 0
# Rename Mystery platform names # Rename Mystery platform names
platform = common.PLATFORM_NAME_OVERRIDES.get(item["platform"], item["platform"]) platform = common.PLATFORM_NAME_OVERRIDES.get(item['platform'], item['platform'])
row = {"reference_id": item["reference_id"], row = {'reference_id': item['reference_id'],
"id": item["id"], 'id': item['id'],
"date": item["date"], 'date': item['date'],
"started": item["started"], 'started': item['started'],
"stopped": item["stopped"], 'stopped': item['stopped'],
"duration": item["duration"], 'duration': item['duration'],
"paused_counter": item["paused_counter"], 'paused_counter': item['paused_counter'],
"user_id": item["user_id"], 'user_id': item['user_id'],
"user": item["user"], 'user': item['user'],
"friendly_name": item["friendly_name"], 'friendly_name': item['friendly_name'],
"platform": platform, 'platform': platform,
"player": item['player'], 'player': item['player'],
"ip_address": item["ip_address"], 'ip_address': item['ip_address'],
"media_type": item["media_type"], 'media_type': item['media_type'],
"rating_key": item["rating_key"], 'rating_key': item['rating_key'],
"parent_rating_key": item["parent_rating_key"], 'parent_rating_key': item['parent_rating_key'],
"grandparent_rating_key": item["grandparent_rating_key"], 'grandparent_rating_key': item['grandparent_rating_key'],
"full_title": item["full_title"], 'full_title': item['full_title'],
"parent_title": item["parent_title"], 'parent_title': item['parent_title'],
"year": item["year"], 'year': item['year'],
"media_index": item["media_index"], 'media_index': item['media_index'],
"parent_media_index": item["parent_media_index"], 'parent_media_index': item['parent_media_index'],
"thumb": thumb, 'thumb': thumb,
"video_decision": item["video_decision"], 'video_decision': item['video_decision'],
"audio_decision": item["audio_decision"], 'audio_decision': item['audio_decision'],
"percent_complete": int(round(item['percent_complete'])), 'percent_complete': int(round(item['percent_complete'])),
"watched_status": watched_status, 'watched_status': watched_status,
"group_count": item["group_count"], 'group_count': item['group_count'],
"group_ids": item["group_ids"] 'group_ids': item['group_ids']
} }
rows.append(row) rows.append(row)
@ -736,7 +736,7 @@ class DataFactory(object):
'session_history_metadata.parent_title, session_history_metadata.grandparent_title, ' \ 'session_history_metadata.parent_title, session_history_metadata.grandparent_title, ' \
'session_history_metadata.full_title, library_sections.section_name, ' \ 'session_history_metadata.full_title, library_sections.section_name, ' \
'session_history_metadata.media_index, session_history_metadata.parent_media_index, ' \ 'session_history_metadata.media_index, session_history_metadata.parent_media_index, ' \
'session_history_metadata.library_id, session_history_metadata.thumb, ' \ 'session_history_metadata.section_id, session_history_metadata.thumb, ' \
'session_history_metadata.parent_thumb, session_history_metadata.grandparent_thumb, ' \ 'session_history_metadata.parent_thumb, session_history_metadata.grandparent_thumb, ' \
'session_history_metadata.art, session_history_metadata.media_type, session_history_metadata.year, ' \ 'session_history_metadata.art, session_history_metadata.media_type, session_history_metadata.year, ' \
'session_history_metadata.originally_available_at, session_history_metadata.added_at, ' \ 'session_history_metadata.originally_available_at, session_history_metadata.added_at, ' \
@ -746,7 +746,7 @@ class DataFactory(object):
'session_history_metadata.guid, session_history_metadata.directors, session_history_metadata.writers, ' \ 'session_history_metadata.guid, session_history_metadata.directors, session_history_metadata.writers, ' \
'session_history_metadata.actors, session_history_metadata.genres, session_history_metadata.studio ' \ 'session_history_metadata.actors, session_history_metadata.genres, session_history_metadata.studio ' \
'FROM session_history_metadata ' \ 'FROM session_history_metadata ' \
'JOIN library_sections ON session_history_metadata.library_id = library_sections.section_id ' \ 'JOIN library_sections ON session_history_metadata.section_id = library_sections.section_id ' \
'WHERE session_history_metadata.rating_key = ?' 'WHERE session_history_metadata.rating_key = ?'
result = monitor_db.select(query=query, args=[rating_key]) result = monitor_db.select(query=query, args=[rating_key])
else: else:
@ -789,7 +789,7 @@ class DataFactory(object):
'genres': genres, 'genres': genres,
'actors': actors, 'actors': actors,
'library_name': item['section_name'], 'library_name': item['section_name'],
'library_id': item['library_id'] 'section_id': item['section_id']
} }
return metadata return metadata
@ -1056,7 +1056,7 @@ class DataFactory(object):
# Update the session_history_metadata table # Update the session_history_metadata table
query = 'UPDATE session_history_metadata SET rating_key = ?, parent_rating_key = ?, ' \ query = 'UPDATE session_history_metadata SET rating_key = ?, parent_rating_key = ?, ' \
'grandparent_rating_key = ?, title = ?, parent_title = ?, grandparent_title = ?, full_title = ?, ' \ 'grandparent_rating_key = ?, title = ?, parent_title = ?, grandparent_title = ?, full_title = ?, ' \
'media_index = ?, parent_media_index = ?, library_id = ?, thumb = ?, parent_thumb = ?, ' \ 'media_index = ?, parent_media_index = ?, section_id = ?, thumb = ?, parent_thumb = ?, ' \
'grandparent_thumb = ?, art = ?, media_type = ?, year = ?, originally_available_at = ?, ' \ 'grandparent_thumb = ?, art = ?, media_type = ?, year = ?, originally_available_at = ?, ' \
'added_at = ?, updated_at = ?, last_viewed_at = ?, content_rating = ?, summary = ?, ' \ 'added_at = ?, updated_at = ?, last_viewed_at = ?, content_rating = ?, summary = ?, ' \
'tagline = ?, rating = ?, duration = ?, guid = ?, directors = ?, writers = ?, actors = ?, ' \ 'tagline = ?, rating = ?, duration = ?, guid = ?, directors = ?, writers = ?, actors = ?, ' \
@ -1065,7 +1065,7 @@ class DataFactory(object):
args = [metadata['rating_key'], metadata['parent_rating_key'], metadata['grandparent_rating_key'], args = [metadata['rating_key'], metadata['parent_rating_key'], metadata['grandparent_rating_key'],
metadata['title'], metadata['parent_title'], metadata['grandparent_title'], full_title, metadata['title'], metadata['parent_title'], metadata['grandparent_title'], full_title,
metadata['media_index'], metadata['parent_media_index'], metadata['library_id'], metadata['thumb'], metadata['media_index'], metadata['parent_media_index'], metadata['section_id'], metadata['thumb'],
metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], metadata['media_type'], metadata['parent_thumb'], metadata['grandparent_thumb'], metadata['art'], metadata['media_type'],
metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'], metadata['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'], metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],
@ -1074,34 +1074,3 @@ class DataFactory(object):
old_rating_key] old_rating_key]
monitor_db.action(query=query, args=args) monitor_db.action(query=query, args=args)
def update_library_ids(self):
from plexpy import pmsconnect
pms_connect = pmsconnect.PmsConnect()
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT id, rating_key FROM session_history_metadata WHERE library_id IS NULL'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy DataFactory :: Unable to execute database query for update_library_id: %s." % e)
return None
for item in result:
id = item['id']
rating_key = item['rating_key']
result = pms_connect.get_metadata_details(rating_key=rating_key)
if result:
metadata = result['metadata']
section_keys = {'id': id}
section_values = {'library_id': metadata['library_id']}
monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
else:
continue
return True

View file

@ -124,8 +124,9 @@ class DataTables(object):
order += ', ' order += ', '
order = order.rstrip(', ')
if order: if order:
order = 'ORDER BY ' + order.rstrip(', ') order = 'ORDER BY ' + order
# Build where parameters # Build where parameters
if parameters['search']['value']: if parameters['search']['value']:

View file

@ -60,7 +60,7 @@ class Libraries(object):
join_tables=['session_history_metadata', join_tables=['session_history_metadata',
'session_history', 'session_history',
'session_history_media_info'], 'session_history_media_info'],
join_evals=[['session_history_metadata.library_id', 'library_sections.section_id'], join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'],
['session_history_metadata.id', 'session_history.id'], ['session_history_metadata.id', 'session_history.id'],
['session_history_metadata.id', 'session_history_media_info.id']], ['session_history_metadata.id', 'session_history_media_info.id']],
kwargs=kwargs) kwargs=kwargs)
@ -120,6 +120,291 @@ class Libraries(object):
return dict return dict
def get_datatables_media_info(self, section_id=None, kwargs=None):
data_tables = datatables.DataTables()
custom_where = ['library_sections.section_id', section_id]
columns = ['session_history.id',
'session_history.started AS last_watched',
'COUNT(DISTINCT session_history.reference_id) AS play_count',
'session_history_metadata.rating_key',
'session_history_metadata.parent_rating_key',
'session_history_metadata.grandparent_rating_key',
'session_history_metadata.full_title',
'session_history_metadata.year',
'session_history_metadata.media_index',
'session_history_metadata.parent_media_index',
'session_history_metadata.thumb',
'session_history_metadata.parent_thumb',
'session_history_metadata.grandparent_thumb',
'session_history_metadata.media_type',
'session_history_metadata.added_at',
'session_history_media_info.container',
'session_history_media_info.bitrate',
'session_history_media_info.video_codec',
'session_history_media_info.video_resolution',
'session_history_media_info.video_framerate',
'session_history_media_info.audio_codec',
'session_history_media_info.audio_channels',
'session_history_media_info.duration AS file_size'
]
try:
query = data_tables.ssp_query(table_name='session_history',
columns=columns,
custom_where=[custom_where],
group_by=['session_history_metadata.rating_key'],
join_types=['JOIN',
'JOIN',
'JOIN'],
join_tables=['library_sections',
'session_history_metadata',
'session_history_media_info'],
join_evals=[['session_history_metadata.section_id', 'library_sections.section_id'],
['session_history.id', 'session_history_metadata.id'],
['session_history.id', 'session_history_media_info.id']],
kwargs=kwargs)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info: %s." % e)
return {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': 'null',
'error': 'Unable to execute database query.'}
results = query['result']
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_watched': item['last_watched'],
'added_at': item['added_at'],
'play_count': item['play_count'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'full_title': item['full_title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': thumb,
'container': item['container'],
'bitrate': item['bitrate'],
'video_codec': item['video_codec'],
'video_resolution': item['video_resolution'],
'video_framerate': item['video_framerate'],
'audio_codec': item['audio_codec'],
'audio_channels': item['audio_channels'],
'file_size': item['file_size']
}
rows.append(row)
dict = {'recordsFiltered': query['filteredCount'],
'recordsTotal': query['totalCount'],
'data': rows,
'draw': query['draw']
}
return dict
def get_datatables_media_info2(self, section_id=None, section_type=None, rating_key=None, kwargs=None):
from plexpy import pmsconnect
import json, os
default_return = {'recordsFiltered': 0,
'recordsTotal': 0,
'draw': 0,
'data': None,
'error': 'Unable to execute database query.'}
if section_id and not str(section_id).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid section_id provided.")
return default_return
elif rating_key and not str(rating_key).isdigit():
logger.warn(u"PlexPy Libraries :: Datatable media info called by invalid rating_key provided.")
return default_return
rows = []
if rating_key:
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key))
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
logger.debug(u"PlexPy Libraries :: No JSON file for rating_key %s." % rating_key)
logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for rating_key %s." % rating_key)
elif section_id:
try:
inFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id)
with open(inFilePath, 'r') as inFile:
rows = json.load(inFile)
library_count = len(rows)
except IOError as e:
logger.debug(u"PlexPy Libraries :: No JSON file for library section_id %s." % section_id)
logger.debug(u"PlexPy Libraries :: Refreshing data and creating new JSON file for section_id %s." % section_id)
if not rows:
# Get the library details
library_details = self.get_details(section_id=section_id)
if library_details['section_id'] == None:
logger.warn(u"PlexPy Libraries :: Library section_id %s not found." % section_id)
return default_return
if not section_type:
section_type = library_details['section_type']
# Get play counts from the database
monitor_db = database.MonitorDatabase()
if section_type == 'show' or section_type == 'artist':
group_by = 'grandparent_rating_key'
elif section_type == 'season' or section_type == 'album':
group_by = 'parent_rating_key'
else:
group_by = 'rating_key'
try:
query = 'SELECT MAX(session_history.started) AS last_watched, COUNT(session_history.id) AS play_count, ' \
'session_history.rating_key, session_history.parent_rating_key, session_history.grandparent_rating_key ' \
'FROM session_history ' \
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' \
'WHERE session_history_metadata.section_id = ? ' \
'GROUP BY session_history.%s ' % group_by
result = monitor_db.select(query, args=[section_id])
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for get_datatables_media_info2: %s." % e)
return default_return
watched_list = {}
for item in result:
watched_list[str(item[group_by])] = {'last_watched': item['last_watched'],
'play_count': item['play_count']}
# Get all library children items
pms_connect = pmsconnect.PmsConnect()
if rating_key:
library_children = pms_connect.get_library_children(rating_key=rating_key,
get_media_info=True)
elif section_id:
library_children = pms_connect.get_library_children(section_id=section_id,
section_type=section_type,
get_media_info=True)
if library_children:
library_count = library_children['library_count']
children_list = library_children['childern_list']
else:
logger.warn(u"PlexPy Libraries :: Unable to get a list of library items.")
return default_return
rows = []
for item in children_list:
thumb = item['thumb']
if item['media_type'] == 'episode' or item['media_type'] == 'track':
full_title = 'E%s - %s' % (item['media_index'], item['title'])
else:
full_title = item['title']
watched_item = watched_list.get(item['rating_key'], None)
if watched_item:
last_watched = watched_item['last_watched']
play_count = watched_item['play_count']
else:
last_watched = None
play_count = None
row = {'section_id': library_details['section_id'],
'section_type': library_details['section_type'],
'last_watched': last_watched,
'added_at': item['added_at'],
'media_type': item['media_type'],
'rating_key': item['rating_key'],
'parent_rating_key': item['parent_rating_key'],
'grandparent_rating_key': item['grandparent_rating_key'],
'full_title': full_title,
'title': item['title'],
'year': item['year'],
'media_index': item['media_index'],
'parent_media_index': item['parent_media_index'],
'thumb': thumb,
'container': item.get('container', ''),
'bitrate': item.get('bitrate', ''),
'video_codec': item.get('video_codec', ''),
'video_resolution': item.get('video_resolution', ''),
'video_framerate': item.get('video_framerate', ''),
'audio_codec': item.get('audio_codec', ''),
'audio_channels': item.get('audio_channels', ''),
'file_size': item.get('file_size', ''),
'play_count': play_count
}
rows.append(row)
if rating_key:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s_%s.json' % (section_id, rating_key))
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
elif section_id:
outFilePath = os.path.join(plexpy.CONFIG.CACHE_DIR,'media_info-%s.json' % section_id)
with open(outFilePath, 'w') as outFile:
json.dump(rows, outFile)
results = []
# Get datatables JSON data
if kwargs.get('json_data'):
json_data = helpers.process_json_kwargs(json_kwargs=kwargs.get('json_data'))
#print json_data
# Search results
search_value = json_data['search']['value'].lower()
if search_value:
searchable_columns = [d['data'] for d in json_data['columns'] if d['searchable']]
for row in rows:
for k,v in row.iteritems():
if k in searchable_columns and search_value in v.lower():
results.append(row)
break
else:
results = rows
filtered_count = len(results)
# Sort results
sort_order = json_data['order']
for order in reversed(sort_order):
sort_key = json_data['columns'][int(order['column'])]['data']
reverse = True if order['dir'] == 'desc' else False
if rating_key and sort_key == 'title':
results = sorted(results, key=lambda k: int(k['media_index']), reverse=reverse)
else:
results = sorted(results, key=lambda k: k[sort_key], reverse=reverse)
# Paginate results
results = results[json_data['start']:(json_data['start'] + json_data['length'])]
dict = {'recordsFiltered': filtered_count,
'recordsTotal': library_count,
'data': results,
'draw': int(json_data['draw'])
}
## Add total disk space used
return dict
def set_config(self, section_id=None, custom_thumb='', do_notify=1, keep_history=1, do_notify_created=1): def set_config(self, section_id=None, custom_thumb='', do_notify=1, keep_history=1, do_notify_created=1):
if section_id: if section_id:
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
@ -234,7 +519,7 @@ class Libraries(object):
'keep_history': 0 'keep_history': 0
} }
def get_watch_time_stats(self, library_id=None): def get_watch_time_stats(self, section_id=None):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
time_queries = [1, 7, 30, 0] time_queries = [1, 7, 30, 0]
@ -243,26 +528,26 @@ class Libraries(object):
for days in time_queries: for days in time_queries:
try: try:
if days > 0: if days > 0:
if str(library_id).isdigit(): if str(section_id).isdigit():
query = 'SELECT (SUM(stopped - started) - ' \ query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \ 'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(session_history.id) AS total_plays ' \ 'COUNT(session_history.id) AS total_plays ' \
'FROM session_history ' \ 'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \ 'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
'AND library_id = ?' % days 'AND section_id = ?' % days
result = monitor_db.select(query, args=[library_id]) result = monitor_db.select(query, args=[section_id])
else: else:
result = [] result = []
else: else:
if str(library_id).isdigit(): if str(section_id).isdigit():
query = 'SELECT (SUM(stopped - started) - ' \ query = 'SELECT (SUM(stopped - started) - ' \
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \ 'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
'COUNT(session_history.id) AS total_plays ' \ 'COUNT(session_history.id) AS total_plays ' \
'FROM session_history ' \ 'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'WHERE library_id = ?' 'WHERE section_id = ?'
result = monitor_db.select(query, args=[library_id]) result = monitor_db.select(query, args=[section_id])
else: else:
result = [] result = []
except Exception as e: except Exception as e:
@ -286,22 +571,22 @@ class Libraries(object):
return library_watch_time_stats return library_watch_time_stats
def get_user_stats(self, library_id=None): def get_user_stats(self, section_id=None):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
user_stats = [] user_stats = []
try: try:
if str(library_id).isdigit(): if str(section_id).isdigit():
query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \ query = 'SELECT (CASE WHEN users.friendly_name IS NULL THEN users.username ' \
'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \ 'ELSE users.friendly_name END) AS user, users.user_id, users.thumb, COUNT(user) AS user_count ' \
'FROM session_history ' \ 'FROM session_history ' \
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \ 'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
'JOIN users ON users.user_id = session_history.user_id ' \ 'JOIN users ON users.user_id = session_history.user_id ' \
'WHERE library_id = ? ' \ 'WHERE section_id = ? ' \
'GROUP BY user ' \ 'GROUP BY user ' \
'ORDER BY user_count DESC' 'ORDER BY user_count DESC'
result = monitor_db.select(query, args=[library_id]) result = monitor_db.select(query, args=[section_id])
else: else:
result = [] result = []
except Exception as e: except Exception as e:
@ -318,7 +603,7 @@ class Libraries(object):
return user_stats return user_stats
def get_recently_watched(self, library_id=None, limit='10'): def get_recently_watched(self, section_id=None, limit='10'):
monitor_db = database.MonitorDatabase() monitor_db = database.MonitorDatabase()
recently_watched = [] recently_watched = []
@ -326,17 +611,17 @@ class Libraries(object):
limit = '10' limit = '10'
try: try:
if str(library_id).isdigit(): if str(section_id).isdigit():
query = 'SELECT session_history.id, session_history.media_type, session_history.rating_key, session_history.parent_rating_key, ' \ query = 'SELECT session_history.id, session_history.media_type, session_history.rating_key, session_history.parent_rating_key, ' \
'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \ 'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \
'year, started, user ' \ 'year, started, user ' \
'FROM session_history_metadata ' \ 'FROM session_history_metadata ' \
'JOIN session_history ON session_history_metadata.id = session_history.id ' \ 'JOIN session_history ON session_history_metadata.id = session_history.id ' \
'WHERE library_id = ? ' \ 'WHERE section_id = ? ' \
'GROUP BY (CASE WHEN session_history.media_type = "track" THEN session_history.parent_rating_key ' \ 'GROUP BY (CASE WHEN session_history.media_type = "track" THEN session_history.parent_rating_key ' \
' ELSE session_history.rating_key END) ' \ ' ELSE session_history.rating_key END) ' \
'ORDER BY started DESC LIMIT ?' 'ORDER BY started DESC LIMIT ?'
result = monitor_db.select(query, args=[library_id, limit]) result = monitor_db.select(query, args=[section_id, limit])
else: else:
result = [] result = []
except Exception as e: except Exception as e:
@ -399,18 +684,18 @@ class Libraries(object):
'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id ' 'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
'FROM session_history_media_info ' 'FROM session_history_media_info '
'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id ' 'JOIN session_history_metadata ON session_history_media_info.id = session_history_metadata.id '
'WHERE session_history_metadata.library_id = ?)', [section_id]) 'WHERE session_history_metadata.section_id = ?)', [section_id])
session_history_del = \ session_history_del = \
monitor_db.action('DELETE FROM ' monitor_db.action('DELETE FROM '
'session_history ' 'session_history '
'WHERE session_history.id IN (SELECT session_history.id ' 'WHERE session_history.id IN (SELECT session_history.id '
'FROM session_history ' 'FROM session_history '
'JOIN session_history_metadata ON session_history.id = session_history_metadata.id ' 'JOIN session_history_metadata ON session_history.id = session_history_metadata.id '
'WHERE session_history_metadata.library_id = ?)', [section_id]) 'WHERE session_history_metadata.section_id = ?)', [section_id])
session_history_metadata_del = \ session_history_metadata_del = \
monitor_db.action('DELETE FROM ' monitor_db.action('DELETE FROM '
'session_history_metadata ' 'session_history_metadata '
'WHERE session_history_metadata.library_id = ?', [section_id]) 'WHERE session_history_metadata.section_id = ?', [section_id])
return 'Deleted all items for section_id %s.' % section_id return 'Deleted all items for section_id %s.' % section_id
else: else:
@ -466,3 +751,49 @@ class Libraries(object):
return 'Unable to re-add library, section_id or section_name not valid.' return 'Unable to re-add library, section_id or section_name not valid.'
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e) logger.warn(u"PlexPy Libraries :: Unable to execute database query for undelete: %s." % e)
def update_section_ids(self):
from plexpy import pmsconnect
pms_connect = pmsconnect.PmsConnect()
monitor_db = database.MonitorDatabase()
try:
query = 'SELECT id, rating_key FROM session_history_metadata WHERE section_id IS NULL'
result = monitor_db.select(query=query)
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to execute database query for update_section_ids: %s." % e)
return None
for item in result:
id = item['id']
rating_key = item['rating_key']
result = pms_connect.get_metadata_details(rating_key=rating_key)
if result:
metadata = result['metadata']
section_keys = {'id': id}
section_values = {'section_id': metadata['section_id']}
monitor_db.upsert('session_history_metadata', key_dict=section_keys, value_dict=section_values)
else:
continue
return True
def delete_datatable_media_info_cache(self, section_id=None):
import os
try:
if section_id.isdigit():
[os.remove(os.path.join(plexpy.CONFIG.CACHE_DIR, f)) for f in os.listdir(plexpy.CONFIG.CACHE_DIR)
if f.startswith('media_info-%s' % section_id) and f.endswith('.json')]
logger.debug(u"PlexPy Libraries :: Deleted media info table cache for section_id %s." % section_id)
return 'Deleted media info table cache for library with id %s.' % section_id
else:
return 'Unable to delete media info table cache, section_id not valid.'
except Exception as e:
logger.warn(u"PlexPy Libraries :: Unable to delete media info table cache: %s." % e)

View file

@ -31,7 +31,7 @@ def notify(stream_data=None, notify_action=None):
user_details = user_data.get_details(user_id=stream_data['user_id']) user_details = user_data.get_details(user_id=stream_data['user_id'])
library_data = libraries.Libraries() library_data = libraries.Libraries()
library_details = library_data.get_details(section_id=stream_data['library_id']) library_details = library_data.get_details(section_id=stream_data['section_id'])
if not user_details['do_notify']: if not user_details['do_notify']:
# logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' is disabled." % user_details['username']) # logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' is disabled." % user_details['username'])

View file

@ -41,7 +41,7 @@ def extract_plexwatch_xml(xml=None):
grandparent_thumb = helpers.get_xml_attr(a, 'grandparentThumb') grandparent_thumb = helpers.get_xml_attr(a, 'grandparentThumb')
grandparent_title = helpers.get_xml_attr(a, 'grandparentTitle') grandparent_title = helpers.get_xml_attr(a, 'grandparentTitle')
guid = helpers.get_xml_attr(a, 'guid') guid = helpers.get_xml_attr(a, 'guid')
library_id = helpers.get_xml_attr(a, 'librarySectionID') section_id = helpers.get_xml_attr(a, 'librarySectionID')
media_index = helpers.get_xml_attr(a, 'index') media_index = helpers.get_xml_attr(a, 'index')
originally_available_at = helpers.get_xml_attr(a, 'originallyAvailableAt') originally_available_at = helpers.get_xml_attr(a, 'originallyAvailableAt')
last_viewed_at = helpers.get_xml_attr(a, 'lastViewedAt') last_viewed_at = helpers.get_xml_attr(a, 'lastViewedAt')
@ -157,7 +157,7 @@ def extract_plexwatch_xml(xml=None):
'title': title, 'title': title,
'tagline': tagline, 'tagline': tagline,
'guid': guid, 'guid': guid,
'library_id': library_id, 'section_id': section_id,
'media_index': media_index, 'media_index': media_index,
'originally_available_at': originally_available_at, 'originally_available_at': originally_available_at,
'last_viewed_at': last_viewed_at, 'last_viewed_at': last_viewed_at,
@ -251,6 +251,8 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
hours=0, minutes=0, seconds=0) hours=0, minutes=0, seconds=0)
plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items', plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items',
hours=0, minutes=0, seconds=0) hours=0, minutes=0, seconds=0)
plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response',
hours=0, minutes=0, seconds=0)
ap = activity_processor.ActivityProcessor() ap = activity_processor.ActivityProcessor()
user_data = users.Users() user_data = users.Users()
@ -372,7 +374,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
'rating': extracted_xml['rating'], 'rating': extracted_xml['rating'],
'duration': extracted_xml['duration'], 'duration': extracted_xml['duration'],
'guid': extracted_xml['guid'], 'guid': extracted_xml['guid'],
'library_id': extracted_xml['library_id'], 'section_id': extracted_xml['section_id'],
'directors': extracted_xml['directors'], 'directors': extracted_xml['directors'],
'writers': extracted_xml['writers'], 'writers': extracted_xml['writers'],
'actors': extracted_xml['actors'], 'actors': extracted_xml['actors'],

View file

@ -44,11 +44,6 @@ def refresh_libraries():
server_id = plexpy.CONFIG.PMS_IDENTIFIER server_id = plexpy.CONFIG.PMS_IDENTIFIER
if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
populate_cards = True
else:
populate_cards = False
library_keys = [] library_keys = []
if library_sections: if library_sections:
@ -56,11 +51,11 @@ def refresh_libraries():
for section in library_sections: for section in library_sections:
section_keys = {'server_id': server_id, section_keys = {'server_id': server_id,
'section_id': section['key']} 'section_id': section['section_id']}
section_values = {'server_id': server_id, section_values = {'server_id': server_id,
'section_id': section['key'], 'section_id': section['section_id'],
'section_name': section['title'], 'section_name': section['section_name'],
'section_type': section['type'], 'section_type': section['section_type'],
'thumb': section['thumb'], 'thumb': section['thumb'],
'art': section['art'], 'art': section['art'],
'count': section['count'], 'count': section['count'],
@ -70,13 +65,42 @@ def refresh_libraries():
monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values) monitor_db.upsert('library_sections', key_dict=section_keys, value_dict=section_values)
library_keys.append(section['key']) library_keys.append(section['section_id'])
if populate_cards: if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', library_keys) plexpy.CONFIG.__setattr__('HOME_LIBRARY_CARDS', library_keys)
plexpy.CONFIG.write() plexpy.CONFIG.write()
if plexpy.CONFIG.UPDATE_SECTION_IDS == 1:
from plexpy import libraries
plexpy.CONFIG.UPDATE_SECTION_IDS = -1
logger.info(u"PlexPy Pmsconnect :: Updating section_id's in database.")
logger.debug(u"PlexPy Pmsconnect :: Disabling monitoring while update in progress.")
plexpy.schedule_job(activity_pinger.check_active_sessions, 'Check for active sessions',
hours=0, minutes=0, seconds=0)
plexpy.schedule_job(activity_pinger.check_recently_added, 'Check for recently added items',
hours=0, minutes=0, seconds=0)
plexpy.schedule_job(activity_pinger.check_server_response, 'Check for server response',
hours=0, minutes=0, seconds=0)
result = libraries.Libraries().update_section_ids()
if result:
logger.debug(u"PlexPy Pmsconnect :: Updated all section_id's in database.")
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 0)
plexpy.CONFIG.write()
else:
logger.debug(u"PlexPy Pmsconnect :: Unable to update section_id's in database.")
plexpy.CONFIG.__setattr__('UPDATE_SECTION_IDS', 1)
plexpy.CONFIG.write()
logger.debug(u"PlexPy Pmsconnect :: Re-enabling monitoring.")
plexpy.initialize_scheduler()
logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.") logger.info(u"PlexPy Pmsconnect :: Libraries list refreshed.")
else: else:
logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.") logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.")
@ -169,7 +193,7 @@ class PmsConnect(object):
return request return request
def get_library_recently_added(self, section_key='', count='0', output_format=''): def get_library_recently_added(self, section_id='', count='0', output_format=''):
""" """
Return list of recently added items. Return list of recently added items.
@ -178,7 +202,7 @@ class PmsConnect(object):
Output: array Output: array
""" """
uri = '/library/sections/' + section_key + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count uri = '/library/sections/' + section_id + '/recentlyAdded?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count
request = self.request_handler.make_request(uri=uri, request = self.request_handler.make_request(uri=uri,
proto=self.protocol, proto=self.protocol,
request_type='GET', request_type='GET',
@ -203,6 +227,23 @@ class PmsConnect(object):
return request return request
def get_childrens_list(self, rating_key='', output_format=''):
"""
Return list of children in requested library item.
Parameters required: rating_key { ratingKey of parent }
Optional parameters: output_format { dict, json }
Output: array
"""
uri = '/library/metadata/' + rating_key + '/allLeaves'
request = self.request_handler.make_request(uri=uri,
proto=self.protocol,
request_type='GET',
output_format=output_format)
return request
def get_server_list(self, output_format=''): def get_server_list(self, output_format=''):
""" """
Return list of local servers. Return list of local servers.
@ -267,7 +308,7 @@ class PmsConnect(object):
return request return request
def get_library_list(self, section_key='', list_type='all', count='0', sort_type='', output_format=''): def get_library_list(self, section_id='', list_type='all', count='0', sort_type='', output_format=''):
""" """
Return list of items in library on server. Return list of items in library on server.
@ -275,7 +316,9 @@ class PmsConnect(object):
Output: array Output: array
""" """
uri = '/library/sections/' + section_key + '/' + list_type +'?X-Plex-Container-Start=0&X-Plex-Container-Size=' + count + sort_type count = '&X-Plex-Container-Size=' + count if count else ''
uri = '/library/sections/' + section_id + '/' + list_type +'?X-Plex-Container-Start=0' + count + sort_type
request = self.request_handler.make_request(uri=uri, request = self.request_handler.make_request(uri=uri,
proto=self.protocol, proto=self.protocol,
request_type='GET', request_type='GET',
@ -363,7 +406,7 @@ class PmsConnect(object):
return request return request
def get_recently_added_details(self, library_id='', count='0'): def get_recently_added_details(self, section_id='', count='0'):
""" """
Return processed and validated list of recently added items. Return processed and validated list of recently added items.
@ -371,8 +414,8 @@ class PmsConnect(object):
Output: array Output: array
""" """
if library_id: if section_id:
recent = self.get_library_recently_added(library_id, count, output_format='xml') recent = self.get_library_recently_added(section_id, count, output_format='xml')
else: else:
recent = self.get_recently_added(count, output_format='xml') recent = self.get_recently_added(count, output_format='xml')
@ -402,7 +445,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'), 'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'library_id': helpers.get_xml_attr(item, 'librarySectionID'), 'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'), 'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'), 'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -424,7 +467,7 @@ class PmsConnect(object):
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'), 'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'), 'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'library_id': helpers.get_xml_attr(item, 'librarySectionID'), 'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'), 'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
'year': helpers.get_xml_attr(item, 'year'), 'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'), 'thumb': helpers.get_xml_attr(item, 'thumb'),
@ -450,7 +493,7 @@ class PmsConnect(object):
try: try:
xml_head = metadata.getElementsByTagName('MediaContainer') xml_head = metadata.getElementsByTagName('MediaContainer')
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s: %s." % e) logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_metadata: %s." % e)
return [] return []
metadata_list = [] metadata_list = []
@ -474,7 +517,7 @@ class PmsConnect(object):
logger.debug(u"PlexPy Pmsconnect :: Metadata failed") logger.debug(u"PlexPy Pmsconnect :: Metadata failed")
return None return None
library_id = helpers.get_xml_attr(a, 'librarySectionID') section_id = helpers.get_xml_attr(a, 'librarySectionID')
library_name = helpers.get_xml_attr(a, 'librarySectionTitle') library_name = helpers.get_xml_attr(a, 'librarySectionTitle')
genres = [] genres = []
@ -500,7 +543,7 @@ class PmsConnect(object):
if metadata_type == 'movie': if metadata_type == 'movie':
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -535,7 +578,7 @@ class PmsConnect(object):
elif metadata_type == 'show': elif metadata_type == 'show':
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -572,7 +615,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
show_details = self.get_metadata_details(parent_rating_key) show_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -609,7 +652,7 @@ class PmsConnect(object):
grandparent_rating_key = helpers.get_xml_attr(metadata_main, 'grandparentRatingKey') grandparent_rating_key = helpers.get_xml_attr(metadata_main, 'grandparentRatingKey')
show_details = self.get_metadata_details(grandparent_rating_key) show_details = self.get_metadata_details(grandparent_rating_key)
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -644,7 +687,7 @@ class PmsConnect(object):
elif metadata_type == 'artist': elif metadata_type == 'artist':
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -681,7 +724,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
artist_details = self.get_metadata_details(parent_rating_key) artist_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -718,7 +761,7 @@ class PmsConnect(object):
parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey') parent_rating_key = helpers.get_xml_attr(metadata_main, 'parentRatingKey')
album_details = self.get_metadata_details(parent_rating_key) album_details = self.get_metadata_details(parent_rating_key)
metadata = {'media_type': metadata_type, metadata = {'media_type': metadata_type,
'library_id': library_id, 'section_id': section_id,
'library_name': library_name, 'library_name': library_name,
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'), 'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'), 'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
@ -798,11 +841,11 @@ class PmsConnect(object):
output = {'metadata': metadata_list} output = {'metadata': metadata_list}
return output return output
def get_library_metadata_details(self, library_id=''): def get_library_metadata_details(self, section_id=''):
""" """
Return processed and validated metadata list for requested library. Return processed and validated metadata list for requested library.
Parameters required: library_id { Plex library key } Parameters required: section_id { Plex library key }
Output: array Output: array
""" """
@ -826,9 +869,9 @@ class PmsConnect(object):
result_data = a.getElementsByTagName('Directory') result_data = a.getElementsByTagName('Directory')
for result in result_data: for result in result_data:
key = helpers.get_xml_attr(result, 'key') key = helpers.get_xml_attr(result, 'key')
if key == library_id: if key == section_id:
metadata = {'media_type': 'library', metadata = {'media_type': 'library',
'library_id': helpers.get_xml_attr(result, 'key'), 'section_id': helpers.get_xml_attr(result, 'key'),
'library': helpers.get_xml_attr(result, 'type'), 'library': helpers.get_xml_attr(result, 'type'),
'title': helpers.get_xml_attr(result, 'title'), 'title': helpers.get_xml_attr(result, 'title'),
'art': helpers.get_xml_attr(result, 'art'), 'art': helpers.get_xml_attr(result, 'art'),
@ -945,7 +988,7 @@ class PmsConnect(object):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier') machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'), 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'), 'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
@ -1067,7 +1110,7 @@ class PmsConnect(object):
if helpers.get_xml_attr(session, 'type') == 'episode': if helpers.get_xml_attr(session, 'type') == 'episode':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'), 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'), 'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
@ -1125,7 +1168,7 @@ class PmsConnect(object):
elif helpers.get_xml_attr(session, 'type') == 'movie': elif helpers.get_xml_attr(session, 'type') == 'movie':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'), 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'), 'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
@ -1183,7 +1226,7 @@ class PmsConnect(object):
elif helpers.get_xml_attr(session, 'type') == 'clip': elif helpers.get_xml_attr(session, 'type') == 'clip':
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'), 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'), 'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
@ -1274,7 +1317,7 @@ class PmsConnect(object):
machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier') machine_id = helpers.get_xml_attr(session.getElementsByTagName('Player')[0], 'machineIdentifier')
session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'), session_output = {'session_key': helpers.get_xml_attr(session, 'sessionKey'),
'library_id': helpers.get_xml_attr(session, 'librarySectionID'), 'section_id': helpers.get_xml_attr(session, 'librarySectionID'),
'media_index': helpers.get_xml_attr(session, 'index'), 'media_index': helpers.get_xml_attr(session, 'index'),
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'), 'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
'art': helpers.get_xml_attr(session, 'art'), 'art': helpers.get_xml_attr(session, 'art'),
@ -1494,9 +1537,9 @@ class PmsConnect(object):
if a.getElementsByTagName('Directory'): if a.getElementsByTagName('Directory'):
result_data = a.getElementsByTagName('Directory') result_data = a.getElementsByTagName('Directory')
for result in result_data: for result in result_data:
libraries_output = {'key': helpers.get_xml_attr(result, 'key'), libraries_output = {'section_id': helpers.get_xml_attr(result, 'key'),
'type': helpers.get_xml_attr(result, 'type'), 'section_type': helpers.get_xml_attr(result, 'type'),
'title': helpers.get_xml_attr(result, 'title'), 'section_name': helpers.get_xml_attr(result, 'title'),
'thumb': helpers.get_xml_attr(result, 'thumb'), 'thumb': helpers.get_xml_attr(result, 'thumb'),
'art': helpers.get_xml_attr(result, 'art') 'art': helpers.get_xml_attr(result, 'art')
} }
@ -1509,38 +1552,46 @@ class PmsConnect(object):
return output return output
def get_library_children(self, library_type='', section_key='', list_type='all', count='1', sort_type = ''): def get_library_children(self, section_id='', section_type='', list_type='all', count='', rating_key='', get_media_info=False):
""" """
Return processed and validated server library items list. Return processed and validated server library items list.
Parameters required: library_type { movie, show, episode, artist } Parameters required: section_type { movie, show, episode, artist }
section_key { unique library key } section_id { unique library key }
Output: array Output: array
""" """
if library_type == 'movie': if section_type == 'movie':
sort_type = '&type=1' sort_type = '&type=1'
elif library_type == 'show': elif section_type == 'show':
sort_type = '&type=2' sort_type = '&type=2'
elif library_type == 'season': elif section_type == 'season':
sort_type = '&type=3' sort_type = '&type=3'
elif library_type == 'episode': elif section_type == 'episode':
sort_type = '&type=4' sort_type = '&type=4'
elif library_type == 'artist': elif section_type == 'artist':
sort_type = '&type=8' sort_type = '&type=8'
elif library_type == 'album': elif section_type == 'album':
sort_type = '&type=9' sort_type = '&type=9'
elif library_type == 'track': elif section_type == 'track':
sort_type = '&type=10' sort_type = '&type=10'
elif library_type == 'photo': elif section_type == 'photo':
sort_type = '' sort_type = ''
elif library_type == 'photoAlbum': elif section_type == 'photoAlbum':
sort_type = '&type=14' sort_type = '&type=14'
elif library_type == 'picture': elif section_type == 'picture':
sort_type = '&type=13' sort_type = '&type=13'
else:
sort_type = ''
library_data = self.get_library_list(section_key, list_type, count, sort_type, output_format='xml') if str(section_id).isdigit():
library_data = self.get_library_list(section_id, list_type, count, sort_type, output_format='xml')
elif str(rating_key).isdigit():
library_data = self.get_children_list(rating_key, output_format='xml')
else:
logger.warn(u"PlexPy Pmsconnect :: get_library_children called by invalid section_id or rating_key provided.")
return []
try: try:
xml_head = library_data.getElementsByTagName('MediaContainer') xml_head = library_data.getElementsByTagName('MediaContainer')
@ -1548,30 +1599,74 @@ class PmsConnect(object):
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_children: %s." % e) logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_library_children: %s." % e)
return [] return []
library_list = [] childern_list = []
for a in xml_head: for a in xml_head:
if a.getAttribute('size'): if a.getAttribute('size'):
if a.getAttribute('size') == '0': if a.getAttribute('size') == '0':
logger.debug(u"PlexPy Pmsconnect :: No library data.") logger.debug(u"PlexPy Pmsconnect :: No library data.")
library_list = {'library_count': '0', childern_list = {'library_count': '0',
'library_list': [] 'childern_list': []
} }
return library_list return childern_list
if rating_key:
library_count = helpers.get_xml_attr(xml_head[0], 'size')
else:
library_count = helpers.get_xml_attr(xml_head[0], 'totalSize')
# Get show/season info from xml_head
if a.getElementsByTagName('Directory'): if a.getElementsByTagName('Directory'):
result_data = a.getElementsByTagName('Directory') item_main = a.getElementsByTagName('Directory')
for result in result_data: item_main = [d for d in item_main if helpers.get_xml_attr(d, 'ratingKey')]
library_output = {'key': helpers.get_xml_attr(result, 'key'), elif a.getElementsByTagName('Video'):
'type': helpers.get_xml_attr(result, 'type'), item_main = a.getElementsByTagName('Video')
'title': helpers.get_xml_attr(result, 'title'), elif a.getElementsByTagName('Track'):
'thumb': helpers.get_xml_attr(result, 'thumb') item_main = a.getElementsByTagName('Track')
} elif a.getElementsByTagName('Photo'):
library_list.append(library_output) item_main = a.getElementsByTagName('Photo')
else:
item_main = []
output = {'library_count': helpers.get_xml_attr(xml_head[0], 'totalSize'), for item in item_main:
'count_type': helpers.get_xml_attr(xml_head[0], 'title2'), item_info = {'section_id': helpers.get_xml_attr(item, 'key'),
'library_list': library_list 'section_type': helpers.get_xml_attr(item, 'type'),
'media_type': helpers.get_xml_attr(item, 'type'),
'rating_key': helpers.get_xml_attr(item, 'ratingKey'),
'parent_rating_key': helpers.get_xml_attr(item, 'parentRatingKey'),
'grandparent_rating_key': helpers.get_xml_attr(item, 'grandparentRatingKey'),
'title': helpers.get_xml_attr(item, 'title'),
'parent_title': helpers.get_xml_attr(item, 'parentTitle'),
'grandparent_title': helpers.get_xml_attr(item, 'grandparentTitle'),
'media_index': helpers.get_xml_attr(item, 'index'),
'parent_media_index': helpers.get_xml_attr(item, 'parentIndex'),
'year': helpers.get_xml_attr(item, 'year'),
'thumb': helpers.get_xml_attr(item, 'thumb'),
'parent_thumb': helpers.get_xml_attr(item, 'parentThumb'),
'grandparent_thumb': helpers.get_xml_attr(item, 'grandparentThumb'),
'added_at': helpers.get_xml_attr(item, 'addedAt')
}
if get_media_info:
item_media = item.getElementsByTagName('Media')
for media in item_media:
media_info = {'container': helpers.get_xml_attr(media, 'container'),
'bitrate': helpers.get_xml_attr(media, 'bitrate'),
'video_codec': helpers.get_xml_attr(media, 'videoCodec'),
'video_resolution': helpers.get_xml_attr(media, 'videoResolution'),
'video_framerate': helpers.get_xml_attr(media, 'videoFrameRate'),
'audio_codec': helpers.get_xml_attr(media, 'audioCodec'),
'audio_channels': helpers.get_xml_attr(media, 'audioChannels'),
'file': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'file'),
'file_size': helpers.get_xml_attr(media.getElementsByTagName('Part')[0], 'size'),
}
item_info.update(media_info)
childern_list.append(item_info)
output = {'library_count': library_count,
'childern_list': childern_list
} }
return output return output
@ -1590,57 +1685,44 @@ class PmsConnect(object):
libraries_list = server_libraries['libraries_list'] libraries_list = server_libraries['libraries_list']
for library in libraries_list: for library in libraries_list:
library_type = library['type'] section_type = library['section_type']
section_key = library['key'] section_id = library['section_id']
library_list = self.get_library_children(library_type, section_key) children_list = self.get_library_children(section_id=section_id, section_type=section_type, count='1')
if library_list['library_count'] != '0': if children_list['library_count'] != '0':
library_stats = {'key': library['key'], library_stats = {'section_id': library['section_id'],
'title': library['title'], 'section_name': library['section_name'],
'type': library_type, 'section_type': section_type,
'thumb': library['thumb'], 'thumb': library['thumb'],
'art': library['art'], 'art': library['art'],
'count': library_list['library_count'], 'count': children_list['library_count']
'count_type': library_list['count_type']
} }
if library_type == 'show': if section_type == 'show':
parent_list = self.get_library_children(library_type='season', section_key=section_key) parent_list = self.get_library_children(section_id=section_id, section_type='season', count='1')
parent_stats = {'parent_count': parent_list['library_count'], parent_stats = {'parent_count': parent_list['library_count']}
'parent_count_type': 'All Seasons'
}
library_stats.update(parent_stats) library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='episode', section_key=section_key) child_list = self.get_library_children(section_id=section_id, section_type='episode', count='1')
child_stats = {'child_count': child_list['library_count'], child_stats = {'child_count': child_list['library_count']}
'child_count_type': 'All Episodes'
}
library_stats.update(child_stats) library_stats.update(child_stats)
if library_type == 'artist': if section_type == 'artist':
parent_list = self.get_library_children(library_type='album', section_key=section_key) parent_list = self.get_library_children(section_id=section_id, section_type='album', count='1')
parent_stats = {'parent_count': parent_list['library_count'], parent_stats = {'parent_count': parent_list['library_count']}
'parent_count_type': 'All Seasons'
}
library_stats.update(parent_stats) library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='track', section_key=section_key) child_list = self.get_library_children(section_id=section_id, section_type='track', count='1')
child_stats = {'child_count': child_list['library_count'], child_stats = {'child_count': child_list['library_count']}
'child_count_type': 'All Albums'
}
library_stats.update(child_stats) library_stats.update(child_stats)
if library_type == 'photo': if section_type == 'photo':
parent_list = self.get_library_children(library_type='photoAlbum', section_key=section_key) parent_list = self.get_library_children(section_id=section_id, section_type='photoAlbum', count='1')
parent_stats = {'parent_count': parent_list['library_count'], parent_stats = {'parent_count': parent_list['library_count']}
'parent_count_type': 'All Photo Albums'
}
library_stats.update(parent_stats) library_stats.update(parent_stats)
child_list = self.get_library_children(library_type='picture', section_key=section_key) child_list = self.get_library_children(section_id=section_id, section_type='picture', count='1')
child_stats = {'child_count': child_list['library_count'], child_stats = {'child_count': child_list['library_count']}
'child_count_type': 'All Photos'
}
library_stats.update(child_stats) library_stats.update(child_stats)
server_library_stats.append(library_stats) server_library_stats.append(library_stats)
@ -1782,7 +1864,7 @@ class PmsConnect(object):
else: else:
match_type = 'index' match_type = 'index'
library_id = None section_id = None
library_name = None library_name = None
# get grandparent rating key # get grandparent rating key
@ -1790,7 +1872,7 @@ class PmsConnect(object):
try: try:
metadata = self.get_metadata_details(rating_key=rating_key) metadata = self.get_metadata_details(rating_key=rating_key)
rating_key = metadata['metadata']['parent_rating_key'] rating_key = metadata['metadata']['parent_rating_key']
library_id = metadata['metadata']['library_id'] section_id = metadata['metadata']['section_id']
library_name = metadata['metadata']['library_name'] library_name = metadata['metadata']['library_name']
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e) logger.warn(u"PlexPy Pmsconnect :: Unable to get parent_rating_key for get_rating_keys_list: %s." % e)
@ -1800,7 +1882,7 @@ class PmsConnect(object):
try: try:
metadata = self.get_metadata_details(rating_key=rating_key) metadata = self.get_metadata_details(rating_key=rating_key)
rating_key = metadata['metadata']['grandparent_rating_key'] rating_key = metadata['metadata']['grandparent_rating_key']
library_id = metadata['metadata']['library_id'] section_id = metadata['metadata']['section_id']
library_name = metadata['metadata']['library_name'] library_name = metadata['metadata']['library_name']
except Exception as e: except Exception as e:
logger.warn(u"PlexPy Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e) logger.warn(u"PlexPy Pmsconnect :: Unable to get grandparent_rating_key for get_rating_keys_list: %s." % e)
@ -1875,7 +1957,7 @@ class PmsConnect(object):
key_list = {key: key_list = {key:
{'rating_key': int(rating_key), {'rating_key': int(rating_key),
'children': parents }, 'children': parents },
'library_id': library_id, 'section_id': section_id,
'library_name': library_name 'library_name': library_name
} }

View file

@ -73,6 +73,11 @@ class Users(object):
rows = [] rows = []
for item in users: for item in users:
if item['friendly_name']:
friendly_name = item['friendly_name']
else:
friendly_name = item['username']
if item['media_type'] == 'episode' and item['parent_thumb']: if item['media_type'] == 'episode' and item['parent_thumb']:
thumb = item['parent_thumb'] thumb = item['parent_thumb']
elif item['media_type'] == 'episode': elif item['media_type'] == 'episode':

View file

@ -234,7 +234,11 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
def libraries(self): def libraries(self):
return serve_template(templatename="libraries.html", title="Libraries") config = {
"update_section_ids": plexpy.CONFIG.UPDATE_SECTION_IDS
}
return serve_template(templatename="libraries.html", title="Libraries", config=config)
@cherrypy.expose @cherrypy.expose
def get_library_list(self, **kwargs): def get_library_list(self, **kwargs):
@ -300,10 +304,10 @@ class WebInterface(object):
return status_message return status_message
@cherrypy.expose @cherrypy.expose
def get_library_watch_time_stats(self, library_id=None, **kwargs): def get_library_watch_time_stats(self, section_id=None, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_watch_time_stats(library_id=library_id) result = library_data.get_watch_time_stats(section_id=section_id)
if result: if result:
return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats") return serve_template(templatename="user_watch_time_stats.html", data=result, title="Watch Stats")
@ -312,10 +316,10 @@ class WebInterface(object):
return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats") return serve_template(templatename="user_watch_time_stats.html", data=None, title="Watch Stats")
@cherrypy.expose @cherrypy.expose
def get_library_user_stats(self, library_id=None, **kwargs): def get_library_user_stats(self, section_id=None, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_user_stats(library_id=library_id) result = library_data.get_user_stats(section_id=section_id)
if result: if result:
return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats") return serve_template(templatename="library_user_stats.html", data=result, title="Player Stats")
@ -324,10 +328,10 @@ class WebInterface(object):
return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats") return serve_template(templatename="library_user_stats.html", data=None, title="Player Stats")
@cherrypy.expose @cherrypy.expose
def get_library_recently_watched(self, library_id=None, limit='10', **kwargs): def get_library_recently_watched(self, section_id=None, limit='10', **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
result = library_data.get_recently_watched(library_id=library_id, limit=limit) result = library_data.get_recently_watched(section_id=section_id, limit=limit)
if result: if result:
return serve_template(templatename="user_recently_watched.html", data=result, title="Recently Watched") return serve_template(templatename="user_recently_watched.html", data=result, title="Recently Watched")
@ -336,10 +340,10 @@ class WebInterface(object):
return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched") return serve_template(templatename="user_recently_watched.html", data=None, title="Recently Watched")
@cherrypy.expose @cherrypy.expose
def get_library_recently_added(self, library_id=None, limit='10', **kwargs): def get_library_recently_added(self, section_id=None, limit='10', **kwargs):
library_data = pmsconnect.PmsConnect() pms_connect = pmsconnect.PmsConnect()
result = library_data.get_recently_added_details(library_id=library_id, count=limit) result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
if result: if result:
return serve_template(templatename="library_recently_added.html", data=result['recently_added'], title="Recently Added") return serve_template(templatename="library_recently_added.html", data=result['recently_added'], title="Recently Added")
@ -347,6 +351,39 @@ class WebInterface(object):
logger.warn(u"Unable to retrieve data for get_library_recently_added.") logger.warn(u"Unable to retrieve data for get_library_recently_added.")
return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added") return serve_template(templatename="library_recently_added.html", data=None, title="Recently Added")
@cherrypy.expose
def get_library_media_info(self, section_id=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_datatables_media_info(section_id=section_id, kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose
def get_library_media_info2(self, section_id=None, section_type=None, rating_key=None, **kwargs):
library_data = libraries.Libraries()
result = library_data.get_datatables_media_info2(section_id=section_id,
section_type=section_type,
rating_key=rating_key,
kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose
def get_library_unwatched(self, section_id=None, section_type=None, **kwargs):
pms_connect = pmsconnect.PmsConnect()
result = pms_connect.get_library_children(section_id=section_id,
section_type=section_type,
get_media_info=True,
kwargs=kwargs)
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps(result)
@cherrypy.expose @cherrypy.expose
def delete_all_library_history(self, section_id, **kwargs): def delete_all_library_history(self, section_id, **kwargs):
library_data = libraries.Libraries() library_data = libraries.Libraries()
@ -395,6 +432,35 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose
def update_section_ids(self, **kwargs):
logger.debug(u"Updating section_id's in database.")
library_data = libraries.Libraries()
result = library_data.update_section_ids()
if result:
logger.debug(u"Updated all section_id's in database.")
plexpy.CONFIG.UPDATE_SECTION_IDS = 0
plexpy.CONFIG.write()
return "Section ids updated."
else:
logger.debug(u"Unable to update section_id's in database.")
return "Unable to update section ids in database."
@cherrypy.expose
def delete_datatable_media_info_cache(self, section_id, **kwargs):
library_data = libraries.Libraries()
if section_id:
delete_row = library_data.delete_datatable_media_info_cache(section_id=section_id)
if delete_row:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': delete_row})
else:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
##### Users ##### ##### Users #####
@ -595,7 +661,7 @@ class WebInterface(object):
custom_where.append(['session_history.reference_id', reference_id]) custom_where.append(['session_history.reference_id', reference_id])
if 'section_id' in kwargs: if 'section_id' in kwargs:
section_id = kwargs.get('section_id', "") section_id = kwargs.get('section_id', "")
custom_where.append(['session_history_metadata.library_id', section_id]) custom_where.append(['session_history_metadata.section_id', section_id])
if 'media_type' in kwargs: if 'media_type' in kwargs:
media_type = kwargs.get('media_type', "") media_type = kwargs.get('media_type', "")
if media_type != 'all': if media_type != 'all':
@ -1348,14 +1414,10 @@ class WebInterface(object):
@cherrypy.expose @cherrypy.expose
def info(self, rating_key=None, source=None, **kwargs): def info(self, rating_key=None, source=None, **kwargs):
# temporary until I find a beter place to put this
#data_factory.update_library_ids()
metadata = None metadata = None
config = { config = {
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER, "pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER
"update_library_ids": plexpy.CONFIG.UPDATE_LIBRARY_IDS
} }
if source == 'history': if source == 'history':
@ -1371,7 +1433,6 @@ class WebInterface(object):
return serve_template(templatename="info.html", data=metadata, title="Info", config=config) return serve_template(templatename="info.html", data=metadata, title="Info", config=config)
else: else:
return self.update_metadata(rating_key) return self.update_metadata(rating_key)
#raise cherrypy.InternalRedirect("/update_metadata?rating_key=" + rating_key)
@cherrypy.expose @cherrypy.expose
def get_item_children(self, rating_key='', **kwargs): def get_item_children(self, rating_key='', **kwargs):
@ -1493,24 +1554,7 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'}) return json.dumps({'message': 'no data received'})
@cherrypy.expose
def update_history_rating_key(self, old_rating_key, new_rating_key, media_type, **kwargs):
data_factory = datafactory.DataFactory()
pms_connect = pmsconnect.PmsConnect()
old_key_list = data_factory.get_rating_keys_list(rating_key=old_rating_key, media_type=media_type)
new_key_list = pms_connect.get_rating_keys_list(rating_key=new_rating_key, media_type=media_type)
update_db = data_factory.update_rating_key(old_key_list=old_key_list,
new_key_list=new_key_list,
media_type=media_type)
if update_db:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': update_db})
else:
cherrypy.response.headers['Content-type'] = 'application/json'
return json.dumps({'message': 'no data received'})
# test code # test code
@cherrypy.expose @cherrypy.expose
@ -1537,22 +1581,6 @@ class WebInterface(object):
else: else:
logger.warn(u"Unable to retrieve data for get_old_rating_keys.") logger.warn(u"Unable to retrieve data for get_old_rating_keys.")
@cherrypy.expose
def update_library_ids(self, **kwargs):
logger.debug(u"Updating library_id's in database.")
data_factory = datafactory.DataFactory()
result = data_factory.update_library_ids()
if result:
logger.debug(u"Updated all library_id's in database.")
plexpy.CONFIG.UPDATE_LIBRARY_IDS = 0
plexpy.CONFIG.write()
return "Library ids updated."
else:
logger.debug(u"Unable to update library_id's in database.")
return "Unable to update library ids in database."
##### API ##### ##### API #####