Compare commits
13 Commits
v2.1.16-be
...
v2.1.17-be
Author | SHA1 | Date | |
---|---|---|---|
![]() |
89d1a5782a | ||
![]() |
97cf2ebe19 | ||
![]() |
4ef36a464a | ||
![]() |
54ec9ad7da | ||
![]() |
bfdfdaaad1 | ||
![]() |
5bd51b2a17 | ||
![]() |
35778cfe72 | ||
![]() |
f81649c4d3 | ||
![]() |
59162713e7 | ||
![]() |
188b728dd0 | ||
![]() |
3446f5543d | ||
![]() |
ab5384cfdf | ||
![]() |
e567134ee1 |
@@ -1,5 +1,14 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v2.1.17-beta (2018-07-22)
|
||||||
|
|
||||||
|
* Notifications:
|
||||||
|
* Change: Use default selected stream for media info in notifications.
|
||||||
|
* UI:
|
||||||
|
* New: Automatically discover localhost Plex servers in server selection dropdown.
|
||||||
|
* Change: Save Datatables state indefinitely.
|
||||||
|
|
||||||
|
|
||||||
## v2.1.16-beta (2018-07-06)
|
## v2.1.16-beta (2018-07-06)
|
||||||
|
|
||||||
* Monitoring:
|
* Monitoring:
|
||||||
|
@@ -75,7 +75,7 @@
|
|||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="home" title="Tautulli">
|
<a class="navbar-brand" href="home" title="Tautulli">
|
||||||
<img src="${http_root}images/logo-tautulli-45.png" height="45" alt="PlexPy">
|
<img src="${http_root}images/logo-tautulli-45.png" height="45" alt="Tautulli">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse navbar-collapse navbar-right" id="navbar-collapse-1">
|
<div class="collapse navbar-collapse navbar-right" id="navbar-collapse-1">
|
||||||
|
@@ -22,11 +22,11 @@ DOCUMENTATION :: END
|
|||||||
% if plexpy.CURRENT_VERSION:
|
% if plexpy.CURRENT_VERSION:
|
||||||
<tr>
|
<tr>
|
||||||
<td>Git Branch:</td>
|
<td>Git Branch:</td>
|
||||||
<td><a class="no-highlight" href="${anon_url('https://github.com/%s/%s/tree/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.CONFIG.GIT_BRANCH))}">${plexpy.CONFIG.GIT_BRANCH}</a></td>
|
<td><a class="no-highlight" href="${anon_url('https://github.com/%s/%s/tree/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.CONFIG.GIT_BRANCH))}" target="_blank">${plexpy.CONFIG.GIT_BRANCH}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Git Commit Hash:</td>
|
<td>Git Commit Hash:</td>
|
||||||
<td><a class="no-highlight" href="${anon_url('https://github.com/%s/%s/commit/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.CURRENT_VERSION))}">${plexpy.CURRENT_VERSION}</a></td>
|
<td><a class="no-highlight" href="${anon_url('https://github.com/%s/%s/commit/%s' % (plexpy.CONFIG.GIT_USER, plexpy.CONFIG.GIT_REPO, plexpy.CURRENT_VERSION))}" target="_blank">${plexpy.CURRENT_VERSION}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
% endif
|
% endif
|
||||||
<tr>
|
<tr>
|
||||||
|
@@ -37,7 +37,7 @@ function showMsg(msg, loader, timeout, ms, error) {
|
|||||||
}
|
}
|
||||||
var message = $("<div class='msg'>" + msg + "</div>");
|
var message = $("<div class='msg'>" + msg + "</div>");
|
||||||
if (loader) {
|
if (loader) {
|
||||||
message = $("<div class='msg'><i class='fa fa-refresh fa-spin'></i> " + msg + "</div>");
|
message = $("<div class='msg'><i class='fa fa-refresh fa-spin'></i> " + msg + "</div>");
|
||||||
feedback.css("padding", "14px 10px");
|
feedback.css("padding", "14px 10px");
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -73,9 +73,9 @@ function confirmAjaxCall(url, msg, data, loader_msg, callback) {
|
|||||||
var result = $.parseJSON(xhr.responseText);
|
var result = $.parseJSON(xhr.responseText);
|
||||||
var msg = result.message;
|
var msg = result.message;
|
||||||
if (result.result == 'success') {
|
if (result.result == 'success') {
|
||||||
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000);
|
showMsg('<i class="fa fa-check"></i> ' + msg, false, true, 5000);
|
||||||
} else {
|
} else {
|
||||||
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true);
|
showMsg('<i class="fa fa-times"></i> ' + msg, false, true, 5000, true);
|
||||||
}
|
}
|
||||||
if (typeof callback === "function") {
|
if (typeof callback === "function") {
|
||||||
callback(result);
|
callback(result);
|
||||||
@@ -103,7 +103,7 @@ function doAjaxCall(url, elem, reload, form, showMsg, callback) {
|
|||||||
dataString = $(formID).serialize();
|
dataString = $(formID).serialize();
|
||||||
}
|
}
|
||||||
// Loader Image
|
// Loader Image
|
||||||
var loader = $("<i class='fa fa-refresh fa-spin ajaxLoader-" + url +"></i>");
|
var loader = $("<div class='msg ajaxLoader-" + url +"'><i class='fa fa-refresh fa-spin'></i> Saving...</div>");
|
||||||
// Data Success Message
|
// Data Success Message
|
||||||
var dataSucces = $(elem).data('success');
|
var dataSucces = $(elem).data('success');
|
||||||
if (typeof dataSucces === "undefined") {
|
if (typeof dataSucces === "undefined") {
|
||||||
@@ -117,8 +117,8 @@ function doAjaxCall(url, elem, reload, form, showMsg, callback) {
|
|||||||
dataError = "There was an error";
|
dataError = "There was an error";
|
||||||
}
|
}
|
||||||
// Get Success & Error message from inline data, else use standard message
|
// Get Success & Error message from inline data, else use standard message
|
||||||
var succesMsg = $("<div class='msg'><i class='fa fa-check'></i> " + dataSucces + "</div>");
|
var succesMsg = $("<div class='msg'><i class='fa fa-check'></i> " + dataSucces + "</div>");
|
||||||
var errorMsg = $("<div class='msg'><i class='fa fa-exclamation-triangle'></i> " + dataError + "</div>");
|
var errorMsg = $("<div class='msg'><i class='fa fa-exclamation-triangle'></i> " + dataError + "</div>");
|
||||||
// Check if checkbox is selected
|
// Check if checkbox is selected
|
||||||
if (form) {
|
if (form) {
|
||||||
if ($('td#select input[type=checkbox]').length > 0 && !$('td#select input[type=checkbox]').is(':checked') ||
|
if ($('td#select input[type=checkbox]').length > 0 && !$('td#select input[type=checkbox]').is(':checked') ||
|
||||||
@@ -187,7 +187,7 @@ function doAjaxCall(url, elem, reload, form, showMsg, callback) {
|
|||||||
},
|
},
|
||||||
complete: function (jqXHR, textStatus) {
|
complete: function (jqXHR, textStatus) {
|
||||||
// Remove loaders and stuff, ajax request is complete!
|
// Remove loaders and stuff, ajax request is complete!
|
||||||
feedback.remove('.ajaxLoader-' + url);
|
$('.ajaxLoader-' + url).remove();
|
||||||
if (typeof callback === "function") {
|
if (typeof callback === "function") {
|
||||||
callback(jqXHR);
|
callback(jqXHR);
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,7 @@ history_table_options = {
|
|||||||
},
|
},
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"processing": false,
|
"processing": false,
|
||||||
"serverSide": true,
|
"serverSide": true,
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
@@ -289,7 +290,7 @@ history_table_options = {
|
|||||||
' (filtered from ' + settings.json.total_duration + ' total)</span>');
|
' (filtered from ' + settings.json.total_duration + ' total)</span>');
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0);
|
showMsg(msg, false, false, 0);
|
||||||
$('[data-toggle="tooltip"]').tooltip('destroy');
|
$('[data-toggle="tooltip"]').tooltip('destroy');
|
||||||
$('[data-toggle="popover"]').popover('destroy');
|
$('[data-toggle="popover"]').popover('destroy');
|
||||||
|
@@ -148,7 +148,7 @@ history_table_modal_options = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ libraries_list_table_options = {
|
|||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"order": [ 2, 'asc'],
|
"order": [ 2, 'asc'],
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"autoWidth": false,
|
"autoWidth": false,
|
||||||
"scrollX": true,
|
"scrollX": true,
|
||||||
@@ -238,7 +239,7 @@ libraries_list_table_options = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
},
|
},
|
||||||
"rowCallback": function (row, rowData) {
|
"rowCallback": function (row, rowData) {
|
||||||
|
@@ -10,6 +10,7 @@ login_log_table_options = {
|
|||||||
"loadingRecords": '<i class="fa fa-refresh fa-spin"></i> Loading items...</div>'
|
"loadingRecords": '<i class="fa fa-refresh fa-spin"></i> Loading items...</div>'
|
||||||
},
|
},
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"processing": false,
|
"processing": false,
|
||||||
"serverSide": true,
|
"serverSide": true,
|
||||||
@@ -110,7 +111,7 @@ login_log_table_options = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
"preDrawCallback": function (settings) {
|
"preDrawCallback": function (settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -6,6 +6,7 @@ var log_table_options = {
|
|||||||
"order": [ 0, 'desc'],
|
"order": [ 0, 'desc'],
|
||||||
"pageLength": 50,
|
"pageLength": 50,
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"language": {
|
"language": {
|
||||||
"search": "Search: ",
|
"search": "Search: ",
|
||||||
"lengthMenu": "Show _MENU_ lines per page",
|
"lengthMenu": "Show _MENU_ lines per page",
|
||||||
@@ -39,7 +40,7 @@ var log_table_options = {
|
|||||||
$('#ajaxMsg').fadeOut();
|
$('#ajaxMsg').fadeOut();
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ media_info_table_options = {
|
|||||||
},
|
},
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"processing": false,
|
"processing": false,
|
||||||
"serverSide": true,
|
"serverSide": true,
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
@@ -299,7 +300,7 @@ media_info_table_options = {
|
|||||||
' (filtered from ' + humanFileSize(settings.json.total_file_size) + ')</span>');
|
' (filtered from ' + humanFileSize(settings.json.total_file_size) + ')</span>');
|
||||||
},
|
},
|
||||||
"preDrawCallback": function (settings) {
|
"preDrawCallback": function (settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
},
|
},
|
||||||
"rowCallback": function (row, rowData, rowIndex) {
|
"rowCallback": function (row, rowData, rowIndex) {
|
||||||
|
@@ -6,6 +6,7 @@ newsletter_log_table_options = {
|
|||||||
"order": [ 0, 'desc'],
|
"order": [ 0, 'desc'],
|
||||||
"pageLength": 50,
|
"pageLength": 50,
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"language": {
|
"language": {
|
||||||
"search":"Search: ",
|
"search":"Search: ",
|
||||||
"lengthMenu": "Show _MENU_ lines per page",
|
"lengthMenu": "Show _MENU_ lines per page",
|
||||||
@@ -140,7 +141,7 @@ newsletter_log_table_options = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -6,6 +6,7 @@ notification_log_table_options = {
|
|||||||
"order": [ 0, 'desc'],
|
"order": [ 0, 'desc'],
|
||||||
"pageLength": 50,
|
"pageLength": 50,
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"language": {
|
"language": {
|
||||||
"search":"Search: ",
|
"search":"Search: ",
|
||||||
"lengthMenu": "Show _MENU_ lines per page",
|
"lengthMenu": "Show _MENU_ lines per page",
|
||||||
@@ -110,7 +111,7 @@ notification_log_table_options = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -6,6 +6,7 @@ var plex_log_table_options = {
|
|||||||
"order": [ 0, 'desc'],
|
"order": [ 0, 'desc'],
|
||||||
"pageLength": 50,
|
"pageLength": 50,
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"language": {
|
"language": {
|
||||||
"search": "Search: ",
|
"search": "Search: ",
|
||||||
"lengthMenu": "Show _MENU_ lines per page",
|
"lengthMenu": "Show _MENU_ lines per page",
|
||||||
@@ -39,7 +40,7 @@ var plex_log_table_options = {
|
|||||||
$('#ajaxMsg').fadeOut();
|
$('#ajaxMsg').fadeOut();
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ sync_table_options = {
|
|||||||
"order": [ [ 0, 'desc'], [ 1, 'asc'], [2, 'asc'] ],
|
"order": [ [ 0, 'desc'], [ 1, 'asc'], [2, 'asc'] ],
|
||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"language": {
|
"language": {
|
||||||
"search": "Search: ",
|
"search": "Search: ",
|
||||||
"lengthMenu": "Show _MENU_ lines per page",
|
"lengthMenu": "Show _MENU_ lines per page",
|
||||||
@@ -147,7 +148,7 @@ sync_table_options = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
"preDrawCallback": function (settings) {
|
"preDrawCallback": function (settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
},
|
},
|
||||||
"rowCallback": function (row, rowData, rowIndex) {
|
"rowCallback": function (row, rowData, rowIndex) {
|
||||||
|
@@ -10,6 +10,7 @@ user_ip_table_options = {
|
|||||||
"loadingRecords": '<i class="fa fa-refresh fa-spin"></i> Loading items...</div>'
|
"loadingRecords": '<i class="fa fa-refresh fa-spin"></i> Loading items...</div>'
|
||||||
},
|
},
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"processing": false,
|
"processing": false,
|
||||||
"serverSide": true,
|
"serverSide": true,
|
||||||
@@ -141,7 +142,7 @@ user_ip_table_options = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ users_list_table_options = {
|
|||||||
"pageLength": 25,
|
"pageLength": 25,
|
||||||
"order": [ 2, 'asc'],
|
"order": [ 2, 'asc'],
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
|
"stateDuration": 0,
|
||||||
"pagingType": "full_numbers",
|
"pagingType": "full_numbers",
|
||||||
"autoWidth": false,
|
"autoWidth": false,
|
||||||
"scrollX": true,
|
"scrollX": true,
|
||||||
@@ -240,7 +241,7 @@ users_list_table_options = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
var msg = "<i class='fa fa-refresh fa-spin'></i> Fetching rows...";
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0)
|
||||||
},
|
},
|
||||||
"rowCallback": function (row, rowData) {
|
"rowCallback": function (row, rowData) {
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<div class="login-logo">
|
<div class="login-logo">
|
||||||
<img src="${http_root}images/logo-tautulli-100.png" height="100" alt="PlexPy">
|
<img src="${http_root}images/logo-tautulli-100.png" height="100" alt="Tautulli">
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 col-sm-offset-3">
|
<div class="col-sm-6 col-sm-offset-3">
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="login-container">
|
<div class="login-container">
|
||||||
<div class="newsletter-logo">
|
<div class="newsletter-logo">
|
||||||
<img src="${http_root}images/newsletter/newsletter-header.png" height="100" alt="PlexPy">
|
<img src="${http_root}images/newsletter/newsletter-header.png" height="100" alt="Tautulli">
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 col-sm-offset-3">
|
<div class="col-sm-6 col-sm-offset-3">
|
||||||
|
@@ -650,12 +650,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group has-feedback" id="pms_ip_group">
|
<div class="form-group has-feedback" id="pms_ip_group">
|
||||||
<label for="pms_ip">Plex IP Address or Hostname</label>
|
<label for="pms_ip_selectize">Plex IP Address or Hostname</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9" id="selectize-pms-ip-container">
|
<div class="col-md-9" id="selectize-pms-ip-container">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select class="form-control pms-settings selectize-pms-ip" id="pms_ip" name="pms_ip" data-parsley-trigger="change" aria-describedby="server-verified" data-parsley-errors-container="#pms_ip_error" required>
|
<select class="form-control pms-settings selectize-pms-ip" id="pms_ip_selectize" data-parsley-trigger="change" aria-describedby="server-verified" data-parsley-errors-container="#pms_ip_error" required>
|
||||||
<option value="${config['pms_ip']}" selected>${config['pms_ip']}</option>
|
<option value="${config['pms_ip']}:${config['pms_port']}"
|
||||||
|
data-identifier="${config['pms_identifier']}"
|
||||||
|
data-ip="${config['pms_ip']}"
|
||||||
|
data-port="${config['pms_port']}"
|
||||||
|
data-local="${int(not int(config['pms_is_remote']))}"
|
||||||
|
data-ssl="${config['pms_ssl']}"
|
||||||
|
data-is_cloud="${config['pms_is_cloud']}"
|
||||||
|
data-label="${config['pms_name'] or 'Local'}"
|
||||||
|
selected>${config['pms_ip']}</option>
|
||||||
</select>
|
</select>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button class="btn btn-form" type="button" id="verify_server_button">Verify Server</button>
|
<button class="btn btn-form" type="button" id="verify_server_button">Verify Server</button>
|
||||||
@@ -738,6 +746,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" id="pms_ip" name="pms_ip" value="${config['pms_ip']}">
|
||||||
<input type="hidden" id="pms_is_cloud" name="pms_is_cloud" value="${config['pms_is_cloud']}">
|
<input type="hidden" id="pms_is_cloud" name="pms_is_cloud" value="${config['pms_is_cloud']}">
|
||||||
<input type="checkbox" name="server_changed" id="server_changed" value="1" style="display: none;">
|
<input type="checkbox" name="server_changed" id="server_changed" value="1" style="display: none;">
|
||||||
|
|
||||||
@@ -2053,7 +2062,7 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var $select_pms = $('#pms_ip').selectize({
|
var $select_pms = $('#pms_ip_selectize').selectize({
|
||||||
createOnBlur: true,
|
createOnBlur: true,
|
||||||
openOnFocus: true,
|
openOnFocus: true,
|
||||||
maxItems: 1,
|
maxItems: 1,
|
||||||
@@ -2064,13 +2073,19 @@ $(document).ready(function() {
|
|||||||
dropdownParent: '#selectize-pms-ip-container',
|
dropdownParent: '#selectize-pms-ip-container',
|
||||||
render: {
|
render: {
|
||||||
item: function (item, escape) {
|
item: function (item, escape) {
|
||||||
|
if (!item.label) {
|
||||||
|
$.extend(item,
|
||||||
|
$(this.revertSettings.$children)
|
||||||
|
.filter('[value=' + item.value + ']').data()
|
||||||
|
);
|
||||||
|
}
|
||||||
var label = item.label || item.value;
|
var label = item.label || item.value;
|
||||||
var caption = item.label ? item.value : null;
|
var caption = item.label ? item.ip : null;
|
||||||
return '<div data-ssl="' + item.httpsRequired +
|
return '<div data-identifier="' + item.clientIdentifier +
|
||||||
'" data-local="' + item.local +
|
|
||||||
'" data-identifier="' + item.clientIdentifier +
|
|
||||||
'" data-ip="' + item.ip +
|
'" data-ip="' + item.ip +
|
||||||
'" data-port="' + item.port +
|
'" data-port="' + item.port +
|
||||||
|
'" data-local="' + item.local +
|
||||||
|
'" data-ssl="' + item.httpsRequired +
|
||||||
'" data-is_cloud="' + item.is_cloud +
|
'" data-is_cloud="' + item.is_cloud +
|
||||||
'" data-label="' + item.label + '">' +
|
'" data-label="' + item.label + '">' +
|
||||||
'<span class="item-text">' + escape(label) + '</span>' +
|
'<span class="item-text">' + escape(label) + '</span>' +
|
||||||
@@ -2080,11 +2095,11 @@ $(document).ready(function() {
|
|||||||
option: function (item, escape) {
|
option: function (item, escape) {
|
||||||
var label = item.label || item.value;
|
var label = item.label || item.value;
|
||||||
var caption = item.label ? item.value : null;
|
var caption = item.label ? item.value : null;
|
||||||
return '<div data-ssl="' + item.httpsRequired +
|
return '<div data-identifier="' + item.clientIdentifier +
|
||||||
'" data-local="' + item.local +
|
|
||||||
'" data-identifier="' + item.clientIdentifier +
|
|
||||||
'" data-ip="' + item.ip +
|
'" data-ip="' + item.ip +
|
||||||
'" data-port="' + item.port +
|
'" data-port="' + item.port +
|
||||||
|
'" data-local="' + item.local +
|
||||||
|
'" data-ssl="' + item.httpsRequired +
|
||||||
'" data-is_cloud="' + item.is_cloud +
|
'" data-is_cloud="' + item.is_cloud +
|
||||||
'" data-label="' + item.label + '">' +
|
'" data-label="' + item.label + '">' +
|
||||||
escape(label) +
|
escape(label) +
|
||||||
@@ -2095,15 +2110,24 @@ $(document).ready(function() {
|
|||||||
create: function(input) {
|
create: function(input) {
|
||||||
return {label: '', value: input};
|
return {label: '', value: input};
|
||||||
},
|
},
|
||||||
|
onInitialize: function () {
|
||||||
|
var s = this;
|
||||||
|
this.revertSettings.$children.each(function () {
|
||||||
|
$.extend(s.options[this.value], $(this).data());
|
||||||
|
});
|
||||||
|
},
|
||||||
onChange: function (item) {
|
onChange: function (item) {
|
||||||
var pms_ip_selected = this.getItem(item)[0];
|
var pms_ip_selected = this.getItem(item)[0];
|
||||||
var identifier = $(pms_ip_selected).data('identifier');
|
var identifier = $(pms_ip_selected).data('identifier');
|
||||||
|
var ip = $(pms_ip_selected).data('ip');
|
||||||
var port = $(pms_ip_selected).data('port');
|
var port = $(pms_ip_selected).data('port');
|
||||||
var local = $(pms_ip_selected).data('local');
|
var local = $(pms_ip_selected).data('local');
|
||||||
var ssl = $(pms_ip_selected).data('ssl');
|
var ssl = $(pms_ip_selected).data('ssl');
|
||||||
var is_cloud = $(pms_ip_selected).data('is_cloud');
|
var is_cloud = $(pms_ip_selected).data('is_cloud');
|
||||||
|
var value = $(pms_ip_selected).data('value');
|
||||||
|
|
||||||
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
||||||
|
$('#pms_ip').val(ip !== 'undefined' ? ip : value);
|
||||||
$('#pms_port').val(port !== 'undefined' ? port : 32400);
|
$('#pms_port').val(port !== 'undefined' ? port : 32400);
|
||||||
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
||||||
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
||||||
@@ -2128,9 +2152,10 @@ $(document).ready(function() {
|
|||||||
},
|
},
|
||||||
success: function (result) {
|
success: function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
var existing_value = $('#pms_ip').val();
|
var existing_ip = $('#pms_ip').val();
|
||||||
|
var existing_port = $('#pms_port').val();
|
||||||
result.forEach(function (item) {
|
result.forEach(function (item) {
|
||||||
if (item.value === existing_value) {
|
if (item.ip === existing_ip && item.port === existing_port) {
|
||||||
select_pms.updateOption(item.value, item);
|
select_pms.updateOption(item.value, item);
|
||||||
} else {
|
} else {
|
||||||
select_pms.addOption(item);
|
select_pms.addOption(item);
|
||||||
|
@@ -203,8 +203,8 @@ DOCUMENTATION :: END
|
|||||||
$('#confirm-modal-update').modal();
|
$('#confirm-modal-update').modal();
|
||||||
$('#confirm-modal-update').one('click', '#confirm-update', function () {
|
$('#confirm-modal-update').one('click', '#confirm-update', function () {
|
||||||
$(this).prop('disabled', true);
|
$(this).prop('disabled', true);
|
||||||
var msg = '<i class="fa fa-refresh fa-spin"></i> Updating database...'
|
var msg = '<i class="fa fa-refresh fa-spin"></i> Updating database...';
|
||||||
showMsg(msg, false, false, 0)
|
showMsg(msg, false, false, 0);
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: 'update_metadata_details',
|
url: 'update_metadata_details',
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
<form>
|
<form>
|
||||||
<div class="wizard-card" data-cardname="card1">
|
<div class="wizard-card" data-cardname="card1">
|
||||||
<div style="float: right;">
|
<div style="float: right;">
|
||||||
<img src="${http_root}images/logo-tautulli-45.png" height="45" alt="PlexPy">
|
<img src="${http_root}images/logo-tautulli-45.png" height="45" alt="Tautulli">
|
||||||
</div>
|
</div>
|
||||||
<h3 style="line-height: 50px;">Welcome!</h3>
|
<h3 style="line-height: 50px;">Welcome!</h3>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
@@ -86,11 +86,19 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<label for="pms_ip">Plex IP or Hostname</label>
|
<label for="pms_ip_selectize">Plex IP Address or Hostname</label>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<select class="form-control pms-settings selectize-pms-ip" id="pms_ip" name="pms_ip">
|
<select class="form-control pms-settings selectize-pms-ip" id="pms_ip_selectize">
|
||||||
<option value="${config['pms_ip']}" selected>${config['pms_ip']}</option>
|
<option value="${config['pms_ip']}:${config['pms_port']}"
|
||||||
|
data-identifier="${config['pms_identifier']}"
|
||||||
|
data-ip="${config['pms_ip']}"
|
||||||
|
data-port="${config['pms_port']}"
|
||||||
|
data-local="${int(not int(config['pms_is_remote']))}"
|
||||||
|
data-ssl="${config['pms_ssl']}"
|
||||||
|
data-is_cloud="${config['pms_is_cloud']}"
|
||||||
|
data-label="${config['pms_name'] or 'Local'}"
|
||||||
|
selected>${config['pms_ip']}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,6 +128,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="pms_valid" data-validate="validatePMSip" value="">
|
<input type="hidden" id="pms_valid" data-validate="validatePMSip" value="">
|
||||||
|
<input type="hidden" id="pms_ip" name="pms_ip" value="${config['pms_ip']}">
|
||||||
<input type="hidden" id="pms_is_cloud" name="pms_is_cloud" value="${config['pms_is_cloud']}">
|
<input type="hidden" id="pms_is_cloud" name="pms_is_cloud" value="${config['pms_is_cloud']}">
|
||||||
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
|
<input type="hidden" id="pms_identifier" name="pms_identifier" value="${config['pms_identifier']}">
|
||||||
<a class="btn btn-dark" id="verify-plex-server" href="#" role="button">Verify</a>
|
<a class="btn btn-dark" id="verify-plex-server" href="#" role="button">Verify</a>
|
||||||
@@ -314,7 +323,7 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var $select_pms = $('#pms_ip').selectize({
|
var $select_pms = $('#pms_ip_selectize').selectize({
|
||||||
createOnBlur: true,
|
createOnBlur: true,
|
||||||
openOnFocus: true,
|
openOnFocus: true,
|
||||||
maxItems: 1,
|
maxItems: 1,
|
||||||
@@ -324,13 +333,19 @@ $(document).ready(function() {
|
|||||||
inputClass: 'form-control selectize-input',
|
inputClass: 'form-control selectize-input',
|
||||||
render: {
|
render: {
|
||||||
item: function (item, escape) {
|
item: function (item, escape) {
|
||||||
|
if (!item.label) {
|
||||||
|
$.extend(item,
|
||||||
|
$(this.revertSettings.$children)
|
||||||
|
.filter('[value=' + item.value + ']').data()
|
||||||
|
);
|
||||||
|
}
|
||||||
var label = item.label || item.value;
|
var label = item.label || item.value;
|
||||||
var caption = item.label ? item.value : null;
|
var caption = item.label ? item.ip : null;
|
||||||
return '<div data-ssl="' + item.httpsRequired +
|
return '<div data-identifier="' + item.clientIdentifier +
|
||||||
'" data-local="' + item.local +
|
|
||||||
'" data-identifier="' + item.clientIdentifier +
|
|
||||||
'" data-ip="' + item.ip +
|
'" data-ip="' + item.ip +
|
||||||
'" data-port="' + item.port +
|
'" data-port="' + item.port +
|
||||||
|
'" data-local="' + item.local +
|
||||||
|
'" data-ssl="' + item.httpsRequired +
|
||||||
'" data-is_cloud="' + item.is_cloud +
|
'" data-is_cloud="' + item.is_cloud +
|
||||||
'" data-label="' + item.label + '">' +
|
'" data-label="' + item.label + '">' +
|
||||||
'<span class="item-text">' + escape(label) + '</span>' +
|
'<span class="item-text">' + escape(label) + '</span>' +
|
||||||
@@ -340,11 +355,11 @@ $(document).ready(function() {
|
|||||||
option: function (item, escape) {
|
option: function (item, escape) {
|
||||||
var label = item.label || item.value;
|
var label = item.label || item.value;
|
||||||
var caption = item.label ? item.value : null;
|
var caption = item.label ? item.value : null;
|
||||||
return '<div data-ssl="' + item.httpsRequired +
|
return '<div data-identifier="' + item.clientIdentifier +
|
||||||
'" data-local="' + item.local +
|
|
||||||
'" data-identifier="' + item.clientIdentifier +
|
|
||||||
'" data-ip="' + item.ip +
|
'" data-ip="' + item.ip +
|
||||||
'" data-port="' + item.port +
|
'" data-port="' + item.port +
|
||||||
|
'" data-local="' + item.local +
|
||||||
|
'" data-ssl="' + item.httpsRequired +
|
||||||
'" data-is_cloud="' + item.is_cloud +
|
'" data-is_cloud="' + item.is_cloud +
|
||||||
'" data-label="' + item.label + '">' +
|
'" data-label="' + item.label + '">' +
|
||||||
escape(label) +
|
escape(label) +
|
||||||
@@ -355,18 +370,27 @@ $(document).ready(function() {
|
|||||||
create: function(input) {
|
create: function(input) {
|
||||||
return {label: '', value: input};
|
return {label: '', value: input};
|
||||||
},
|
},
|
||||||
|
onInitialize: function () {
|
||||||
|
var s = this;
|
||||||
|
this.revertSettings.$children.each(function () {
|
||||||
|
$.extend(s.options[this.value], $(this).data());
|
||||||
|
});
|
||||||
|
},
|
||||||
onChange: function (item) {
|
onChange: function (item) {
|
||||||
var pms_ip_selected = this.getItem(item)[0];
|
var pms_ip_selected = this.getItem(item)[0];
|
||||||
var identifier = $(pms_ip_selected).data('identifier');
|
var identifier = $(pms_ip_selected).data('identifier');
|
||||||
|
var ip = $(pms_ip_selected).data('ip');
|
||||||
var port = $(pms_ip_selected).data('port');
|
var port = $(pms_ip_selected).data('port');
|
||||||
var local = $(pms_ip_selected).data('local');
|
var local = $(pms_ip_selected).data('local');
|
||||||
var ssl = $(pms_ip_selected).data('ssl');
|
var ssl = $(pms_ip_selected).data('ssl');
|
||||||
var is_cloud = $(pms_ip_selected).data('is_cloud');
|
var is_cloud = $(pms_ip_selected).data('is_cloud');
|
||||||
|
var value = $(pms_ip_selected).data('value');
|
||||||
|
|
||||||
$("#pms_valid").val(identifier !== 'undefined' ? 'valid' : '');
|
$("#pms_valid").val(identifier !== 'undefined' ? 'valid' : '');
|
||||||
$("#pms-verify-status").html(identifier !== 'undefined' ? '<i class="fa fa-check"></i> Server found!' : '').fadeIn('fast');
|
$("#pms-verify-status").html(identifier !== 'undefined' ? '<i class="fa fa-check"></i> Server found!' : '').fadeIn('fast');
|
||||||
|
|
||||||
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
$("#pms_identifier").val(identifier !== 'undefined' ? identifier : '');
|
||||||
|
$('#pms_ip').val(ip !== 'undefined' ? ip : value);
|
||||||
$('#pms_port').val(port !== 'undefined' ? port : 32400);
|
$('#pms_port').val(port !== 'undefined' ? port : 32400);
|
||||||
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
$('#pms_is_remote_checkbox').prop('checked', (local !== 'undefined' && local === 0));
|
||||||
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
$('#pms_is_remote').val(local !== 'undefined' && local === 0 ? 1 : 0);
|
||||||
@@ -399,9 +423,10 @@ $(document).ready(function() {
|
|||||||
},
|
},
|
||||||
success: function (result) {
|
success: function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
var existing_value = $('#pms_ip').val();
|
var existing_ip = $('#pms_ip').val();
|
||||||
|
var existing_port = $('#pms_port').val();
|
||||||
result.forEach(function (item) {
|
result.forEach(function (item) {
|
||||||
if (item.value === existing_value) {
|
if (item.ip === existing_ip && item.port === existing_port) {
|
||||||
select_pms.updateOption(item.value, item);
|
select_pms.updateOption(item.value, item);
|
||||||
} else {
|
} else {
|
||||||
select_pms.addOption(item);
|
select_pms.addOption(item);
|
||||||
|
@@ -1,127 +0,0 @@
|
|||||||
# Copyright (c) 2009 Raymond Hettinger
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person
|
|
||||||
# obtaining a copy of this software and associated documentation files
|
|
||||||
# (the "Software"), to deal in the Software without restriction,
|
|
||||||
# including without limitation the rights to use, copy, modify, merge,
|
|
||||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
|
||||||
# and to permit persons to whom the Software is furnished to do so,
|
|
||||||
# subject to the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be
|
|
||||||
# included in all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
# OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
from UserDict import DictMixin
|
|
||||||
|
|
||||||
class OrderedDict(dict, DictMixin):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwds):
|
|
||||||
if len(args) > 1:
|
|
||||||
raise TypeError('expected at most 1 arguments, got %d' % len(args))
|
|
||||||
try:
|
|
||||||
self.__end
|
|
||||||
except AttributeError:
|
|
||||||
self.clear()
|
|
||||||
self.update(*args, **kwds)
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
self.__end = end = []
|
|
||||||
end += [None, end, end] # sentinel node for doubly linked list
|
|
||||||
self.__map = {} # key --> [key, prev, next]
|
|
||||||
dict.clear(self)
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
if key not in self:
|
|
||||||
end = self.__end
|
|
||||||
curr = end[1]
|
|
||||||
curr[2] = end[1] = self.__map[key] = [key, curr, end]
|
|
||||||
dict.__setitem__(self, key, value)
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
dict.__delitem__(self, key)
|
|
||||||
key, prev, next = self.__map.pop(key)
|
|
||||||
prev[2] = next
|
|
||||||
next[1] = prev
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
end = self.__end
|
|
||||||
curr = end[2]
|
|
||||||
while curr is not end:
|
|
||||||
yield curr[0]
|
|
||||||
curr = curr[2]
|
|
||||||
|
|
||||||
def __reversed__(self):
|
|
||||||
end = self.__end
|
|
||||||
curr = end[1]
|
|
||||||
while curr is not end:
|
|
||||||
yield curr[0]
|
|
||||||
curr = curr[1]
|
|
||||||
|
|
||||||
def popitem(self, last=True):
|
|
||||||
if not self:
|
|
||||||
raise KeyError('dictionary is empty')
|
|
||||||
if last:
|
|
||||||
key = reversed(self).next()
|
|
||||||
else:
|
|
||||||
key = iter(self).next()
|
|
||||||
value = self.pop(key)
|
|
||||||
return key, value
|
|
||||||
|
|
||||||
def __reduce__(self):
|
|
||||||
items = [[k, self[k]] for k in self]
|
|
||||||
tmp = self.__map, self.__end
|
|
||||||
del self.__map, self.__end
|
|
||||||
inst_dict = vars(self).copy()
|
|
||||||
self.__map, self.__end = tmp
|
|
||||||
if inst_dict:
|
|
||||||
return (self.__class__, (items,), inst_dict)
|
|
||||||
return self.__class__, (items,)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return list(self)
|
|
||||||
|
|
||||||
setdefault = DictMixin.setdefault
|
|
||||||
update = DictMixin.update
|
|
||||||
pop = DictMixin.pop
|
|
||||||
values = DictMixin.values
|
|
||||||
items = DictMixin.items
|
|
||||||
iterkeys = DictMixin.iterkeys
|
|
||||||
itervalues = DictMixin.itervalues
|
|
||||||
iteritems = DictMixin.iteritems
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
if not self:
|
|
||||||
return '%s()' % (self.__class__.__name__,)
|
|
||||||
return '%s(%r)' % (self.__class__.__name__, self.items())
|
|
||||||
|
|
||||||
def copy(self):
|
|
||||||
return self.__class__(self)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def fromkeys(cls, iterable, value=None):
|
|
||||||
d = cls()
|
|
||||||
for key in iterable:
|
|
||||||
d[key] = value
|
|
||||||
return d
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if isinstance(other, OrderedDict):
|
|
||||||
if len(self) != len(other):
|
|
||||||
return False
|
|
||||||
for p, q in zip(self.items(), other.items()):
|
|
||||||
if p != q:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
return dict.__eq__(self, other)
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
return not self == other
|
|
2895
lib/pkg_resources.py
2895
lib/pkg_resources.py
File diff suppressed because it is too large
Load Diff
@@ -422,7 +422,7 @@ def initialize_scheduler():
|
|||||||
schedule_job(activity_pinger.connect_server, 'Check for server response',
|
schedule_job(activity_pinger.connect_server, 'Check for server response',
|
||||||
hours=0, minutes=0, seconds=0)
|
hours=0, minutes=0, seconds=0)
|
||||||
schedule_job(web_socket.send_ping, 'Websocket ping',
|
schedule_job(web_socket.send_ping, 'Websocket ping',
|
||||||
hours=0, minutes=0, seconds=10)
|
hours=0, minutes=0, seconds=10 * bool(CONFIG.WEBSOCKET_MONITOR_PING_PONG))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Cancel all jobs
|
# Cancel all jobs
|
||||||
|
@@ -607,6 +607,7 @@ _CONFIG_DEFINITIONS = {
|
|||||||
'UPDATE_NOTIFIERS_DB': (int, 'General', 1),
|
'UPDATE_NOTIFIERS_DB': (int, 'General', 1),
|
||||||
'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1),
|
'VERIFY_SSL_CERT': (bool_int, 'Advanced', 1),
|
||||||
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
|
'VIDEO_LOGGING_ENABLE': (int, 'Monitoring', 1),
|
||||||
|
'WEBSOCKET_MONITOR_PING_PONG': (int, 'Advanced', 0),
|
||||||
'WEBSOCKET_CONNECTION_ATTEMPTS': (int, 'Advanced', 5),
|
'WEBSOCKET_CONNECTION_ATTEMPTS': (int, 'Advanced', 5),
|
||||||
'WEBSOCKET_CONNECTION_TIMEOUT': (int, 'Advanced', 5),
|
'WEBSOCKET_CONNECTION_TIMEOUT': (int, 'Advanced', 5),
|
||||||
'WEEK_START_MONDAY': (int, 'General', 0),
|
'WEEK_START_MONDAY': (int, 'General', 0),
|
||||||
@@ -802,6 +803,7 @@ class Config(object):
|
|||||||
if self.VIDEO_LOGGING_ENABLE == 0:
|
if self.VIDEO_LOGGING_ENABLE == 0:
|
||||||
self.MOVIE_LOGGING_ENABLE = 0
|
self.MOVIE_LOGGING_ENABLE = 0
|
||||||
self.TV_LOGGING_ENABLE = 0
|
self.TV_LOGGING_ENABLE = 0
|
||||||
|
|
||||||
self.CONFIG_VERSION = 1
|
self.CONFIG_VERSION = 1
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 1:
|
if self.CONFIG_VERSION == 1:
|
||||||
@@ -817,6 +819,7 @@ class Config(object):
|
|||||||
if 'library_statistics' in home_library_cards:
|
if 'library_statistics' in home_library_cards:
|
||||||
home_library_cards.remove('library_statistics')
|
home_library_cards.remove('library_statistics')
|
||||||
self.HOME_LIBRARY_CARDS = home_library_cards
|
self.HOME_LIBRARY_CARDS = home_library_cards
|
||||||
|
|
||||||
self.CONFIG_VERSION = 2
|
self.CONFIG_VERSION = 2
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 2:
|
if self.CONFIG_VERSION == 2:
|
||||||
@@ -836,10 +839,13 @@ class Config(object):
|
|||||||
self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = rep(self.NOTIFY_ON_WATCHED_SUBJECT_TEXT)
|
self.NOTIFY_ON_WATCHED_SUBJECT_TEXT = rep(self.NOTIFY_ON_WATCHED_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_WATCHED_BODY_TEXT = rep(self.NOTIFY_ON_WATCHED_BODY_TEXT)
|
self.NOTIFY_ON_WATCHED_BODY_TEXT = rep(self.NOTIFY_ON_WATCHED_BODY_TEXT)
|
||||||
self.NOTIFY_SCRIPTS_ARGS_TEXT = rep(self.NOTIFY_SCRIPTS_ARGS_TEXT)
|
self.NOTIFY_SCRIPTS_ARGS_TEXT = rep(self.NOTIFY_SCRIPTS_ARGS_TEXT)
|
||||||
|
|
||||||
self.CONFIG_VERSION = 3
|
self.CONFIG_VERSION = 3
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 3:
|
if self.CONFIG_VERSION == 3:
|
||||||
if self.HTTP_ROOT == '/': self.HTTP_ROOT = ''
|
if self.HTTP_ROOT == '/':
|
||||||
|
self.HTTP_ROOT = ''
|
||||||
|
|
||||||
self.CONFIG_VERSION = 4
|
self.CONFIG_VERSION = 4
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 4:
|
if self.CONFIG_VERSION == 4:
|
||||||
@@ -851,20 +857,26 @@ class Config(object):
|
|||||||
home_sections = self.HOME_SECTIONS
|
home_sections = self.HOME_SECTIONS
|
||||||
home_sections.remove('library_stats')
|
home_sections.remove('library_stats')
|
||||||
self.HOME_SECTIONS = home_sections
|
self.HOME_SECTIONS = home_sections
|
||||||
|
|
||||||
self.CONFIG_VERSION = 5
|
self.CONFIG_VERSION = 5
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 5:
|
if self.CONFIG_VERSION == 5:
|
||||||
self.MONITOR_PMS_UPDATES = 0
|
self.MONITOR_PMS_UPDATES = 0
|
||||||
|
|
||||||
self.CONFIG_VERSION = 6
|
self.CONFIG_VERSION = 6
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 6:
|
if self.CONFIG_VERSION == 6:
|
||||||
if self.GIT_USER.lower() == 'drzoidberg33':
|
if self.GIT_USER.lower() == 'drzoidberg33':
|
||||||
self.GIT_USER = 'JonnyWong16'
|
self.GIT_USER = 'JonnyWong16'
|
||||||
|
|
||||||
self.CONFIG_VERSION = 7
|
self.CONFIG_VERSION = 7
|
||||||
|
|
||||||
if self.CONFIG_VERSION == 7:
|
if self.CONFIG_VERSION == 7:
|
||||||
def rep(s):
|
def rep(s):
|
||||||
return s.replace('<tv>','<episode>').replace('</tv>','</episode>').replace('<music>','<track>').replace('</music>','</track>')
|
return s.replace('<tv>', '<episode>') \
|
||||||
|
.replace('</tv>', '</episode>') \
|
||||||
|
.replace('<music>', '<track>') \
|
||||||
|
.replace('</music>', '</track>')
|
||||||
|
|
||||||
self.NOTIFY_ON_START_SUBJECT_TEXT = rep(self.NOTIFY_ON_START_SUBJECT_TEXT)
|
self.NOTIFY_ON_START_SUBJECT_TEXT = rep(self.NOTIFY_ON_START_SUBJECT_TEXT)
|
||||||
self.NOTIFY_ON_START_BODY_TEXT = rep(self.NOTIFY_ON_START_BODY_TEXT)
|
self.NOTIFY_ON_START_BODY_TEXT = rep(self.NOTIFY_ON_START_BODY_TEXT)
|
||||||
@@ -904,3 +916,7 @@ class Config(object):
|
|||||||
self.GIT_REPO = 'Tautulli'
|
self.GIT_REPO = 'Tautulli'
|
||||||
|
|
||||||
self.CONFIG_VERSION = 11
|
self.CONFIG_VERSION = 11
|
||||||
|
|
||||||
|
if self.CONFIG_VERSION == 11:
|
||||||
|
self.ANON_REDIRECT = self.ANON_REDIRECT.replace('http://www.nullrefer.com/?',
|
||||||
|
'https://www.nullrefer.com/?')
|
||||||
|
@@ -33,7 +33,9 @@ class HTTPHandler(object):
|
|||||||
Retrieve data from Plex Server
|
Retrieve data from Plex Server
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, urls, headers=None, token=None, timeout=10, ssl_verify=True):
|
def __init__(self, urls, headers=None, token=None, timeout=10, ssl_verify=True, silent=False):
|
||||||
|
self._silent = silent
|
||||||
|
|
||||||
if isinstance(urls, basestring):
|
if isinstance(urls, basestring):
|
||||||
self.urls = urls.split() or urls.split(',')
|
self.urls = urls.split() or urls.split(',')
|
||||||
else:
|
else:
|
||||||
@@ -131,6 +133,7 @@ class HTTPHandler(object):
|
|||||||
for work in pool.imap_unordered(part, urls, chunk):
|
for work in pool.imap_unordered(part, urls, chunk):
|
||||||
yield work
|
yield work
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if not self._silent:
|
||||||
logger.error(u"Failed to yield request: %s" % e)
|
logger.error(u"Failed to yield request: %s" % e)
|
||||||
finally:
|
finally:
|
||||||
pool.close()
|
pool.close()
|
||||||
@@ -141,12 +144,15 @@ class HTTPHandler(object):
|
|||||||
try:
|
try:
|
||||||
r = session.request(self.request_type, url, headers=self.headers, timeout=self.timeout)
|
r = session.request(self.request_type, url, headers=self.headers, timeout=self.timeout)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
|
if not self._silent:
|
||||||
logger.warn(u"Failed to access uri endpoint %s with error %s" % (self.uri, e))
|
logger.warn(u"Failed to access uri endpoint %s with error %s" % (self.uri, e))
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if not self._silent:
|
||||||
logger.warn(u"Failed to access uri endpoint %s. Is your server maybe accepting SSL connections only? %s" % (self.uri, e))
|
logger.warn(u"Failed to access uri endpoint %s. Is your server maybe accepting SSL connections only? %s" % (self.uri, e))
|
||||||
return None
|
return None
|
||||||
except:
|
except:
|
||||||
|
if not self._silent:
|
||||||
logger.warn(u"Failed to access uri endpoint %s with Uncaught exception." % self.uri)
|
logger.warn(u"Failed to access uri endpoint %s with Uncaught exception." % self.uri)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -157,6 +163,7 @@ class HTTPHandler(object):
|
|||||||
if response_status in (200, 201):
|
if response_status in (200, 201):
|
||||||
return self._http_format_output(response_content, response_headers)
|
return self._http_format_output(response_content, response_headers)
|
||||||
else:
|
else:
|
||||||
|
if not self._silent:
|
||||||
logger.warn(u"Failed to access uri endpoint %s. Status code %r" % (self.uri, response_status))
|
logger.warn(u"Failed to access uri endpoint %s. Status code %r" % (self.uri, response_status))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -183,5 +190,6 @@ class HTTPHandler(object):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if not self._silent:
|
||||||
logger.warn(u"Failed format response from uri %s to %s error %s" % (self.uri, self.output_format, e))
|
logger.warn(u"Failed format response from uri %s to %s error %s" % (self.uri, self.output_format, e))
|
||||||
return None
|
return None
|
||||||
|
@@ -633,7 +633,8 @@ class Libraries(object):
|
|||||||
if 'media_info' in child_metadata and len(child_metadata['media_info']) > 0:
|
if 'media_info' in child_metadata and len(child_metadata['media_info']) > 0:
|
||||||
media_info = child_metadata['media_info'][0]
|
media_info = child_metadata['media_info'][0]
|
||||||
if 'parts' in media_info and len (media_info['parts']) > 0:
|
if 'parts' in media_info and len (media_info['parts']) > 0:
|
||||||
media_part_info = media_info['parts'][0]
|
media_part_info = next((p for p in media_info['parts'] if p['selected']),
|
||||||
|
media_info['parts'][0])
|
||||||
|
|
||||||
file_size += helpers.cast_to_int(media_part_info.get('file_size', 0))
|
file_size += helpers.cast_to_int(media_part_info.get('file_size', 0))
|
||||||
|
|
||||||
|
@@ -486,20 +486,24 @@ def build_media_notify_params(notify_action=None, session=None, timeline=None, m
|
|||||||
if 'media_info' in notify_params and len(notify_params['media_info']) > 0:
|
if 'media_info' in notify_params and len(notify_params['media_info']) > 0:
|
||||||
media_info = notify_params['media_info'][0]
|
media_info = notify_params['media_info'][0]
|
||||||
if 'parts' in media_info and len(media_info['parts']) > 0:
|
if 'parts' in media_info and len(media_info['parts']) > 0:
|
||||||
media_part_info = media_info.pop('parts')[0]
|
parts = media_info.pop('parts')
|
||||||
|
media_part_info = next((p for p in parts if p['selected']), parts[0])
|
||||||
|
|
||||||
stream_video = stream_audio = stream_subtitle = False
|
|
||||||
if 'streams' in media_part_info:
|
if 'streams' in media_part_info:
|
||||||
for stream in media_part_info.pop('streams'):
|
streams = media_part_info.pop('streams')
|
||||||
if not stream_video and stream['type'] == '1':
|
video_streams = [s for s in streams if s['type'] == '1']
|
||||||
media_part_info.update(stream)
|
audio_streams = [s for s in streams if s['type'] == '2']
|
||||||
stream_video = True
|
subtitle_streams = [s for s in streams if s['type'] == '3']
|
||||||
if not stream_audio and stream['type'] == '2':
|
|
||||||
media_part_info.update(stream)
|
if video_streams:
|
||||||
stream_audio = True
|
video_stream = next((s for s in video_streams if s['selected']), video_streams[0])
|
||||||
if not stream_subtitle and stream['type'] == '3':
|
media_part_info.update(video_stream)
|
||||||
media_part_info.update(stream)
|
if audio_streams:
|
||||||
stream_subtitle = True
|
audio_stream = next((s for s in audio_streams if s['selected']), audio_streams[0])
|
||||||
|
media_part_info.update(audio_stream)
|
||||||
|
if subtitle_streams:
|
||||||
|
subtitle_stream = next((s for s in subtitle_streams if s['selected']), subtitle_streams[0])
|
||||||
|
media_part_info.update(subtitle_stream)
|
||||||
|
|
||||||
notify_params.update(media_info)
|
notify_params.update(media_info)
|
||||||
notify_params.update(media_part_info)
|
notify_params.update(media_part_info)
|
||||||
|
@@ -3000,7 +3000,7 @@ class SCRIPTS(Notifier):
|
|||||||
'TAUTULLI_URL': helpers.get_plexpy_url(hostname='localhost'),
|
'TAUTULLI_URL': helpers.get_plexpy_url(hostname='localhost'),
|
||||||
'TAUTULLI_APIKEY': plexpy.CONFIG.API_KEY,
|
'TAUTULLI_APIKEY': plexpy.CONFIG.API_KEY,
|
||||||
'TAUTULLI_ENCODING': plexpy.SYS_ENCODING,
|
'TAUTULLI_ENCODING': plexpy.SYS_ENCODING,
|
||||||
'PYTHONPATH': (';' if os.name == 'nt' else ':').join(sys.path)
|
'PYTHONPATH': os.pathsep.join([p for p in sys.path if p])
|
||||||
})
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@@ -685,6 +685,27 @@ class PlexTV(object):
|
|||||||
|
|
||||||
def discover(self, include_cloud=True, all_servers=False):
|
def discover(self, include_cloud=True, all_servers=False):
|
||||||
""" Query plex for all servers online. Returns the ones you own in a selectize format """
|
""" Query plex for all servers online. Returns the ones you own in a selectize format """
|
||||||
|
|
||||||
|
# Try to discover localhost server
|
||||||
|
local_machine_identifier = None
|
||||||
|
request_handler = http_handler.HTTPHandler(urls='http://127.0.0.1:32400', timeout=1,
|
||||||
|
ssl_verify=False, silent=True)
|
||||||
|
request = request_handler.make_request(uri='/identity', request_type='GET', output_format='xml')
|
||||||
|
if request:
|
||||||
|
xml_head = request.getElementsByTagName('MediaContainer')[0]
|
||||||
|
local_machine_identifier = xml_head.getAttribute('machineIdentifier')
|
||||||
|
|
||||||
|
local_server = {'httpsRequired': '0',
|
||||||
|
'clientIdentifier': local_machine_identifier,
|
||||||
|
'label': 'Local',
|
||||||
|
'ip': '127.0.0.1',
|
||||||
|
'port': '32400',
|
||||||
|
'uri': 'http://127.0.0.1:32400',
|
||||||
|
'local': '1',
|
||||||
|
'value': '127.0.0.1:32400',
|
||||||
|
'is_cloud': False
|
||||||
|
}
|
||||||
|
|
||||||
servers = self.get_plextv_resources(include_https=True, output_format='xml')
|
servers = self.get_plextv_resources(include_https=True, output_format='xml')
|
||||||
clean_servers = []
|
clean_servers = []
|
||||||
|
|
||||||
@@ -725,6 +746,12 @@ class PlexTV(object):
|
|||||||
helpers.get_xml_attr(c, 'local') == '0':
|
helpers.get_xml_attr(c, 'local') == '0':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if helpers.get_xml_attr(d, 'clientIdentifier') == local_machine_identifier:
|
||||||
|
local_server['httpsRequired'] = helpers.get_xml_attr(d, 'httpsRequired')
|
||||||
|
local_server['label'] = helpers.get_xml_attr(d, 'name')
|
||||||
|
clean_servers.append(local_server)
|
||||||
|
local_machine_identifier = None
|
||||||
|
|
||||||
server = {'httpsRequired': '1' if is_cloud else helpers.get_xml_attr(d, 'httpsRequired'),
|
server = {'httpsRequired': '1' if is_cloud else helpers.get_xml_attr(d, 'httpsRequired'),
|
||||||
'clientIdentifier': helpers.get_xml_attr(d, 'clientIdentifier'),
|
'clientIdentifier': helpers.get_xml_attr(d, 'clientIdentifier'),
|
||||||
'label': helpers.get_xml_attr(d, 'name'),
|
'label': helpers.get_xml_attr(d, 'name'),
|
||||||
@@ -732,11 +759,16 @@ class PlexTV(object):
|
|||||||
'port': helpers.get_xml_attr(c, 'port'),
|
'port': helpers.get_xml_attr(c, 'port'),
|
||||||
'uri': helpers.get_xml_attr(c, 'uri'),
|
'uri': helpers.get_xml_attr(c, 'uri'),
|
||||||
'local': helpers.get_xml_attr(c, 'local'),
|
'local': helpers.get_xml_attr(c, 'local'),
|
||||||
'value': helpers.get_xml_attr(c, 'address'),
|
'value': helpers.get_xml_attr(c, 'address') + ':' + helpers.get_xml_attr(c, 'port'),
|
||||||
'is_cloud': is_cloud
|
'is_cloud': is_cloud
|
||||||
}
|
}
|
||||||
clean_servers.append(server)
|
clean_servers.append(server)
|
||||||
|
|
||||||
|
if local_machine_identifier:
|
||||||
|
clean_servers.append(local_server)
|
||||||
|
|
||||||
|
clean_servers.sort(key=lambda s: (s['label'], -int(s['local']), s['ip']))
|
||||||
|
|
||||||
return clean_servers
|
return clean_servers
|
||||||
|
|
||||||
def get_plex_downloads(self):
|
def get_plex_downloads(self):
|
||||||
|
@@ -1213,7 +1213,8 @@ class PmsConnect(object):
|
|||||||
'video_width': helpers.get_xml_attr(stream, 'width'),
|
'video_width': helpers.get_xml_attr(stream, 'width'),
|
||||||
'video_language': helpers.get_xml_attr(stream, 'language'),
|
'video_language': helpers.get_xml_attr(stream, 'language'),
|
||||||
'video_language_code': helpers.get_xml_attr(stream, 'languageCode'),
|
'video_language_code': helpers.get_xml_attr(stream, 'languageCode'),
|
||||||
'video_profile': helpers.get_xml_attr(stream, 'profile')
|
'video_profile': helpers.get_xml_attr(stream, 'profile'),
|
||||||
|
'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
|
||||||
})
|
})
|
||||||
|
|
||||||
elif helpers.get_xml_attr(stream, 'streamType') == '2':
|
elif helpers.get_xml_attr(stream, 'streamType') == '2':
|
||||||
@@ -1227,7 +1228,8 @@ class PmsConnect(object):
|
|||||||
'audio_sample_rate': helpers.get_xml_attr(stream, 'samplingRate'),
|
'audio_sample_rate': helpers.get_xml_attr(stream, 'samplingRate'),
|
||||||
'audio_language': helpers.get_xml_attr(stream, 'language'),
|
'audio_language': helpers.get_xml_attr(stream, 'language'),
|
||||||
'audio_language_code': helpers.get_xml_attr(stream, 'languageCode'),
|
'audio_language_code': helpers.get_xml_attr(stream, 'languageCode'),
|
||||||
'audio_profile': helpers.get_xml_attr(stream, 'profile')
|
'audio_profile': helpers.get_xml_attr(stream, 'profile'),
|
||||||
|
'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
|
||||||
})
|
})
|
||||||
|
|
||||||
elif helpers.get_xml_attr(stream, 'streamType') == '3':
|
elif helpers.get_xml_attr(stream, 'streamType') == '3':
|
||||||
@@ -1239,14 +1241,16 @@ class PmsConnect(object):
|
|||||||
'subtitle_forced': int(helpers.get_xml_attr(stream, 'forced') == '1'),
|
'subtitle_forced': int(helpers.get_xml_attr(stream, 'forced') == '1'),
|
||||||
'subtitle_location': 'external' if helpers.get_xml_attr(stream, 'key') else 'embedded',
|
'subtitle_location': 'external' if helpers.get_xml_attr(stream, 'key') else 'embedded',
|
||||||
'subtitle_language': helpers.get_xml_attr(stream, 'language'),
|
'subtitle_language': helpers.get_xml_attr(stream, 'language'),
|
||||||
'subtitle_language_code': helpers.get_xml_attr(stream, 'languageCode')
|
'subtitle_language_code': helpers.get_xml_attr(stream, 'languageCode'),
|
||||||
|
'selected': int(helpers.get_xml_attr(stream, 'selected') == '1')
|
||||||
})
|
})
|
||||||
|
|
||||||
parts.append({'id': helpers.get_xml_attr(part, 'id'),
|
parts.append({'id': helpers.get_xml_attr(part, 'id'),
|
||||||
'file': helpers.get_xml_attr(part, 'file'),
|
'file': helpers.get_xml_attr(part, 'file'),
|
||||||
'file_size': helpers.get_xml_attr(part, 'size'),
|
'file_size': helpers.get_xml_attr(part, 'size'),
|
||||||
'indexes': int(helpers.get_xml_attr(part, 'indexes') == 'sd'),
|
'indexes': int(helpers.get_xml_attr(part, 'indexes') == 'sd'),
|
||||||
'streams': streams
|
'streams': streams,
|
||||||
|
'selected': int(helpers.get_xml_attr(part, 'selected') == '1')
|
||||||
})
|
})
|
||||||
|
|
||||||
audio_channels = helpers.get_xml_attr(media, 'audioChannels')
|
audio_channels = helpers.get_xml_attr(media, 'audioChannels')
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
PLEXPY_BRANCH = "beta"
|
PLEXPY_BRANCH = "beta"
|
||||||
PLEXPY_RELEASE_VERSION = "v2.1.16-beta"
|
PLEXPY_RELEASE_VERSION = "v2.1.17-beta"
|
||||||
|
@@ -60,6 +60,7 @@ def on_connect():
|
|||||||
plexpy.PLEX_SERVER_UP = True
|
plexpy.PLEX_SERVER_UP = True
|
||||||
|
|
||||||
plexpy.initialize_scheduler()
|
plexpy.initialize_scheduler()
|
||||||
|
if plexpy.CONFIG.WEBSOCKET_MONITOR_PING_PONG:
|
||||||
send_ping()
|
send_ping()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -110,6 +110,7 @@ class WebInterface(object):
|
|||||||
"pms_is_cloud": plexpy.CONFIG.PMS_IS_CLOUD,
|
"pms_is_cloud": plexpy.CONFIG.PMS_IS_CLOUD,
|
||||||
"pms_token": plexpy.CONFIG.PMS_TOKEN,
|
"pms_token": plexpy.CONFIG.PMS_TOKEN,
|
||||||
"pms_uuid": plexpy.CONFIG.PMS_UUID,
|
"pms_uuid": plexpy.CONFIG.PMS_UUID,
|
||||||
|
"pms_name": plexpy.CONFIG.PMS_NAME,
|
||||||
"logging_ignore_interval": plexpy.CONFIG.LOGGING_IGNORE_INTERVAL
|
"logging_ignore_interval": plexpy.CONFIG.LOGGING_IGNORE_INTERVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2802,6 +2803,7 @@ class WebInterface(object):
|
|||||||
"pms_url_manual": checked(plexpy.CONFIG.PMS_URL_MANUAL),
|
"pms_url_manual": checked(plexpy.CONFIG.PMS_URL_MANUAL),
|
||||||
"pms_uuid": plexpy.CONFIG.PMS_UUID,
|
"pms_uuid": plexpy.CONFIG.PMS_UUID,
|
||||||
"pms_web_url": plexpy.CONFIG.PMS_WEB_URL,
|
"pms_web_url": plexpy.CONFIG.PMS_WEB_URL,
|
||||||
|
"pms_name": plexpy.CONFIG.PMS_NAME,
|
||||||
"date_format": plexpy.CONFIG.DATE_FORMAT,
|
"date_format": plexpy.CONFIG.DATE_FORMAT,
|
||||||
"time_format": plexpy.CONFIG.TIME_FORMAT,
|
"time_format": plexpy.CONFIG.TIME_FORMAT,
|
||||||
"week_start_monday": checked(plexpy.CONFIG.WEEK_START_MONDAY),
|
"week_start_monday": checked(plexpy.CONFIG.WEEK_START_MONDAY),
|
||||||
@@ -4614,7 +4616,8 @@ class WebInterface(object):
|
|||||||
"video_language_code": "",
|
"video_language_code": "",
|
||||||
"video_profile": "high",
|
"video_profile": "high",
|
||||||
"video_ref_frames": "4",
|
"video_ref_frames": "4",
|
||||||
"video_width": "1920"
|
"video_width": "1920",
|
||||||
|
"selected": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"audio_bitrate": "384",
|
"audio_bitrate": "384",
|
||||||
@@ -4627,7 +4630,8 @@ class WebInterface(object):
|
|||||||
"audio_profile": "",
|
"audio_profile": "",
|
||||||
"audio_sample_rate": "48000",
|
"audio_sample_rate": "48000",
|
||||||
"id": "511664",
|
"id": "511664",
|
||||||
"type": "2"
|
"type": "2",
|
||||||
|
"selected": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "511953",
|
"id": "511953",
|
||||||
@@ -4638,7 +4642,8 @@ class WebInterface(object):
|
|||||||
"subtitle_language": "English",
|
"subtitle_language": "English",
|
||||||
"subtitle_language_code": "eng",
|
"subtitle_language_code": "eng",
|
||||||
"subtitle_location": "external",
|
"subtitle_location": "external",
|
||||||
"type": "3"
|
"type": "3",
|
||||||
|
"selected": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user