Merge pull request #373 from Hellowlol/scripts

Scripts
This commit is contained in:
JonnyWong16 2016-01-12 21:05:26 -08:00
commit e321479712
6 changed files with 595 additions and 130 deletions

View file

@ -48,7 +48,7 @@ from plexpy import helpers
<div class="form-group">
<label for="${item['name']}">${item['label']}</label>
<div class="row">
<div class="col-md-5">
<div class="col-md-8">
<select class="form-control" id="${item['name']}" name="${item['name']}" >
% for key, value in sorted(item['select_options'].iteritems()):
% if key == item['value']:
@ -79,6 +79,41 @@ from plexpy import helpers
<input class="form-control" type="text" id="test_body" name="test_body" value="Test notification">
<p class="help-block">Set a custom body.</p>
</div>
%if agent['name'] == 'Scripts':
<div class="form-group">
<label for="test_script">Script path</label>
<select class="form-control" id="test_script" name="test_script" >
% for key, value in sorted(data[1]['select_options'].iteritems()):
<option value="${key}">${value}</option>
% endfor
</select>
<p class="help-block">Pick your script</p>
</div>
<div class="form-group">
<label for="test_script_action">Script action</label>
<select class="form-control" id="test_script_action" name="test_script_action">
<option value=""></option>
<option value="buffer">Buffer warning</option>
<option value="watched">Watched</option>
<option value="play">Playback start</option>
<option value="pause">Playback stopp</option>
<option value="resume">Playback resume</option>
<option value="stop">Playback stop</option>
<option value="extdown">Plex Server Remote Down</option>
<option value="extup">Plex Server Remote Up</option>
<option value="intdown">Plex Server Down</option>
<option value="intup">Plex Server Up</option>
<option value="created">Recently added</option>
</select>
<p class="help-block">Pick your action</p>
</div>
<div class="form-group">
<label for="test_script_args">Script args</label>
<input class="form-control" type="text" id="test_script_args" name="test_script_args" value="">
<p class="help-block">Set a custom script args: -zomg --x.</p>
</div>
% endif
<div class="form-group">
<div class="row">
<div class="col-md-8">
@ -148,7 +183,10 @@ from plexpy import helpers
url: 'test_notifier',
data: { config_id: '${agent["id"]}',
subject: $('#test_subject').val(),
body: $('#test_body').val() },
body: $('#test_body').val(),
notify_action: $('#test_script_action').val(),
script: $('#test_script').val(),
script_args: $('#test_script_args').val() },
cache: false,
async: true,
complete: function (xhr, status) {
@ -164,6 +202,12 @@ from plexpy import helpers
return false;
});
$('#scripts_folder').on('change', function () {
doAjaxCall('set_notification_config', $(this), 'tabs', true);
reloadModal();
return false;
});
// Never send checkbox values directly, always substitute value in hidden input.
$('.checkboxes').click(function () {
var configToggle = $(this).data('id');

View file

@ -751,7 +751,22 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
</ul>
</li>
</ul>
<ul id="accordion-scripts" class="accordion list-unstyled">
<li>
<div class="link"><i class="glyphicon glyphicon-console"></i>&nbsp;Script <i class="fa fa-chevron-down"></i></div>
<ul class="submenu">
<li>
<div class="form-group">
<label for="notify_scripts_args_text">Script arguments</label>
<input class="form-control" type="text" id="notify_scripts_args_text" name="notify_scripts_args_text" value="${config['notify_scripts_args_text']}" data-parsley-trigger="change">
<p class="help-block">Set arguments passed to the script</p>
</div>
</li>
</ul>
</li>
</ul>
<p><input type="button" class="btn btn-bright save-button" value="Save" data-success="Changes saved successfully"></p>
</div>
<div role="tabpanel" class="tab-pane" id="tabs-10">
@ -1111,6 +1126,14 @@ available_notification_agents = sorted(notifiers.available_notification_agents()
<td><strong>{transcode_audio_channels}</strong></td>
<td>The audio channels of the transcoded media.</td>
</tr>
<tr>
<td><strong>{streams}</strong></td>
<td>The number of concurrent streams.</td>
</tr>
<tr>
<td><strong>{action}</strong></td>
<td>The action that trigged the notification.</td>
</tr>
</tbody>
</table>
<table class="notification-params">
@ -1575,6 +1598,7 @@ $(document).ready(function() {
var accordion_session = new Accordion($('#accordion-session'), false);
var accordion_timeline = new Accordion($('#accordion-timeline'), false);
var accordion_scripts = new Accordion($('#accordion-scripts'), false);
var cards = "${config['home_stats_cards']}".split(/[\s,]+/);
cards.forEach(function (item) {

View file

@ -1,6 +1,4 @@
import plexpy.logger
import itertools
import os
import re
from configobj import ConfigObj
@ -14,8 +12,6 @@ def bool_int(value):
value = 0
return int(bool(value))
_CONFIG_DEFINITIONS = {
'DATE_FORMAT': (str, 'General', 'YYYY-MM-DD'),
'GROUPING_GLOBAL_HISTORY': (int, 'PlexWatch', 0),
@ -194,6 +190,7 @@ _CONFIG_DEFINITIONS = {
'NOTIFY_ON_EXTUP_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server remote access is back up.'),
'NOTIFY_ON_INTUP_SUBJECT_TEXT': (unicode, 'Monitoring', 'PlexPy ({server_name})'),
'NOTIFY_ON_INTUP_BODY_TEXT': (unicode, 'Monitoring', 'The Plex Media Server is back up.'),
'NOTIFY_SCRIPTS_ARGS_TEXT': (unicode, 'Monitoring', ''),
'OSX_NOTIFY_APP': (str, 'OSX_Notify', '/Applications/PlexPy'),
'OSX_NOTIFY_ENABLED': (int, 'OSX_Notify', 0),
'OSX_NOTIFY_ON_PLAY': (int, 'OSX_Notify', 0),
@ -298,6 +295,30 @@ _CONFIG_DEFINITIONS = {
'SLACK_ON_INTDOWN': (int, 'Slack', 0),
'SLACK_ON_EXTUP': (int, 'Slack', 0),
'SLACK_ON_INTUP': (int, 'Slack', 0),
'SCRIPTS_ENABLED': (int, 'Scripts', 0),
'SCRIPTS_FOLDER': (unicode, 'Scripts', ''),
'SCRIPTS_ON_PLAY': (int, 'Scripts', 0),
'SCRIPTS_ON_STOP': (int, 'Scripts', 0),
'SCRIPTS_ON_PAUSE': (int, 'Scripts', 0),
'SCRIPTS_ON_RESUME': (int, 'Scripts', 0),
'SCRIPTS_ON_BUFFER': (int, 'Scripts', 0),
'SCRIPTS_ON_WATCHED': (int, 'Scripts', 0),
'SCRIPTS_ON_CREATED': (int, 'Scripts', 0),
'SCRIPTS_ON_EXTDOWN': (int, 'Scripts', 0),
'SCRIPTS_ON_EXTUP': (int, 'Scripts', 0),
'SCRIPTS_ON_INTDOWN': (int, 'Scripts', 0),
'SCRIPTS_ON_INTUP': (int, 'Scripts', 0),
'SCRIPTS_ON_PLAY_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_STOP_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_PAUSE_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_RESUME_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_BUFFER_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_WATCHED_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_CREATED_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_EXTDOWN_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_EXTUP_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_INTDOWN_SCRIPT': (unicode, 'Scripts', ''),
'SCRIPTS_ON_INTUP_SCRIPT': (unicode, 'Scripts', ''),
'TELEGRAM_BOT_TOKEN': (str, 'Telegram', ''),
'TELEGRAM_ENABLED': (int, 'Telegram', 0),
'TELEGRAM_CHAT_ID': (str, 'Telegram', ''),
@ -351,6 +372,8 @@ _CONFIG_DEFINITIONS = {
'XBMC_ON_EXTUP': (int, 'XBMC', 0),
'XBMC_ON_INTUP': (int, 'XBMC', 0)
}
# pylint:disable=R0902
# it might be nice to refactor for fewer instance variables
class Config(object):

View file

@ -13,15 +13,17 @@
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, config, notifiers, database, helpers, plextv, pmsconnect
import plexpy
import re
import time
from plexpy import logger, config, notifiers, database, helpers, plextv, pmsconnect
import plexpy
def notify(stream_data=None, notify_action=None):
from plexpy import users
if stream_data and notify_action:
# Check if notifications enabled for user
user_data = users.Users()
@ -41,7 +43,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -51,7 +56,9 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -61,7 +68,9 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -71,7 +80,9 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -80,7 +91,9 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -94,7 +107,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -106,7 +122,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -118,7 +137,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -127,7 +149,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -136,7 +161,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -145,7 +173,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -154,7 +185,10 @@ def notify(stream_data=None, notify_action=None):
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])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=stream_data, state=notify_action, agent_info=agent)
@ -181,7 +215,9 @@ def notify_timeline(timeline_data=None, notify_action=None):
notify_strings = build_notify_text(timeline=timeline_data, state=notify_action)
notifiers.send_notification(config_id=agent['id'],
subject=notify_strings[0],
body=notify_strings[1])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
# Set the notification state in the db
set_notify_state(session=timeline_data, state=notify_action, agent_info=agent)
@ -192,25 +228,33 @@ def notify_timeline(timeline_data=None, notify_action=None):
notify_strings = build_server_notify_text(state=notify_action)
notifiers.send_notification(config_id=agent['id'],
subject=notify_strings[0],
body=notify_strings[1])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
if agent['on_intdown'] and notify_action == 'intdown':
# Build and send notification
notify_strings = build_server_notify_text(state=notify_action)
notifiers.send_notification(config_id=agent['id'],
subject=notify_strings[0],
body=notify_strings[1])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
if agent['on_extup'] and notify_action == 'extup':
# Build and send notification
notify_strings = build_server_notify_text(state=notify_action)
notifiers.send_notification(config_id=agent['id'],
subject=notify_strings[0],
body=notify_strings[1])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
if agent['on_intup'] and notify_action == 'intup':
# Build and send notification
notify_strings = build_server_notify_text(state=notify_action)
notifiers.send_notification(config_id=agent['id'],
subject=notify_strings[0],
body=notify_strings[1])
body=notify_strings[1],
notify_action=notify_action,
script_args=notify_strings[2])
else:
logger.debug(u"PlexPy Notifier :: Notify timeline called but incomplete data received.")
@ -237,6 +281,7 @@ def get_notify_state(session):
return notify_states
def get_notify_state_timeline(timeline):
monitor_db = database.MonitorDatabase()
result = monitor_db.select('SELECT on_created, agent_id '
@ -293,7 +338,6 @@ def set_notify_state(session, state, agent_info):
def build_notify_text(session=None, timeline=None, state=None):
import re
# Get the server name
server_name = plexpy.CONFIG.PMS_NAME
@ -318,6 +362,8 @@ def build_notify_text(session=None, timeline=None, state=None):
pms_connect = pmsconnect.PmsConnect()
metadata_list = pms_connect.get_metadata_details(rating_key=rating_key)
stream_count = pms_connect.get_current_activity().get('stream_count', '')
if metadata_list:
metadata = metadata_list['metadata']
else:
@ -327,13 +373,13 @@ def build_notify_text(session=None, timeline=None, state=None):
# Check for exclusion tags
if metadata['media_type'] == 'movie':
# Regex pattern to remove the text in the tags we don't want
pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<music>[^>]+.</music>\n*', re.IGNORECASE|re.DOTALL)
pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
elif metadata['media_type'] == 'show' or metadata['media_type'] == 'episode':
# Regex pattern to remove the text in the tags we don't want
pattern = re.compile('\n*<movie>[^>]+.</movie>\n*|\n*?<music>[^>]+.</music>\n*', re.IGNORECASE|re.DOTALL)
pattern = re.compile('\n*<movie>[^>]+.</movie>\n*|\n*?<music>[^>]+.</music>\n*', re.IGNORECASE | re.DOTALL)
elif metadata['media_type'] == 'artist' or metadata['media_type'] == 'track':
# Regex pattern to remove the text in the tags we don't want
pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<movie>[^>]+.</movie>\n*', re.IGNORECASE|re.DOTALL)
pattern = re.compile('\n*<tv>[^>]+.</tv>\n*|\n*<movie>[^>]+.</movie>\n*', re.IGNORECASE | re.DOTALL)
else:
pattern = None
@ -356,6 +402,7 @@ def build_notify_text(session=None, timeline=None, state=None):
on_watched_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT))
on_created_subject = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT))
on_created_body = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT))
script_args_text = strip_tag(re.sub(pattern, '', plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT))
else:
on_start_subject = plexpy.CONFIG.NOTIFY_ON_START_SUBJECT_TEXT
on_start_body = plexpy.CONFIG.NOTIFY_ON_START_BODY_TEXT
@ -371,6 +418,7 @@ def build_notify_text(session=None, timeline=None, state=None):
on_watched_body = plexpy.CONFIG.NOTIFY_ON_WATCHED_BODY_TEXT
on_created_subject = plexpy.CONFIG.NOTIFY_ON_CREATED_SUBJECT_TEXT
on_created_body = plexpy.CONFIG.NOTIFY_ON_CREATED_BODY_TEXT
script_args_text = plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT
# Create a title
if metadata['media_type'] == 'episode' or metadata['media_type'] == 'track':
@ -465,7 +513,7 @@ def build_notify_text(session=None, timeline=None, state=None):
artist_name = metadata['grandparent_title']
album_name = metadata['parent_title']
track_name = metadata['title']
available_params = {'server_name': server_name,
'server_uptime': server_uptime,
'user': user,
@ -516,12 +564,29 @@ def build_notify_text(session=None, timeline=None, state=None):
'summary': metadata['summary'],
'tagline': metadata['tagline'],
'rating': metadata['rating'],
'duration': duration
'duration': duration,
'action': state,
'streams': stream_count
}
# Default subject text
subject_text = 'PlexPy (%s)' % server_name
# Default scripts args
script_args = []
# Regex to match {param} but not "{param}"
params_to_quote = re.compile(r'(?<!\")([\{][^}]+[\}])(?!\"\})')
script_args_text = re.sub(params_to_quote, r'"\g<0>"', script_args_text)
if script_args_text:
try:
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
except LookupError as e:
logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
except Exception as e:
logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)
if state == 'play':
# Default body text
body_text = '%s (%s) is watching %s' % (session['friendly_name'],
@ -543,9 +608,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'stop':
# Default body text
body_text = '%s (%s) has stopped %s' % (session['friendly_name'],
@ -567,9 +632,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'pause':
# Default body text
body_text = '%s (%s) has paused %s' % (session['friendly_name'],
@ -591,9 +656,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'resume':
# Default body text
body_text = '%s (%s) has resumed %s' % (session['friendly_name'],
@ -615,9 +680,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'buffer':
# Default body text
body_text = '%s (%s) is buffering %s' % (session['friendly_name'],
@ -639,9 +704,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'watched':
# Default body text
body_text = '%s (%s) has watched %s' % (session['friendly_name'],
@ -663,9 +728,9 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'created':
# Default body text
body_text = '%s was recently added to Plex.' % full_title
@ -685,12 +750,13 @@ def build_notify_text(session=None, timeline=None, state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return None
def build_server_notify_text(state=None):
# Get the server name
server_name = plexpy.CONFIG.PMS_NAME
@ -716,11 +782,28 @@ def build_server_notify_text(state=None):
on_intup_body = plexpy.CONFIG.NOTIFY_ON_INTUP_BODY_TEXT
available_params = {'server_name': server_name,
'server_uptime': server_uptime}
'server_uptime': server_uptime,
'action': state}
# Default text
subject_text = 'PlexPy (%s)' % server_name
# Default scripts args
script_args = []
script_args_text = plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT
# Regex to match {param} but not "{param}"
params_to_quote = re.compile(r'(?<!\")([\{][^}]+[\}])(?!\"\})')
script_args_text = re.sub(params_to_quote, r'"\g<0>"', script_args_text)
if script_args_text:
try:
script_args = [unicode(arg).format(**available_params) for arg in script_args_text.split()]
except LookupError as e:
logger.error(u"PlexPy Notifier :: Unable to parse field %s in script argument. Using fallback." % e)
except Exception as e:
logger.error(u"PlexPy Notifier :: Unable to parse custom script arguments %s. Using fallback." % e)
if state == 'extdown':
# Default body text
body_text = 'The Plex Media Server remote access is down.'
@ -740,9 +823,10 @@ def build_server_notify_text(state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'intdown':
# Default body text
body_text = 'The Plex Media Server is down.'
@ -762,9 +846,9 @@ def build_server_notify_text(state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
if state == 'extup':
# Default body text
body_text = 'The Plex Media Server remote access is back up.'
@ -784,9 +868,9 @@ def build_server_notify_text(state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
elif state == 'intup':
# Default body text
body_text = 'The Plex Media Server is back up.'
@ -806,14 +890,16 @@ def build_server_notify_text(state=None):
except:
logger.error(u"PlexPy Notifier :: Unable to parse custom notification body. Using fallback.")
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return [subject_text, body_text]
return [subject_text, body_text, script_args]
else:
return None
def strip_tag(data):
import re
p = re.compile(r'<.*?>')
return p.sub('', data)
return p.sub('', data)

View file

@ -13,32 +13,31 @@
# You should have received a copy of the GNU General Public License
# along with PlexPy. If not, see <http://www.gnu.org/licenses/>.
from plexpy import logger, helpers, common, request
from plexpy.helpers import checked, radio
from xml.dom import minidom
from httplib import HTTPSConnection
from urlparse import parse_qsl
from urlparse import urlparse
from urllib import urlencode
from pynma import pynma
import base64
import json
import cherrypy
from email.mime.text import MIMEText
import email.utils
from httplib import HTTPSConnection
import os
import shlex
import smtplib
import subprocess
from urllib import urlencode
import urllib
import urllib2
import plexpy
import os.path
import subprocess
import gntp.notifier
import json
from urlparse import parse_qsl
from pynma import pynma
import gntp.notifier
import oauth2 as oauth
import pythontwitter as twitter
from email.mime.text import MIMEText
import smtplib
import email.utils
import plexpy
from plexpy import logger, helpers, request
from plexpy.helpers import checked
AGENT_IDS = {"Growl": 0,
"Prowl": 1,
@ -54,7 +53,9 @@ AGENT_IDS = {"Growl": 0,
"Twitter": 11,
"IFTTT": 12,
"Telegram": 13,
"Slack":14}
"Slack": 14,
"Scripts": 15}
def available_notification_agents():
agents = [{'name': 'Growl',
@ -294,7 +295,25 @@ def available_notification_agents():
'on_intdown': plexpy.CONFIG.SLACK_ON_INTDOWN,
'on_extup': plexpy.CONFIG.SLACK_ON_EXTUP,
'on_intup': plexpy.CONFIG.SLACK_ON_INTUP
}
},
{'name': 'Scripts',
'id': AGENT_IDS['Scripts'],
'config_prefix': 'scripts',
'has_config': True,
'state': checked(plexpy.CONFIG.SCRIPTS_ENABLED),
'on_play': plexpy.CONFIG.SCRIPTS_ON_PLAY,
'on_stop': plexpy.CONFIG.SCRIPTS_ON_STOP,
'on_pause': plexpy.CONFIG.SCRIPTS_ON_PAUSE,
'on_resume': plexpy.CONFIG.SCRIPTS_ON_RESUME,
'on_buffer': plexpy.CONFIG.SCRIPTS_ON_BUFFER,
'on_watched': plexpy.CONFIG.SCRIPTS_ON_WATCHED,
'on_created': plexpy.CONFIG.SCRIPTS_ON_CREATED,
'on_extdown': plexpy.CONFIG.SCRIPTS_ON_EXTDOWN,
'on_extup': plexpy.CONFIG.SCRIPTS_ON_EXTUP,
'on_intdown': plexpy.CONFIG.SCRIPTS_ON_INTDOWN,
'on_intup': plexpy.CONFIG.SCRIPTS_ON_INTUP
}
]
# OSX Notifications should only be visible if it can be used
@ -320,6 +339,7 @@ def available_notification_agents():
return agents
def get_notification_agent_config(config_id):
if config_id:
config_id = int(config_id)
@ -364,17 +384,21 @@ def get_notification_agent_config(config_id):
iftttClient = IFTTT()
return iftttClient.return_config_options()
elif config_id == 13:
telegramClient = TELEGRAM()
return telegramClient.return_config_options()
telegramClient = TELEGRAM()
return telegramClient.return_config_options()
elif config_id == 14:
slackClient = SLACK()
return slackClient.return_config_options()
elif config_id == 15:
script = Scripts()
return script.return_config_options()
else:
return []
else:
return []
def send_notification(config_id, subject, body):
def send_notification(config_id, subject, body, **kwargs):
if str(config_id).isdigit():
config_id = int(config_id)
@ -418,11 +442,14 @@ def send_notification(config_id, subject, body):
iftttClient = IFTTT()
iftttClient.notify(subject=subject, message=body)
elif config_id == 13:
telegramClient = TELEGRAM()
telegramClient.notify(message=body, event=subject)
telegramClient = TELEGRAM()
telegramClient.notify(message=body, event=subject)
elif config_id == 14:
slackClient = SLACK()
slackClient.notify(message=body, event=subject)
elif config_id == 15:
scripts = Scripts()
scripts.notify(message=body, subject=subject, **kwargs)
else:
logger.debug(u"PlexPy Notifier :: Unknown agent id received.")
else:
@ -503,7 +530,7 @@ class GROWL(object):
logger.info(u"Growl notifications sent.")
def updateLibrary(self):
#For uniformity reasons not removed
# For uniformity reasons not removed
return
def test(self, host, password):
@ -530,6 +557,7 @@ class GROWL(object):
return config_option
class PROWL(object):
"""
Prowl notifications.
@ -556,9 +584,10 @@ class PROWL(object):
'priority': plexpy.CONFIG.PROWL_PRIORITY}
http_handler.request("POST",
"/publicapi/add",
headers={'Content-type': "application/x-www-form-urlencoded"},
body=urlencode(data))
"/publicapi/add",
headers={'Content-type': "application/x-www-form-urlencoded"},
body=urlencode(data))
response = http_handler.getresponse()
request_status = response.status
@ -573,7 +602,7 @@ class PROWL(object):
return False
def updateLibrary(self):
#For uniformity reasons not removed
# For uniformity reasons not removed
return
def test(self, keys, priority):
@ -601,6 +630,7 @@ class PROWL(object):
return config_option
class XBMC(object):
"""
XBMC notifications
@ -640,19 +670,19 @@ class XBMC(object):
header = subject
message = message
time = "3000" # in ms
time = "3000" # in ms
for host in hosts:
logger.info('Sending notification command to XMBC @ ' + host)
try:
version = self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})['version']['major']
if version < 12: #Eden
if version < 12: # Eden
notification = header + "," + message + "," + time
notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')'}
request = self._sendhttp(host, notifycommand)
else: #Frodo
else: # Frodo
params = {'title': header, 'message': message, 'displaytime': int(time)}
request = self._sendjson(host, 'GUI.ShowNotification', params)
@ -685,6 +715,7 @@ class XBMC(object):
return config_option
class Plex(object):
def __init__(self):
@ -725,7 +756,7 @@ class Plex(object):
header = subject
message = message
time = "3000" # in ms
time = "3000" # in ms
for host in hosts:
logger.info('Sending notification command to Plex Media Server @ ' + host)
@ -763,6 +794,7 @@ class Plex(object):
return config_option
class NMA(object):
def __init__(self):
@ -821,6 +853,7 @@ class NMA(object):
return config_option
class PUSHBULLET(object):
def __init__(self):
@ -848,10 +881,11 @@ class PUSHBULLET(object):
data['channel_tag'] = self.channel_tag
http_handler.request("POST",
"/v2/pushes",
headers={'Content-type': "application/json",
'Authorization': 'Basic %s' % base64.b64encode(plexpy.CONFIG.PUSHBULLET_APIKEY + ":")},
body=json.dumps(data))
"/v2/pushes",
headers={'Content-type': "application/json",
'Authorization': 'Basic %s' % base64.b64encode(plexpy.CONFIG.PUSHBULLET_APIKEY + ":")},
body=json.dumps(data))
response = http_handler.getresponse()
request_status = response.status
# logger.debug(u"PushBullet response status: %r" % request_status)
@ -880,8 +914,9 @@ class PUSHBULLET(object):
if plexpy.CONFIG.PUSHBULLET_APIKEY:
http_handler = HTTPSConnection("api.pushbullet.com")
http_handler.request("GET", "/v2/devices",
headers={'Content-type': "application/json",
'Authorization': 'Basic %s' % base64.b64encode(plexpy.CONFIG.PUSHBULLET_APIKEY + ":")})
headers={'Content-type': "application/json",
'Authorization': 'Basic %s' % base64.b64encode(plexpy.CONFIG.PUSHBULLET_APIKEY + ":")})
response = http_handler.getresponse()
request_status = response.status
@ -926,6 +961,7 @@ class PUSHBULLET(object):
return config_option
class PUSHALOT(object):
def __init__(self):
@ -937,9 +973,9 @@ class PUSHALOT(object):
pushalot_authorizationtoken = plexpy.CONFIG.PUSHALOT_APIKEY
#logger.debug(u"Pushalot event: " + event)
#logger.debug(u"Pushalot message: " + message)
#logger.debug(u"Pushalot api: " + pushalot_authorizationtoken)
# logger.debug(u"Pushalot event: " + event)
# logger.debug(u"Pushalot message: " + message)
# logger.debug(u"Pushalot api: " + pushalot_authorizationtoken)
http_handler = HTTPSConnection("pushalot.com")
@ -948,15 +984,15 @@ class PUSHALOT(object):
'Body': message.encode("utf-8")}
http_handler.request("POST",
"/api/sendmessage",
headers={'Content-type': "application/x-www-form-urlencoded"},
body=urlencode(data))
"/api/sendmessage",
headers={'Content-type': "application/x-www-form-urlencoded"},
body=urlencode(data))
response = http_handler.getresponse()
request_status = response.status
#logger.debug(u"Pushalot response status: %r" % request_status)
#logger.debug(u"Pushalot response headers: %r" % response.getheaders())
#logger.debug(u"Pushalot response body: %r" % response.read())
# logger.debug(u"Pushalot response status: %r" % request_status)
# logger.debug(u"Pushalot response headers: %r" % response.getheaders())
# logger.debug(u"Pushalot response body: %r" % response.read())
if request_status == 200:
logger.info(u"Pushalot notifications sent.")
@ -979,6 +1015,7 @@ class PUSHALOT(object):
return config_option
class PUSHOVER(object):
def __init__(self):
@ -1025,7 +1062,7 @@ class PUSHOVER(object):
return False
def updateLibrary(self):
#For uniformity reasons not removed
# For uniformity reasons not removed
return
def test(self, keys, priority, sound):
@ -1042,7 +1079,7 @@ class PUSHOVER(object):
http_handler.request("GET", "/1/sounds.json?token=" + self.application_token)
response = http_handler.getresponse()
request_status = response.status
if request_status == 200:
data = json.loads(response.read())
sounds = data.get('sounds', {})
@ -1054,7 +1091,7 @@ class PUSHOVER(object):
else:
logger.info(u"Unable to retrieve Pushover notification sounds list.")
return {'': ''}
else:
return {'': ''}
@ -1089,6 +1126,7 @@ class PUSHOVER(object):
return config_option
class TwitterNotifier(object):
REQUEST_TOKEN_URL = 'https://api.twitter.com/oauth/request_token'
@ -1186,24 +1224,25 @@ class TwitterNotifier(object):
'description': 'Step 1: Click Request button above. (Ensure you allow the browser pop-up).',
'input_type': 'button'
},
{'label': 'Authorisation Key',
'value': '',
'name': 'twitter_key',
'description': 'Step 2: Input the authorisation key you received from Step 1.',
'input_type': 'text'
{'label': 'Authorisation Key',
'value': '',
'name': 'twitter_key',
'description': 'Step 2: Input the authorisation key you received from Step 1.',
'input_type': 'text'
},
{'label': 'Verify Key',
'value': 'Verify Key',
'name': 'twitterStep2',
'description': 'Step 3: Verify the key.',
'input_type': 'button'
{'label': 'Verify Key',
'value': 'Verify Key',
'name': 'twitterStep2',
'description': 'Step 3: Verify the key.',
'input_type': 'button'
},
{'input_type': 'nosave'
{'input_type': 'nosave'
}
]
return config_option
class OSX_NOTIFY(object):
def __init__(self):
@ -1211,7 +1250,7 @@ class OSX_NOTIFY(object):
self.objc = __import__("objc")
self.AppKit = __import__("AppKit")
except:
#logger.error(u"PlexPy Notifier :: Cannot load OSX Notifications agent.")
# logger.error(u"PlexPy Notifier :: Cannot load OSX Notifications agent.")
pass
def validate(self):
@ -1228,7 +1267,7 @@ class OSX_NOTIFY(object):
def wrapper(self, *args, **kwargs):
return func(self, old_IMP, *args, **kwargs)
new_IMP = self.objc.selector(wrapper, selector=old_IMP.selector,
signature=old_IMP.signature)
signature=old_IMP.signature)
self.objc.classAddMethod(cls, SEL, new_IMP)
def notify(self, title, subtitle=None, text=None, sound=True, image=None):
@ -1258,7 +1297,7 @@ class OSX_NOTIFY(object):
if image:
source_img = self.AppKit.NSImage.alloc().initByReferencingFile_(image)
notification.setContentImage_(source_img)
#notification.set_identityImage_(source_img)
# notification.set_identityImage_(source_img)
notification.setHasActionButton_(False)
notification_center = NSUserNotificationCenter.defaultUserNotificationCenter()
@ -1287,6 +1326,7 @@ class OSX_NOTIFY(object):
return config_option
class BOXCAR(object):
def __init__(self):
@ -1347,7 +1387,7 @@ class BOXCAR(object):
'flourish': 'Flourish',
'harp': 'Harp',
'light': 'Light',
'magic-chime':'Magic Chime',
'magic-chime': 'Magic Chime',
'magic-coin': 'Magic Coin',
'no-sound': 'No Sound',
'notifier-1': 'Notifier (1)',
@ -1363,6 +1403,7 @@ class BOXCAR(object):
return config_option
class Email(object):
def __init__(self):
@ -1523,10 +1564,12 @@ class IFTTT(object):
' as value1 and value2 respectively.',
'input_type': 'text'
}
]
return config_option
class TELEGRAM(object):
def __init__(self):
@ -1565,7 +1608,7 @@ class TELEGRAM(object):
return False
def updateLibrary(self):
#For uniformity reasons not removed
# For uniformity reasons not removed
return
def test(self, bot_token, chat_id):
@ -1676,3 +1719,240 @@ class SLACK(object):
]
return config_option
class Scripts(object):
def __init__(self, **kwargs):
pass
def conf(self, options):
return cherrypy.config['config'].get('Scripts', options)
def updateLibrary(self):
# For uniformity reasons not removed
return
def test(self, subject, message, *args, **kwargs):
self.notify(subject, message, *args, **kwargs)
return
def list_scripts(self):
scriptdir = plexpy.CONFIG.SCRIPTS_FOLDER
scripts = {'': ''}
if scriptdir and not os.path.exists(scriptdir):
os.makedirs(scriptdir)
for root, dirs, files in os.walk(scriptdir):
for f in files:
name, ext = os.path.splitext(f)
if ext in ('.rb', '.pl', '.bat', '.py', '.sh', '.cmd', '.php'):
rfp = os.path.join(os.path.relpath(root, scriptdir), f)
fp = os.path.join(root, f)
scripts[fp] = rfp
return scripts
def notify(self, subject='', message='', notify_action='', script_args='', *args, **kwargs):
"""
Args:
subject(string, optional): Head text,
message(string, optional): Body text,
notify_action(string): 'play'
script_args(list): ["python2", '-p', '-zomg']
"""
logger.debug(u'Trying to run notify script subject: %s message: %s, action: %s script_args: %s' %
(subject, message, notify_action, script_args))
prefix = ''
script = kwargs.get('script', '') # for manual scripts
if not plexpy.CONFIG.SCRIPTS_FOLDER:
return
# Make sure we use the correct script..
if notify_action == 'play':
script = plexpy.CONFIG.SCRIPTS_ON_PLAY_SCRIPT
elif notify_action == 'stop':
script = plexpy.CONFIG.SCRIPTS_ON_STOP_SCRIPT
elif notify_action == 'pause':
script = plexpy.CONFIG.SCRIPTS_ON_PAUSE_SCRIPT
elif notify_action == 'resume':
script = plexpy.CONFIG.SCRIPTS_ON_RESUME_SCRIPT
elif notify_action == 'buffer':
script = plexpy.CONFIG.SCRIPTS_ON_BUFFER_SCRIPT
elif notify_action == 'extdown':
script = plexpy.CONFIG.SCRIPTS_ON_EXTDOWN_SCRIPT
elif notify_action == 'extup':
script = plexpy.CONFIG.SCRIPTS_ON_EXTUP_SCRIPT
elif notify_action == 'intdown':
script = plexpy.CONFIG.SCRIPTS_ON_INTDOWN_SCRIPT
elif notify_action == 'intup':
script = plexpy.CONFIG.SCRIPTS_ON_INTUP_SCRIPT
elif notify_action == 'created':
script = plexpy.CONFIG.SCRIPTS_ON_CREATED_SCRIPT
elif notify_action == 'watched':
script = plexpy.CONFIG.SCRIPTS_ON_WATCHED_SCRIPT
# Dont try to run the script
# if the action does not have one
if not script:
logger.debug(u'%s has no script, exiting..' % notify_action)
return
name, ext = os.path.splitext(script)
if ext == '.py':
prefix = 'python'
elif ext == '.php':
prefix = 'php'
elif ext == '.pl':
prefix = 'perl'
elif ext == '.rb':
prefix = 'ruby'
if os.name == 'nt':
script = script.encode(plexpy.SYS_ENCODING, 'ignore')
script = [script]
if prefix:
script.insert(0, prefix)
# for manual notifications
if script_args and isinstance(script_args, basestring):
# attemps for format it for the user
script_args = shlex.split(script_args)
# Windows handles unicode very badly.
# https://bugs.python.org/issue19264
if script_args and os.name == 'nt':
script_args = [s.encode(plexpy.SYS_ENCODING, 'ignore') for s in script_args]
# Allow overrides for shitty systems
if prefix and script_args:
if script_args[0] in ['python2', 'python', 'php', 'ruby', 'perl']:
script[0] = script_args[0]
del script_args[0]
script.extend(script_args)
logger.debug(u'Full script is %s' % script)
try:
p = subprocess.Popen(script, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=plexpy.CONFIG.SCRIPTS_FOLDER)
out, error = p.communicate()
status = p.returncode
if out and status:
out = out.strip()
logger.debug(u'%s returned %s' % (script, out))
if error:
error = error.strip()
logger.error(u'%s' % error)
except OSError as out:
logger.error(u'Failed to run %s error %s' % (script, out))
def return_config_options(self):
config_option = [{'label': 'Script folder',
'value': plexpy.CONFIG.SCRIPTS_FOLDER,
'name': 'scripts_folder',
'description': 'Add your script folder.',
'input_type': 'text',
},
{'label': 'Playback Start',
'value': plexpy.CONFIG.SCRIPTS_ON_PLAY_SCRIPT,
'name': 'scripts_on_play_script',
'description': 'Pick the script for on play.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Playback Stop',
'value': plexpy.CONFIG.SCRIPTS_ON_STOP_SCRIPT,
'name': 'scripts_on_stop_script',
'description': 'Pick the script for on stop.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Playback Pause',
'value': plexpy.CONFIG.SCRIPTS_ON_PAUSE_SCRIPT,
'name': 'scripts_on_pause_script',
'description': 'Pick the script for on pause.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Playback Resume',
'value': plexpy.CONFIG.SCRIPTS_ON_RESUME_SCRIPT,
'name': 'scripts_on_resume_script',
'description': 'Pick the script for on resume.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Watched',
'value': plexpy.CONFIG.SCRIPTS_ON_WATCHED_SCRIPT,
'name': 'scripts_on_watched_script',
'description': 'Pick the script for on watched.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Buffer Warnings',
'value': plexpy.CONFIG.SCRIPTS_ON_BUFFER_SCRIPT,
'name': 'scripts_on_buffer_script',
'description': 'Pick the script for buffer warnings.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Recently Added',
'value': plexpy.CONFIG.SCRIPTS_ON_CREATED_SCRIPT,
'name': 'scripts_on_created_script',
'description': 'Pick the script for recently added.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Plex Remote Access Down',
'value': plexpy.CONFIG.SCRIPTS_ON_EXTDOWN_SCRIPT,
'name': 'scripts_on_extdown_script',
'description': 'Pick the script for external connection down.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Plex Remote Access Up',
'value': plexpy.CONFIG.SCRIPTS_ON_EXTUP_SCRIPT,
'name': 'scripts_on_extup_script',
'description': 'Pick the script for external connection up.',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Plex Server Down',
'value': plexpy.CONFIG.SCRIPTS_ON_INTDOWN_SCRIPT,
'name': 'scripts_on_intdown_script',
'description': 'Pick the script for pms down',
'input_type': 'select',
'select_options': self.list_scripts()
},
{'label': 'Plex Server Up',
'value': plexpy.CONFIG.SCRIPTS_ON_INTUP_SCRIPT,
'name': 'scripts_on_intup_script',
'description': 'Pick the script for pms up',
'input_type': 'select',
'select_options': self.list_scripts()
}
]
return config_option

View file

@ -476,6 +476,7 @@ class WebInterface(object):
"notify_on_extup_body_text": plexpy.CONFIG.NOTIFY_ON_EXTUP_BODY_TEXT,
"notify_on_intup_subject_text": plexpy.CONFIG.NOTIFY_ON_INTUP_SUBJECT_TEXT,
"notify_on_intup_body_text": plexpy.CONFIG.NOTIFY_ON_INTUP_BODY_TEXT,
"notify_scripts_args_text": plexpy.CONFIG.NOTIFY_SCRIPTS_ARGS_TEXT,
"home_stats_length": plexpy.CONFIG.HOME_STATS_LENGTH,
"home_stats_type": checked(plexpy.CONFIG.HOME_STATS_TYPE),
"home_stats_count": plexpy.CONFIG.HOME_STATS_COUNT,
@ -554,7 +555,7 @@ class WebInterface(object):
# Get new server URLs for SSL communications.
plextv.get_real_pms_url()
# Get new server friendly name
pmsconnect.get_server_friendly_name()
@ -662,6 +663,7 @@ class WebInterface(object):
@cherrypy.expose
def test_notifier(self, config_id=None, subject='PlexPy', body='Test notification', **kwargs):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
print kwargs
if config_id.isdigit():
agents = notifiers.available_notification_agents()
@ -671,10 +673,10 @@ class WebInterface(object):
break
else:
this_agent = None
if this_agent:
logger.debug("Sending test %s notification." % this_agent['name'])
notifiers.send_notification(this_agent['id'], subject, body)
notifiers.send_notification(this_agent['id'], subject, body, **kwargs)
return "Notification sent."
else:
logger.debug("Unable to send test notification, invalid notification agent ID %s." % config_id)
@ -682,7 +684,7 @@ class WebInterface(object):
else:
logger.debug("Unable to send test notification, no notification agent ID received.")
return "No notification agent ID received."
@cherrypy.expose
def twitterStep1(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
@ -1339,12 +1341,12 @@ class WebInterface(object):
plexpy.CONFIG.__setattr__('PMS_SSL', ssl)
plexpy.CONFIG.__setattr__('PMS_IS_REMOTE', remote)
plexpy.CONFIG.write()
plextv.get_real_pms_url()
pms_connect = pmsconnect.PmsConnect()
request = pms_connect.get_local_server_identity()
if request:
cherrypy.response.headers['Content-type'] = 'application/xml'
return request
@ -1420,6 +1422,12 @@ class WebInterface(object):
return serve_template(templatename="notification_triggers_modal.html", title="Notification Triggers",
data=this_agent)
@cherrypy.expose
def testScripts(self, *args, **kwargs):
''' Used for manual testing for now cba with adding buttion '''
script = notifiers.Scripts()
return script.test(*args, **kwargs)
@cherrypy.expose
def delete_history_rows(self, row_id, **kwargs):
data_factory = datafactory.DataFactory()