mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-06 21:21:15 -07:00
Add media info table to library page
This commit is contained in:
parent
10e4d562ab
commit
381c3da31c
28 changed files with 1415 additions and 462 deletions
|
@ -71,9 +71,20 @@ img {
|
|||
-moz-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 {
|
||||
padding: 5px 5px;
|
||||
}
|
||||
.navbar-right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 15px;
|
||||
}
|
||||
.nav > li > a {
|
||||
color: #999;
|
||||
-webkit-transition: all 0.3s ease;
|
||||
|
@ -2542,12 +2553,22 @@ a .home-platforms-instance-list-oval:hover,
|
|||
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 {
|
||||
display: none;
|
||||
}
|
||||
table.display tr.shown + tr > td {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
table.display tr.shown + tr:hover {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
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'] {
|
||||
margin-top: 0;
|
||||
margin-left: -4px;
|
||||
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;
|
||||
height: 0 !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
table[id^='media_info_child'] table[id^='media_info_child'] thead th {
|
||||
line-height: 25px;
|
||||
height: 35px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
#search_form {
|
||||
width: 300px;
|
||||
padding: 8px 15px;
|
||||
|
|
|
@ -25,18 +25,18 @@
|
|||
<table class="display" id="history_table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align='left' id="delete_row">Delete</th>
|
||||
<th align='left' id="time">Time</th>
|
||||
<th align='left' id="friendly_name">User</th>
|
||||
<th align='left' id="ip_address">IP Address</th>
|
||||
<th align='left' id="platform">Platform</th>
|
||||
<th align='left' id="device">Player</th>
|
||||
<th align='left' id="title">Title</th>
|
||||
<th align='left' id="started">Started</th>
|
||||
<th align='left' id="paused_counter">Paused</th>
|
||||
<th align='left' id="stopped">Stopped</th>
|
||||
<th align='left' id="duration">Duration</th>
|
||||
<th align='left' id="percent_complete"></th>
|
||||
<th align="left" id="delete_row">Delete</th>
|
||||
<th align="left" id="time">Time</th>
|
||||
<th align="left" id="friendly_name">User</th>
|
||||
<th align="left" id="ip_address">IP Address</th>
|
||||
<th align="left" id="platform">Platform</th>
|
||||
<th align="left" id="device">Player</th>
|
||||
<th align="left" id="title">Title</th>
|
||||
<th align="left" id="started">Started</th>
|
||||
<th align="left" id="paused_counter">Paused</th>
|
||||
<th align="left" id="stopped">Stopped</th>
|
||||
<th align="left" id="duration">Duration</th>
|
||||
<th align="left" id="percent_complete"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -83,8 +83,8 @@
|
|||
type: 'post',
|
||||
data: function (d) {
|
||||
return {
|
||||
'json_data': JSON.stringify(d),
|
||||
'media_type': media_type
|
||||
json_data: JSON.stringify(d),
|
||||
media_type: media_type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
</h4>
|
||||
</div>
|
||||
<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>
|
||||
<tr>
|
||||
<th align='left' id="started">Started</th>
|
||||
<th align='left' id="stopped">Stopped</th>
|
||||
<th align='left' id="friendly_name">User</th>
|
||||
<th align='left' id="player">Player</th>
|
||||
<th align='left' id="title">Title</th>
|
||||
<th align="left" id="started">Started</th>
|
||||
<th align="left" id="stopped">Stopped</th>
|
||||
<th align="left" id="friendly_name">User</th>
|
||||
<th align="left" id="player">Player</th>
|
||||
<th align="left" id="title">Title</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -34,12 +34,13 @@
|
|||
$(document).ready(function() {
|
||||
$('#date-header').html(moment('${data}','YYYY-MM-DD').format('ddd MMM Do YYYY'));
|
||||
history_table_modal_options.ajax = {
|
||||
"url": "get_history",
|
||||
url: 'get_history',
|
||||
type: "post",
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ),
|
||||
'grouping': false,
|
||||
'start_date': '${data}'
|
||||
return {
|
||||
json_data: JSON.stringify(d),
|
||||
grouping: false,
|
||||
start_date: '${data}'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,29 +54,29 @@ DOCUMENTATION :: END
|
|||
<div class="summary-navbar-list">
|
||||
<ul class="list-unstyled breadcrumb">
|
||||
% if data['media_type'] == 'movie':
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
|
||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'show':
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
|
||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'season':
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_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 class="active">Season ${data['media_index']}</li>
|
||||
% elif data['media_type'] == 'episode':
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_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><a href="info?rating_key=${data['parent_rating_key']}">Season ${data['parent_media_index']}</a></li>
|
||||
<li class="active">Episode ${data['media_index']} - ${data['title']}</li>
|
||||
% elif data['media_type'] == 'artist':
|
||||
<li><a href="library?section_id=${data['library_id']}">${data['library_name']}</a></li>
|
||||
<li><a href="library?section_id=${data['section_id']}">${data['library_name']}</a></li>
|
||||
<li class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'album':
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_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 class="active">${data['title']}</li>
|
||||
% elif data['media_type'] == 'track':
|
||||
<li class="hidden-xs hidden-sm"><a href="library?section_id=${data['library_id']}">${data['library_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><a href="info?rating_key=${data['parent_rating_key']}">${data['parent_title']}</a></li>
|
||||
<li class="active">Track ${data['media_index']} - ${data['title']}</li>
|
||||
|
@ -288,14 +288,6 @@ DOCUMENTATION :: END
|
|||
</div>
|
||||
% endif
|
||||
<div class='col-md-12'>
|
||||
<!-- Need to find a place to put this -->
|
||||
% if data['media_type'] == 'library' and config['update_library_ids'] == 1:
|
||||
<div id="update_library_ids_mssage" style="text-align: center; margin-top: 20px;">
|
||||
<i class="fa fa-refresh fa-spin"></i> Updating library ids in the database. This could take a few minutes depending on the size of your database.
|
||||
<br />
|
||||
The history table will refresh automatically when the update is complete. Please wait...
|
||||
</div>
|
||||
% endif
|
||||
<div class='table-card-header'>
|
||||
<div class="header-bar">
|
||||
<span>Watch History for <strong>${data['title']}</strong></span>
|
||||
|
@ -370,41 +362,17 @@ DOCUMENTATION :: END
|
|||
% if data:
|
||||
<script src="interfaces/default/js/tables/history_table.js"></script>
|
||||
<!-- Need to find a place to put this -->
|
||||
% if data['media_type'] == 'library':
|
||||
% if 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 ),
|
||||
'library_id': "${data['library_id']}" };
|
||||
}
|
||||
}
|
||||
}
|
||||
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']}" };
|
||||
return {
|
||||
json_data: JSON.stringify( d ),
|
||||
grandparent_rating_key: "${data['rating_key']}"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -416,8 +384,10 @@ DOCUMENTATION :: END
|
|||
url: 'get_history',
|
||||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ),
|
||||
'parent_rating_key': "${data['rating_key']}" };
|
||||
return {
|
||||
json_data: JSON.stringify( d ),
|
||||
parent_rating_key: "${data['rating_key']}"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,8 +399,10 @@ DOCUMENTATION :: END
|
|||
url: 'get_history',
|
||||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ),
|
||||
'rating_key': "${data['rating_key']}" };
|
||||
return {
|
||||
json_data: JSON.stringify( d ),
|
||||
rating_key: "${data['rating_key']}"
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ history_table_options = {
|
|||
}
|
||||
},
|
||||
"searchable": false,
|
||||
"width": "8%",
|
||||
"width": "7%",
|
||||
"className": "no-wrap expand-history"
|
||||
},
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ history_table_options = {
|
|||
$(td).html(cellData);
|
||||
}
|
||||
},
|
||||
"width": "8%",
|
||||
"width": "7%",
|
||||
"className": "no-wrap hidden-xs"
|
||||
},
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ history_table_options = {
|
|||
$(td).html('n/a');
|
||||
}
|
||||
},
|
||||
"width": "8%",
|
||||
"width": "7%",
|
||||
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control-ip"
|
||||
},
|
||||
{
|
||||
|
@ -106,7 +106,7 @@ history_table_options = {
|
|||
$(td).html(cellData);
|
||||
}
|
||||
},
|
||||
"width": "8%",
|
||||
"width": "7%",
|
||||
"className": "no-wrap hidden-md hidden-sm hidden-xs modal-control"
|
||||
},
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ history_table_options = {
|
|||
}
|
||||
}
|
||||
},
|
||||
"width": "35%"
|
||||
"width": "33%"
|
||||
},
|
||||
{
|
||||
"targets": [7],
|
||||
|
@ -226,7 +226,7 @@ history_table_options = {
|
|||
"searchable": false,
|
||||
"orderable": false,
|
||||
"className": "no-wrap hidden-md hidden-sm hidden-xs",
|
||||
"width": "1%"
|
||||
"width": "2%"
|
||||
},
|
||||
],
|
||||
"drawCallback": function (settings) {
|
||||
|
@ -260,7 +260,7 @@ history_table_options = {
|
|||
var rowData = this.data();
|
||||
if (rowData['group_count'] != 1 && rowData['reference_id'] in history_child_table) {
|
||||
// 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();
|
||||
createChildTable(this, rowData)
|
||||
}
|
||||
|
@ -426,13 +426,13 @@ function childTableOptions(rowData) {
|
|||
history_child_options.pageLength = 10;
|
||||
history_child_options.bStateSave = false;
|
||||
history_child_options.ajax = {
|
||||
"url": "get_history",
|
||||
type: "post",
|
||||
url: 'get_history',
|
||||
type: 'post',
|
||||
data: function (d) {
|
||||
return {
|
||||
'json_data': JSON.stringify(d),
|
||||
'grouping': false,
|
||||
'reference_id': rowData['reference_id']
|
||||
json_data: JSON.stringify(d),
|
||||
grouping: false,
|
||||
reference_id: rowData['reference_id']
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +469,7 @@ function childTableOptions(rowData) {
|
|||
// Format the detailed history child table
|
||||
function childTableFormat(rowData) {
|
||||
return '<div class="slider">' +
|
||||
'<table id="history_child-' + rowData['reference_id'] + '">' +
|
||||
'<table id="history_child-' + rowData['reference_id'] + '" width="100%">' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
'<th align="left" id="delete_row">Delete</th>' +
|
||||
|
|
|
@ -39,7 +39,7 @@ history_table_modal_options = {
|
|||
},
|
||||
"searchable": false,
|
||||
"className": "no-wrap",
|
||||
"width": "5%"
|
||||
"width": "10%"
|
||||
},
|
||||
{
|
||||
"targets": [1],
|
||||
|
@ -53,7 +53,7 @@ history_table_modal_options = {
|
|||
},
|
||||
"searchable": false,
|
||||
"className": "no-wrap",
|
||||
"width": "5%"
|
||||
"width": "10%"
|
||||
},
|
||||
{
|
||||
"targets": [2],
|
||||
|
@ -69,7 +69,8 @@ history_table_modal_options = {
|
|||
$(td).html(cellData);
|
||||
}
|
||||
},
|
||||
"className": "no-wrap hidden-xs"
|
||||
"className": "no-wrap hidden-xs",
|
||||
"width": "15%"
|
||||
},
|
||||
{
|
||||
"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 + ' ' + 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],
|
||||
|
@ -113,7 +115,8 @@ history_table_modal_options = {
|
|||
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"width": "30%"
|
||||
}
|
||||
],
|
||||
"drawCallback": function (settings) {
|
||||
|
|
|
@ -14,7 +14,7 @@ libraries_list_table_options = {
|
|||
"processing": false,
|
||||
"serverSide": true,
|
||||
"pageLength": 10,
|
||||
"order": [ 1, 'asc'],
|
||||
"order": [ 2, 'asc'],
|
||||
"autoWidth": true,
|
||||
"stateSave": true,
|
||||
"pagingType": "bootstrap",
|
||||
|
@ -40,14 +40,14 @@ libraries_list_table_options = {
|
|||
"targets": [1],
|
||||
"data": "library_thumb",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData === '') {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(interfaces/default/images/cover.png);"></div></a>');
|
||||
} else {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
if (rowData['library_thumb'].substring(0, 4) == "http") {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(' + rowData['library_thumb'] + ');"></div></a>');
|
||||
} else {
|
||||
$(td).html('<a href="library?section_id=' + rowData['section_id'] + '"><div class="libraries-poster-face" style="background-image: url(pms_image_proxy?img=' + rowData['library_thumb'] + '&width=80&height=80&fallback=poster);"></div></a>');
|
||||
}
|
||||
} 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,
|
||||
|
@ -59,12 +59,12 @@ libraries_list_table_options = {
|
|||
"targets": [2],
|
||||
"data": "section_name",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== '') {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html('<div data-id="' + rowData['section_id'] + '">' +
|
||||
'<a href="library?section_id=' + rowData['section_id'] + '">' + cellData + '</a>' +
|
||||
'</div>');
|
||||
} else {
|
||||
$(td).html(cellData);
|
||||
$(td).html('n/a');
|
||||
}
|
||||
},
|
||||
"width": "10%",
|
||||
|
@ -74,7 +74,7 @@ libraries_list_table_options = {
|
|||
"targets": [3],
|
||||
"data": "section_type",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== '') {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(cellData);
|
||||
}
|
||||
},
|
||||
|
@ -85,10 +85,8 @@ libraries_list_table_options = {
|
|||
"targets": [4],
|
||||
"data": "count",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== null) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(cellData);
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -99,10 +97,8 @@ libraries_list_table_options = {
|
|||
"targets": [5],
|
||||
"data": "parent_count",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== null) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(cellData);
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -113,10 +109,8 @@ libraries_list_table_options = {
|
|||
"targets": [6],
|
||||
"data": "child_count",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== null) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(cellData);
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -126,11 +120,11 @@ libraries_list_table_options = {
|
|||
{
|
||||
"targets": [7],
|
||||
"data": "last_accessed",
|
||||
"render": function (data, type, full) {
|
||||
if (data) {
|
||||
return moment(data, "X").fromNow();
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(moment(cellData, "X").fromNow());
|
||||
} else {
|
||||
return "never";
|
||||
$(td).html("never");
|
||||
}
|
||||
},
|
||||
"searchable": false,
|
||||
|
@ -141,7 +135,7 @@ libraries_list_table_options = {
|
|||
"targets": [8],
|
||||
"data":"last_watched",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== '') {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
var media_type = '';
|
||||
var thumb_popover = ''
|
||||
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 + ' ' + thumb_popover + '</div></a></div>');
|
||||
} else if (rowData['media_type']) {
|
||||
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
|
||||
}
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
}
|
||||
},
|
||||
"width": "25%",
|
||||
"className": "hidden-sm hidden-xs"
|
||||
|
|
420
data/interfaces/default/js/tables/media_info_table.js
Normal file
420
data/interfaces/default/js/tables/media_info_table.js
Normal 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 + ' ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + date + '</div></a></div>');
|
||||
} else {
|
||||
$(td).html('<div style="float: left;"><i class="fa fa-fw"></i> ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + 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 + ' ' + 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> Fetching 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);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -4,7 +4,7 @@ var plex_log_table_options = {
|
|||
"serverSide": false,
|
||||
"pagingType": "bootstrap",
|
||||
"order": [ 0, 'desc'],
|
||||
"pageLength": 10,
|
||||
"pageLength": 50,
|
||||
"stateSave": true,
|
||||
"language": {
|
||||
"search":"Search: ",
|
||||
|
|
|
@ -54,13 +54,13 @@ users_list_table_options = {
|
|||
"targets": [2],
|
||||
"data": "friendly_name",
|
||||
"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'] + '">' +
|
||||
'<a href="user?user_id=' + rowData['user_id'] + '">' + cellData + '</a>' +
|
||||
'<input type="text" class="hidden" value="' + cellData + '">' +
|
||||
'</div>');
|
||||
} else {
|
||||
$(td).html(cellData);
|
||||
$(td).html('n/a');
|
||||
}
|
||||
},
|
||||
"width": "10%",
|
||||
|
@ -69,11 +69,11 @@ users_list_table_options = {
|
|||
{
|
||||
"targets": [3],
|
||||
"data": "last_seen",
|
||||
"render": function ( data, type, full ) {
|
||||
if (data) {
|
||||
return moment(data, "X").fromNow();
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(moment(cellData, "X").fromNow());
|
||||
} else {
|
||||
return "never";
|
||||
$(td).html("never");
|
||||
}
|
||||
},
|
||||
"searchable": false,
|
||||
|
@ -105,7 +105,7 @@ users_list_table_options = {
|
|||
"targets": [5],
|
||||
"data": "platform",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== '') {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
$(td).html(cellData);
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
|
@ -118,7 +118,7 @@ users_list_table_options = {
|
|||
"targets": [6],
|
||||
"data":"player",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData) {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
var transcode_dec = '';
|
||||
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>';
|
||||
|
@ -139,7 +139,7 @@ users_list_table_options = {
|
|||
"targets": [7],
|
||||
"data":"last_watched",
|
||||
"createdCell": function (td, cellData, rowData, row, col) {
|
||||
if (cellData !== '') {
|
||||
if (cellData !== null && cellData !== '') {
|
||||
var media_type = '';
|
||||
var thumb_popover = ''
|
||||
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 + ' ' + thumb_popover + '</div></a></div>');
|
||||
} else if (rowData['media_type']) {
|
||||
$(td).html('<a href="info?rating_key=' + rowData['rating_key'] + '">' + cellData + '</a>');
|
||||
}
|
||||
} else {
|
||||
$(td).html('n/a');
|
||||
}
|
||||
}
|
||||
},
|
||||
"width": "30%",
|
||||
"className": "hidden-sm hidden-xs"
|
||||
|
|
|
@ -7,6 +7,17 @@
|
|||
|
||||
<%def name="body()">
|
||||
<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="header-bar">
|
||||
<span><i class="fa fa-book"></i> All Libraries</span>
|
||||
|
@ -20,7 +31,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<tr>
|
||||
<th align="left" id="edit_row">Edit</th>
|
||||
|
@ -74,7 +85,9 @@
|
|||
url: 'get_library_list',
|
||||
type: 'POST',
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ) };
|
||||
return {
|
||||
json_data: JSON.stringify(d)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,6 +171,14 @@
|
|||
});
|
||||
|
||||
$("#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({
|
||||
url: 'refresh_libraries_list',
|
||||
cache: false,
|
||||
|
@ -173,5 +194,9 @@
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
if ("${config['update_section_ids']}" == "-1") {
|
||||
$("#refresh-libraries-list").prop('disabled', true);
|
||||
}
|
||||
</script>
|
||||
</%def>
|
|
@ -67,6 +67,7 @@ DOCUMENTATION :: END
|
|||
<ul class="user-info-nav">
|
||||
<li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
|
||||
<li><a id="history-tab-btn" href="#libraryHistory" data-toggle="tab">History</a></li>
|
||||
<li><a id="media-info-tab-btn" href="#libraryMediaInfo" data-toggle="tab">Media Info</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -170,18 +171,62 @@ DOCUMENTATION :: END
|
|||
<table class="display" id="history_table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align='left' id="delete">Delete</th>
|
||||
<th align='left' id="time">Time</th>
|
||||
<th align='left' id="friendly_name">User</th>
|
||||
<th align='left' id="ip_address">IP Address</th>
|
||||
<th align='left' id="platform">Platform</th>
|
||||
<th align='left' id="player">Player</th>
|
||||
<th align='left' id="title">Title</th>
|
||||
<th align='left' id="started">Started</th>
|
||||
<th align='left' id="paused_counter">Paused</th>
|
||||
<th align='left' id="stopped">Stopped</th>
|
||||
<th align='left' id="duration">Duration</th>
|
||||
<th align='left' id="percent_complete"></th>
|
||||
<th align="left" id="delete">Delete</th>
|
||||
<th align="left" id="time">Time</th>
|
||||
<th align="left" id="friendly_name">User</th>
|
||||
<th align="left" id="ip_address">IP Address</th>
|
||||
<th align="left" id="platform">Platform</th>
|
||||
<th align="left" id="player">Player</th>
|
||||
<th align="left" id="title">Title</th>
|
||||
<th align="left" id="started">Started</th>
|
||||
<th align="left" id="paused_counter">Paused</th>
|
||||
<th align="left" id="stopped">Stopped</th>
|
||||
<th align="left" id="duration">Duration</th>
|
||||
<th align="left" id="percent_complete"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane" id="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>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
|
@ -250,6 +295,7 @@ DOCUMENTATION :: END
|
|||
% if data:
|
||||
<script src="interfaces/default/js/moment-with-locale.js"></script>
|
||||
<script src="interfaces/default/js/tables/history_table.js"></script>
|
||||
<script src="interfaces/default/js/tables/media_info_table.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
|
@ -267,7 +313,7 @@ DOCUMENTATION :: END
|
|||
$.ajax({
|
||||
url: 'get_library_watch_time_stats',
|
||||
async: true,
|
||||
data: { library_id: section_id },
|
||||
data: { section_id: section_id },
|
||||
complete: function(xhr, status) {
|
||||
$("#library-time-stats").html(xhr.responseText);
|
||||
}
|
||||
|
@ -277,7 +323,7 @@ DOCUMENTATION :: END
|
|||
$.ajax({
|
||||
url: 'get_library_user_stats',
|
||||
async: true,
|
||||
data: { library_id: section_id },
|
||||
data: { section_id: section_id },
|
||||
complete: function(xhr, status) {
|
||||
$("#library-user-stats").html(xhr.responseText);
|
||||
}
|
||||
|
@ -290,8 +336,8 @@ DOCUMENTATION :: END
|
|||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return {
|
||||
'json_data': JSON.stringify( d ),
|
||||
'section_id': section_id
|
||||
json_data: JSON.stringify( d ),
|
||||
section_id: section_id
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -304,9 +350,44 @@ DOCUMENTATION :: END
|
|||
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() {
|
||||
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
|
||||
$("#toggle-edit-library-modal").click(function() {
|
||||
|
@ -374,7 +455,7 @@ DOCUMENTATION :: END
|
|||
url: 'get_library_recently_watched',
|
||||
async: true,
|
||||
data: {
|
||||
library_id: section_id,
|
||||
section_id: section_id,
|
||||
limit: containerSize
|
||||
},
|
||||
complete: function(xhr, status) {
|
||||
|
@ -398,7 +479,7 @@ DOCUMENTATION :: END
|
|||
url: 'get_library_recently_added',
|
||||
async: true,
|
||||
data: {
|
||||
library_id: section_id,
|
||||
section_id: section_id,
|
||||
limit: containerSize
|
||||
},
|
||||
complete: function(xhr, status) {
|
||||
|
@ -413,8 +494,9 @@ DOCUMENTATION :: END
|
|||
recentlyWatched();
|
||||
recentlyAdded();
|
||||
});
|
||||
});
|
||||
|
||||
$('div.art-face').animate({ opacity: 0.2 }, { duration: 1000 });
|
||||
});
|
||||
</script>
|
||||
% endif
|
||||
</%def>
|
|
@ -19,7 +19,7 @@ parent_title Returns the name of the artist.
|
|||
grandparent_title Returns the name of the show.
|
||||
media_index Returns the index number of the episode.
|
||||
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.
|
||||
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.
|
||||
|
@ -39,7 +39,11 @@ DOCUMENTATION :: END
|
|||
<a href="info?rating_key=${item['rating_key']}">
|
||||
<div class="dashboard-recent-media-poster">
|
||||
% 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);">
|
||||
% 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':
|
||||
<div class="dashboard-recent-media-poster-face" style="background-image: url(pms_image_proxy?img=${item['thumb']}&width=300&height=450&fallback=poster);">
|
||||
% endif
|
||||
|
|
|
@ -19,7 +19,7 @@ parent_title Returns the name of the artist.
|
|||
grandparent_title Returns the name of the show.
|
||||
media_index Returns the index number of the episode.
|
||||
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.
|
||||
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.
|
||||
|
|
|
@ -181,18 +181,18 @@ from plexpy import helpers
|
|||
<table class="display" id="history_table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align='left' id="delete">Delete</th>
|
||||
<th align='left' id="time">Time</th>
|
||||
<th align='left' id="friendly_name">User</th>
|
||||
<th align='left' id="ip_address">IP Address</th>
|
||||
<th align='left' id="platform">Platform</th>
|
||||
<th align='left' id="player">Player</th>
|
||||
<th align='left' id="title">Title</th>
|
||||
<th align='left' id="started">Started</th>
|
||||
<th align='left' id="paused_counter">Paused</th>
|
||||
<th align='left' id="stopped">Stopped</th>
|
||||
<th align='left' id="duration">Duration</th>
|
||||
<th align='left' id="percent_complete"></th>
|
||||
<th align="left" id="delete">Delete</th>
|
||||
<th align="left" id="time">Time</th>
|
||||
<th align="left" id="friendly_name">User</th>
|
||||
<th align="left" id="ip_address">IP Address</th>
|
||||
<th align="left" id="platform">Platform</th>
|
||||
<th align="left" id="player">Player</th>
|
||||
<th align="left" id="title">Title</th>
|
||||
<th align="left" id="started">Started</th>
|
||||
<th align="left" id="paused_counter">Paused</th>
|
||||
<th align="left" id="stopped">Stopped</th>
|
||||
<th align="left" id="duration">Duration</th>
|
||||
<th align="left" id="percent_complete"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
|
@ -221,17 +221,17 @@ from plexpy import helpers
|
|||
<table class="display" id="sync_table" width="100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th align='left' id="state">State</th>
|
||||
<th align='left' id="username">Username</th>
|
||||
<th align='left' id="sync_title">Title</th>
|
||||
<th align='left' id="type">Type</th>
|
||||
<th align='left' id="sync_platform">Platform</th>
|
||||
<th align='left' id="device">Device</th>
|
||||
<th align='left' id="size">Total Size</th>
|
||||
<th align='left' id="items">Total Items</th>
|
||||
<th align='left' id="converted">Converted</th>
|
||||
<th align='left' id="downloaded">Downloaded</th>
|
||||
<th align='left' id="sync_percent_complete">Complete</th>
|
||||
<th align="left" id="state">State</th>
|
||||
<th align="left" id="username">Username</th>
|
||||
<th align="left" id="sync_title">Title</th>
|
||||
<th align="left" id="type">Type</th>
|
||||
<th align="left" id="sync_platform">Platform</th>
|
||||
<th align="left" id="device">Device</th>
|
||||
<th align="left" id="size">Total Size</th>
|
||||
<th align="left" id="items">Total Items</th>
|
||||
<th align="left" id="converted">Converted</th>
|
||||
<th align="left" id="downloaded">Downloaded</th>
|
||||
<th align="left" id="sync_percent_complete">Complete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
|
@ -342,9 +342,9 @@ from plexpy import helpers
|
|||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return {
|
||||
'json_data': JSON.stringify( d ),
|
||||
'user_id': user_id,
|
||||
'media_type': media_type
|
||||
json_data: JSON.stringify( d ),
|
||||
user_id: user_id,
|
||||
media_type: media_type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -391,8 +391,9 @@ from plexpy import helpers
|
|||
url: 'get_user_ips',
|
||||
type: 'post',
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ),
|
||||
'user_id': user_id
|
||||
return {
|
||||
json_data: JSON.stringify( d ),
|
||||
user_id: user_id
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<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>
|
||||
<tr>
|
||||
<th align="left" id="edit_row">Edit</th>
|
||||
|
@ -77,7 +77,9 @@
|
|||
url: 'get_user_list',
|
||||
type: 'POST',
|
||||
data: function ( d ) {
|
||||
return { 'json_data': JSON.stringify( d ) };
|
||||
return {
|
||||
json_data: JSON.stringify(d)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,7 @@ def dbcheck():
|
|||
# sessions table :: This is a temp table that logs currently active sessions
|
||||
c_db.execute(
|
||||
'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, '
|
||||
'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, '
|
||||
|
@ -413,7 +413,7 @@ def dbcheck():
|
|||
'CREATE TABLE IF NOT EXISTS session_history_metadata (id INTEGER PRIMARY KEY, '
|
||||
'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, '
|
||||
'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, '
|
||||
'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)'
|
||||
|
@ -594,11 +594,11 @@ def dbcheck():
|
|||
|
||||
# Upgrade sessions table from earlier versions
|
||||
try:
|
||||
c_db.execute('SELECT library_id from sessions')
|
||||
c_db.execute('SELECT section_id from sessions')
|
||||
except sqlite3.OperationalError:
|
||||
logger.debug(u"Altering database. Updating database table sessions.")
|
||||
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
|
||||
|
@ -644,11 +644,11 @@ def dbcheck():
|
|||
|
||||
# Upgrade session_history_metadata table from earlier versions
|
||||
try:
|
||||
c_db.execute('SELECT library_id from session_history_metadata')
|
||||
c_db.execute('SELECT section_id from session_history_metadata')
|
||||
except sqlite3.OperationalError:
|
||||
logger.debug(u"Altering database. Updating database table session_history_metadata.")
|
||||
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
|
||||
|
|
|
@ -192,7 +192,7 @@ def check_recently_added():
|
|||
recently_added = recently_added_list['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']:
|
||||
continue
|
||||
|
@ -221,7 +221,7 @@ def check_recently_added():
|
|||
if not plexpy.CONFIG.NOTIFY_RECENTLY_ADDED_GRANDPARENT:
|
||||
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:
|
||||
logger.debug(u"PlexPy Monitor :: Library item %s has been added to Plex." % str(item['rating_key']))
|
||||
|
|
|
@ -29,7 +29,7 @@ class ActivityProcessor(object):
|
|||
def write_session(self, session=None, notify=True):
|
||||
if session:
|
||||
values = {'session_key': session['session_key'],
|
||||
'library_id': session['library_id'],
|
||||
'section_id': session['section_id'],
|
||||
'rating_key': session['rating_key'],
|
||||
'media_type': session['media_type'],
|
||||
'state': session['state'],
|
||||
|
@ -104,7 +104,7 @@ class ActivityProcessor(object):
|
|||
user_details = user_data.get_details(user_id=session['user_id'])
|
||||
|
||||
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:
|
||||
logging_enabled = False
|
||||
|
@ -257,7 +257,7 @@ class ActivityProcessor(object):
|
|||
# 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, ' \
|
||||
'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, ' \
|
||||
'summary, tagline, rating, duration, guid, directors, writers, actors, genres, studio) VALUES ' \
|
||||
'(last_insert_rowid(), ' \
|
||||
|
@ -265,7 +265,7 @@ class ActivityProcessor(object):
|
|||
|
||||
args = [session['rating_key'], session['parent_rating_key'], session['grandparent_rating_key'],
|
||||
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['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
|
||||
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],
|
||||
|
|
|
@ -372,7 +372,7 @@ _CONFIG_DEFINITIONS = {
|
|||
'TWITTER_ON_EXTUP': (int, 'Twitter', 0),
|
||||
'TWITTER_ON_INTUP': (int, 'Twitter', 0),
|
||||
'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),
|
||||
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
|
||||
'XBMC_ENABLED': (int, 'XBMC', 0),
|
||||
|
|
|
@ -98,12 +98,12 @@ class DataFactory(object):
|
|||
for item in history:
|
||||
filter_duration += int(item['duration'])
|
||||
|
||||
if item["media_type"] == 'episode' and item["parent_thumb"]:
|
||||
thumb = item["parent_thumb"]
|
||||
elif item["media_type"] == 'episode':
|
||||
thumb = item["grandparent_thumb"]
|
||||
if item['media_type'] == 'episode' and item['parent_thumb']:
|
||||
thumb = item['parent_thumb']
|
||||
elif item['media_type'] == 'episode':
|
||||
thumb = item['grandparent_thumb']
|
||||
else:
|
||||
thumb = item["thumb"]
|
||||
thumb = item['thumb']
|
||||
|
||||
if item['percent_complete'] >= watched_percent:
|
||||
watched_status = 1
|
||||
|
@ -113,37 +113,37 @@ class DataFactory(object):
|
|||
watched_status = 0
|
||||
|
||||
# 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"],
|
||||
"id": item["id"],
|
||||
"date": item["date"],
|
||||
"started": item["started"],
|
||||
"stopped": item["stopped"],
|
||||
"duration": item["duration"],
|
||||
"paused_counter": item["paused_counter"],
|
||||
"user_id": item["user_id"],
|
||||
"user": item["user"],
|
||||
"friendly_name": item["friendly_name"],
|
||||
"platform": platform,
|
||||
"player": item['player'],
|
||||
"ip_address": item["ip_address"],
|
||||
"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"],
|
||||
"parent_title": item["parent_title"],
|
||||
"year": item["year"],
|
||||
"media_index": item["media_index"],
|
||||
"parent_media_index": item["parent_media_index"],
|
||||
"thumb": thumb,
|
||||
"video_decision": item["video_decision"],
|
||||
"audio_decision": item["audio_decision"],
|
||||
"percent_complete": int(round(item['percent_complete'])),
|
||||
"watched_status": watched_status,
|
||||
"group_count": item["group_count"],
|
||||
"group_ids": item["group_ids"]
|
||||
row = {'reference_id': item['reference_id'],
|
||||
'id': item['id'],
|
||||
'date': item['date'],
|
||||
'started': item['started'],
|
||||
'stopped': item['stopped'],
|
||||
'duration': item['duration'],
|
||||
'paused_counter': item['paused_counter'],
|
||||
'user_id': item['user_id'],
|
||||
'user': item['user'],
|
||||
'friendly_name': item['friendly_name'],
|
||||
'platform': platform,
|
||||
'player': item['player'],
|
||||
'ip_address': item['ip_address'],
|
||||
'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'],
|
||||
'parent_title': item['parent_title'],
|
||||
'year': item['year'],
|
||||
'media_index': item['media_index'],
|
||||
'parent_media_index': item['parent_media_index'],
|
||||
'thumb': thumb,
|
||||
'video_decision': item['video_decision'],
|
||||
'audio_decision': item['audio_decision'],
|
||||
'percent_complete': int(round(item['percent_complete'])),
|
||||
'watched_status': watched_status,
|
||||
'group_count': item['group_count'],
|
||||
'group_ids': item['group_ids']
|
||||
}
|
||||
|
||||
rows.append(row)
|
||||
|
@ -736,7 +736,7 @@ class DataFactory(object):
|
|||
'session_history_metadata.parent_title, session_history_metadata.grandparent_title, ' \
|
||||
'session_history_metadata.full_title, library_sections.section_name, ' \
|
||||
'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.art, session_history_metadata.media_type, session_history_metadata.year, ' \
|
||||
'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.actors, session_history_metadata.genres, session_history_metadata.studio ' \
|
||||
'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 = ?'
|
||||
result = monitor_db.select(query=query, args=[rating_key])
|
||||
else:
|
||||
|
@ -789,7 +789,7 @@ class DataFactory(object):
|
|||
'genres': genres,
|
||||
'actors': actors,
|
||||
'library_name': item['section_name'],
|
||||
'library_id': item['library_id']
|
||||
'section_id': item['section_id']
|
||||
}
|
||||
|
||||
return metadata
|
||||
|
@ -1056,7 +1056,7 @@ class DataFactory(object):
|
|||
# Update the session_history_metadata table
|
||||
query = 'UPDATE session_history_metadata SET rating_key = ?, parent_rating_key = ?, ' \
|
||||
'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 = ?, ' \
|
||||
'added_at = ?, updated_at = ?, last_viewed_at = ?, content_rating = ?, summary = ?, ' \
|
||||
'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'],
|
||||
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['year'], metadata['originally_available_at'], metadata['added_at'], metadata['updated_at'],
|
||||
metadata['last_viewed_at'], metadata['content_rating'], metadata['summary'], metadata['tagline'],
|
||||
|
@ -1074,34 +1074,3 @@ class DataFactory(object):
|
|||
old_rating_key]
|
||||
|
||||
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
|
|
@ -124,8 +124,9 @@ class DataTables(object):
|
|||
|
||||
order += ', '
|
||||
|
||||
order = order.rstrip(', ')
|
||||
if order:
|
||||
order = 'ORDER BY ' + order.rstrip(', ')
|
||||
order = 'ORDER BY ' + order
|
||||
|
||||
# Build where parameters
|
||||
if parameters['search']['value']:
|
||||
|
|
|
@ -60,7 +60,7 @@ class Libraries(object):
|
|||
join_tables=['session_history_metadata',
|
||||
'session_history',
|
||||
'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_media_info.id']],
|
||||
kwargs=kwargs)
|
||||
|
@ -120,6 +120,291 @@ class Libraries(object):
|
|||
|
||||
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):
|
||||
if section_id:
|
||||
monitor_db = database.MonitorDatabase()
|
||||
|
@ -234,7 +519,7 @@ class Libraries(object):
|
|||
'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()
|
||||
|
||||
time_queries = [1, 7, 30, 0]
|
||||
|
@ -243,26 +528,26 @@ class Libraries(object):
|
|||
for days in time_queries:
|
||||
try:
|
||||
if days > 0:
|
||||
if str(library_id).isdigit():
|
||||
if str(section_id).isdigit():
|
||||
query = 'SELECT (SUM(stopped - started) - ' \
|
||||
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
|
||||
'COUNT(session_history.id) AS total_plays ' \
|
||||
'FROM session_history ' \
|
||||
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
||||
'AND library_id = ?' % days
|
||||
result = monitor_db.select(query, args=[library_id])
|
||||
'AND section_id = ?' % days
|
||||
result = monitor_db.select(query, args=[section_id])
|
||||
else:
|
||||
result = []
|
||||
else:
|
||||
if str(library_id).isdigit():
|
||||
if str(section_id).isdigit():
|
||||
query = 'SELECT (SUM(stopped - started) - ' \
|
||||
'SUM(CASE WHEN paused_counter is null THEN 0 ELSE paused_counter END)) as total_time, ' \
|
||||
'COUNT(session_history.id) AS total_plays ' \
|
||||
'FROM session_history ' \
|
||||
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
'WHERE library_id = ?'
|
||||
result = monitor_db.select(query, args=[library_id])
|
||||
'WHERE section_id = ?'
|
||||
result = monitor_db.select(query, args=[section_id])
|
||||
else:
|
||||
result = []
|
||||
except Exception as e:
|
||||
|
@ -286,22 +571,22 @@ class Libraries(object):
|
|||
|
||||
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()
|
||||
|
||||
user_stats = []
|
||||
|
||||
try:
|
||||
if str(library_id).isdigit():
|
||||
if str(section_id).isdigit():
|
||||
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 ' \
|
||||
'FROM session_history ' \
|
||||
'JOIN session_history_metadata ON session_history_metadata.id = session_history.id ' \
|
||||
'JOIN users ON users.user_id = session_history.user_id ' \
|
||||
'WHERE library_id = ? ' \
|
||||
'WHERE section_id = ? ' \
|
||||
'GROUP BY user ' \
|
||||
'ORDER BY user_count DESC'
|
||||
result = monitor_db.select(query, args=[library_id])
|
||||
result = monitor_db.select(query, args=[section_id])
|
||||
else:
|
||||
result = []
|
||||
except Exception as e:
|
||||
|
@ -318,7 +603,7 @@ class Libraries(object):
|
|||
|
||||
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()
|
||||
recently_watched = []
|
||||
|
||||
|
@ -326,17 +611,17 @@ class Libraries(object):
|
|||
limit = '10'
|
||||
|
||||
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, ' \
|
||||
'title, parent_title, grandparent_title, thumb, parent_thumb, grandparent_thumb, media_index, parent_media_index, ' \
|
||||
'year, started, user ' \
|
||||
'FROM session_history_metadata ' \
|
||||
'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 ' \
|
||||
' ELSE session_history.rating_key END) ' \
|
||||
'ORDER BY started DESC LIMIT ?'
|
||||
result = monitor_db.select(query, args=[library_id, limit])
|
||||
result = monitor_db.select(query, args=[section_id, limit])
|
||||
else:
|
||||
result = []
|
||||
except Exception as e:
|
||||
|
@ -399,18 +684,18 @@ class Libraries(object):
|
|||
'WHERE session_history_media_info.id IN (SELECT session_history_media_info.id '
|
||||
'FROM session_history_media_info '
|
||||
'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 = \
|
||||
monitor_db.action('DELETE FROM '
|
||||
'session_history '
|
||||
'WHERE session_history.id IN (SELECT session_history.id '
|
||||
'FROM session_history '
|
||||
'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 = \
|
||||
monitor_db.action('DELETE FROM '
|
||||
'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
|
||||
else:
|
||||
|
@ -466,3 +751,49 @@ class Libraries(object):
|
|||
return 'Unable to re-add library, section_id or section_name not valid.'
|
||||
except Exception as 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)
|
|
@ -31,7 +31,7 @@ def notify(stream_data=None, notify_action=None):
|
|||
user_details = user_data.get_details(user_id=stream_data['user_id'])
|
||||
|
||||
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']:
|
||||
# logger.debug(u"PlexPy NotificationHandler :: Notifications for user '%s' is disabled." % user_details['username'])
|
||||
|
|
|
@ -41,7 +41,7 @@ def extract_plexwatch_xml(xml=None):
|
|||
grandparent_thumb = helpers.get_xml_attr(a, 'grandparentThumb')
|
||||
grandparent_title = helpers.get_xml_attr(a, 'grandparentTitle')
|
||||
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')
|
||||
originally_available_at = helpers.get_xml_attr(a, 'originallyAvailableAt')
|
||||
last_viewed_at = helpers.get_xml_attr(a, 'lastViewedAt')
|
||||
|
@ -157,7 +157,7 @@ def extract_plexwatch_xml(xml=None):
|
|||
'title': title,
|
||||
'tagline': tagline,
|
||||
'guid': guid,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'media_index': media_index,
|
||||
'originally_available_at': originally_available_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)
|
||||
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)
|
||||
|
||||
ap = activity_processor.ActivityProcessor()
|
||||
user_data = users.Users()
|
||||
|
@ -372,7 +374,7 @@ def import_from_plexwatch(database=None, table_name=None, import_ignore_interval
|
|||
'rating': extracted_xml['rating'],
|
||||
'duration': extracted_xml['duration'],
|
||||
'guid': extracted_xml['guid'],
|
||||
'library_id': extracted_xml['library_id'],
|
||||
'section_id': extracted_xml['section_id'],
|
||||
'directors': extracted_xml['directors'],
|
||||
'writers': extracted_xml['writers'],
|
||||
'actors': extracted_xml['actors'],
|
||||
|
|
|
@ -44,11 +44,6 @@ def refresh_libraries():
|
|||
|
||||
server_id = plexpy.CONFIG.PMS_IDENTIFIER
|
||||
|
||||
if plexpy.CONFIG.HOME_LIBRARY_CARDS == ['first_run']:
|
||||
populate_cards = True
|
||||
else:
|
||||
populate_cards = False
|
||||
|
||||
library_keys = []
|
||||
|
||||
if library_sections:
|
||||
|
@ -56,11 +51,11 @@ def refresh_libraries():
|
|||
|
||||
for section in library_sections:
|
||||
section_keys = {'server_id': server_id,
|
||||
'section_id': section['key']}
|
||||
'section_id': section['section_id']}
|
||||
section_values = {'server_id': server_id,
|
||||
'section_id': section['key'],
|
||||
'section_name': section['title'],
|
||||
'section_type': section['type'],
|
||||
'section_id': section['section_id'],
|
||||
'section_name': section['section_name'],
|
||||
'section_type': section['section_type'],
|
||||
'thumb': section['thumb'],
|
||||
'art': section['art'],
|
||||
'count': section['count'],
|
||||
|
@ -70,13 +65,42 @@ def refresh_libraries():
|
|||
|
||||
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.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.")
|
||||
else:
|
||||
logger.warn(u"PlexPy Pmsconnect :: Unable to refresh libraries list.")
|
||||
|
@ -169,7 +193,7 @@ class PmsConnect(object):
|
|||
|
||||
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.
|
||||
|
||||
|
@ -178,7 +202,7 @@ class PmsConnect(object):
|
|||
|
||||
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,
|
||||
proto=self.protocol,
|
||||
request_type='GET',
|
||||
|
@ -203,6 +227,23 @@ class PmsConnect(object):
|
|||
|
||||
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=''):
|
||||
"""
|
||||
Return list of local servers.
|
||||
|
@ -267,7 +308,7 @@ class PmsConnect(object):
|
|||
|
||||
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.
|
||||
|
||||
|
@ -275,7 +316,9 @@ class PmsConnect(object):
|
|||
|
||||
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,
|
||||
proto=self.protocol,
|
||||
request_type='GET',
|
||||
|
@ -363,7 +406,7 @@ class PmsConnect(object):
|
|||
|
||||
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.
|
||||
|
||||
|
@ -371,8 +414,8 @@ class PmsConnect(object):
|
|||
|
||||
Output: array
|
||||
"""
|
||||
if library_id:
|
||||
recent = self.get_library_recently_added(library_id, count, output_format='xml')
|
||||
if section_id:
|
||||
recent = self.get_library_recently_added(section_id, count, output_format='xml')
|
||||
else:
|
||||
recent = self.get_recently_added(count, output_format='xml')
|
||||
|
||||
|
@ -402,7 +445,7 @@ class PmsConnect(object):
|
|||
'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'),
|
||||
'library_id': helpers.get_xml_attr(item, 'librarySectionID'),
|
||||
'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
|
||||
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
|
||||
'year': helpers.get_xml_attr(item, 'year'),
|
||||
'thumb': helpers.get_xml_attr(item, 'thumb'),
|
||||
|
@ -424,7 +467,7 @@ class PmsConnect(object):
|
|||
'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'),
|
||||
'library_id': helpers.get_xml_attr(item, 'librarySectionID'),
|
||||
'section_id': helpers.get_xml_attr(item, 'librarySectionID'),
|
||||
'library_name': helpers.get_xml_attr(item, 'librarySectionTitle'),
|
||||
'year': helpers.get_xml_attr(item, 'year'),
|
||||
'thumb': helpers.get_xml_attr(item, 'thumb'),
|
||||
|
@ -450,7 +493,7 @@ class PmsConnect(object):
|
|||
try:
|
||||
xml_head = metadata.getElementsByTagName('MediaContainer')
|
||||
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 []
|
||||
|
||||
metadata_list = []
|
||||
|
@ -474,7 +517,7 @@ class PmsConnect(object):
|
|||
logger.debug(u"PlexPy Pmsconnect :: Metadata failed")
|
||||
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')
|
||||
|
||||
genres = []
|
||||
|
@ -500,7 +543,7 @@ class PmsConnect(object):
|
|||
|
||||
if metadata_type == 'movie':
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
|
||||
|
@ -535,7 +578,7 @@ class PmsConnect(object):
|
|||
|
||||
elif metadata_type == 'show':
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'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')
|
||||
show_details = self.get_metadata_details(parent_rating_key)
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'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')
|
||||
show_details = self.get_metadata_details(grandparent_rating_key)
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
|
||||
|
@ -644,7 +687,7 @@ class PmsConnect(object):
|
|||
|
||||
elif metadata_type == 'artist':
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'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')
|
||||
artist_details = self.get_metadata_details(parent_rating_key)
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'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')
|
||||
album_details = self.get_metadata_details(parent_rating_key)
|
||||
metadata = {'media_type': metadata_type,
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name,
|
||||
'rating_key': helpers.get_xml_attr(metadata_main, 'ratingKey'),
|
||||
'parent_rating_key': helpers.get_xml_attr(metadata_main, 'parentRatingKey'),
|
||||
|
@ -798,11 +841,11 @@ class PmsConnect(object):
|
|||
output = {'metadata': metadata_list}
|
||||
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.
|
||||
|
||||
Parameters required: library_id { Plex library key }
|
||||
Parameters required: section_id { Plex library key }
|
||||
|
||||
Output: array
|
||||
"""
|
||||
|
@ -826,9 +869,9 @@ class PmsConnect(object):
|
|||
result_data = a.getElementsByTagName('Directory')
|
||||
for result in result_data:
|
||||
key = helpers.get_xml_attr(result, 'key')
|
||||
if key == library_id:
|
||||
if key == section_id:
|
||||
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'),
|
||||
'title': helpers.get_xml_attr(result, 'title'),
|
||||
'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')
|
||||
|
||||
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'),
|
||||
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
|
||||
'art': helpers.get_xml_attr(session, 'art'),
|
||||
|
@ -1067,7 +1110,7 @@ class PmsConnect(object):
|
|||
|
||||
if helpers.get_xml_attr(session, 'type') == 'episode':
|
||||
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'),
|
||||
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
|
||||
'art': helpers.get_xml_attr(session, 'art'),
|
||||
|
@ -1125,7 +1168,7 @@ class PmsConnect(object):
|
|||
|
||||
elif helpers.get_xml_attr(session, 'type') == 'movie':
|
||||
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'),
|
||||
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
|
||||
'art': helpers.get_xml_attr(session, 'art'),
|
||||
|
@ -1183,7 +1226,7 @@ class PmsConnect(object):
|
|||
|
||||
elif helpers.get_xml_attr(session, 'type') == 'clip':
|
||||
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'),
|
||||
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
|
||||
'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')
|
||||
|
||||
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'),
|
||||
'parent_media_index': helpers.get_xml_attr(session, 'parentIndex'),
|
||||
'art': helpers.get_xml_attr(session, 'art'),
|
||||
|
@ -1494,9 +1537,9 @@ class PmsConnect(object):
|
|||
if a.getElementsByTagName('Directory'):
|
||||
result_data = a.getElementsByTagName('Directory')
|
||||
for result in result_data:
|
||||
libraries_output = {'key': helpers.get_xml_attr(result, 'key'),
|
||||
'type': helpers.get_xml_attr(result, 'type'),
|
||||
'title': helpers.get_xml_attr(result, 'title'),
|
||||
libraries_output = {'section_id': helpers.get_xml_attr(result, 'key'),
|
||||
'section_type': helpers.get_xml_attr(result, 'type'),
|
||||
'section_name': helpers.get_xml_attr(result, 'title'),
|
||||
'thumb': helpers.get_xml_attr(result, 'thumb'),
|
||||
'art': helpers.get_xml_attr(result, 'art')
|
||||
}
|
||||
|
@ -1509,38 +1552,46 @@ class PmsConnect(object):
|
|||
|
||||
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.
|
||||
|
||||
Parameters required: library_type { movie, show, episode, artist }
|
||||
section_key { unique library key }
|
||||
Parameters required: section_type { movie, show, episode, artist }
|
||||
section_id { unique library key }
|
||||
|
||||
Output: array
|
||||
"""
|
||||
|
||||
if library_type == 'movie':
|
||||
if section_type == 'movie':
|
||||
sort_type = '&type=1'
|
||||
elif library_type == 'show':
|
||||
elif section_type == 'show':
|
||||
sort_type = '&type=2'
|
||||
elif library_type == 'season':
|
||||
elif section_type == 'season':
|
||||
sort_type = '&type=3'
|
||||
elif library_type == 'episode':
|
||||
elif section_type == 'episode':
|
||||
sort_type = '&type=4'
|
||||
elif library_type == 'artist':
|
||||
elif section_type == 'artist':
|
||||
sort_type = '&type=8'
|
||||
elif library_type == 'album':
|
||||
elif section_type == 'album':
|
||||
sort_type = '&type=9'
|
||||
elif library_type == 'track':
|
||||
elif section_type == 'track':
|
||||
sort_type = '&type=10'
|
||||
elif library_type == 'photo':
|
||||
elif section_type == 'photo':
|
||||
sort_type = ''
|
||||
elif library_type == 'photoAlbum':
|
||||
elif section_type == 'photoAlbum':
|
||||
sort_type = '&type=14'
|
||||
elif library_type == 'picture':
|
||||
elif section_type == 'picture':
|
||||
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:
|
||||
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)
|
||||
return []
|
||||
|
||||
library_list = []
|
||||
childern_list = []
|
||||
|
||||
for a in xml_head:
|
||||
if a.getAttribute('size'):
|
||||
if a.getAttribute('size') == '0':
|
||||
logger.debug(u"PlexPy Pmsconnect :: No library data.")
|
||||
library_list = {'library_count': '0',
|
||||
'library_list': []
|
||||
childern_list = {'library_count': '0',
|
||||
'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'):
|
||||
result_data = a.getElementsByTagName('Directory')
|
||||
for result in result_data:
|
||||
library_output = {'key': helpers.get_xml_attr(result, 'key'),
|
||||
'type': helpers.get_xml_attr(result, 'type'),
|
||||
'title': helpers.get_xml_attr(result, 'title'),
|
||||
'thumb': helpers.get_xml_attr(result, 'thumb')
|
||||
}
|
||||
library_list.append(library_output)
|
||||
item_main = a.getElementsByTagName('Directory')
|
||||
item_main = [d for d in item_main if helpers.get_xml_attr(d, 'ratingKey')]
|
||||
elif a.getElementsByTagName('Video'):
|
||||
item_main = a.getElementsByTagName('Video')
|
||||
elif a.getElementsByTagName('Track'):
|
||||
item_main = a.getElementsByTagName('Track')
|
||||
elif a.getElementsByTagName('Photo'):
|
||||
item_main = a.getElementsByTagName('Photo')
|
||||
else:
|
||||
item_main = []
|
||||
|
||||
output = {'library_count': helpers.get_xml_attr(xml_head[0], 'totalSize'),
|
||||
'count_type': helpers.get_xml_attr(xml_head[0], 'title2'),
|
||||
'library_list': library_list
|
||||
for item in item_main:
|
||||
item_info = {'section_id': helpers.get_xml_attr(item, 'key'),
|
||||
'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
|
||||
|
@ -1590,57 +1685,44 @@ class PmsConnect(object):
|
|||
libraries_list = server_libraries['libraries_list']
|
||||
|
||||
for library in libraries_list:
|
||||
library_type = library['type']
|
||||
section_key = library['key']
|
||||
library_list = self.get_library_children(library_type, section_key)
|
||||
section_type = library['section_type']
|
||||
section_id = library['section_id']
|
||||
children_list = self.get_library_children(section_id=section_id, section_type=section_type, count='1')
|
||||
|
||||
if library_list['library_count'] != '0':
|
||||
library_stats = {'key': library['key'],
|
||||
'title': library['title'],
|
||||
'type': library_type,
|
||||
if children_list['library_count'] != '0':
|
||||
library_stats = {'section_id': library['section_id'],
|
||||
'section_name': library['section_name'],
|
||||
'section_type': section_type,
|
||||
'thumb': library['thumb'],
|
||||
'art': library['art'],
|
||||
'count': library_list['library_count'],
|
||||
'count_type': library_list['count_type']
|
||||
'count': children_list['library_count']
|
||||
}
|
||||
|
||||
if library_type == 'show':
|
||||
parent_list = self.get_library_children(library_type='season', section_key=section_key)
|
||||
parent_stats = {'parent_count': parent_list['library_count'],
|
||||
'parent_count_type': 'All Seasons'
|
||||
}
|
||||
if section_type == 'show':
|
||||
parent_list = self.get_library_children(section_id=section_id, section_type='season', count='1')
|
||||
parent_stats = {'parent_count': parent_list['library_count']}
|
||||
library_stats.update(parent_stats)
|
||||
|
||||
child_list = self.get_library_children(library_type='episode', section_key=section_key)
|
||||
child_stats = {'child_count': child_list['library_count'],
|
||||
'child_count_type': 'All Episodes'
|
||||
}
|
||||
child_list = self.get_library_children(section_id=section_id, section_type='episode', count='1')
|
||||
child_stats = {'child_count': child_list['library_count']}
|
||||
library_stats.update(child_stats)
|
||||
|
||||
if library_type == 'artist':
|
||||
parent_list = self.get_library_children(library_type='album', section_key=section_key)
|
||||
parent_stats = {'parent_count': parent_list['library_count'],
|
||||
'parent_count_type': 'All Seasons'
|
||||
}
|
||||
if section_type == 'artist':
|
||||
parent_list = self.get_library_children(section_id=section_id, section_type='album', count='1')
|
||||
parent_stats = {'parent_count': parent_list['library_count']}
|
||||
library_stats.update(parent_stats)
|
||||
|
||||
child_list = self.get_library_children(library_type='track', section_key=section_key)
|
||||
child_stats = {'child_count': child_list['library_count'],
|
||||
'child_count_type': 'All Albums'
|
||||
}
|
||||
child_list = self.get_library_children(section_id=section_id, section_type='track', count='1')
|
||||
child_stats = {'child_count': child_list['library_count']}
|
||||
library_stats.update(child_stats)
|
||||
|
||||
if library_type == 'photo':
|
||||
parent_list = self.get_library_children(library_type='photoAlbum', section_key=section_key)
|
||||
parent_stats = {'parent_count': parent_list['library_count'],
|
||||
'parent_count_type': 'All Photo Albums'
|
||||
}
|
||||
if section_type == 'photo':
|
||||
parent_list = self.get_library_children(section_id=section_id, section_type='photoAlbum', count='1')
|
||||
parent_stats = {'parent_count': parent_list['library_count']}
|
||||
library_stats.update(parent_stats)
|
||||
|
||||
child_list = self.get_library_children(library_type='picture', section_key=section_key)
|
||||
child_stats = {'child_count': child_list['library_count'],
|
||||
'child_count_type': 'All Photos'
|
||||
}
|
||||
child_list = self.get_library_children(section_id=section_id, section_type='picture', count='1')
|
||||
child_stats = {'child_count': child_list['library_count']}
|
||||
library_stats.update(child_stats)
|
||||
|
||||
server_library_stats.append(library_stats)
|
||||
|
@ -1782,7 +1864,7 @@ class PmsConnect(object):
|
|||
else:
|
||||
match_type = 'index'
|
||||
|
||||
library_id = None
|
||||
section_id = None
|
||||
library_name = None
|
||||
|
||||
# get grandparent rating key
|
||||
|
@ -1790,7 +1872,7 @@ class PmsConnect(object):
|
|||
try:
|
||||
metadata = self.get_metadata_details(rating_key=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']
|
||||
except Exception as 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:
|
||||
metadata = self.get_metadata_details(rating_key=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']
|
||||
except Exception as 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:
|
||||
{'rating_key': int(rating_key),
|
||||
'children': parents },
|
||||
'library_id': library_id,
|
||||
'section_id': section_id,
|
||||
'library_name': library_name
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,11 @@ class Users(object):
|
|||
|
||||
rows = []
|
||||
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']:
|
||||
thumb = item['parent_thumb']
|
||||
elif item['media_type'] == 'episode':
|
||||
|
|
|
@ -234,7 +234,11 @@ class WebInterface(object):
|
|||
|
||||
@cherrypy.expose
|
||||
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
|
||||
def get_library_list(self, **kwargs):
|
||||
|
@ -300,10 +304,10 @@ class WebInterface(object):
|
|||
return status_message
|
||||
|
||||
@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()
|
||||
result = library_data.get_watch_time_stats(library_id=library_id)
|
||||
result = library_data.get_watch_time_stats(section_id=section_id)
|
||||
|
||||
if result:
|
||||
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")
|
||||
|
||||
@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()
|
||||
result = library_data.get_user_stats(library_id=library_id)
|
||||
result = library_data.get_user_stats(section_id=section_id)
|
||||
|
||||
if result:
|
||||
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")
|
||||
|
||||
@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()
|
||||
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:
|
||||
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")
|
||||
|
||||
@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()
|
||||
result = library_data.get_recently_added_details(library_id=library_id, count=limit)
|
||||
pms_connect = pmsconnect.PmsConnect()
|
||||
result = pms_connect.get_recently_added_details(section_id=section_id, count=limit)
|
||||
|
||||
if result:
|
||||
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.")
|
||||
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
|
||||
def delete_all_library_history(self, section_id, **kwargs):
|
||||
library_data = libraries.Libraries()
|
||||
|
@ -395,6 +432,35 @@ class WebInterface(object):
|
|||
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||
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 #####
|
||||
|
||||
|
@ -595,7 +661,7 @@ class WebInterface(object):
|
|||
custom_where.append(['session_history.reference_id', reference_id])
|
||||
if 'section_id' in kwargs:
|
||||
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:
|
||||
media_type = kwargs.get('media_type', "")
|
||||
if media_type != 'all':
|
||||
|
@ -1348,14 +1414,10 @@ class WebInterface(object):
|
|||
|
||||
@cherrypy.expose
|
||||
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
|
||||
|
||||
config = {
|
||||
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER,
|
||||
"update_library_ids": plexpy.CONFIG.UPDATE_LIBRARY_IDS
|
||||
"pms_identifier": plexpy.CONFIG.PMS_IDENTIFIER
|
||||
}
|
||||
|
||||
if source == 'history':
|
||||
|
@ -1371,7 +1433,6 @@ class WebInterface(object):
|
|||
return serve_template(templatename="info.html", data=metadata, title="Info", config=config)
|
||||
else:
|
||||
return self.update_metadata(rating_key)
|
||||
#raise cherrypy.InternalRedirect("/update_metadata?rating_key=" + rating_key)
|
||||
|
||||
@cherrypy.expose
|
||||
def get_item_children(self, rating_key='', **kwargs):
|
||||
|
@ -1493,24 +1554,7 @@ class WebInterface(object):
|
|||
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||
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
|
||||
@cherrypy.expose
|
||||
|
@ -1537,22 +1581,6 @@ class WebInterface(object):
|
|||
else:
|
||||
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 #####
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue