mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
New pause, resume and buffer notification options.
Reworked notification config in settings menu.
This commit is contained in:
parent
b7baf1a05d
commit
a96482ee3c
9 changed files with 532 additions and 131 deletions
|
@ -1368,7 +1368,7 @@ input[type="color"],
|
||||||
}
|
}
|
||||||
.stacked-configs > li > span > a.toggle-left {
|
.stacked-configs > li > span > a.toggle-left {
|
||||||
color: #444;
|
color: #444;
|
||||||
padding-right: 2px;
|
padding-right: 8px;
|
||||||
}
|
}
|
||||||
.stacked-configs > li > span > a:hover {
|
.stacked-configs > li > span > a:hover {
|
||||||
color: #eee;
|
color: #eee;
|
||||||
|
|
98
data/interfaces/default/notification_triggers_modal.html
Normal file
98
data/interfaces/default/notification_triggers_modal.html
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
<%!
|
||||||
|
from plexpy import helpers
|
||||||
|
%>
|
||||||
|
% if data:
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="fa fa-remove"></i></button>
|
||||||
|
<h4 class="modal-title" id="notification-triggers-modal-header">${data['name']} Notification Triggers</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<p class="help-block">
|
||||||
|
Watched notifications are only applicable for video items.
|
||||||
|
</p>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_play" ${helpers.checked(data['on_play'])} class="toggle-switches">
|
||||||
|
Notify on playback start
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a new media item is started.</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_stop" ${helpers.checked(data['on_stop'])} class="toggle-switches">
|
||||||
|
Notify on playback stop
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a media item is stopped.</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_pause" ${helpers.checked(data['on_pause'])} class="toggle-switches">
|
||||||
|
Notify on playback pause
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a media item is paused.</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_resume" ${helpers.checked(data['on_resume'])} class="toggle-switches">
|
||||||
|
Notify on playback resume
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a media item is resumed from a paused state.</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_watched" ${helpers.checked(data['on_watched'])} class="toggle-switches">
|
||||||
|
Notify on watched
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a video item reaches the defined watch percentage.</p>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" data-size="small" data-id="${data['id']}" data-config-name="${data['config_prefix']}_on_buffer" ${helpers.checked(data['on_buffer'])} class="toggle-switches">
|
||||||
|
Notify on buffer warning
|
||||||
|
</label>
|
||||||
|
<p class="help-block">Trigger notification when a media item triggers the defined buffer threshold.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<input type="button" class="btn btn-bright" data-dismiss="modal" value="Close">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$('.toggle-switches').click(function() {
|
||||||
|
var configToggle = $(this).data('id');
|
||||||
|
var toggle = $(this);
|
||||||
|
if ($(this).is(":checked")) {
|
||||||
|
var data = {};
|
||||||
|
data[$(this).data('config-name')] = 1;
|
||||||
|
$.ajax({
|
||||||
|
url: 'set_notification_config',
|
||||||
|
data: data,
|
||||||
|
async: true,
|
||||||
|
success: function(data) {
|
||||||
|
console.log('success');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var data = {};
|
||||||
|
data[$(this).data('config-name')] = 0;
|
||||||
|
$.ajax({
|
||||||
|
url: 'set_notification_config',
|
||||||
|
data: data,
|
||||||
|
async: true,
|
||||||
|
success: function(data) {
|
||||||
|
console.log('success');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
% endif
|
|
@ -5,6 +5,8 @@ from plexpy import notifiers
|
||||||
|
|
||||||
available_notification_agents = notifiers.available_notification_agents()
|
available_notification_agents = notifiers.available_notification_agents()
|
||||||
%>
|
%>
|
||||||
|
<%def name="headIncludes()">
|
||||||
|
</%def>
|
||||||
|
|
||||||
<%def name="headerIncludes()">
|
<%def name="headerIncludes()">
|
||||||
</%def>
|
</%def>
|
||||||
|
@ -79,7 +81,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block">Set your preferred time format. <a href="javascript:void(0)" data-target="#dateTimeOptionsModal" data-toggle="modal">Click here</a> to see the parameter list.</p>
|
<p class="help-block">Set your preferred time format. <a href="javascript:void(0)" data-target="#dateTimeOptionsModal" data-toggle="modal">Click here</a> to see the parameter list.</p>
|
||||||
</div>
|
</div>
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-2">
|
<div role="tabpanel" class="tab-pane" id="tabs-2">
|
||||||
<div class="padded-header">
|
<div class="padded-header">
|
||||||
|
@ -127,7 +129,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-3">
|
<div role="tabpanel" class="tab-pane" id="tabs-3">
|
||||||
|
|
||||||
|
@ -179,7 +181,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
<p class="help-block">Current API key: <strong><br/>${config['api_key']}</strong></p>
|
<p class="help-block">Current API key: <strong><br/>${config['api_key']}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-4">
|
<div role="tabpanel" class="tab-pane" id="tabs-4">
|
||||||
|
|
||||||
|
@ -260,7 +262,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
<p class="help-block">Refresh the user list when PlexPy starts.</p>
|
<p class="help-block">Refresh the user list when PlexPy starts.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-6">
|
<div role="tabpanel" class="tab-pane" id="tabs-6">
|
||||||
<div class="padded-header">
|
<div class="padded-header">
|
||||||
|
@ -304,7 +306,7 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block"><a href="javascript:void(0)" id="toggle-plexwatch-import-modal" data-target="#plexwatch-import-modal" data-toggle="modal">Click here to Import an existing Plexwatch database.</a></p>
|
<p class="help-block"><a href="javascript:void(0)" id="toggle-plexwatch-import-modal" data-target="#plexwatch-import-modal" data-toggle="modal">Click here to Import an existing Plexwatch database.</a></p>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-7">
|
<div role="tabpanel" class="tab-pane" id="tabs-7">
|
||||||
|
|
||||||
|
@ -359,7 +361,30 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<div class="padded-header">
|
||||||
|
<h3>Buffer Warnings</h3>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">Note: Buffer warnings only work on certain Plex clients. Android and PlexWeb do not report buffer events accurately or at all.</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="buffer_threshold">Buffer Threshold</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<input type="text" class="form-control" data-parsley-type="integer" id="buffer_threshold" name="buffer_threshold" value="${config['buffer_threshold']}" data-parsley-range="[1,50]" data-parsley-trigger="change" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">How many buffer events should we wait before triggering the first warning. Buffer events increment on each monitor ping if play state is buffering.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="buffer_wait">Buffer Wait</label>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-2">
|
||||||
|
<input type="text" class="form-control" data-parsley-type="integer" id="buffer_wait" name="buffer_wait" value="${config['buffer_wait']}" data-parsley-min="0" data-parsley-trigger="change" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="help-block">The value (in seconds) PlexPy should wait before triggering the next buffer warning. 0 to always trigger.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-8">
|
<div role="tabpanel" class="tab-pane" id="tabs-8">
|
||||||
|
|
||||||
|
@ -438,6 +463,40 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="link"><i class="fa fa-pause"></i>Playback Pause<i class="fa fa-chevron-down"></i></div>
|
||||||
|
<ul class="submenu">
|
||||||
|
<li>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_pause_subject_text">Subject Line</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_pause_subject_text" name="notify_on_pause_subject_text" value="${config['notify_on_pause_subject_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom subject line.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_pause_body_text">Message Body</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_pause_body_text" name="notify_on_pause_body_text" value="${config['notify_on_pause_body_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom body.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="link"><i class="fa fa-play"></i>Playback Resume<i class="fa fa-chevron-down"></i></div>
|
||||||
|
<ul class="submenu">
|
||||||
|
<li>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_resume_subject_text">Subject Line</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_resume_subject_text" name="notify_on_resume_subject_text" value="${config['notify_on_resume_subject_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom subject line.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_resume_body_text">Message Body</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_resume_body_text" name="notify_on_resume_body_text" value="${config['notify_on_resume_body_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom body.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="link"><i class="fa fa-eye"></i>Watched<i class="fa fa-chevron-down"></i></div>
|
<div class="link"><i class="fa fa-eye"></i>Watched<i class="fa fa-chevron-down"></i></div>
|
||||||
<ul class="submenu">
|
<ul class="submenu">
|
||||||
|
@ -455,9 +514,26 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="link"><i class="fa fa-spinner"></i>Buffer Warnings<i class="fa fa-chevron-down"></i></div>
|
||||||
|
<ul class="submenu">
|
||||||
|
<li>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_buffer_subject_text">Subject Line</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_buffer_subject_text" name="notify_on_buffer_subject_text" value="${config['notify_on_buffer_subject_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom subject line.</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="notify_on_buffer_body_text">Message Body</label>
|
||||||
|
<input class="form-control" type="text" id="notify_on_buffer_body_text" name="notify_on_buffer_body_text" value="${config['notify_on_buffer_body_text']}" data-parsley-trigger="change" required>
|
||||||
|
<p class="help-block">Set a custom body.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully">
|
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="tabs-9">
|
<div role="tabpanel" class="tab-pane" id="tabs-9">
|
||||||
|
|
||||||
|
@ -465,18 +541,18 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
<h3>Notification Agents</h3>
|
<h3>Notification Agents</h3>
|
||||||
</div>
|
</div>
|
||||||
<p class="help-block">
|
<p class="help-block">
|
||||||
Toggle the desired notification option and configure it by selecting the settings icon to the right.
|
Toggle the desired notification options by clicking the bolt icon and configure it by selecting the settings icon to the right.
|
||||||
Watched notifications are only applicable for video items.
|
|
||||||
</p>
|
</p>
|
||||||
<br/>
|
<br/>
|
||||||
<ul class="stacked-configs list-unstyled">
|
<ul class="stacked-configs list-unstyled">
|
||||||
% for agent in available_notification_agents:
|
% for agent in available_notification_agents:
|
||||||
<li>
|
<li>
|
||||||
<span>
|
<span>
|
||||||
<!--<input type="checkbox" name="${agent['config_prefix']}_enabled" id="${agent['config_prefix']}" value="1" ${agent['state']}> ${agent['name']}-->
|
% if agent['on_play'] or agent['on_stop'] or agent['on_pause'] or agent['on_resume'] or agent['on_buffer'] or agent['on_watched']:
|
||||||
<a class="toggle-left notify-toggle-icon" href="javascript:void(0)" data-toggle="tooltip" data-placement="top" title data-title="Notify on playback start" data-id="${agent['id']}" data-config-name="${agent['config_prefix']}_on_play" data-config-value="${agent['on_play']}"><i class="fa fa-play"></i></a>
|
<a href="javascript:void(0)" data-target="#notification-triggers-modal" data-id="${agent['id']}" class="toggle-notification-triggers-modal toggle-left active" data-toggle="modal"><i class="fa fa-lg fa-flash"></i></a>
|
||||||
<a class="toggle-left notify-toggle-icon" href="javascript:void(0)" data-toggle="tooltip" data-placement="top" title data-title="Notify on stop" data-id="${agent['id']}" data-config-name="${agent['config_prefix']}_on_stop" data-config-value="${agent['on_stop']}"><i class="fa fa-stop"></i></a>
|
% else:
|
||||||
<a class="toggle-left notify-toggle-icon" href="javascript:void(0)" data-toggle="tooltip" data-placement="top" title data-title="Notify on watched" data-id="${agent['id']}" data-config-name="${agent['config_prefix']}_on_watched" data-config-value="${agent['on_watched']}"><i class="fa fa-eye"></i></a>
|
<a href="javascript:void(0)" data-target="#notification-triggers-modal" data-id="${agent['id']}" class="toggle-notification-triggers-modal toggle-left" data-toggle="modal"><i class="fa fa-lg fa-flash"></i></a>
|
||||||
|
% endif
|
||||||
${agent['name']}
|
${agent['name']}
|
||||||
% if agent['has_config']:
|
% if agent['has_config']:
|
||||||
<a href="javascript:void(0)" rel="tooltip" data-target="#notification-config-modal" data-placement="top" title data-title="Open configuration" data-id="${agent['id']}" class="toggle-notification-config-modal toggle-right" data-toggle="modal"><i class="fa fa-lg fa-cog"></i></a>
|
<a href="javascript:void(0)" rel="tooltip" data-target="#notification-config-modal" data-placement="top" title data-title="Open configuration" data-id="${agent['id']}" class="toggle-notification-config-modal toggle-right" data-toggle="modal"><i class="fa fa-lg fa-cog"></i></a>
|
||||||
|
@ -661,7 +737,8 @@ available_notification_agents = notifiers.available_notification_agents()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="plexwatch-import-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="plexwatch-import-modal"></div>
|
<div id="plexwatch-import-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="plexwatch-import-modal"></div>
|
||||||
<div id="notification-config-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notification-setting-modal"></div>
|
<div id="notification-config-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notification-config-modal"></div>
|
||||||
|
<div id="notification-triggers-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notification-triggers-modal"></div>
|
||||||
<div id="notify-text-sub-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notify-text-sub-modal">
|
<div id="notify-text-sub-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="notify-text-sub-modal">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
|
@ -977,7 +1054,7 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load PlexWatch import modal
|
// Load notification agent config modal
|
||||||
$(".toggle-notification-config-modal").click(function() {
|
$(".toggle-notification-config-modal").click(function() {
|
||||||
var configId = $(this).data('id');
|
var configId = $(this).data('id');
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -991,100 +1068,18 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.notify-toggle-icon').tooltip();
|
// Load notification triggers config modal
|
||||||
|
$(".toggle-notification-triggers-modal").click(function() {
|
||||||
$('.notify-toggle-icon').each(function() {
|
var configId = $(this).data('id');
|
||||||
if ($(this).data('config-value') == 1) {
|
$.ajax({
|
||||||
$(this).addClass("active");
|
url: 'get_notification_agent_triggers',
|
||||||
}
|
data: { config_id: configId },
|
||||||
});
|
cache: false,
|
||||||
|
async: true,
|
||||||
$('.notify-toggle-icon').click(function() {
|
complete: function(xhr, status) {
|
||||||
var configToggle = $(this).data('id');
|
$("#notification-triggers-modal").html(xhr.responseText);
|
||||||
var toggle = $(this);
|
|
||||||
if ($(this).hasClass("active")) {
|
|
||||||
var data = {};
|
|
||||||
data[$(this).data('config-name')] = 0;
|
|
||||||
$.ajax({
|
|
||||||
url: 'set_notification_config',
|
|
||||||
data: data,
|
|
||||||
async: true,
|
|
||||||
success: function(data) {
|
|
||||||
toggle.removeClass("active");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var data = {};
|
|
||||||
data[$(this).data('config-name')] = 1;
|
|
||||||
$.ajax({
|
|
||||||
url: 'set_notification_config',
|
|
||||||
data: data,
|
|
||||||
async: true,
|
|
||||||
success: function(data) {
|
|
||||||
toggle.addClass("active");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($("#tv_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#tv_notify_options").show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#tv_notify_options").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#tv_notify_enable").click(function(){
|
|
||||||
if ($("#tv_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#tv_notify_options").slideDown();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#tv_notify_options").slideUp();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($("#movie_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#movie_notify_options").show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#movie_notify_options").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#movie_notify_enable").click(function(){
|
|
||||||
if ($("#movie_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#movie_notify_options").slideDown();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#movie_notify_options").slideUp();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($("#music_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#music_notify_options").show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#music_notify_options").hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#music_notify_enable").click(function(){
|
|
||||||
if ($("#music_notify_enable").is(":checked"))
|
|
||||||
{
|
|
||||||
$("#music_notify_options").slideDown();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$("#music_notify_options").slideUp();
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#osxnotifyregister').click(function () {
|
$('#osxnotifyregister').click(function () {
|
||||||
|
|
|
@ -348,7 +348,8 @@ def dbcheck():
|
||||||
'bitrate INTEGER, video_resolution TEXT, video_framerate TEXT, aspect_ratio TEXT, '
|
'bitrate INTEGER, video_resolution TEXT, video_framerate TEXT, aspect_ratio TEXT, '
|
||||||
'audio_channels INTEGER, transcode_protocol TEXT, transcode_container TEXT, '
|
'audio_channels INTEGER, transcode_protocol TEXT, transcode_container TEXT, '
|
||||||
'transcode_video_codec TEXT, transcode_audio_codec TEXT, transcode_audio_channels INTEGER,'
|
'transcode_video_codec TEXT, transcode_audio_codec TEXT, transcode_audio_channels INTEGER,'
|
||||||
'transcode_width INTEGER, transcode_height INTEGER)'
|
'transcode_width INTEGER, transcode_height INTEGER, buffer_count INTEGER DEFAULT 0, '
|
||||||
|
'buffer_last_triggered INTEGER)'
|
||||||
)
|
)
|
||||||
|
|
||||||
# session_history table :: This is a history table which logs essential stream details
|
# session_history table :: This is a history table which logs essential stream details
|
||||||
|
@ -529,7 +530,8 @@ def dbcheck():
|
||||||
c_db.execute(
|
c_db.execute(
|
||||||
'CREATE TABLE IF NOT EXISTS notify_log (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
'CREATE TABLE IF NOT EXISTS notify_log (id INTEGER PRIMARY KEY AUTOINCREMENT, '
|
||||||
'session_key INTEGER, rating_key INTEGER, user_id INTEGER, user TEXT, '
|
'session_key INTEGER, rating_key INTEGER, user_id INTEGER, user TEXT, '
|
||||||
'agent_id INTEGER, agent_name TEXT, on_play INTEGER, on_stop INTEGER, on_watched INTEGER)'
|
'agent_id INTEGER, agent_name TEXT, on_play INTEGER, on_stop INTEGER, on_watched INTEGER, '
|
||||||
|
'on_pause INTEGER, on_resume INTEGER, on_buffer INTEGER)'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Upgrade sessions table from earlier versions
|
# Upgrade sessions table from earlier versions
|
||||||
|
@ -550,6 +552,33 @@ def dbcheck():
|
||||||
'ALTER TABLE users ADD COLUMN keep_history INTEGER DEFAULT 1'
|
'ALTER TABLE users ADD COLUMN keep_history INTEGER DEFAULT 1'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Upgrade sessions table from earlier versions
|
||||||
|
try:
|
||||||
|
c_db.execute('SELECT on_pause from notify_log')
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
logger.debug(u"Altering database. Updating database table sessions.")
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notify_log ADD COLUMN on_pause INTEGER'
|
||||||
|
)
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notify_log ADD COLUMN on_resume INTEGER'
|
||||||
|
)
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE notify_log ADD COLUMN on_buffer INTEGER'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Upgrade sessions table from earlier versions
|
||||||
|
try:
|
||||||
|
c_db.execute('SELECT buffer_count from sessions')
|
||||||
|
except sqlite3.OperationalError:
|
||||||
|
logger.debug(u"Altering database. Updating database table sessions.")
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE sessions ADD COLUMN buffer_count INTEGER DEFAULT 0'
|
||||||
|
)
|
||||||
|
c_db.execute(
|
||||||
|
'ALTER TABLE sessions ADD COLUMN buffer_last_triggered INTEGER'
|
||||||
|
)
|
||||||
|
|
||||||
conn_db.commit()
|
conn_db.commit()
|
||||||
c_db.close()
|
c_db.close()
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,12 @@ _CONFIG_DEFINITIONS = {
|
||||||
'BOXCAR_TOKEN': (str, 'Boxcar', ''),
|
'BOXCAR_TOKEN': (str, 'Boxcar', ''),
|
||||||
'BOXCAR_ON_PLAY': (int, 'Boxcar', 0),
|
'BOXCAR_ON_PLAY': (int, 'Boxcar', 0),
|
||||||
'BOXCAR_ON_STOP': (int, 'Boxcar', 0),
|
'BOXCAR_ON_STOP': (int, 'Boxcar', 0),
|
||||||
|
'BOXCAR_ON_PAUSE': (int, 'Boxcar', 0),
|
||||||
|
'BOXCAR_ON_RESUME': (int, 'Boxcar', 0),
|
||||||
|
'BOXCAR_ON_BUFFER': (int, 'Boxcar', 0),
|
||||||
'BOXCAR_ON_WATCHED': (int, 'Boxcar', 0),
|
'BOXCAR_ON_WATCHED': (int, 'Boxcar', 0),
|
||||||
|
'BUFFER_THRESHOLD': (int, 'Monitoring', 3),
|
||||||
|
'BUFFER_WAIT': (int, 'Monitoring', 900),
|
||||||
'CACHE_DIR': (str, 'General', ''),
|
'CACHE_DIR': (str, 'General', ''),
|
||||||
'CACHE_SIZEMB': (int, 'Advanced', 32),
|
'CACHE_SIZEMB': (int, 'Advanced', 32),
|
||||||
'CHECK_GITHUB': (int, 'General', 1),
|
'CHECK_GITHUB': (int, 'General', 1),
|
||||||
|
@ -58,6 +63,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'EMAIL_TLS': (int, 'Email', 0),
|
'EMAIL_TLS': (int, 'Email', 0),
|
||||||
'EMAIL_ON_PLAY': (int, 'Email', 0),
|
'EMAIL_ON_PLAY': (int, 'Email', 0),
|
||||||
'EMAIL_ON_STOP': (int, 'Email', 0),
|
'EMAIL_ON_STOP': (int, 'Email', 0),
|
||||||
|
'EMAIL_ON_PAUSE': (int, 'Email', 0),
|
||||||
|
'EMAIL_ON_RESUME': (int, 'Email', 0),
|
||||||
|
'EMAIL_ON_BUFFER': (int, 'Email', 0),
|
||||||
'EMAIL_ON_WATCHED': (int, 'Email', 0),
|
'EMAIL_ON_WATCHED': (int, 'Email', 0),
|
||||||
'ENABLE_HTTPS': (int, 'General', 0),
|
'ENABLE_HTTPS': (int, 'General', 0),
|
||||||
'FIRST_RUN_COMPLETE': (int, 'General', 0),
|
'FIRST_RUN_COMPLETE': (int, 'General', 0),
|
||||||
|
@ -70,6 +78,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'GROWL_PASSWORD': (str, 'Growl', ''),
|
'GROWL_PASSWORD': (str, 'Growl', ''),
|
||||||
'GROWL_ON_PLAY': (int, 'Growl', 0),
|
'GROWL_ON_PLAY': (int, 'Growl', 0),
|
||||||
'GROWL_ON_STOP': (int, 'Growl', 0),
|
'GROWL_ON_STOP': (int, 'Growl', 0),
|
||||||
|
'GROWL_ON_PAUSE': (int, 'Growl', 0),
|
||||||
|
'GROWL_ON_RESUME': (int, 'Growl', 0),
|
||||||
|
'GROWL_ON_BUFFER': (int, 'Growl', 0),
|
||||||
'GROWL_ON_WATCHED': (int, 'Growl', 0),
|
'GROWL_ON_WATCHED': (int, 'Growl', 0),
|
||||||
'HOME_STATS_LENGTH': (int, 'General', 30),
|
'HOME_STATS_LENGTH': (int, 'General', 30),
|
||||||
'HTTPS_CERT': (str, 'General', ''),
|
'HTTPS_CERT': (str, 'General', ''),
|
||||||
|
@ -101,18 +112,30 @@ _CONFIG_DEFINITIONS = {
|
||||||
'NMA_PRIORITY': (int, 'NMA', 0),
|
'NMA_PRIORITY': (int, 'NMA', 0),
|
||||||
'NMA_ON_PLAY': (int, 'NMA', 0),
|
'NMA_ON_PLAY': (int, 'NMA', 0),
|
||||||
'NMA_ON_STOP': (int, 'NMA', 0),
|
'NMA_ON_STOP': (int, 'NMA', 0),
|
||||||
|
'NMA_ON_PAUSE': (int, 'NMA', 0),
|
||||||
|
'NMA_ON_RESUME': (int, 'NMA', 0),
|
||||||
|
'NMA_ON_BUFFER': (int, 'NMA', 0),
|
||||||
'NMA_ON_WATCHED': (int, 'NMA', 0),
|
'NMA_ON_WATCHED': (int, 'NMA', 0),
|
||||||
'NOTIFY_WATCHED_PERCENT': (int, 'Monitoring', 85),
|
'NOTIFY_WATCHED_PERCENT': (int, 'Monitoring', 85),
|
||||||
'NOTIFY_ON_START_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
'NOTIFY_ON_START_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
'NOTIFY_ON_START_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) started playing {title}.'),
|
'NOTIFY_ON_START_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) started playing {title}.'),
|
||||||
'NOTIFY_ON_STOP_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
'NOTIFY_ON_STOP_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
'NOTIFY_ON_STOP_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has stopped {title}.'),
|
'NOTIFY_ON_STOP_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has stopped {title}.'),
|
||||||
|
'NOTIFY_ON_PAUSE_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
|
'NOTIFY_ON_PAUSE_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has paused {title}.'),
|
||||||
|
'NOTIFY_ON_RESUME_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
|
'NOTIFY_ON_RESUME_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has resumed {title}.'),
|
||||||
|
'NOTIFY_ON_BUFFER_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
|
'NOTIFY_ON_BUFFER_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) is buffering {title}.'),
|
||||||
'NOTIFY_ON_WATCHED_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
'NOTIFY_ON_WATCHED_SUBJECT_TEXT': (str, 'Monitoring', 'PlexPy ({server_name})'),
|
||||||
'NOTIFY_ON_WATCHED_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has watched {title}.'),
|
'NOTIFY_ON_WATCHED_BODY_TEXT': (str, 'Monitoring', '{user} ({player}) has watched {title}.'),
|
||||||
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'),
|
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'),
|
||||||
'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0),
|
'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0),
|
||||||
'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0),
|
'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0),
|
||||||
'OSX_NOTIFY_ON_STOP': (int, 'OSX_Notify', 0),
|
'OSX_NOTIFY_ON_STOP': (int, 'OSX_Notify', 0),
|
||||||
|
'OSX_NOTIFY_ON_PAUSE': (int, 'OSX_Notify', 0),
|
||||||
|
'OSX_NOTIFY_ON_RESUME': (int, 'OSX_Notify', 0),
|
||||||
|
'OSX_NOTIFY_ON_BUFFER': (int, 'OSX_Notify', 0),
|
||||||
'OSX_NOTIFY_ON_WATCHED': (int, 'OSX_Notify', 0),
|
'OSX_NOTIFY_ON_WATCHED': (int, 'OSX_Notify', 0),
|
||||||
'PLEX_CLIENT_HOST': (str, 'Plex', ''),
|
'PLEX_CLIENT_HOST': (str, 'Plex', ''),
|
||||||
'PLEX_ENABLED': (int, 'Plex', 0),
|
'PLEX_ENABLED': (int, 'Plex', 0),
|
||||||
|
@ -120,17 +143,26 @@ _CONFIG_DEFINITIONS = {
|
||||||
'PLEX_USERNAME': (str, 'Plex', ''),
|
'PLEX_USERNAME': (str, 'Plex', ''),
|
||||||
'PLEX_ON_PLAY': (int, 'Plex', 0),
|
'PLEX_ON_PLAY': (int, 'Plex', 0),
|
||||||
'PLEX_ON_STOP': (int, 'Plex', 0),
|
'PLEX_ON_STOP': (int, 'Plex', 0),
|
||||||
|
'PLEX_ON_PAUSE': (int, 'Plex', 0),
|
||||||
|
'PLEX_ON_RESUME': (int, 'Plex', 0),
|
||||||
|
'PLEX_ON_BUFFER': (int, 'Plex', 0),
|
||||||
'PLEX_ON_WATCHED': (int, 'Plex', 0),
|
'PLEX_ON_WATCHED': (int, 'Plex', 0),
|
||||||
'PROWL_ENABLED': (int, 'Prowl', 0),
|
'PROWL_ENABLED': (int, 'Prowl', 0),
|
||||||
'PROWL_KEYS': (str, 'Prowl', ''),
|
'PROWL_KEYS': (str, 'Prowl', ''),
|
||||||
'PROWL_PRIORITY': (int, 'Prowl', 0),
|
'PROWL_PRIORITY': (int, 'Prowl', 0),
|
||||||
'PROWL_ON_PLAY': (int, 'Prowl', 0),
|
'PROWL_ON_PLAY': (int, 'Prowl', 0),
|
||||||
'PROWL_ON_STOP': (int, 'Prowl', 0),
|
'PROWL_ON_STOP': (int, 'Prowl', 0),
|
||||||
|
'PROWL_ON_PAUSE': (int, 'Prowl', 0),
|
||||||
|
'PROWL_ON_RESUME': (int, 'Prowl', 0),
|
||||||
|
'PROWL_ON_BUFFER': (int, 'Prowl', 0),
|
||||||
'PROWL_ON_WATCHED': (int, 'Prowl', 0),
|
'PROWL_ON_WATCHED': (int, 'Prowl', 0),
|
||||||
'PUSHALOT_APIKEY': (str, 'Pushalot', ''),
|
'PUSHALOT_APIKEY': (str, 'Pushalot', ''),
|
||||||
'PUSHALOT_ENABLED': (int, 'Pushalot', 0),
|
'PUSHALOT_ENABLED': (int, 'Pushalot', 0),
|
||||||
'PUSHALOT_ON_PLAY': (int, 'Pushalot', 0),
|
'PUSHALOT_ON_PLAY': (int, 'Pushalot', 0),
|
||||||
'PUSHALOT_ON_STOP': (int, 'Pushalot', 0),
|
'PUSHALOT_ON_STOP': (int, 'Pushalot', 0),
|
||||||
|
'PUSHALOT_ON_PAUSE': (int, 'Pushalot', 0),
|
||||||
|
'PUSHALOT_ON_RESUME': (int, 'Pushalot', 0),
|
||||||
|
'PUSHALOT_ON_BUFFER': (int, 'Pushalot', 0),
|
||||||
'PUSHALOT_ON_WATCHED': (int, 'Pushalot', 0),
|
'PUSHALOT_ON_WATCHED': (int, 'Pushalot', 0),
|
||||||
'PUSHBULLET_APIKEY': (str, 'PushBullet', ''),
|
'PUSHBULLET_APIKEY': (str, 'PushBullet', ''),
|
||||||
'PUSHBULLET_DEVICEID': (str, 'PushBullet', ''),
|
'PUSHBULLET_DEVICEID': (str, 'PushBullet', ''),
|
||||||
|
@ -138,6 +170,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'PUSHBULLET_ENABLED': (int, 'PushBullet', 0),
|
'PUSHBULLET_ENABLED': (int, 'PushBullet', 0),
|
||||||
'PUSHBULLET_ON_PLAY': (int, 'PushBullet', 0),
|
'PUSHBULLET_ON_PLAY': (int, 'PushBullet', 0),
|
||||||
'PUSHBULLET_ON_STOP': (int, 'PushBullet', 0),
|
'PUSHBULLET_ON_STOP': (int, 'PushBullet', 0),
|
||||||
|
'PUSHBULLET_ON_PAUSE': (int, 'PushBullet', 0),
|
||||||
|
'PUSHBULLET_ON_RESUME': (int, 'PushBullet', 0),
|
||||||
|
'PUSHBULLET_ON_BUFFER': (int, 'PushBullet', 0),
|
||||||
'PUSHBULLET_ON_WATCHED': (int, 'PushBullet', 0),
|
'PUSHBULLET_ON_WATCHED': (int, 'PushBullet', 0),
|
||||||
'PUSHOVER_APITOKEN': (str, 'Pushover', ''),
|
'PUSHOVER_APITOKEN': (str, 'Pushover', ''),
|
||||||
'PUSHOVER_ENABLED': (int, 'Pushover', 0),
|
'PUSHOVER_ENABLED': (int, 'Pushover', 0),
|
||||||
|
@ -145,6 +180,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'PUSHOVER_PRIORITY': (int, 'Pushover', 0),
|
'PUSHOVER_PRIORITY': (int, 'Pushover', 0),
|
||||||
'PUSHOVER_ON_PLAY': (int, 'Pushover', 0),
|
'PUSHOVER_ON_PLAY': (int, 'Pushover', 0),
|
||||||
'PUSHOVER_ON_STOP': (int, 'Pushover', 0),
|
'PUSHOVER_ON_STOP': (int, 'Pushover', 0),
|
||||||
|
'PUSHOVER_ON_PAUSE': (int, 'Pushover', 0),
|
||||||
|
'PUSHOVER_ON_RESUME': (int, 'Pushover', 0),
|
||||||
|
'PUSHOVER_ON_BUFFER': (int, 'Pushover', 0),
|
||||||
'PUSHOVER_ON_WATCHED': (int, 'Pushover', 0),
|
'PUSHOVER_ON_WATCHED': (int, 'Pushover', 0),
|
||||||
'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12),
|
'REFRESH_USERS_INTERVAL': (int, 'Monitoring', 12),
|
||||||
'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1),
|
'REFRESH_USERS_ON_STARTUP': (int, 'Monitoring', 1),
|
||||||
|
@ -165,6 +203,9 @@ _CONFIG_DEFINITIONS = {
|
||||||
'XBMC_USERNAME': (str, 'XBMC', ''),
|
'XBMC_USERNAME': (str, 'XBMC', ''),
|
||||||
'XBMC_ON_PLAY': (int, 'XBMC', 0),
|
'XBMC_ON_PLAY': (int, 'XBMC', 0),
|
||||||
'XBMC_ON_STOP': (int, 'XBMC', 0),
|
'XBMC_ON_STOP': (int, 'XBMC', 0),
|
||||||
|
'XBMC_ON_PAUSE': (int, 'XBMC', 0),
|
||||||
|
'XBMC_ON_RESUME': (int, 'XBMC', 0),
|
||||||
|
'XBMC_ON_BUFFER': (int, 'XBMC', 0),
|
||||||
'XBMC_ON_WATCHED': (int, 'XBMC', 0)
|
'XBMC_ON_WATCHED': (int, 'XBMC', 0)
|
||||||
}
|
}
|
||||||
# pylint:disable=R0902
|
# pylint:disable=R0902
|
||||||
|
|
|
@ -59,6 +59,11 @@ def check_active_sessions():
|
||||||
# Push it on it's own thread so we don't hold up our db actions
|
# Push it on it's own thread so we don't hold up our db actions
|
||||||
threading.Thread(target=notification_handler.notify,
|
threading.Thread(target=notification_handler.notify,
|
||||||
kwargs=dict(stream_data=stream, notify_action='pause')).start()
|
kwargs=dict(stream_data=stream, notify_action='pause')).start()
|
||||||
|
if session['state'] == 'playing' and stream['state'] == 'paused':
|
||||||
|
# Push any notifications -
|
||||||
|
# Push it on it's own thread so we don't hold up our db actions
|
||||||
|
threading.Thread(target=notification_handler.notify,
|
||||||
|
kwargs=dict(stream_data=stream, notify_action='resume')).start()
|
||||||
if stream['state'] == 'paused':
|
if stream['state'] == 'paused':
|
||||||
# The stream is still paused so we need to increment the paused_counter
|
# The stream is still paused so we need to increment the paused_counter
|
||||||
# Using the set config parameter as the interval, probably not the most accurate but
|
# Using the set config parameter as the interval, probably not the most accurate but
|
||||||
|
@ -67,6 +72,47 @@ def check_active_sessions():
|
||||||
monitor_db.action('UPDATE sessions SET paused_counter = ? '
|
monitor_db.action('UPDATE sessions SET paused_counter = ? '
|
||||||
'WHERE session_key = ? AND rating_key = ?',
|
'WHERE session_key = ? AND rating_key = ?',
|
||||||
[paused_counter, stream['session_key'], stream['rating_key']])
|
[paused_counter, stream['session_key'], stream['rating_key']])
|
||||||
|
if session['state'] == 'buffering':
|
||||||
|
# The stream is buffering so we need to increment the buffer_count
|
||||||
|
# We're going just increment on every monitor ping,
|
||||||
|
# would be difficult to keep track otherwise
|
||||||
|
monitor_db.action('UPDATE sessions SET buffer_count = buffer_count + 1 '
|
||||||
|
'WHERE session_key = ? AND rating_key = ?',
|
||||||
|
[stream['session_key'], stream['rating_key']])
|
||||||
|
|
||||||
|
# Check the current buffer count and last buffer to determine if we should notify
|
||||||
|
buffer_values = monitor_db.select('SELECT buffer_count, buffer_last_triggered '
|
||||||
|
'FROM sessions '
|
||||||
|
'WHERE session_key = ? AND rating_key = ?',
|
||||||
|
[stream['session_key'], stream['rating_key']])
|
||||||
|
|
||||||
|
if buffer_values[0]['buffer_count'] >= plexpy.CONFIG.BUFFER_THRESHOLD:
|
||||||
|
# Push any notifications -
|
||||||
|
# Push it on it's own thread so we don't hold up our db actions
|
||||||
|
# Our first buffer notification
|
||||||
|
if buffer_values[0]['buffer_count'] == plexpy.CONFIG.BUFFER_THRESHOLD:
|
||||||
|
logger.info(u"PlexPy Monitor :: User '%s' has triggered a buffer warning."
|
||||||
|
% stream['user'])
|
||||||
|
# Set the buffer trigger time
|
||||||
|
monitor_db.action('UPDATE sessions '
|
||||||
|
'SET buffer_last_triggered = strftime("%s","now") '
|
||||||
|
'WHERE session_key = ? AND rating_key = ?',
|
||||||
|
[stream['session_key'], stream['rating_key']])
|
||||||
|
|
||||||
|
threading.Thread(target=notification_handler.notify,
|
||||||
|
kwargs=dict(stream_data=stream, notify_action='buffer')).start()
|
||||||
|
else:
|
||||||
|
# Subsequent buffer notifications after wait time
|
||||||
|
if int(time.time()) > buffer_values[0]['buffer_last_triggered'] + \
|
||||||
|
plexpy.CONFIG.BUFFER_WAIT:
|
||||||
|
logger.info(u"PlexPy Monitor :: User '%s' has triggered multiple buffer warnings."
|
||||||
|
% stream['user'])
|
||||||
|
threading.Thread(target=notification_handler.notify,
|
||||||
|
kwargs=dict(stream_data=stream, notify_action='buffer')).start()
|
||||||
|
|
||||||
|
logger.debug(u"PlexPy Monitor :: Stream buffering. Count is now %s. Last triggered %s."
|
||||||
|
% (buffer_values[0][0], buffer_values[0][1]))
|
||||||
|
|
||||||
# Check if the user has reached the offset in the media we defined as the "watched" percent
|
# Check if the user has reached the offset in the media we defined as the "watched" percent
|
||||||
# Don't trigger if state is buffer as some clients push the progress to the end when
|
# Don't trigger if state is buffer as some clients push the progress to the end when
|
||||||
# buffering on start.
|
# buffering on start.
|
||||||
|
|
|
@ -52,6 +52,33 @@ def notify(stream_data=None, notify_action=None):
|
||||||
|
|
||||||
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_pause'] and notify_action == 'pause':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
|
||||||
|
set_notify_state(session=stream_data, state='pause', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_resume'] and notify_action == 'resume':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
|
||||||
|
set_notify_state(session=stream_data, state='resume', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_buffer'] and notify_action == 'buffer':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
|
||||||
|
set_notify_state(session=stream_data, state='buffer', agent_info=agent)
|
||||||
|
|
||||||
elif agent['on_watched'] and notify_action == 'watched':
|
elif agent['on_watched'] and notify_action == 'watched':
|
||||||
# Get the current states for notifications from our db
|
# Get the current states for notifications from our db
|
||||||
notify_states = get_notify_state(session=stream_data)
|
notify_states = get_notify_state(session=stream_data)
|
||||||
|
@ -100,6 +127,33 @@ def notify(stream_data=None, notify_action=None):
|
||||||
# Set the notification state in the db
|
# Set the notification state in the db
|
||||||
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
set_notify_state(session=stream_data, state='stop', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_pause'] and notify_action == 'pause':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
# Set the notification state in the db
|
||||||
|
set_notify_state(session=stream_data, state='pause', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_resume'] and notify_action == 'resume':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
# Set the notification state in the db
|
||||||
|
set_notify_state(session=stream_data, state='resume', agent_info=agent)
|
||||||
|
|
||||||
|
elif agent['on_buffer'] and notify_action == 'buffer':
|
||||||
|
# Build and send notification
|
||||||
|
notify_strings = build_notify_text(session=stream_data, state=notify_action)
|
||||||
|
notifiers.send_notification(config_id=agent['id'],
|
||||||
|
subject=notify_strings[0],
|
||||||
|
body=notify_strings[1])
|
||||||
|
# Set the notification state in the db
|
||||||
|
set_notify_state(session=stream_data, state='buffer', agent_info=agent)
|
||||||
|
|
||||||
elif stream_data['media_type'] == 'clip':
|
elif stream_data['media_type'] == 'clip':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@ -110,7 +164,7 @@ def notify(stream_data=None, notify_action=None):
|
||||||
|
|
||||||
def get_notify_state(session):
|
def get_notify_state(session):
|
||||||
monitor_db = database.MonitorDatabase()
|
monitor_db = database.MonitorDatabase()
|
||||||
result = monitor_db.select('SELECT on_play, on_stop, on_watched, agent_id '
|
result = monitor_db.select('SELECT on_play, on_stop, on_pause, on_resume, on_buffer, on_watched, agent_id '
|
||||||
'FROM notify_log '
|
'FROM notify_log '
|
||||||
'WHERE session_key = ? '
|
'WHERE session_key = ? '
|
||||||
'AND rating_key = ? '
|
'AND rating_key = ? '
|
||||||
|
@ -121,8 +175,11 @@ def get_notify_state(session):
|
||||||
for item in result:
|
for item in result:
|
||||||
notify_state = {'on_play': item[0],
|
notify_state = {'on_play': item[0],
|
||||||
'on_stop': item[1],
|
'on_stop': item[1],
|
||||||
'on_watched': item[2],
|
'on_pause': item[2],
|
||||||
'agent_id': item[3]}
|
'on_resume': item[3],
|
||||||
|
'on_buffer': item[4],
|
||||||
|
'on_watched': item[5],
|
||||||
|
'agent_id': item[6]}
|
||||||
notify_states.append(notify_state)
|
notify_states.append(notify_state)
|
||||||
|
|
||||||
return notify_states
|
return notify_states
|
||||||
|
@ -136,6 +193,12 @@ def set_notify_state(session, state, agent_info):
|
||||||
values = {'on_play': int(time.time())}
|
values = {'on_play': int(time.time())}
|
||||||
elif state == 'stop':
|
elif state == 'stop':
|
||||||
values = {'on_stop': int(time.time())}
|
values = {'on_stop': int(time.time())}
|
||||||
|
elif state == 'pause':
|
||||||
|
values = {'on_pause': int(time.time())}
|
||||||
|
elif state == 'resume':
|
||||||
|
values = {'on_resume': int(time.time())}
|
||||||
|
elif state == 'buffer':
|
||||||
|
values = {'on_buffer': int(time.time())}
|
||||||
elif state == 'watched':
|
elif state == 'watched':
|
||||||
values = {'on_watched': int(time.time())}
|
values = {'on_watched': int(time.time())}
|
||||||
else:
|
else:
|
||||||
|
@ -173,34 +236,28 @@ def build_notify_text(session, state):
|
||||||
if session['media_type'] == 'episode':
|
if session['media_type'] == 'episode':
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
# Regex pattern to remove the text in the tags we don't want
|
||||||
pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>', re.IGNORECASE)
|
pattern = re.compile('<movie>[^>]+.</movie>|<music>[^>]+.</music>', re.IGNORECASE)
|
||||||
|
|
||||||
# Remove the unwanted tags and strip any unmatch tags too.
|
|
||||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
|
||||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
|
||||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
|
||||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
|
||||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
|
||||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
|
||||||
elif session['media_type'] == 'movie':
|
elif session['media_type'] == 'movie':
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
# Regex pattern to remove the text in the tags we don't want
|
||||||
pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>', re.IGNORECASE)
|
pattern = re.compile('<tv>[^>]+.</tv>|<music>[^>]+.</music>', re.IGNORECASE)
|
||||||
|
|
||||||
# Remove the unwanted tags and strip any unmatch tags too.
|
|
||||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
|
||||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
|
||||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
|
||||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
|
||||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
|
||||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
|
||||||
elif session['media_type'] == 'track':
|
elif session['media_type'] == 'track':
|
||||||
# Regex pattern to remove the text in the tags we don't want
|
# Regex pattern to remove the text in the tags we don't want
|
||||||
pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', re.IGNORECASE)
|
pattern = re.compile('<tv>[^>]+.</tv>|<movie>[^>]+.</movie>', re.IGNORECASE)
|
||||||
|
else:
|
||||||
|
pattern = None
|
||||||
|
|
||||||
|
if session['media_type'] == 'episode' or session['media_type'] == 'movie' or session['media_type'] == 'track' \
|
||||||
|
and pattern:
|
||||||
# Remove the unwanted tags and strip any unmatch tags too.
|
# Remove the unwanted tags and strip any unmatch tags too.
|
||||||
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
on_start_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT))
|
||||||
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
on_start_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT))
|
||||||
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
on_stop_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT))
|
||||||
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
on_stop_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT))
|
||||||
|
on_pause_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT))
|
||||||
|
on_pause_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT))
|
||||||
|
on_resume_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT))
|
||||||
|
on_resume_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT))
|
||||||
|
on_buffer_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT))
|
||||||
|
on_buffer_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT))
|
||||||
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
on_watched_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT))
|
||||||
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
|
||||||
else:
|
else:
|
||||||
|
@ -208,6 +265,12 @@ def build_notify_text(session, state):
|
||||||
on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
|
on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
|
||||||
on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
|
on_stop_subject = plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT
|
||||||
on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
|
on_stop_body = plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT
|
||||||
|
on_pause_subject = plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT
|
||||||
|
on_pause_body = plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT
|
||||||
|
on_resume_subject = plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT
|
||||||
|
on_resume_body = plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT
|
||||||
|
on_buffer_subject = plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT
|
||||||
|
on_buffer_body = plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT
|
||||||
on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
|
on_watched_subject = plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT
|
||||||
on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
|
on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
|
||||||
|
|
||||||
|
@ -310,6 +373,78 @@ def build_notify_text(session, state):
|
||||||
except:
|
except:
|
||||||
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||||
|
|
||||||
|
return [subject_text, body_text]
|
||||||
|
else:
|
||||||
|
return [subject_text, body_text]
|
||||||
|
elif state == 'pause':
|
||||||
|
# Default body text
|
||||||
|
body_text = '%s (%s) has paused %s' % (session['friendly_name'],
|
||||||
|
session['player'],
|
||||||
|
full_title)
|
||||||
|
|
||||||
|
if on_pause_subject and on_pause_body:
|
||||||
|
try:
|
||||||
|
subject_text = on_pause_subject.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
body_text = on_pause_body.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||||
|
|
||||||
|
return [subject_text, body_text]
|
||||||
|
else:
|
||||||
|
return [subject_text, body_text]
|
||||||
|
elif state == 'resume':
|
||||||
|
# Default body text
|
||||||
|
body_text = '%s (%s) has resumed %s' % (session['friendly_name'],
|
||||||
|
session['player'],
|
||||||
|
full_title)
|
||||||
|
|
||||||
|
if on_resume_subject and on_resume_body:
|
||||||
|
try:
|
||||||
|
subject_text = on_resume_subject.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
body_text = on_resume_body.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||||
|
|
||||||
|
return [subject_text, body_text]
|
||||||
|
else:
|
||||||
|
return [subject_text, body_text]
|
||||||
|
elif state == 'buffer':
|
||||||
|
# Default body text
|
||||||
|
body_text = '%s (%s) is buffering %s' % (session['friendly_name'],
|
||||||
|
session['player'],
|
||||||
|
full_title)
|
||||||
|
|
||||||
|
if on_buffer_subject and on_buffer_body:
|
||||||
|
try:
|
||||||
|
subject_text = on_buffer_subject.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification subject. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification subject. Using fallback.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
body_text = on_buffer_body.format(**available_params)
|
||||||
|
except LookupError, e:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse field %s in notification body. Using fallback." % e)
|
||||||
|
except:
|
||||||
|
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
|
||||||
|
|
||||||
return [subject_text, body_text]
|
return [subject_text, body_text]
|
||||||
else:
|
else:
|
||||||
return [subject_text, body_text]
|
return [subject_text, body_text]
|
||||||
|
|
|
@ -59,6 +59,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.GROWL_ENABLED),
|
'state': checked(plexpy.CONFIG.GROWL_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.GROWL_ON_PLAY,
|
'on_play': plexpy.CONFIG.GROWL_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.GROWL_ON_STOP,
|
'on_stop': plexpy.CONFIG.GROWL_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.GROWL_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.GROWL_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.GROWL_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.GROWL_ON_WATCHED
|
'on_watched': plexpy.CONFIG.GROWL_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Prowl',
|
{'name': 'Prowl',
|
||||||
|
@ -68,6 +71,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.PROWL_ENABLED),
|
'state': checked(plexpy.CONFIG.PROWL_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.PROWL_ON_PLAY,
|
'on_play': plexpy.CONFIG.PROWL_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.PROWL_ON_STOP,
|
'on_stop': plexpy.CONFIG.PROWL_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.PROWL_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.PROWL_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.PROWL_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.PROWL_ON_WATCHED
|
'on_watched': plexpy.CONFIG.PROWL_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'XBMC',
|
{'name': 'XBMC',
|
||||||
|
@ -77,6 +83,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.XBMC_ENABLED),
|
'state': checked(plexpy.CONFIG.XBMC_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.XBMC_ON_PLAY,
|
'on_play': plexpy.CONFIG.XBMC_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.XBMC_ON_STOP,
|
'on_stop': plexpy.CONFIG.XBMC_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.XBMC_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.XBMC_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.XBMC_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.XBMC_ON_WATCHED
|
'on_watched': plexpy.CONFIG.XBMC_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Plex',
|
{'name': 'Plex',
|
||||||
|
@ -86,6 +95,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.PLEX_ENABLED),
|
'state': checked(plexpy.CONFIG.PLEX_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.PLEX_ON_PLAY,
|
'on_play': plexpy.CONFIG.PLEX_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.PLEX_ON_STOP,
|
'on_stop': plexpy.CONFIG.PLEX_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.PLEX_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.PLEX_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.PLEX_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.PLEX_ON_WATCHED
|
'on_watched': plexpy.CONFIG.PLEX_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'NotifyMyAndroid',
|
{'name': 'NotifyMyAndroid',
|
||||||
|
@ -95,6 +107,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.NMA_ENABLED),
|
'state': checked(plexpy.CONFIG.NMA_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.NMA_ON_PLAY,
|
'on_play': plexpy.CONFIG.NMA_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.NMA_ON_STOP,
|
'on_stop': plexpy.CONFIG.NMA_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.NMA_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.NMA_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.NMA_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.NMA_ON_WATCHED
|
'on_watched': plexpy.CONFIG.NMA_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Pushalot',
|
{'name': 'Pushalot',
|
||||||
|
@ -104,6 +119,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.PUSHALOT_ENABLED),
|
'state': checked(plexpy.CONFIG.PUSHALOT_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.PUSHALOT_ON_PLAY,
|
'on_play': plexpy.CONFIG.PUSHALOT_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.PUSHALOT_ON_STOP,
|
'on_stop': plexpy.CONFIG.PUSHALOT_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.PUSHALOT_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.PUSHALOT_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.PUSHALOT_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.PUSHALOT_ON_WATCHED
|
'on_watched': plexpy.CONFIG.PUSHALOT_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Pushbullet',
|
{'name': 'Pushbullet',
|
||||||
|
@ -113,6 +131,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.PUSHBULLET_ENABLED),
|
'state': checked(plexpy.CONFIG.PUSHBULLET_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.PUSHBULLET_ON_PLAY,
|
'on_play': plexpy.CONFIG.PUSHBULLET_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.PUSHBULLET_ON_STOP,
|
'on_stop': plexpy.CONFIG.PUSHBULLET_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.PUSHBULLET_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.PUSHBULLET_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.PUSHBULLET_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.PUSHBULLET_ON_WATCHED
|
'on_watched': plexpy.CONFIG.PUSHBULLET_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Pushover',
|
{'name': 'Pushover',
|
||||||
|
@ -122,6 +143,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.PUSHOVER_ENABLED),
|
'state': checked(plexpy.CONFIG.PUSHOVER_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.PUSHOVER_ON_PLAY,
|
'on_play': plexpy.CONFIG.PUSHOVER_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.PUSHOVER_ON_STOP,
|
'on_stop': plexpy.CONFIG.PUSHOVER_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.PUSHOVER_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.PUSHOVER_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.PUSHOVER_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.PUSHOVER_ON_WATCHED
|
'on_watched': plexpy.CONFIG.PUSHOVER_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'Boxcar2',
|
{'name': 'Boxcar2',
|
||||||
|
@ -131,6 +155,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.BOXCAR_ENABLED),
|
'state': checked(plexpy.CONFIG.BOXCAR_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.BOXCAR_ON_PLAY,
|
'on_play': plexpy.CONFIG.BOXCAR_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.BOXCAR_ON_STOP,
|
'on_stop': plexpy.CONFIG.BOXCAR_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.BOXCAR_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.BOXCAR_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.BOXCAR_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.BOXCAR_ON_WATCHED
|
'on_watched': plexpy.CONFIG.BOXCAR_ON_WATCHED
|
||||||
},
|
},
|
||||||
{'name': 'E-mail',
|
{'name': 'E-mail',
|
||||||
|
@ -140,6 +167,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.EMAIL_ENABLED),
|
'state': checked(plexpy.CONFIG.EMAIL_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.EMAIL_ON_PLAY,
|
'on_play': plexpy.CONFIG.EMAIL_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.EMAIL_ON_STOP,
|
'on_stop': plexpy.CONFIG.EMAIL_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.EMAIL_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.EMAIL_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.EMAIL_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.EMAIL_ON_WATCHED
|
'on_watched': plexpy.CONFIG.EMAIL_ON_WATCHED
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -154,6 +184,9 @@ def available_notification_agents():
|
||||||
'state': checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED),
|
'state': checked(plexpy.CONFIG.OSX_NOTIFY_ENABLED),
|
||||||
'on_play': plexpy.CONFIG.OSX_NOTIFY_ON_PLAY,
|
'on_play': plexpy.CONFIG.OSX_NOTIFY_ON_PLAY,
|
||||||
'on_stop': plexpy.CONFIG.OSX_NOTIFY_ON_STOP,
|
'on_stop': plexpy.CONFIG.OSX_NOTIFY_ON_STOP,
|
||||||
|
'on_pause': plexpy.CONFIG.OSX_NOTIFY_ON_PAUSE,
|
||||||
|
'on_resume': plexpy.CONFIG.OSX_NOTIFY_ON_RESUME,
|
||||||
|
'on_buffer': plexpy.CONFIG.OSX_NOTIFY_ON_BUFFER,
|
||||||
'on_watched': plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED
|
'on_watched': plexpy.CONFIG.OSX_NOTIFY_ON_WATCHED
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -436,9 +436,17 @@ class WebInterface(object):
|
||||||
"notify_on_start_body_text": plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT,
|
"notify_on_start_body_text": plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT,
|
||||||
"notify_on_stop_subject_text": plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT,
|
"notify_on_stop_subject_text": plexpy.CONFIG.NOTIFY_ON_STOP_SUBJECT_TEXT,
|
||||||
"notify_on_stop_body_text": plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT,
|
"notify_on_stop_body_text": plexpy.CONFIG.NOTIFY_ON_STOP_BODY_TEXT,
|
||||||
|
"notify_on_pause_subject_text": plexpy.CONFIG.NOTIFY_ON_PAUSE_SUBJECT_TEXT,
|
||||||
|
"notify_on_pause_body_text": plexpy.CONFIG.NOTIFY_ON_PAUSE_BODY_TEXT,
|
||||||
|
"notify_on_resume_subject_text": plexpy.CONFIG.NOTIFY_ON_RESUME_SUBJECT_TEXT,
|
||||||
|
"notify_on_resume_body_text": plexpy.CONFIG.NOTIFY_ON_RESUME_BODY_TEXT,
|
||||||
|
"notify_on_buffer_subject_text": plexpy.CONFIG.NOTIFY_ON_BUFFER_SUBJECT_TEXT,
|
||||||
|
"notify_on_buffer_body_text": plexpy.CONFIG.NOTIFY_ON_BUFFER_BODY_TEXT,
|
||||||
"notify_on_watched_subject_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT,
|
"notify_on_watched_subject_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_SUBJECT_TEXT,
|
||||||
"notify_on_watched_body_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT,
|
"notify_on_watched_body_text": plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT,
|
||||||
"home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH
|
"home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH,
|
||||||
|
"buffer_threshold": plexpy.CONFIG.BUFFER_THRESHOLD,
|
||||||
|
"buffer_wait": plexpy.CONFIG.BUFFER_WAIT
|
||||||
}
|
}
|
||||||
|
|
||||||
return serve_template(templatename="settings.html", title="Settings", config=config)
|
return serve_template(templatename="settings.html", title="Settings", config=config)
|
||||||
|
@ -1226,3 +1234,19 @@ class WebInterface(object):
|
||||||
|
|
||||||
return serve_template(templatename="notification_config.html", title="Notification Configuration",
|
return serve_template(templatename="notification_config.html", title="Notification Configuration",
|
||||||
data=config, checkboxes=checkboxes)
|
data=config, checkboxes=checkboxes)
|
||||||
|
|
||||||
|
@cherrypy.expose
|
||||||
|
def get_notification_agent_triggers(self, config_id, **kwargs):
|
||||||
|
if config_id.isdigit():
|
||||||
|
agents = notifiers.available_notification_agents()
|
||||||
|
for agent in agents:
|
||||||
|
if int(config_id) == agent['id']:
|
||||||
|
this_agent = agent
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
this_agent = None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return serve_template(templatename="notification_triggers_modal.html", title="Notification Triggers",
|
||||||
|
data=this_agent)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue