From 1e616fa585d1b64e58b7da0208a2ca032146399e Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 30 Dec 2015 12:59:52 -0800 Subject: [PATCH 1/5] Allow SSL when verifying server in settings --- data/interfaces/default/settings.html | 5 ++++- data/interfaces/default/welcome.html | 5 ++++- plexpy/webserve.py | 24 ++++++++++++++---------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/data/interfaces/default/settings.html b/data/interfaces/default/settings.html index 2683860b..2251df3b 100644 --- a/data/interfaces/default/settings.html +++ b/data/interfaces/default/settings.html @@ -1422,12 +1422,15 @@ $(document).ready(function() { function verifyServer(_callback) { var pms_ip = $("#pms_ip").val() var pms_port = $("#pms_port").val() + var pms_identifier = $("#pms_identifier").val() + var pms_ssl = $("#pms_ssl").val() + var pms_is_remote = $("#pms_is_remote").val() if (($("#pms_ip").val() !== '') || ($("#pms_port").val() !== '')) { $("#pms-verify").html(''); $('#pms-verify').fadeIn('fast'); $.ajax({ url: 'get_server_id', - data : { hostname: pms_ip, port: pms_port }, + data : { hostname: pms_ip, port: pms_port, identifier: pms_identifier, ssl: pms_ssl, remote: pms_is_remote }, cache: true, async: true, timeout: 5000, diff --git a/data/interfaces/default/welcome.html b/data/interfaces/default/welcome.html index 93a5b518..10654801 100644 --- a/data/interfaces/default/welcome.html +++ b/data/interfaces/default/welcome.html @@ -372,12 +372,15 @@ from plexpy import common $("#verify-plex-server").click(function() { var pms_ip = $("#pms_ip").val() var pms_port = $("#pms_port").val() + var pms_identifier = $("#pms_identifier").val() + var pms_ssl = $("#pms_ssl").val() + var pms_is_remote = $("#pms_is_remote").val() if (($("#pms_ip").val() !== '') || ($("#pms_port").val() !== '')) { $("#pms-verify-status").html(' Validating server...'); $('#pms-verify-status').fadeIn('fast'); $.ajax({ url: 'get_server_id', - data : { hostname: pms_ip, port: pms_port }, + data : { hostname: pms_ip, port: pms_port, identifier: pms_identifier, ssl: pms_ssl, remote: pms_is_remote }, cache: true, async: true, timeout: 5000, diff --git a/plexpy/webserve.py b/plexpy/webserve.py index 542147d7..f2bef4ae 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -1335,19 +1335,23 @@ class WebInterface(object): return serve_template(templatename="plexwatch_import.html", title="Import PlexWatch Database") @cherrypy.expose - def get_server_id(self, hostname=None, port=None, **kwargs): + def get_server_id(self, hostname=None, port=None, identifier=None, ssl=0, remote=0, **kwargs): from plexpy import http_handler if hostname and port: - request_handler = http_handler.HTTPHandler(host=hostname, - port=port, - token=None) - uri = '/identity' - request = request_handler.make_request(uri=uri, - proto='http', - request_type='GET', - output_format='', - no_token=True) + # Set PMS attributes to get the real PMS url + plexpy.CONFIG.__setattr__('PMS_IP', hostname) + plexpy.CONFIG.__setattr__('PMS_PORT', port) + plexpy.CONFIG.__setattr__('PMS_IDENTIFIER', identifier) + 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 From f31c4dcccdb7a84d9e9bc2d61934b360789f5030 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 30 Dec 2015 15:34:59 -0800 Subject: [PATCH 2/5] Add test notification for all agents --- .../default/notification_config.html | 44 ++++++++++++--- plexpy/notifiers.py | 12 ---- plexpy/webserve.py | 55 ++++++++----------- 3 files changed, 59 insertions(+), 52 deletions(-) diff --git a/data/interfaces/default/notification_config.html b/data/interfaces/default/notification_config.html index ec384bcd..0267f478 100644 --- a/data/interfaces/default/notification_config.html +++ b/data/interfaces/default/notification_config.html @@ -66,6 +66,27 @@ from plexpy import helpers % endfor +
+

Test ${agent['name']}

+

Test if ${agent['name']} notifications are working. See logs for troubleshooting.

+
+ + +

Set a custom subject line.

+
+
+ + +

Set a custom body.

+
+
+
+
+ +
+
+
+
@@ -120,16 +141,21 @@ from plexpy import helpers $.get("/twitterStep2", { 'key': twitter_key }, function (data) { $('#ajaxMsg').html(" " + data); }); $('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut(); }); - $('#testTwitter').click(function () { - $.get("/testTwitter", - function (data) { $('#ajaxMsg').html(" " + data); }); - $('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut(); - }); - $('#testIFTTT').click(function () { - $.get("/test_ifttt", - function (data) { $('#ajaxMsg').html(" " + data); }); - $('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut(); + $('#test_notifier').click(function () { + doAjaxCall('set_notification_config', $(this), 'tabs', true); + $.ajax({ + url: 'test_notifier', + data: { config_id: '${agent["id"]}', + subject: $('#test_subject').val(), + body: $('#test_body').val() }, + cache: false, + async: true, + complete: function (xhr, status) { + msg = '  ' + xhr.responseText; + showMsg(msg, false, true, 2000); + } + }); }); $('#testSlack').click(function() { diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index df024958..87cfaefa 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1198,12 +1198,6 @@ class TwitterNotifier(object): 'description': 'Step 3: Verify the key.', 'input_type': 'button' }, - {'label': 'Test Twitter', - 'value': 'Test Twitter', - 'name': 'testTwitter', - 'description': 'Test if Twitter notifications are working. See logs for troubleshooting.', - 'input_type': 'button' - }, {'input_type': 'nosave' } ] @@ -1522,12 +1516,6 @@ class IFTTT(object): 'description': 'The Ifttt maker event to fire. The notification subject and body will be sent' ' as value1 and value2 respectively.', 'input_type': 'text' - }, - {'label': 'Test Event', - 'value': 'Test Event', - 'name': 'testIFTTT', - 'description': 'Test if IFTTT notifications are working. See logs for troubleshooting.', - 'input_type': 'button' } ] diff --git a/plexpy/webserve.py b/plexpy/webserve.py index f2bef4ae..a9eaae6c 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -659,6 +659,30 @@ class WebInterface(object): return a.fetchData() + @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" + + 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 + + if this_agent: + logger.debug("Sending test %s notification." % this_agent['name']) + notifiers.send_notification(this_agent['id'], subject, body) + return "Notification sent." + else: + logger.debug("Unable to send test notification, invalid notification agent ID %s." % config_id) + return "Invalid notification agent ID %s." % config_id + 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" @@ -676,37 +700,6 @@ class WebInterface(object): else: return "Unable to verify key" - @cherrypy.expose - def testTwitter(self): - cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" - tweet = notifiers.TwitterNotifier() - result = tweet.test_notify() - if result: - return "Tweet successful, check your twitter to make sure it worked" - else: - return "Error sending tweet" - - @cherrypy.expose - def test_ifttt(self): - cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" - event = notifiers.IFTTT() - result = event.test() - if result: - return "Notification successful." - else: - return "Error sending event." - - @cherrypy.expose - def test_slack(self): - cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" - event = notifiers.SLACK() - result = event.test() - - if result: - return "Notification successful." - else: - return "Error sending event." - @cherrypy.expose def osxnotifyregister(self, app): cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" From 6d5b5e15d5580f77a77c4d6b98752b6ac79875cb Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Wed, 30 Dec 2015 15:50:42 -0800 Subject: [PATCH 3/5] Remove PlexPy Pushover API token * User's own API token is now required --- .../default/notification_config.html | 7 +-- plexpy/notifiers.py | 52 +++++++++---------- plexpy/webserve.py | 4 +- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/data/interfaces/default/notification_config.html b/data/interfaces/default/notification_config.html index 0267f478..286ac1b0 100644 --- a/data/interfaces/default/notification_config.html +++ b/data/interfaces/default/notification_config.html @@ -158,12 +158,7 @@ from plexpy import helpers }); }); - $('#testSlack').click(function() { - $.get("/test_slack", function(data) { $('#ajaxMsg').html("" + data); }); - $('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut(); - }); - - $('#pushbullet_apikey').on('change', function () { + $('#pushbullet_apikey, #pushover_apitoken').on('change', function () { doAjaxCall('set_notification_config', $(this), 'tabs', true); reloadModal(); return false; diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 87cfaefa..1c06d2a2 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -983,15 +983,11 @@ class PUSHOVER(object): def __init__(self): self.enabled = plexpy.CONFIG.PUSHOVER_ENABLED + self.application_token = plexpy.CONFIG.PUSHOVER_APITOKEN self.keys = plexpy.CONFIG.PUSHOVER_KEYS self.priority = plexpy.CONFIG.PUSHOVER_PRIORITY self.sound = plexpy.CONFIG.PUSHOVER_SOUND - if plexpy.CONFIG.PUSHOVER_APITOKEN: - self.application_token = plexpy.CONFIG.PUSHOVER_APITOKEN - else: - self.application_token = "aVny3NZFwZaXC642c831b4wd7KUhQS" - def conf(self, options): return cherrypy.config['config'].get('Pushover', options) @@ -1041,25 +1037,35 @@ class PUSHOVER(object): self.notify('Main Screen Activate', 'Test Message') def get_sounds(self): - http_handler = HTTPSConnection("api.pushover.net") - 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', {}) - sounds.update({'': ''}) - return sounds - elif request_status >= 400 and request_status < 500: - logger.info(u"Unable to retrieve Pushover notification sounds list: %s" % response.reason) - return {'': ''} + if plexpy.CONFIG.PUSHOVER_APITOKEN: + http_handler = HTTPSConnection("api.pushover.net") + 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', {}) + sounds.update({'': ''}) + return sounds + elif request_status >= 400 and request_status < 500: + logger.info(u"Unable to retrieve Pushover notification sounds list: %s" % response.reason) + return {'': ''} + else: + logger.info(u"Unable to retrieve Pushover notification sounds list.") + return {'': ''} + else: - logger.info(u"Unable to retrieve Pushover notification sounds list.") return {'': ''} def return_config_options(self): - config_option = [{'label': 'Pushover User or Group Key', + config_option = [{'label': 'Pushover API Token', + 'value': plexpy.CONFIG.PUSHOVER_APITOKEN, + 'name': 'pushover_apitoken', + 'description': 'Your Pushover API token.', + 'input_type': 'text' + }, + {'label': 'Pushover User or Group Key', 'value': self.keys, 'name': 'pushover_keys', 'description': 'Your Pushover user or group key.', @@ -1078,12 +1084,6 @@ class PUSHOVER(object): 'description': 'Set the notification sound. Leave blank for the default sound.', 'input_type': 'select', 'select_options': self.get_sounds() - }, - {'label': 'Pushover API Token', - 'value': plexpy.CONFIG.PUSHOVER_APITOKEN, - 'name': 'pushover_apitoken', - 'description': 'Your Pushover API token. Leave blank to use PlexPy default.', - 'input_type': 'text' } ] diff --git a/plexpy/webserve.py b/plexpy/webserve.py index a9eaae6c..39bc34aa 100644 --- a/plexpy/webserve.py +++ b/plexpy/webserve.py @@ -554,8 +554,8 @@ class WebInterface(object): # Get new server URLs for SSL communications. plextv.get_real_pms_url() - - # Get new server friendly name + + # Get new server friendly name pmsconnect.get_server_friendly_name() # Reconfigure scheduler if intervals changed From 65f27ee6058f4de665f845b4d35d965defecd8cc Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Thu, 31 Dec 2015 12:46:26 -0800 Subject: [PATCH 4/5] Add Email from name option --- data/interfaces/default/notification_config.html | 4 ++-- plexpy/config.py | 1 + plexpy/notifiers.py | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/data/interfaces/default/notification_config.html b/data/interfaces/default/notification_config.html index 286ac1b0..8732e6a9 100644 --- a/data/interfaces/default/notification_config.html +++ b/data/interfaces/default/notification_config.html @@ -66,9 +66,9 @@ from plexpy import helpers % endfor -
+

Test ${agent['name']}

-

Test if ${agent['name']} notifications are working. See logs for troubleshooting.

+

Test if ${agent['name']} notifications are working. See logs for troubleshooting.

diff --git a/plexpy/config.py b/plexpy/config.py index 30947823..a7d4f3b3 100644 --- a/plexpy/config.py +++ b/plexpy/config.py @@ -61,6 +61,7 @@ _CONFIG_DEFINITIONS = { 'CONFIG_VERSION': (str, 'General', '0'), 'DO_NOT_OVERRIDE_GIT_BRANCH': (int, 'General', 0), 'EMAIL_ENABLED': (int, 'Email', 0), + 'EMAIL_FROM_NAME': (str, 'Email', 'PlexPy'), 'EMAIL_FROM': (str, 'Email', ''), 'EMAIL_TO': (str, 'Email', ''), 'EMAIL_CC': (str, 'Email', ''), diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 1c06d2a2..01ed313e 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1374,7 +1374,7 @@ class Email(object): message = MIMEText(message, 'plain', "utf-8") message['Subject'] = subject - message['From'] = email.utils.formataddr(('PlexPy', plexpy.CONFIG.EMAIL_FROM)) + message['From'] = email.utils.formataddr((plexpy.CONFIG.EMAIL_FROM_NAME, plexpy.CONFIG.EMAIL_FROM)) message['To'] = plexpy.CONFIG.EMAIL_TO message['CC'] = plexpy.CONFIG.EMAIL_CC @@ -1405,7 +1405,13 @@ class Email(object): return False def return_config_options(self): - config_option = [{'label': 'From', + config_option = [{'label': 'From Name', + 'value': plexpy.CONFIG.EMAIL_FROM_NAME, + 'name': 'email_from_name', + 'description': 'The name of the sender.', + 'input_type': 'text' + }, + {'label': 'From', 'value': plexpy.CONFIG.EMAIL_FROM, 'name': 'email_from', 'description': 'The email address of the sender.', From b73a259f68cf95345d4a72e00e497f85a62783c7 Mon Sep 17 00:00:00 2001 From: JonnyWong16 Date: Thu, 31 Dec 2015 20:13:54 -0800 Subject: [PATCH 5/5] Clean up Slack agent --- plexpy/notifiers.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 01ed313e..16100738 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1658,27 +1658,21 @@ class SLACK(object): {'label': 'Slack Channel', 'value': self.channel, 'name': 'slack_channel', - 'description': 'Your slack channel name. (Begin with \'#\')', + 'description': 'Your Slack channel name (begin with \'#\'). Leave blank for webhook integration default.', 'input_type': 'text' }, {'label': 'Slack Username', 'value': self.username, 'name': 'slack_username', - 'description': 'Slack username which will be shown', + 'description': 'The Slack username which will be shown. Leave blank for webhook integration default.', 'input_type': 'text' }, {'label': 'Slack Icon', 'value': self.icon_emoji, - 'description': 'Your icon you wish to show, use Slack emoji or image url', + 'description': 'The icon you wish to show, use Slack emoji or image url. Leave blank for webhook integration default.', 'name': 'slack_icon_emoji', 'input_type': 'text' - }, - {'label': 'Test Event', - 'value': 'Test Event', - 'name': 'testSlack', - 'description': 'Test if Slack notifications are working. See logs for troubleshooting.', - 'input_type': 'button' - } + } ] return config_option