diff --git a/CHANGES.md b/CHANGES.md index cb9e935b..c9bc3651 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -91,6 +91,8 @@ * Update jsonrpclib library r20 to (b59217c) * Change cachecontrol library to ensure cache file exists before attempting delete * Fix saving root dirs +* Change pushbullet from urllib2 to requests +* Change to make pushbullet error messages clearer [develop changelog] * Update Requests library 2.7.0 (ab1f493) to 2.7.0 (8b5e457) diff --git a/gui/slick/js/configNotifications.js b/gui/slick/js/configNotifications.js index e6469a3e..62dcd4e3 100644 --- a/gui/slick/js/configNotifications.js +++ b/gui/slick/js/configNotifications.js @@ -489,10 +489,11 @@ $(document).ready(function(){ $.get(sbRoot + '/home/getPushbulletDevices', {'accessToken': pushbullet_access_token}) .done(function (data) { var devices = jQuery.parseJSON(data || '{}').devices; + var error = jQuery.parseJSON(data || '{}').error; $('#pushbullet_device_list').html(''); + if (devices) { // add default option to send to all devices $('#pushbullet_device_list').append(''); - if (devices) { for (var i = 0; i < devices.length; i++) { // only list active device targets if (devices[i].active == true) { @@ -507,7 +508,11 @@ $(document).ready(function(){ } $('#getPushbulletDevices').prop('disabled', false); if (msg) { - $('#testPushbullet-result').html(msg); + if (error.message) { + $('#testPushbullet-result').html(error.message); + } else { + $('#testPushbullet-result').html(msg); + } } }); diff --git a/sickbeard/notifiers/pushbullet.py b/sickbeard/notifiers/pushbullet.py index 7254cc68..71349254 100644 --- a/sickbeard/notifiers/pushbullet.py +++ b/sickbeard/notifiers/pushbullet.py @@ -16,16 +16,13 @@ # You should have received a copy of the GNU General Public License # along with SickGear. If not, see . -import urllib -import urllib2 -import socket import base64 - +import simplejson as json import sickbeard from sickbeard import logger from sickbeard.common import notifyStrings, NOTIFY_SNATCH, NOTIFY_DOWNLOAD, NOTIFY_SUBTITLE_DOWNLOAD, NOTIFY_GIT_UPDATE, NOTIFY_GIT_UPDATE_TEXT -from sickbeard.exceptions import ex +import requests PUSHAPI_ENDPOINT = 'https://api.pushbullet.com/v2/pushes' DEVICEAPI_ENDPOINT = 'https://api.pushbullet.com/v2/devices' @@ -40,54 +37,38 @@ class PushbulletNotifier: # get devices from pushbullet try: - req = urllib2.Request(DEVICEAPI_ENDPOINT) base64string = base64.encodestring('%s:%s' % (accessToken, ''))[:-1] - req.add_header('Authorization', 'Basic %s' % base64string) - handle = urllib2.urlopen(req) - if handle: - result = handle.read() - handle.close() - return result - except urllib2.URLError: - return None - except socket.timeout: - return None + headers = {'Authorization': 'Basic %s' % base64string} + return requests.get(DEVICEAPI_ENDPOINT, headers=headers).text + except Exception as e: + return json.dumps({'error': {'message': 'Error failed to connect: %s' % e}}) def _sendPushbullet(self, title, body, accessToken, device_iden): # build up the URL and parameters - body = body.strip().encode('utf-8') - - data = urllib.urlencode({ + payload = { 'type': 'note', 'title': title, - 'body': body, + 'body': body.strip().encode('utf-8'), 'device_iden': device_iden - }) + } # send the request to pushbullet try: - req = urllib2.Request(PUSHAPI_ENDPOINT) base64string = base64.encodestring('%s:%s' % (accessToken, ''))[:-1] - req.add_header('Authorization', 'Basic %s' % base64string) - handle = urllib2.urlopen(req, data) - handle.close() - except socket.timeout: - return False - except urllib2.URLError as e: + headers = {'Authorization': 'Basic %s' % base64string, 'Content-Type': 'application/json'} + result = requests.post(PUSHAPI_ENDPOINT, headers=headers, data=json.dumps(payload)) + result.raise_for_status() + except Exception as e: + try: + e = result.json()['error']['message'] + except: + pass + logger.log(u'PUSHBULLET: %s' % e, logger.WARNING) + return 'Error sending Pushbullet notification: %s' % e - if e.code == 404: - logger.log(u'PUSHBULLET: Access token is wrong/not associated to a device.', logger.ERROR) - elif e.code == 401: - logger.log(u'PUSHBULLET: Unauthorized, not a valid access token.', logger.ERROR) - elif e.code == 400: - logger.log(u'PUSHBULLET: Bad request, missing required parameter.', logger.ERROR) - elif e.code == 503: - logger.log(u'PUSHBULLET: Pushbullet server to busy to handle the request at this time.', logger.WARNING) - return False - - logger.log(u'PUSHBULLET: Notification successful.', logger.MESSAGE) - return True + logger.log(u'PUSHBULLET: Pushbullet notification succeeded', logger.MESSAGE) + return 'Pushbullet notification succeeded' def _notifyPushbullet(self, title, body, accessToken=None, device_iden=None, force=False): """ diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 3a0a4103..81716633 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -953,11 +953,7 @@ class Home(MainHandler): if None is not accessToken and starify(accessToken, True): accessToken = sickbeard.PUSHBULLET_ACCESS_TOKEN - result = notifiers.pushbullet_notifier.test_notify(accessToken, device_iden) - if result: - return 'Pushbullet notification succeeded. Check your device to make sure it worked' - else: - return 'Error sending Pushbullet notification' + return notifiers.pushbullet_notifier.test_notify(accessToken, device_iden) def getPushbulletDevices(self, accessToken=None): self.set_header('Cache-Control', 'max-age=0,no-cache,no-store') @@ -965,11 +961,7 @@ class Home(MainHandler): if None is not accessToken and starify(accessToken, True): accessToken = sickbeard.PUSHBULLET_ACCESS_TOKEN - result = notifiers.pushbullet_notifier.get_devices(accessToken) - if result: - return result - else: - return 'Error sending Pushbullet notification' + return notifiers.pushbullet_notifier.get_devices(accessToken) def shutdown(self, pid=None):