Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
00c0c96b1b | ||
![]() |
0aa2537d1e | ||
![]() |
14489e1db9 | ||
![]() |
bff4eaba56 | ||
![]() |
4a5d2f8502 | ||
![]() |
72af2fa281 | ||
![]() |
cf70b3e989 | ||
![]() |
7ebd74a54a | ||
![]() |
9a650b5cd6 | ||
![]() |
ffa1331802 | ||
![]() |
dacb4ea7d6 | ||
![]() |
ae5889dbac | ||
![]() |
7b169e9439 | ||
![]() |
541d2904d3 | ||
![]() |
2080bbcbca | ||
![]() |
f4c38008a1 | ||
![]() |
2d38b15f1b | ||
![]() |
13257b9f86 | ||
![]() |
22f106b357 | ||
![]() |
352b5aadba | ||
![]() |
f86c9ea947 | ||
![]() |
2f5f0ba1e1 | ||
![]() |
6a72923182 | ||
![]() |
d62f7b2a5f | ||
![]() |
8ca6255ff3 | ||
![]() |
d3b3afd593 | ||
![]() |
57cb5ff6cf | ||
![]() |
39f3da6cde | ||
![]() |
5a236c9357 | ||
![]() |
4b0eab57a8 | ||
![]() |
74a232630a | ||
![]() |
71d023ab77 | ||
![]() |
786a374233 | ||
![]() |
41899872cd | ||
![]() |
076659db52 | ||
![]() |
8f665622d6 | ||
![]() |
5cc6e0b172 | ||
![]() |
bff22900cb | ||
![]() |
5e79c9fd62 |
30
CHANGELOG.md
@@ -1,5 +1,35 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.3.16 (2016-05-01)
|
||||||
|
|
||||||
|
* Fix: Viewing photos crashing PlexPy.
|
||||||
|
* Fix: Persist Users > Edit mode on datatable page change.
|
||||||
|
* Fix: PMS update notifications broken.
|
||||||
|
* Change: Cache notifications poster with thread ID to avoid overwritting images.
|
||||||
|
|
||||||
|
|
||||||
|
## v1.3.15 (2016-04-18)
|
||||||
|
|
||||||
|
* Fix: Slack notifications failing when using and icon URL.
|
||||||
|
* Fix: 127.0.0.1 showing as an external IP address on the history tables.
|
||||||
|
* Fix: Regression file sizes not shown in the media info table footer.
|
||||||
|
* Fix: Retrieving proper PMS URL when multiple connections are published to plex.tv.
|
||||||
|
* Fix: Some typos in the logger.
|
||||||
|
* Fix: Some other typos in the WebUI. (Thanks @xtjoeytx)
|
||||||
|
* Change: Optimized mobile web app icons and spash screens. (Thanks @alotufo)
|
||||||
|
|
||||||
|
|
||||||
|
## v1.3.14 (2016-03-29)
|
||||||
|
|
||||||
|
* Fix: Regression for missing notify_action for script notifications.
|
||||||
|
* Fix: Typo for home stats cards in the settings.
|
||||||
|
|
||||||
|
|
||||||
|
## v1.3.13 (2016-03-27)
|
||||||
|
|
||||||
|
* Fix: Only mask strings longer than 5 characters in logs.
|
||||||
|
|
||||||
|
|
||||||
## v1.3.12 (2016-03-27)
|
## v1.3.12 (2016-03-27)
|
||||||
|
|
||||||
* Fix: "Check GitHub for updates" not rescheduling when toggling setting.
|
* Fix: "Check GitHub for updates" not rescheduling when toggling setting.
|
||||||
|
42
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
### Reporting Issues:
|
||||||
|
|
||||||
|
To ensure that a develpoer has enough information to work with please include all of the following information.
|
||||||
|
|
||||||
|
**Use proper markdown syntax to structure your post (i.e. code/log in code blocks).**
|
||||||
|
|
||||||
|
**Make sure you provide the following information below:**
|
||||||
|
- [ ] Version
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Branch
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Commit hash
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Operating system
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Python version
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] What you did?
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] What happened?
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] What you expected?
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] How can we reproduce your issue?
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] What are your (relevant) settings?
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Include a link to your **FULL** (not just a few lines!) log file that has the error. Please use [Gist](http://gist.github.com) or [Pastebin](http://pastebin.com/).
|
||||||
|
|
||||||
|
Close your issue when it's solved! If you found the solution yourself please comment so that others benefit from it.
|
||||||
|
|
||||||
|
#### Link to log:
|
@@ -113,6 +113,8 @@ img {
|
|||||||
}
|
}
|
||||||
.btn {
|
.btn {
|
||||||
outline:0px !important;
|
outline:0px !important;
|
||||||
|
}
|
||||||
|
.btn:not(select) {
|
||||||
-webkit-appearance:none;
|
-webkit-appearance:none;
|
||||||
}
|
}
|
||||||
.btn-dark {
|
.btn-dark {
|
||||||
|
@@ -12,6 +12,14 @@
|
|||||||
<span><i class="fa fa-bar-chart"></i> Graphs</span>
|
<span><i class="fa fa-bar-chart"></i> Graphs</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-bar hidden-xs">
|
<div class="button-bar hidden-xs">
|
||||||
|
<div class="btn-group" id="user-selection">
|
||||||
|
<label>
|
||||||
|
<select name="graph-user" id="graph-user" class="btn" style="color: inherit;">
|
||||||
|
<option value="">All Users</option>
|
||||||
|
<option disabled>────────────</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="btn-group" data-toggle="buttons" id="yaxis-selection">
|
<div class="btn-group" data-toggle="buttons" id="yaxis-selection">
|
||||||
% if config['graph_type'] == 'duration':
|
% if config['graph_type'] == 'duration':
|
||||||
<label class="btn btn-dark">
|
<label class="btn btn-dark">
|
||||||
@@ -281,6 +289,10 @@
|
|||||||
complete: function(xhr, status) {
|
complete: function(xhr, status) {
|
||||||
$('#history-modal').modal('show');
|
$('#history-modal').modal('show');
|
||||||
$("#history-modal").html(xhr.responseText);
|
$("#history-modal").html(xhr.responseText);
|
||||||
|
var opt = $('#graph-user :selected');
|
||||||
|
if (opt.prev().length) {
|
||||||
|
$('#history_table_modal_filter input[type=search]').val(opt.text()).trigger("input");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -308,9 +320,28 @@
|
|||||||
var yaxis = "${config['graph_type']}";
|
var yaxis = "${config['graph_type']}";
|
||||||
var current_range = ${config['graph_days']};
|
var current_range = ${config['graph_days']};
|
||||||
var current_tab = "${'#' + config['graph_tab']}";
|
var current_tab = "${'#' + config['graph_tab']}";
|
||||||
|
var selected_user_id = undefined;
|
||||||
|
|
||||||
$('.days').html(current_range);
|
$('.days').html(current_range);
|
||||||
|
|
||||||
|
// Load user ids and names (for the selector)
|
||||||
|
$.ajax({
|
||||||
|
url: 'get_user_names',
|
||||||
|
type: 'get',
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data) {
|
||||||
|
var select = $('#graph-user');
|
||||||
|
data.sort(function(a, b) {
|
||||||
|
return a.friendly_name.localeCompare(b.friendly_name);
|
||||||
|
});
|
||||||
|
data.forEach(function(item) {
|
||||||
|
select.append('<option value="' + item.user_id + '">' +
|
||||||
|
item.friendly_name + '</option>');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var music_visible = (${config['music_logging_enable']} == 1 ? true : false);
|
var music_visible = (${config['music_logging_enable']} == 1 ? true : false);
|
||||||
|
|
||||||
function loadGraphsTab1(time_range, yaxis) {
|
function loadGraphsTab1(time_range, yaxis) {
|
||||||
@@ -321,7 +352,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_date",
|
url: "get_plays_by_date",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var dateArray = [];
|
var dateArray = [];
|
||||||
@@ -348,7 +379,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_dayofweek",
|
url: "get_plays_by_dayofweek",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_dayofweek_options.xAxis.categories = data.categories;
|
hc_plays_by_dayofweek_options.xAxis.categories = data.categories;
|
||||||
@@ -361,7 +392,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_hourofday",
|
url: "get_plays_by_hourofday",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_hourofday_options.xAxis.categories = data.categories;
|
hc_plays_by_hourofday_options.xAxis.categories = data.categories;
|
||||||
@@ -374,7 +405,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_top_10_platforms",
|
url: "get_plays_by_top_10_platforms",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_platform_options.xAxis.categories = data.categories;
|
hc_plays_by_platform_options.xAxis.categories = data.categories;
|
||||||
@@ -387,7 +418,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_top_10_users",
|
url: "get_plays_by_top_10_users",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_user_options.xAxis.categories = data.categories;
|
hc_plays_by_user_options.xAxis.categories = data.categories;
|
||||||
@@ -406,7 +437,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_stream_type",
|
url: "get_plays_by_stream_type",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
var dateArray = [];
|
var dateArray = [];
|
||||||
@@ -432,7 +463,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_source_resolution",
|
url: "get_plays_by_source_resolution",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_source_resolution_options.xAxis.categories = data.categories;
|
hc_plays_by_source_resolution_options.xAxis.categories = data.categories;
|
||||||
@@ -444,7 +475,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_by_stream_resolution",
|
url: "get_plays_by_stream_resolution",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_stream_resolution_options.xAxis.categories = data.categories;
|
hc_plays_by_stream_resolution_options.xAxis.categories = data.categories;
|
||||||
@@ -456,7 +487,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_stream_type_by_top_10_platforms",
|
url: "get_stream_type_by_top_10_platforms",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_platform_by_stream_type_options.xAxis.categories = data.categories;
|
hc_plays_by_platform_by_stream_type_options.xAxis.categories = data.categories;
|
||||||
@@ -468,7 +499,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_stream_type_by_top_10_users",
|
url: "get_stream_type_by_top_10_users",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { time_range: time_range, y_axis: yaxis },
|
data: { time_range: time_range, y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_user_by_stream_type_options.xAxis.categories = data.categories;
|
hc_plays_by_user_by_stream_type_options.xAxis.categories = data.categories;
|
||||||
@@ -486,7 +517,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "get_plays_per_month",
|
url: "get_plays_per_month",
|
||||||
type: 'get',
|
type: 'get',
|
||||||
data: { y_axis: yaxis },
|
data: { y_axis: yaxis, user_id: selected_user_id },
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
hc_plays_by_month_options.yAxis.min = 0;
|
hc_plays_by_month_options.yAxis.min = 0;
|
||||||
@@ -556,6 +587,14 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// User changed
|
||||||
|
$('#graph-user').on('change', function() {
|
||||||
|
selected_user_id = $(this).val() || undefined;
|
||||||
|
if (current_tab == '#tabs-1') { loadGraphsTab1(current_range, yaxis); }
|
||||||
|
if (current_tab == '#tabs-2') { loadGraphsTab2(current_range, yaxis); }
|
||||||
|
if (current_tab == '#tabs-3') { loadGraphsTab3(yaxis); }
|
||||||
|
});
|
||||||
|
|
||||||
// Y-axis changed
|
// Y-axis changed
|
||||||
$('#yaxis-selection').on('change', function() {
|
$('#yaxis-selection').on('change', function() {
|
||||||
yaxis = $('input[name=yaxis-options]:checked', '#yaxis-selection').val();
|
yaxis = $('input[name=yaxis-options]:checked', '#yaxis-selection').val();
|
||||||
@@ -598,7 +637,7 @@
|
|||||||
|
|
||||||
$('.yaxis-text').html('Play count');
|
$('.yaxis-text').html('Play count');
|
||||||
} else {
|
} else {
|
||||||
yaxis_format = function() { return moment.duration(this.value, 'seconds').format("m [mins]"); };
|
yaxis_format = function() { return moment.duration(this.value, 'seconds').format("H [h] m [m]"); };
|
||||||
tooltip_format = function() {
|
tooltip_format = function() {
|
||||||
if (moment(this.x, 'X').isValid() && (this.x > 946684800)) {
|
if (moment(this.x, 'X').isValid() && (this.x > 946684800)) {
|
||||||
var s = '<b>'+ moment(this.x).format("ddd MMM D") +'</b>';
|
var s = '<b>'+ moment(this.x).format("ddd MMM D") +'</b>';
|
||||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 391 KiB After Width: | Height: | Size: 349 KiB |
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 148 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 4.4 MiB |
Before Width: | Height: | Size: 5.2 MiB After Width: | Height: | Size: 4.5 MiB |
Before Width: | Height: | Size: 6.2 MiB After Width: | Height: | Size: 4.7 MiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 6.2 MiB After Width: | Height: | Size: 4.6 MiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 977 KiB After Width: | Height: | Size: 788 KiB |
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 457 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 455 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 460 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 466 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 457 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 463 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 464 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 454 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 456 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 7.4 KiB |
@@ -39,7 +39,6 @@ function showMsg(msg,loader,timeout,ms,error) {
|
|||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
feedback.css("background-color", "rgba(255,0,0,0.5)");
|
feedback.css("background-color", "rgba(255,0,0,0.5)");
|
||||||
console.log('is error');
|
|
||||||
}
|
}
|
||||||
$(feedback).html(message);
|
$(feedback).html(message);
|
||||||
feedback.fadeIn();
|
feedback.fadeIn();
|
||||||
@@ -49,6 +48,7 @@ function showMsg(msg,loader,timeout,ms,error) {
|
|||||||
message.fadeOut(function(){
|
message.fadeOut(function(){
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
feedback.fadeOut();
|
feedback.fadeOut();
|
||||||
|
feedback.css("background-color", "");
|
||||||
});
|
});
|
||||||
},ms);
|
},ms);
|
||||||
}
|
}
|
||||||
@@ -242,7 +242,8 @@ function isPrivateIP(ip_address) {
|
|||||||
// get IPv4 mapped address (xxx.xxx.xxx.xxx) from IPv6 addresss (::ffff:xxx.xxx.xxx.xxx)
|
// get IPv4 mapped address (xxx.xxx.xxx.xxx) from IPv6 addresss (::ffff:xxx.xxx.xxx.xxx)
|
||||||
var parts = ip_address.split(":");
|
var parts = ip_address.split(":");
|
||||||
var parts = parts[parts.length - 1].split('.');
|
var parts = parts[parts.length - 1].split('.');
|
||||||
if (parts[0] === '10' ||
|
if ((parts[0] === '127' && parts[1] === '0' && parts[2] === '0' && parts[3] === '1') ||
|
||||||
|
(parts[0] === '10') ||
|
||||||
(parts[0] === '172' && (parseInt(parts[1], 10) >= 16 && parseInt(parts[1], 10) <= 31)) ||
|
(parts[0] === '172' && (parseInt(parts[1], 10) >= 16 && parseInt(parts[1], 10) <= 31)) ||
|
||||||
(parts[0] === '192' && parts[1] === '168')) {
|
(parts[0] === '192' && parts[1] === '168')) {
|
||||||
return true;
|
return true;
|
||||||
|
@@ -276,7 +276,7 @@ media_info_table_options = {
|
|||||||
get_file_sizes = false;
|
get_file_sizes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#media_info_table_info").append('<span class="hidden-md hidden-sm hidden-xs"> with a total file size of ' +
|
$("#media_info_table-SID-" + section_id + "_info").append('<span class="hidden-md hidden-sm hidden-xs"> with a total file size of ' +
|
||||||
Math.round(settings.json.filtered_file_size / Math.pow(1024, 3)).toString() + ' GiB' +
|
Math.round(settings.json.filtered_file_size / Math.pow(1024, 3)).toString() + ' GiB' +
|
||||||
' (filtered from ' + Math.round(settings.json.total_file_size / Math.pow(1024, 3)).toString() + ' GiB)</span>');
|
' (filtered from ' + Math.round(settings.json.total_file_size / Math.pow(1024, 3)).toString() + ' GiB)</span>');
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,23 @@
|
|||||||
var users_to_delete = [];
|
var users_to_delete = [];
|
||||||
var users_to_purge = [];
|
var users_to_purge = [];
|
||||||
|
|
||||||
|
function toggleEditNames() {
|
||||||
|
if ($('.edit-control').hasClass('hidden')) {
|
||||||
|
$('.edit-user-control > .edit-user-name').each(function () {
|
||||||
|
a = $(this).children('a');
|
||||||
|
input = $(this).children('input');
|
||||||
|
a.text(input.val());
|
||||||
|
a.removeClass('hidden');
|
||||||
|
input.addClass('hidden');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$('.edit-user-control > .edit-user-name').each(function () {
|
||||||
|
$(this).children('a').addClass('hidden');
|
||||||
|
$(this).children('input').removeClass('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
users_list_table_options = {
|
users_list_table_options = {
|
||||||
"language": {
|
"language": {
|
||||||
"search": "Search: ",
|
"search": "Search: ",
|
||||||
@@ -217,6 +234,7 @@ users_list_table_options = {
|
|||||||
$('.edit-control').each(function () {
|
$('.edit-control').each(function () {
|
||||||
$(this).removeClass('hidden');
|
$(this).removeClass('hidden');
|
||||||
});
|
});
|
||||||
|
toggleEditNames();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"preDrawCallback": function(settings) {
|
"preDrawCallback": function(settings) {
|
||||||
|
@@ -269,13 +269,13 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
|
|||||||
<li class="card card-sortable">
|
<li class="card card-sortable">
|
||||||
<div class="card-handle"><i class="fa fa-bars"></i></div>
|
<div class="card-handle"><i class="fa fa-bars"></i></div>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="hscard-top_music" name="hscard-top_music" value="top_music"> Most Listened Music
|
<input type="checkbox" id="hscard-top_music" name="hscard-top_music" value="top_music"> Most Listened to Artist
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
<li class="card card-sortable">
|
<li class="card card-sortable">
|
||||||
<div class="card-handle"><i class="fa fa-bars"></i></div>
|
<div class="card-handle"><i class="fa fa-bars"></i></div>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="hscard-popular_music" name="hscard-popular_music" value="popular_music"> Most Popular Music
|
<input type="checkbox" id="hscard-popular_music" name="hscard-popular_music" value="popular_music"> Most Popular Artist
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
<li class="card card-sortable">
|
<li class="card card-sortable">
|
||||||
@@ -832,7 +832,7 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
|
|||||||
</div>
|
</div>
|
||||||
<div id="notify_recently_added_delay_error" class="alert alert-danger settings-alert" role="alert"></div>
|
<div id="notify_recently_added_delay_error" class="alert alert-danger settings-alert" role="alert"></div>
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block">Set the delay for recently added notifications to allow metadata to be processed. Minimum 60 seconds.</p>
|
<p class="help-block">Set the delay (in seconds) for recently added notifications to allow metadata to be processed. Minimum 60 seconds.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="padded-header">
|
<div class="padded-header">
|
||||||
@@ -1484,6 +1484,10 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{user}</strong></td>
|
<td><strong>{user}</strong></td>
|
||||||
|
<td>The friendly name of the person streaming.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>{username}</strong></td>
|
||||||
<td>The username of the person streaming.</td>
|
<td>The username of the person streaming.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -1604,7 +1608,11 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{session_key}</strong></td>
|
<td><strong>{session_key}</strong></td>
|
||||||
<td>The unique identifier for the session.</td>
|
<td>The unique identifier for the stream session.</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><strong>{transcode_key}</strong></td>
|
||||||
|
<td>The unique identifier for the transcode session.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><strong>{user_id}</strong></td>
|
<td><strong>{user_id}</strong></td>
|
||||||
|
@@ -156,14 +156,7 @@
|
|||||||
$(this).addClass('hidden');
|
$(this).addClass('hidden');
|
||||||
$('#row-edit-mode-alert').fadeOut(200);
|
$('#row-edit-mode-alert').fadeOut(200);
|
||||||
});
|
});
|
||||||
$('.edit-user-control > .edit-user-name').each(function () {
|
toggleEditNames();
|
||||||
a = $(this).children('a');
|
|
||||||
input = $(this).children('input');
|
|
||||||
a.text(input.val());
|
|
||||||
a.removeClass('hidden');
|
|
||||||
input.addClass('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
users_to_delete = [];
|
users_to_delete = [];
|
||||||
users_to_purge = [];
|
users_to_purge = [];
|
||||||
@@ -171,10 +164,7 @@
|
|||||||
$(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger');
|
$(this).find('button.btn-danger').toggleClass('btn-warning').toggleClass('btn-danger');
|
||||||
$(this).removeClass('hidden');
|
$(this).removeClass('hidden');
|
||||||
});
|
});
|
||||||
$('.edit-user-control > .edit-user-name').each(function () {
|
toggleEditNames();
|
||||||
$(this).children('a').addClass('hidden');
|
|
||||||
$(this).children('input').removeClass('hidden');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -127,7 +127,7 @@ from plexpy import common
|
|||||||
</div>
|
</div>
|
||||||
<div class="wizard-card" data-cardname="card5" data-validate="validateNotifications">
|
<div class="wizard-card" data-cardname="card5" data-validate="validateNotifications">
|
||||||
<h3>Notifications</h3>
|
<h3>Notifications</h3>
|
||||||
<p class="help-block">PlexPy supports a wide variety of notification options. To set up a notification agent conifgure this in <strong>Settings -> Notification Agents</strong>
|
<p class="help-block">PlexPy supports a wide variety of notification options. To set up a notification agent configure this in <strong>Settings -> Notification Agents</strong>
|
||||||
after you have completed this setup wizard.</p><br/>
|
after you have completed this setup wizard.</p><br/>
|
||||||
<div class="wizard-input-section">
|
<div class="wizard-input-section">
|
||||||
<input type="checkbox" name="movie_notify_enable" id="movie_notify_enable" value="1" ${config['movie_notify_enable']}> Enable notifications on Movie playback
|
<input type="checkbox" name="movie_notify_enable" id="movie_notify_enable" value="1" ${config['movie_notify_enable']}> Enable notifications on Movie playback
|
||||||
|
@@ -396,8 +396,8 @@ def dbcheck():
|
|||||||
|
|
||||||
# sessions table :: This is a temp table that logs currently active sessions
|
# sessions table :: This is a temp table that logs currently active sessions
|
||||||
c_db.execute(
|
c_db.execute(
|
||||||
'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
'CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, session_key INTEGER, '
|
||||||
'session_key INTEGER, rating_key INTEGER, section_id INTEGER, media_type TEXT, started INTEGER, stopped INTEGER, '
|
'transcode_key TEXT, rating_key INTEGER, section_id INTEGER, media_type TEXT, started INTEGER, stopped INTEGER, '
|
||||||
'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, '
|
'paused_counter INTEGER DEFAULT 0, state TEXT, user_id INTEGER, user TEXT, friendly_name TEXT, '
|
||||||
'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, '
|
'ip_address TEXT, machine_id TEXT, player TEXT, platform TEXT, title TEXT, parent_title TEXT, '
|
||||||
'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
|
'grandparent_title TEXT, parent_rating_key INTEGER, grandparent_rating_key INTEGER, '
|
||||||
@@ -630,6 +630,15 @@ def dbcheck():
|
|||||||
'ALTER TABLE sessions ADD COLUMN stopped INTEGER'
|
'ALTER TABLE sessions ADD COLUMN stopped INTEGER'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Upgrade sessions table from earlier versions
|
||||||
|
try:
|
||||||
|
c_db.execute('SELECT transcode_key FROM sessions')
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
logger.debug(u"Altering database. Updating database table sessions.")
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE sessions ADD COLUMN transcode_key TEXT'
|
||||||
|
)
|
||||||
|
|
||||||
# Upgrade session_history table from earlier versions
|
# Upgrade session_history table from earlier versions
|
||||||
try:
|
try:
|
||||||
c_db.execute('SELECT reference_id FROM session_history')
|
c_db.execute('SELECT reference_id FROM session_history')
|
||||||
|
@@ -29,6 +29,7 @@ class ActivityProcessor(object):
|
|||||||
def write_session(self, session=None, notify=True):
|
def write_session(self, session=None, notify=True):
|
||||||
if session:
|
if session:
|
||||||
values = {'session_key': session['session_key'],
|
values = {'session_key': session['session_key'],
|
||||||
|
'transcode_key': session['transcode_key'],
|
||||||
'section_id': session['section_id'],
|
'section_id': session['section_id'],
|
||||||
'rating_key': session['rating_key'],
|
'rating_key': session['rating_key'],
|
||||||
'media_type': session['media_type'],
|
'media_type': session['media_type'],
|
||||||
|
@@ -458,10 +458,11 @@ class Config(object):
|
|||||||
|
|
||||||
for key, subkeys in self._config.iteritems():
|
for key, subkeys in self._config.iteritems():
|
||||||
for subkey, value in subkeys.iteritems():
|
for subkey, value in subkeys.iteritems():
|
||||||
if str(value).strip() and subkey.upper() not in _WHITELIST_KEYS and any(bk in subkey.upper() for bk in _BLACKLIST_KEYS):
|
if isinstance(value, basestring) and len(value.strip()) > 5 and \
|
||||||
blacklist.append(str(value).strip())
|
subkey.upper() not in _WHITELIST_KEYS and any(bk in subkey.upper() for bk in _BLACKLIST_KEYS):
|
||||||
|
blacklist.append(value.strip())
|
||||||
|
|
||||||
plexpy.logger._BLACKLIST_WORDS = filter(None, blacklist)
|
plexpy.logger._BLACKLIST_WORDS = blacklist
|
||||||
|
|
||||||
def _define(self, name):
|
def _define(self, name):
|
||||||
key = name.upper()
|
key = name.upper()
|
||||||
|
140
plexpy/graphs.py
@@ -24,12 +24,14 @@ class Graphs(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_total_plays_per_day(self, time_range='30', y_axis='plays'):
|
def get_total_plays_per_day(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT date(started, "unixepoch", "localtime") AS date_played, ' \
|
query = 'SELECT date(started, "unixepoch", "localtime") AS date_played, ' \
|
||||||
@@ -37,9 +39,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY date_played ' \
|
'GROUP BY date_played ' \
|
||||||
'ORDER BY started ASC' % time_range
|
'ORDER BY started ASC' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -51,9 +53,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY date_played ' \
|
'GROUP BY date_played ' \
|
||||||
'ORDER BY started ASC' % time_range
|
'ORDER BY started ASC' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -102,12 +104,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_per_dayofweek(self, time_range='30', y_axis='plays'):
|
def get_total_plays_per_dayofweek(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT strftime("%%w", datetime(started, "unixepoch", "localtime")) AS daynumber, ' \
|
query = 'SELECT strftime("%%w", datetime(started, "unixepoch", "localtime")) AS daynumber, ' \
|
||||||
@@ -123,9 +127,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY dayofweek ' \
|
'GROUP BY dayofweek ' \
|
||||||
'ORDER BY daynumber' % time_range
|
'ORDER BY daynumber' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -145,9 +149,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY dayofweek ' \
|
'GROUP BY dayofweek ' \
|
||||||
'ORDER BY daynumber' % time_range
|
'ORDER BY daynumber' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -193,12 +197,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_per_hourofday(self, time_range='30', y_axis='plays'):
|
def get_total_plays_per_hourofday(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT strftime("%%H", datetime(started, "unixepoch", "localtime")) AS hourofday, ' \
|
query = 'SELECT strftime("%%H", datetime(started, "unixepoch", "localtime")) AS hourofday, ' \
|
||||||
@@ -206,9 +212,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY hourofday ' \
|
'GROUP BY hourofday ' \
|
||||||
'ORDER BY hourofday' % time_range
|
'ORDER BY hourofday' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -220,9 +226,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") ' \
|
'WHERE datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime") %s' \
|
||||||
'GROUP BY hourofday ' \
|
'GROUP BY hourofday ' \
|
||||||
'ORDER BY hourofday' % time_range
|
'ORDER BY hourofday' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -270,25 +276,27 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_per_month(self, y_axis='plays'):
|
def get_total_plays_per_month(self, y_axis='plays', user_id=None):
|
||||||
import time as time
|
import time as time
|
||||||
|
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) AS datestring, ' \
|
query = 'SELECT strftime("%%Y-%%m", datetime(started, "unixepoch", "localtime")) AS datestring, ' \
|
||||||
'SUM(CASE WHEN media_type = "episode" THEN 1 ELSE 0 END) AS tv_count, ' \
|
'SUM(CASE WHEN media_type = "episode" THEN 1 ELSE 0 END) AS tv_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
'SUM(CASE WHEN media_type = "movie" THEN 1 ELSE 0 END) AS movie_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") ' \
|
'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") %s' \
|
||||||
'GROUP BY strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) ' \
|
'GROUP BY strftime("%%Y-%%m", datetime(started, "unixepoch", "localtime")) ' \
|
||||||
'ORDER BY datestring DESC LIMIT 12'
|
'ORDER BY datestring DESC LIMIT 12' % (user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
query = 'SELECT strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) AS datestring, ' \
|
query = 'SELECT strftime("%%Y-%%m", datetime(started, "unixepoch", "localtime")) AS datestring, ' \
|
||||||
'SUM(CASE WHEN media_type = "episode" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "episode" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS tv_count, ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS tv_count, ' \
|
||||||
'SUM(CASE WHEN media_type = "movie" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "movie" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
@@ -296,9 +304,9 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN media_type = "track" AND stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS music_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") ' \
|
'WHERE datetime(started, "unixepoch", "localtime") >= datetime("now", "-12 months", "localtime") %s' \
|
||||||
'GROUP BY strftime("%Y-%m", datetime(started, "unixepoch", "localtime")) ' \
|
'GROUP BY strftime("%%Y-%%m", datetime(started, "unixepoch", "localtime")) ' \
|
||||||
'ORDER BY datestring DESC LIMIT 12'
|
'ORDER BY datestring DESC LIMIT 12' % (user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -351,12 +359,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_by_top_10_platforms(self, time_range='30', y_axis='plays'):
|
def get_total_plays_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT platform, ' \
|
query = 'SELECT platform, ' \
|
||||||
@@ -365,10 +375,10 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count, ' \
|
'SUM(CASE WHEN media_type = "track" THEN 1 ELSE 0 END) AS music_count, ' \
|
||||||
'COUNT(id) AS total_count ' \
|
'COUNT(id) AS total_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) ' \
|
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) %s' \
|
||||||
'GROUP BY platform ' \
|
'GROUP BY platform ' \
|
||||||
'ORDER BY total_count DESC ' \
|
'ORDER BY total_count DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -382,10 +392,10 @@ class Graphs(object):
|
|||||||
'SUM(CASE WHEN stopped > 0 THEN (stopped - started) ' \
|
'SUM(CASE WHEN stopped > 0 THEN (stopped - started) ' \
|
||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS total_duration ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS total_duration ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) ' \
|
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) %s' \
|
||||||
'GROUP BY platform ' \
|
'GROUP BY platform ' \
|
||||||
'ORDER BY total_duration DESC ' \
|
'ORDER BY total_duration DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -414,12 +424,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_by_top_10_users(self, time_range='30', y_axis='plays'):
|
def get_total_plays_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND users.user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT ' \
|
query = 'SELECT ' \
|
||||||
@@ -430,10 +442,10 @@ class Graphs(object):
|
|||||||
'COUNT(session_history.id) AS total_count ' \
|
'COUNT(session_history.id) AS total_count ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'JOIN users ON session_history.user_id = users.user_id ' \
|
'JOIN users ON session_history.user_id = users.user_id ' \
|
||||||
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) ' \
|
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) %s' \
|
||||||
'GROUP BY session_history.user_id ' \
|
'GROUP BY session_history.user_id ' \
|
||||||
'ORDER BY total_count DESC ' \
|
'ORDER BY total_count DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -449,10 +461,10 @@ class Graphs(object):
|
|||||||
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS total_duration ' \
|
' - (CASE WHEN paused_counter IS NULL THEN 0 ELSE paused_counter END) ELSE 0 END) AS total_duration ' \
|
||||||
'FROM session_history ' \
|
'FROM session_history ' \
|
||||||
'JOIN users ON session_history.user_id = users.user_id ' \
|
'JOIN users ON session_history.user_id = users.user_id ' \
|
||||||
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) ' \
|
'WHERE (datetime(stopped, "unixepoch", "localtime") >= datetime("now", "-%s days", "localtime")) %s' \
|
||||||
'GROUP BY session_history.user_id ' \
|
'GROUP BY session_history.user_id ' \
|
||||||
'ORDER BY total_duration DESC ' \
|
'ORDER BY total_duration DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -481,12 +493,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_per_stream_type(self, time_range='30', y_axis='plays'):
|
def get_total_plays_per_stream_type(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT date(session_history.started, "unixepoch", "localtime") AS date_played, ' \
|
query = 'SELECT date(session_history.started, "unixepoch", "localtime") AS date_played, ' \
|
||||||
@@ -501,9 +515,9 @@ class Graphs(object):
|
|||||||
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime")) AND ' \
|
'datetime("now", "-%s days", "localtime")) AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR ' \
|
||||||
'session_history.media_type = "track") ' \
|
'session_history.media_type = "track") %s' \
|
||||||
'GROUP BY date_played ' \
|
'GROUP BY date_played ' \
|
||||||
'ORDER BY started ASC' % time_range
|
'ORDER BY started ASC' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -522,9 +536,9 @@ class Graphs(object):
|
|||||||
'WHERE datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime") AND ' \
|
'datetime("now", "-%s days", "localtime") AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR ' \
|
||||||
'session_history.media_type = "track") ' \
|
'session_history.media_type = "track") %s' \
|
||||||
'GROUP BY date_played ' \
|
'GROUP BY date_played ' \
|
||||||
'ORDER BY started ASC' % time_range
|
'ORDER BY started ASC' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -573,12 +587,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_by_source_resolution(self, time_range='30', y_axis='plays'):
|
def get_total_plays_by_source_resolution(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT session_history_media_info.video_resolution AS resolution, ' \
|
query = 'SELECT session_history_media_info.video_resolution AS resolution, ' \
|
||||||
@@ -593,10 +609,10 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime")) AND ' \
|
'datetime("now", "-%s days", "localtime")) AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie") %s' \
|
||||||
'GROUP BY resolution ' \
|
'GROUP BY resolution ' \
|
||||||
'ORDER BY total_count DESC ' \
|
'ORDER BY total_count DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -616,10 +632,10 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime")) AND ' \
|
'datetime("now", "-%s days", "localtime")) AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie") %s' \
|
||||||
'GROUP BY resolution ' \
|
'GROUP BY resolution ' \
|
||||||
'ORDER BY total_duration DESC ' \
|
'ORDER BY total_duration DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -648,12 +664,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_total_plays_by_stream_resolution(self, time_range='30', y_axis='plays'):
|
def get_total_plays_by_stream_resolution(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT ' \
|
query = 'SELECT ' \
|
||||||
@@ -678,10 +696,10 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime")) AND ' \
|
'datetime("now", "-%s days", "localtime")) AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie") %s' \
|
||||||
'GROUP BY resolution ' \
|
'GROUP BY resolution ' \
|
||||||
'ORDER BY total_count DESC ' \
|
'ORDER BY total_count DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -711,10 +729,10 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
'WHERE (datetime(session_history.stopped, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime")) AND ' \
|
'datetime("now", "-%s days", "localtime")) AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie") %s' \
|
||||||
'GROUP BY resolution ' \
|
'GROUP BY resolution ' \
|
||||||
'ORDER BY total_duration DESC ' \
|
'ORDER BY total_duration DESC ' \
|
||||||
'LIMIT 10' % time_range
|
'LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -743,12 +761,14 @@ class Graphs(object):
|
|||||||
'series': [series_1_output, series_2_output, series_3_output]}
|
'series': [series_1_output, series_2_output, series_3_output]}
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays'):
|
def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT session_history.platform AS platform, ' \
|
query = 'SELECT session_history.platform AS platform, ' \
|
||||||
@@ -763,9 +783,9 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime") AND ' \
|
'datetime("now", "-%s days", "localtime") AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") %s' \
|
||||||
'GROUP BY platform ' \
|
'GROUP BY platform ' \
|
||||||
'ORDER BY total_count DESC LIMIT 10' % time_range
|
'ORDER BY total_count DESC LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -786,9 +806,9 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime") AND ' \
|
'datetime("now", "-%s days", "localtime") AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") %s' \
|
||||||
'GROUP BY platform ' \
|
'GROUP BY platform ' \
|
||||||
'ORDER BY total_duration DESC LIMIT 10' % time_range
|
'ORDER BY total_duration DESC LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -818,12 +838,14 @@ class Graphs(object):
|
|||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays'):
|
def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
if not time_range.isdigit():
|
if not time_range.isdigit():
|
||||||
time_range = '30'
|
time_range = '30'
|
||||||
|
|
||||||
|
user_cond = ('AND users.user_id = %s ' % user_id) if user_id and user_id.isdigit() else ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if y_axis == 'plays':
|
if y_axis == 'plays':
|
||||||
query = 'SELECT ' \
|
query = 'SELECT ' \
|
||||||
@@ -840,9 +862,9 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime") AND ' \
|
'datetime("now", "-%s days", "localtime") AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") %s' \
|
||||||
'GROUP BY username ' \
|
'GROUP BY username ' \
|
||||||
'ORDER BY total_count DESC LIMIT 10' % time_range
|
'ORDER BY total_count DESC LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
else:
|
else:
|
||||||
@@ -865,9 +887,9 @@ class Graphs(object):
|
|||||||
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
'JOIN session_history_media_info ON session_history.id = session_history_media_info.id ' \
|
||||||
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
'WHERE datetime(session_history.started, "unixepoch", "localtime") >= ' \
|
||||||
'datetime("now", "-%s days", "localtime") AND ' \
|
'datetime("now", "-%s days", "localtime") AND ' \
|
||||||
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") ' \
|
'(session_history.media_type = "episode" OR session_history.media_type = "movie" OR session_history.media_type = "track") %s' \
|
||||||
'GROUP BY username ' \
|
'GROUP BY username ' \
|
||||||
'ORDER BY total_duration DESC LIMIT 10' % time_range
|
'ORDER BY total_duration DESC LIMIT 10' % (time_range, user_cond)
|
||||||
|
|
||||||
result = monitor_db.select(query)
|
result = monitor_db.select(query)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
import arrow
|
import arrow
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import threading
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
@@ -463,12 +464,8 @@ def build_notify_text(session=None, timeline=None, notify_action=None, agent_id=
|
|||||||
plex_tv = plextv.PlexTV()
|
plex_tv = plextv.PlexTV()
|
||||||
server_times = plex_tv.get_server_times()
|
server_times = plex_tv.get_server_times()
|
||||||
|
|
||||||
# Get the server version
|
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
|
||||||
server_identity = pms_connect.get_server_identity()
|
|
||||||
|
|
||||||
if server_times:
|
if server_times:
|
||||||
updated_at = server_times[0]['updated_at']
|
updated_at = server_times['updated_at']
|
||||||
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
|
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
|
||||||
else:
|
else:
|
||||||
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
|
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
|
||||||
@@ -626,11 +623,15 @@ def build_notify_text(session=None, timeline=None, notify_action=None, agent_id=
|
|||||||
# If no previous poster_url
|
# If no previous poster_url
|
||||||
if not poster_url and plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS:
|
if not poster_url and plexpy.CONFIG.NOTIFY_UPLOAD_POSTERS:
|
||||||
try:
|
try:
|
||||||
|
thread_name = str(threading.current_thread().ident)
|
||||||
# Retrieve the poster from Plex and cache to file
|
# Retrieve the poster from Plex and cache to file
|
||||||
urllib.urlretrieve(plexpy.CONFIG.PMS_URL + thumb + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN,
|
urllib.urlretrieve(plexpy.CONFIG.PMS_URL + thumb + '?X-Plex-Token=' + plexpy.CONFIG.PMS_TOKEN,
|
||||||
os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'))
|
os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster-'+thread_name+'.jpg'))
|
||||||
# Upload thumb to Imgur and get link
|
# Upload thumb to Imgur and get link
|
||||||
poster_url = helpers.uploadToImgur(os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster.jpg'), poster_title)
|
poster_url = helpers.uploadToImgur(os.path.join(plexpy.CONFIG.CACHE_DIR,
|
||||||
|
'cache-poster-'+thread_name+'.jpg'), poster_title)
|
||||||
|
# Delete the cached poster
|
||||||
|
os.remove(os.path.join(plexpy.CONFIG.CACHE_DIR, 'cache-poster-'+thread_name+'.jpg'))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to retrieve poster for rating_key %s: %s." % (str(rating_key), e))
|
logger.error(u"PlexPy Notifier :: Unable to retrieve poster for rating_key %s: %s." % (str(rating_key), e))
|
||||||
|
|
||||||
@@ -653,13 +654,14 @@ def build_notify_text(session=None, timeline=None, notify_action=None, agent_id=
|
|||||||
available_params = {# Global paramaters
|
available_params = {# Global paramaters
|
||||||
'server_name': server_name,
|
'server_name': server_name,
|
||||||
'server_uptime': server_uptime,
|
'server_uptime': server_uptime,
|
||||||
'server_version': server_identity.get('version',''),
|
'server_version': server_times.get('version',''),
|
||||||
'action': notify_action.title(),
|
'action': notify_action.title(),
|
||||||
'datestamp': arrow.now().format(date_format),
|
'datestamp': arrow.now().format(date_format),
|
||||||
'timestamp': arrow.now().format(time_format),
|
'timestamp': arrow.now().format(time_format),
|
||||||
# Stream parameters
|
# Stream parameters
|
||||||
'streams': stream_count,
|
'streams': stream_count,
|
||||||
'user': session.get('friendly_name',''),
|
'user': session.get('friendly_name',''),
|
||||||
|
'username': session.get('user',''),
|
||||||
'platform': session.get('platform',''),
|
'platform': session.get('platform',''),
|
||||||
'player': session.get('player',''),
|
'player': session.get('player',''),
|
||||||
'ip_address': session.get('ip_address','N/A'),
|
'ip_address': session.get('ip_address','N/A'),
|
||||||
@@ -690,6 +692,7 @@ def build_notify_text(session=None, timeline=None, notify_action=None, agent_id=
|
|||||||
'transcode_audio_codec': session.get('transcode_audio_codec',''),
|
'transcode_audio_codec': session.get('transcode_audio_codec',''),
|
||||||
'transcode_audio_channels': session.get('transcode_audio_channels',''),
|
'transcode_audio_channels': session.get('transcode_audio_channels',''),
|
||||||
'session_key': session.get('session_key',''),
|
'session_key': session.get('session_key',''),
|
||||||
|
'transcode_key': session.get('transcode_key',''),
|
||||||
'user_id': session.get('user_id',''),
|
'user_id': session.get('user_id',''),
|
||||||
'machine_id': session.get('machine_id',''),
|
'machine_id': session.get('machine_id',''),
|
||||||
# Metadata parameters
|
# Metadata parameters
|
||||||
@@ -743,9 +746,9 @@ def build_notify_text(session=None, timeline=None, notify_action=None, agent_id=
|
|||||||
try:
|
try:
|
||||||
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
|
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
|
||||||
except LookupError as e:
|
except LookupError as e:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
|
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in script argument. Using fallback." % e)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)
|
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom script arguments %s. Using fallback." % e)
|
||||||
|
|
||||||
if notify_action == 'play':
|
if notify_action == 'play':
|
||||||
# Default body text
|
# Default body text
|
||||||
@@ -929,16 +932,13 @@ def build_server_notify_text(notify_action=None, agent_id=None):
|
|||||||
plex_tv = plextv.PlexTV()
|
plex_tv = plextv.PlexTV()
|
||||||
server_times = plex_tv.get_server_times()
|
server_times = plex_tv.get_server_times()
|
||||||
|
|
||||||
# Get the server version
|
|
||||||
pms_connect = pmsconnect.PmsConnect()
|
|
||||||
server_identity = pms_connect.get_server_identity()
|
|
||||||
|
|
||||||
update_status = {}
|
update_status = {}
|
||||||
if notify_action == 'pmsupdate':
|
if notify_action == 'pmsupdate':
|
||||||
|
pms_connect = pmsconnect.PmsConnect()
|
||||||
update_status = pms_connect.get_update_staus()
|
update_status = pms_connect.get_update_staus()
|
||||||
|
|
||||||
if server_times:
|
if server_times:
|
||||||
updated_at = server_times[0]['updated_at']
|
updated_at = server_times['updated_at']
|
||||||
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
|
server_uptime = helpers.human_duration(int(time.time() - helpers.cast_to_int(updated_at)))
|
||||||
else:
|
else:
|
||||||
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
|
logger.error(u"PlexPy NotificationHandler :: Unable to retrieve server uptime.")
|
||||||
@@ -961,7 +961,7 @@ def build_server_notify_text(notify_action=None, agent_id=None):
|
|||||||
available_params = {# Global paramaters
|
available_params = {# Global paramaters
|
||||||
'server_name': server_name,
|
'server_name': server_name,
|
||||||
'server_uptime': server_uptime,
|
'server_uptime': server_uptime,
|
||||||
'server_version': server_identity.get('version',''),
|
'server_version': server_times.get('version',''),
|
||||||
'action': notify_action.title(),
|
'action': notify_action.title(),
|
||||||
'datestamp': arrow.now().format(date_format),
|
'datestamp': arrow.now().format(date_format),
|
||||||
'timestamp': arrow.now().format(time_format),
|
'timestamp': arrow.now().format(time_format),
|
||||||
@@ -980,9 +980,9 @@ def build_server_notify_text(notify_action=None, agent_id=None):
|
|||||||
try:
|
try:
|
||||||
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
|
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
|
||||||
except LookupError as e:
|
except LookupError as e:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
|
logger.error(u"PlexPy NotificationHandler :: Unable to parse field %s in script argument. Using fallback." % e)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)
|
logger.error(u"PlexPy NotificationHandler :: Unable to parse custom script arguments %s. Using fallback." % e)
|
||||||
|
|
||||||
if notify_action == 'extdown':
|
if notify_action == 'extdown':
|
||||||
# Default body text
|
# Default body text
|
||||||
|
@@ -487,7 +487,7 @@ def send_notification(agent_id, subject, body, notify_action, **kwargs):
|
|||||||
slackClient.notify(message=body, event=subject)
|
slackClient.notify(message=body, event=subject)
|
||||||
elif agent_id == 15:
|
elif agent_id == 15:
|
||||||
scripts = Scripts()
|
scripts = Scripts()
|
||||||
scripts.notify(message=body, subject=subject, **kwargs)
|
scripts.notify(message=body, subject=subject, notify_action=notify_action, **kwargs)
|
||||||
elif agent_id == 16:
|
elif agent_id == 16:
|
||||||
facebook = FacebookNotifier()
|
facebook = FacebookNotifier()
|
||||||
facebook.notify(subject=subject, message=body, **kwargs)
|
facebook.notify(subject=subject, message=body, **kwargs)
|
||||||
@@ -1776,7 +1776,7 @@ class SLACK(object):
|
|||||||
if urlparse(self.icon_emoji).scheme == '':
|
if urlparse(self.icon_emoji).scheme == '':
|
||||||
data['icon_emoji'] = self.icon_emoji
|
data['icon_emoji'] = self.icon_emoji
|
||||||
else:
|
else:
|
||||||
data['icon_url'] = self.icon_url
|
data['icon_url'] = self.icon_emoji
|
||||||
|
|
||||||
url = urlparse(self.slack_hook).path
|
url = urlparse(self.slack_hook).path
|
||||||
|
|
||||||
@@ -1884,7 +1884,7 @@ class Scripts(object):
|
|||||||
script_args(list): ["python2", '-p', '-zomg']
|
script_args(list): ["python2", '-p', '-zomg']
|
||||||
"""
|
"""
|
||||||
logger.debug(u"PlexPy Notifiers :: Trying to run notify script, action: %s, arguments: %s" %
|
logger.debug(u"PlexPy Notifiers :: Trying to run notify script, action: %s, arguments: %s" %
|
||||||
(notify_action if notify_action else None, script_args if script_args else None))
|
(notify_action or None, script_args or None))
|
||||||
|
|
||||||
if script_args is None:
|
if script_args is None:
|
||||||
script_args = []
|
script_args = []
|
||||||
|
@@ -71,32 +71,37 @@ def get_real_pms_url():
|
|||||||
|
|
||||||
if plexpy.CONFIG.PMS_SSL:
|
if plexpy.CONFIG.PMS_SSL:
|
||||||
result = PlexTV().get_server_urls(include_https=True)
|
result = PlexTV().get_server_urls(include_https=True)
|
||||||
process_urls = True
|
|
||||||
elif plexpy.CONFIG.PMS_IS_REMOTE:
|
|
||||||
result = PlexTV().get_server_urls(include_https=False)
|
|
||||||
process_urls = True
|
|
||||||
else:
|
else:
|
||||||
result = PlexTV().get_server_urls(include_https=False)
|
result = PlexTV().get_server_urls(include_https=False)
|
||||||
process_urls = False
|
|
||||||
|
|
||||||
if process_urls:
|
# Only need to retrieve PMS_URL if using SSL
|
||||||
|
if plexpy.CONFIG.PMS_SSL:
|
||||||
if result:
|
if result:
|
||||||
for item in result:
|
if plexpy.CONFIG.PMS_IS_REMOTE:
|
||||||
if plexpy.CONFIG.PMS_IS_REMOTE and item['local'] == '0':
|
# Get all remote connections
|
||||||
plexpy.CONFIG.__setattr__('PMS_URL', item['uri'])
|
connections = [c for c in result if c['local'] == '0' and 'plex.direct' in c['uri']]
|
||||||
|
else:
|
||||||
|
# Get all local connections
|
||||||
|
connections = [c for c in result if c['local'] == '1' and 'plex.direct' in c['uri']]
|
||||||
|
|
||||||
|
if connections:
|
||||||
|
# Get connection with matching address, otherwise return first connection
|
||||||
|
conn = next((c for c in connections if c['address'] == plexpy.CONFIG.PMS_IP), connections[0])
|
||||||
|
plexpy.CONFIG.__setattr__('PMS_URL', conn['uri'])
|
||||||
plexpy.CONFIG.write()
|
plexpy.CONFIG.write()
|
||||||
logger.info(u"PlexPy PlexTV :: Server URL retrieved.")
|
logger.info(u"PlexPy PlexTV :: Server URL retrieved.")
|
||||||
if not plexpy.CONFIG.PMS_IS_REMOTE and item['local'] == '1' and 'plex.direct' in item['uri']:
|
|
||||||
plexpy.CONFIG.__setattr__('PMS_URL', item['uri'])
|
# get_server_urls() failed or PMS_URL not found, fallback url doesn't use SSL
|
||||||
|
if not plexpy.CONFIG.PMS_URL:
|
||||||
|
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
|
||||||
plexpy.CONFIG.write()
|
plexpy.CONFIG.write()
|
||||||
logger.info(u"PlexPy PlexTV :: Server URL retrieved.")
|
logger.warn(u"PlexPy PlexTV :: Unable to retrieve server URLs. Using user-defined value without SSL.")
|
||||||
else:
|
|
||||||
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
|
# Not using SSL, remote has no effect
|
||||||
plexpy.CONFIG.write()
|
|
||||||
logger.warn(u"PlexPy PlexTV :: Unable to retrieve server URLs. Using user-defined value.")
|
|
||||||
else:
|
else:
|
||||||
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
|
plexpy.CONFIG.__setattr__('PMS_URL', fallback_url)
|
||||||
plexpy.CONFIG.write()
|
plexpy.CONFIG.write()
|
||||||
|
logger.info(u"PlexPy PlexTV :: Using user-defined URL.")
|
||||||
|
|
||||||
|
|
||||||
class PlexTV(object):
|
class PlexTV(object):
|
||||||
@@ -450,19 +455,20 @@ class PlexTV(object):
|
|||||||
|
|
||||||
def get_server_times(self):
|
def get_server_times(self):
|
||||||
servers = self.get_plextv_server_list(output_format='xml')
|
servers = self.get_plextv_server_list(output_format='xml')
|
||||||
server_times = []
|
server_times = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
xml_head = servers.getElementsByTagName('Server')
|
xml_head = servers.getElementsByTagName('Server')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_times: %s." % e)
|
logger.warn(u"PlexPy PlexTV :: Unable to parse XML for get_server_times: %s." % e)
|
||||||
return []
|
return {}
|
||||||
|
|
||||||
for a in xml_head:
|
for a in xml_head:
|
||||||
if helpers.get_xml_attr(a, 'machineIdentifier') == plexpy.CONFIG.PMS_IDENTIFIER:
|
if helpers.get_xml_attr(a, 'machineIdentifier') == plexpy.CONFIG.PMS_IDENTIFIER:
|
||||||
server_times.append({"created_at": helpers.get_xml_attr(a, 'createdAt'),
|
server_times = {"created_at": helpers.get_xml_attr(a, 'createdAt'),
|
||||||
"updated_at": helpers.get_xml_attr(a, 'updatedAt')
|
"updated_at": helpers.get_xml_attr(a, 'updatedAt'),
|
||||||
})
|
"version": helpers.get_xml_attr(a, 'version')
|
||||||
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
return server_times
|
return server_times
|
||||||
|
@@ -939,7 +939,7 @@ class PmsConnect(object):
|
|||||||
try:
|
try:
|
||||||
xml_head = session_data.getElementsByTagName('MediaContainer')
|
xml_head = session_data.getElementsByTagName('MediaContainer')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_sessions: %s." % e)
|
logger.warn(u"PlexPy Pmsconnect :: Unable to parse XML for get_current_activity: %s." % e)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
session_list = []
|
session_list = []
|
||||||
@@ -1001,6 +1001,7 @@ class PmsConnect(object):
|
|||||||
|
|
||||||
if session.getElementsByTagName('TranscodeSession'):
|
if session.getElementsByTagName('TranscodeSession'):
|
||||||
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
||||||
|
transcode_key = helpers.get_xml_attr(transcode_session, 'key')
|
||||||
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
||||||
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
||||||
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
||||||
@@ -1011,6 +1012,7 @@ class PmsConnect(object):
|
|||||||
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
||||||
duration = helpers.get_xml_attr(transcode_session, 'duration')
|
duration = helpers.get_xml_attr(transcode_session, 'duration')
|
||||||
else:
|
else:
|
||||||
|
transcode_key = ''
|
||||||
throttled = '0'
|
throttled = '0'
|
||||||
transcode_progress = '0'
|
transcode_progress = '0'
|
||||||
transcode_speed = ''
|
transcode_speed = ''
|
||||||
@@ -1051,6 +1053,7 @@ class PmsConnect(object):
|
|||||||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||||
|
'transcode_key': transcode_key,
|
||||||
'throttled': throttled,
|
'throttled': throttled,
|
||||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||||
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
||||||
@@ -1099,6 +1102,7 @@ class PmsConnect(object):
|
|||||||
|
|
||||||
if session.getElementsByTagName('TranscodeSession'):
|
if session.getElementsByTagName('TranscodeSession'):
|
||||||
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
||||||
|
transcode_key = helpers.get_xml_attr(transcode_session, 'key')
|
||||||
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
||||||
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
||||||
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
||||||
@@ -1112,6 +1116,7 @@ class PmsConnect(object):
|
|||||||
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
||||||
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
||||||
else:
|
else:
|
||||||
|
transcode_key = ''
|
||||||
throttled = '0'
|
throttled = '0'
|
||||||
transcode_progress = '0'
|
transcode_progress = '0'
|
||||||
transcode_speed = ''
|
transcode_speed = ''
|
||||||
@@ -1174,6 +1179,7 @@ class PmsConnect(object):
|
|||||||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||||
|
'transcode_key': transcode_key,
|
||||||
'throttled': throttled,
|
'throttled': throttled,
|
||||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||||
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
||||||
@@ -1232,6 +1238,7 @@ class PmsConnect(object):
|
|||||||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||||
|
'transcode_key': transcode_key,
|
||||||
'throttled': throttled,
|
'throttled': throttled,
|
||||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||||
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
||||||
@@ -1290,6 +1297,7 @@ class PmsConnect(object):
|
|||||||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||||
|
'transcode_key': transcode_key,
|
||||||
'throttled': throttled,
|
'throttled': throttled,
|
||||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||||
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
||||||
@@ -1329,6 +1337,7 @@ class PmsConnect(object):
|
|||||||
|
|
||||||
if session.getElementsByTagName('TranscodeSession'):
|
if session.getElementsByTagName('TranscodeSession'):
|
||||||
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
transcode_session = session.getElementsByTagName('TranscodeSession')[0]
|
||||||
|
transcode_key = helpers.get_xml_attr(transcode_session, 'key')
|
||||||
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
throttled = helpers.get_xml_attr(transcode_session, 'throttled')
|
||||||
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
transcode_progress = helpers.get_xml_attr(transcode_session, 'progress')
|
||||||
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
transcode_speed = helpers.get_xml_attr(transcode_session, 'speed')
|
||||||
@@ -1339,6 +1348,7 @@ class PmsConnect(object):
|
|||||||
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
transcode_container = helpers.get_xml_attr(transcode_session, 'container')
|
||||||
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
transcode_protocol = helpers.get_xml_attr(transcode_session, 'protocol')
|
||||||
else:
|
else:
|
||||||
|
transcode_key = ''
|
||||||
throttled = '0'
|
throttled = '0'
|
||||||
transcode_progress = '0'
|
transcode_progress = '0'
|
||||||
transcode_speed = ''
|
transcode_speed = ''
|
||||||
@@ -1381,6 +1391,7 @@ class PmsConnect(object):
|
|||||||
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
'rating_key': helpers.get_xml_attr(session, 'ratingKey'),
|
||||||
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
'parent_rating_key': helpers.get_xml_attr(session, 'parentRatingKey'),
|
||||||
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
'grandparent_rating_key': helpers.get_xml_attr(session, 'grandparentRatingKey'),
|
||||||
|
'transcode_key': transcode_key,
|
||||||
'throttled': throttled,
|
'throttled': throttled,
|
||||||
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
'transcode_progress': int(round(helpers.cast_to_float(transcode_progress), 0)),
|
||||||
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
'transcode_speed': str(round(helpers.cast_to_float(transcode_speed), 1)),
|
||||||
|
@@ -21,6 +21,23 @@ class Users(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_user_names(self, kwargs=None):
|
||||||
|
monitor_db = database.MonitorDatabase()
|
||||||
|
|
||||||
|
try:
|
||||||
|
query = 'SELECT user_id, ' \
|
||||||
|
'(CASE WHEN users.friendly_name IS NULL OR TRIM(users.friendly_name) = "" \
|
||||||
|
THEN users.username ELSE users.friendly_name END) AS friendly_name ' \
|
||||||
|
'FROM users ' \
|
||||||
|
'WHERE deleted_user = 0'
|
||||||
|
|
||||||
|
result = monitor_db.select(query)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warn(u"PlexPy Graphs :: Unable to execute database query for get_user_names: %s." % e)
|
||||||
|
return None
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def get_datatables_list(self, kwargs=None):
|
def get_datatables_list(self, kwargs=None):
|
||||||
data_tables = datatables.DataTables()
|
data_tables = datatables.DataTables()
|
||||||
|
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
PLEXPY_VERSION = "master"
|
PLEXPY_VERSION = "master"
|
||||||
PLEXPY_RELEASE_VERSION = "1.3.12"
|
PLEXPY_RELEASE_VERSION = "1.3.16"
|
||||||
|
@@ -864,10 +864,20 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_date(self, time_range='30', y_axis='plays', **kwargs):
|
def get_user_names(self, **kwargs):
|
||||||
|
|
||||||
|
user_data = users.Users()
|
||||||
|
user_names = user_data.get_user_names(kwargs=kwargs)
|
||||||
|
|
||||||
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|
return json.dumps(user_names)
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
@addtoapi()
|
||||||
|
def get_plays_by_date(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_per_day(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_per_day(time_range=time_range, user_id=user_id, y_axis=y_axis)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -877,10 +887,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_dayofweek(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_dayofweek(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_per_dayofweek(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_per_dayofweek(time_range=time_range, user_id=user_id, y_axis=y_axis)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -890,10 +900,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_hourofday(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_hourofday(self, time_range='30', user_id=None, y_axis='plays', **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_per_hourofday(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_per_hourofday(time_range=time_range, user_id=user_id, y_axis=y_axis)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -903,10 +913,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_per_month(self, y_axis='plays', **kwargs):
|
def get_plays_per_month(self, y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_per_month(y_axis=y_axis)
|
result = graph.get_total_plays_per_month(y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -916,10 +926,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_top_10_platforms(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_by_top_10_platforms(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_by_top_10_platforms(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -929,10 +939,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_top_10_users(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_by_top_10_users(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_by_top_10_users(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -942,10 +952,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_stream_type(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_stream_type(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_per_stream_type(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_per_stream_type(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -955,10 +965,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_source_resolution(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_source_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_by_source_resolution(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_by_source_resolution(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -968,10 +978,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_plays_by_stream_resolution(self, time_range='30', y_axis='plays', **kwargs):
|
def get_plays_by_stream_resolution(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_total_plays_by_stream_resolution(time_range=time_range, y_axis=y_axis)
|
result = graph.get_total_plays_by_stream_resolution(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -981,10 +991,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays', **kwargs):
|
def get_stream_type_by_top_10_users(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_stream_type_by_top_10_users(time_range=time_range, y_axis=y_axis)
|
result = graph.get_stream_type_by_top_10_users(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
@@ -994,10 +1004,10 @@ class WebInterface(object):
|
|||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@addtoapi()
|
@addtoapi()
|
||||||
def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays', **kwargs):
|
def get_stream_type_by_top_10_platforms(self, time_range='30', y_axis='plays', user_id=None, **kwargs):
|
||||||
|
|
||||||
graph = graphs.Graphs()
|
graph = graphs.Graphs()
|
||||||
result = graph.get_stream_type_by_top_10_platforms(time_range=time_range, y_axis=y_axis)
|
result = graph.get_stream_type_by_top_10_platforms(time_range=time_range, y_axis=y_axis, user_id=user_id)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
cherrypy.response.headers['Content-type'] = 'application/json'
|
cherrypy.response.headers['Content-type'] = 'application/json'
|
||||||
|