From e7efb3f804146989eae8b12971e240daf85e4507 Mon Sep 17 00:00:00 2001 From: Safihre Date: Wed, 26 Feb 2020 13:50:19 +0100 Subject: [PATCH] Use PyObjC instead of C-module to send notifications on macOS --- .travis.yml | 1 + SABnzbd.py | 3 +- po/main/SABnzbd.pot | 140 ++++++++++++-------------- sabnzbd/interface.py | 2 +- sabnzbd/notifier.py | 280 ++++++++++++++++++++++++--------------------------- 5 files changed, 198 insertions(+), 228 deletions(-) diff --git a/.travis.yml b/.travis.yml index 774ebb8..04d746c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,6 +68,7 @@ script: sabnzbd/misc.py sabnzbd/lang.py sabnzbd/nzbparser.py + sabnzbd/notifier.py sabnzbd/rss.py sabnzbd/par2file.py sabnzbd/version.py diff --git a/SABnzbd.py b/SABnzbd.py index 2841ea1..c63a9a9 100755 --- a/SABnzbd.py +++ b/SABnzbd.py @@ -1384,8 +1384,7 @@ def main(): if sabnzbd.FOUNDATION: import sabnzbd.osxmenu sabnzbd.osxmenu.notify("SAB_Launched", None) - notifier.send_notification('SABnzbd%s' % notifier.hostname(), - T('SABnzbd %s started') % sabnzbd.__version__, 'startup') + notifier.send_notification('SABnzbd', T('SABnzbd %s started') % sabnzbd.__version__, 'startup') # Now's the time to check for a new version check_latest_version() autorestarted = False diff --git a/po/main/SABnzbd.pot b/po/main/SABnzbd.pot index a8dd7a0..832402a 100644 --- a/po/main/SABnzbd.pot +++ b/po/main/SABnzbd.pot @@ -12,7 +12,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 7bit\n" -"POT-Creation-Date: 2020-02-22 10:13+0100\n" +"POT-Creation-Date: 2020-02-26 13:46+0100\n" "Generated-By: pygettext.py 1.5\n" @@ -104,62 +104,6 @@ msgstr "" msgid "SABnzbd shutdown finished" msgstr "" -#: sabnzbd/utils/servertests.py -msgid "The hostname is not set." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "There are no connections set. Please set at least one connection." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Password masked in ******, please re-enter" -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Invalid server details" -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Timed out: Try enabling SSL or connecting on a different port." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Timed out" -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Unknown SSL protocol: Try disabling SSL or connecting on a different port." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Invalid server address." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Server quit during login sequence." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Server requires username and password." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Connection Successful!" -msgstr "" - -#: sabnzbd/utils/servertests.py # sabnzbd/interface.py # sabnzbd/newswrapper.py -msgid "Authentication failed, check username/password." -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Too many connections, please pause downloading or try again later" -msgstr "" - -#: sabnzbd/utils/servertests.py -msgid "Could not determine connection result (%s)" -msgstr "" - #: sabnzbd/__init__.py [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "" @@ -606,6 +550,10 @@ msgstr "" msgid "Try our new skin Glitter! Fresh new design that is optimized for desktop and mobile devices. Go to Config -> General to change your skin." msgstr "" +#: sabnzbd/interface.py # sabnzbd/newswrapper.py # sabnzbd/utils/servertests.py +msgid "Authentication failed, check username/password." +msgstr "" + #: sabnzbd/interface.py msgid "Unsuccessful login attempt from %s" msgstr "" @@ -998,6 +946,10 @@ msgstr "" msgid "Not available" msgstr "" +#: sabnzbd/notifier.py +msgid "Failed to send macOS notification" +msgstr "" + #: sabnzbd/notifier.py [Warning message] # sabnzbd/notifier.py msgid "Failed to send Prowl message" msgstr "" @@ -1470,7 +1422,7 @@ msgstr "" msgid "Indexer id (%s) not found for ratings file" msgstr "" -#: sabnzbd/rating.py # sabnzbd/skintext.py [Address of Growl server] +#: sabnzbd/rating.py msgid "Server address" msgstr "" @@ -3558,26 +3510,6 @@ msgstr "" msgid "Notification Sent!" msgstr "" -#: sabnzbd/skintext.py [Header Growl section] -msgid "Growl" -msgstr "" - -#: sabnzbd/skintext.py [Don't translate "Growl"] -msgid "Enable Growl" -msgstr "" - -#: sabnzbd/skintext.py [Don't translate "Growl"] -msgid "Only use for remote Growl server (host:port)" -msgstr "" - -#: sabnzbd/skintext.py [Growl server password] -msgid "Server password" -msgstr "" - -#: sabnzbd/skintext.py [Don't translate "Growl"] -msgid "Optional password for Growl server" -msgstr "" - #: sabnzbd/skintext.py [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "" @@ -4510,3 +4442,55 @@ msgstr "" msgid "URL Fetching failed; %s" msgstr "" +#: sabnzbd/utils/servertests.py +msgid "The hostname is not set." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "There are no connections set. Please set at least one connection." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Password masked in ******, please re-enter" +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Invalid server details" +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Timed out: Try enabling SSL or connecting on a different port." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Timed out" +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Unknown SSL protocol: Try disabling SSL or connecting on a different port." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Invalid server address." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Server quit during login sequence." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Server requires username and password." +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Connection Successful!" +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Too many connections, please pause downloading or try again later" +msgstr "" + +#: sabnzbd/utils/servertests.py +msgid "Could not determine connection result (%s)" +msgstr "" + diff --git a/sabnzbd/interface.py b/sabnzbd/interface.py index 49e8948..ba37b68 100644 --- a/sabnzbd/interface.py +++ b/sabnzbd/interface.py @@ -2554,7 +2554,7 @@ class ConfigNotify: conf['categories'] = list_cats(False) conf['lastmail'] = self.__lastmail conf['have_ntfosd'] = sabnzbd.notifier.have_ntfosd() - conf['have_ncenter'] = sabnzbd.DARWIN and bool(sabnzbd.notifier.ncenter_path()) + conf['have_ncenter'] = sabnzbd.DARWIN and sabnzbd.FOUNDATION conf['scripts'] = list_scripts(default=False, none=True) for kw in LIST_EMAIL: diff --git a/sabnzbd/notifier.py b/sabnzbd/notifier.py index 2003ac3..b8609ef 100644 --- a/sabnzbd/notifier.py +++ b/sabnzbd/notifier.py @@ -32,13 +32,16 @@ from threading import Thread import sabnzbd import sabnzbd.cfg from sabnzbd.encoding import platform_btou -from sabnzbd.constants import NOTIFY_KEYS -from sabnzbd.misc import split_host from sabnzbd.filesystem import make_script_path from sabnzbd.newsunpack import external_script +if sabnzbd.FOUNDATION: + import Foundation + import objc + try: import warnings + # Make any warnings exceptions, so that pynotify is ignored # PyNotify will not work with Python 2.5 (due to next three lines) with warnings.catch_warnings(): @@ -47,8 +50,8 @@ try: _HAVE_NTFOSD = True # Check for working version, not all pynotify are the same - if not hasattr(pynotify, 'init'): - _HAVE_NTFOSD = False + if not hasattr(pynotify, "init"): + _HAVE_NTFOSD = False except: _HAVE_NTFOSD = False @@ -58,26 +61,26 @@ except: ############################################################################## TT = lambda x: x NOTIFICATION = { - 'startup': TT('Startup/Shutdown'), #: Notification - 'download': TT('Added NZB'), #: Notification - 'pp': TT('Post-processing started'), # : Notification - 'complete': TT('Job finished'), #: Notification - 'failed': TT('Job failed'), #: Notification - 'warning': TT('Warning'), #: Notification - 'error': TT('Error'), #: Notification - 'disk_full': TT('Disk full'), #: Notification - 'queue_done': TT('Queue finished'), #: Notification - 'new_login': TT('User logged in'), #: Notification - 'other': TT('Other Messages') #: Notification + "startup": TT("Startup/Shutdown"), #: Notification + "download": TT("Added NZB"), #: Notification + "pp": TT("Post-processing started"), # : Notification + "complete": TT("Job finished"), #: Notification + "failed": TT("Job failed"), #: Notification + "warning": TT("Warning"), #: Notification + "error": TT("Error"), #: Notification + "disk_full": TT("Disk full"), #: Notification + "queue_done": TT("Queue finished"), #: Notification + "new_login": TT("User logged in"), #: Notification + "other": TT("Other Messages"), #: Notification } def get_icon(): - icon = os.path.join(os.path.join(sabnzbd.DIR_PROG, 'icons'), 'sabnzbd.ico') + icon = os.path.join(os.path.join(sabnzbd.DIR_PROG, "icons"), "sabnzbd.ico") if not os.path.isfile(icon): - icon = os.path.join(sabnzbd.DIR_PROG, 'sabnzbd.ico') + icon = os.path.join(sabnzbd.DIR_PROG, "sabnzbd.ico") if os.path.isfile(icon): - fp = open(icon, 'rb') + fp = open(icon, "rb") icon = fp.read() fp.close() else: @@ -93,18 +96,18 @@ def have_ntfosd(): def check_classes(gtype, section): """ Check if `gtype` is enabled in `section` """ try: - return sabnzbd.config.get_config(section, '%s_prio_%s' % (section, gtype))() > 0 + return sabnzbd.config.get_config(section, "%s_prio_%s" % (section, gtype))() > 0 except TypeError: - logging.debug('Incorrect Notify option %s:%s_prio_%s', section, section, gtype) + logging.debug("Incorrect Notify option %s:%s_prio_%s", section, section, gtype) return False def get_prio(gtype, section): """ Check prio of `gtype` in `section` """ try: - return sabnzbd.config.get_config(section, '%s_prio_%s' % (section, gtype))() + return sabnzbd.config.get_config(section, "%s_prio_%s" % (section, gtype))() except TypeError: - logging.debug('Incorrect Notify option %s:%s_prio_%s', section, section, gtype) + logging.debug("Incorrect Notify option %s:%s_prio_%s", section, section, gtype) return -1000 @@ -117,10 +120,10 @@ def check_cat(section, job_cat, keyword=None): try: if not keyword: keyword = section - section_cats = sabnzbd.config.get_config(section, '%s_cats' % keyword)() - return ['*'] == section_cats or job_cat in section_cats + section_cats = sabnzbd.config.get_config(section, "%s_cats" % keyword)() + return ["*"] == section_cats or job_cat in section_cats except TypeError: - logging.debug('Incorrect Notify option %s:%s_cats', section, section) + logging.debug("Incorrect Notify option %s:%s_cats", section, section) return True @@ -128,37 +131,37 @@ def send_notification(title, msg, gtype, job_cat=None): """ Send Notification message """ # Notification Center if sabnzbd.DARWIN and sabnzbd.cfg.ncenter_enable(): - if check_classes(gtype, 'ncenter') and check_cat('ncenter', job_cat): + if check_classes(gtype, "ncenter") and check_cat("ncenter", job_cat): send_notification_center(title, msg, gtype) # Windows if sabnzbd.WIN32 and sabnzbd.cfg.acenter_enable(): - if check_classes(gtype, 'acenter') and check_cat('acenter', job_cat): + if check_classes(gtype, "acenter") and check_cat("acenter", job_cat): send_windows(title, msg, gtype) # Prowl - if sabnzbd.cfg.prowl_enable() and check_cat('prowl', job_cat): + if sabnzbd.cfg.prowl_enable() and check_cat("prowl", job_cat): if sabnzbd.cfg.prowl_apikey(): Thread(target=send_prowl, args=(title, msg, gtype)).start() # Pushover - if sabnzbd.cfg.pushover_enable() and check_cat('pushover', job_cat): + if sabnzbd.cfg.pushover_enable() and check_cat("pushover", job_cat): if sabnzbd.cfg.pushover_token(): Thread(target=send_pushover, args=(title, msg, gtype)).start() # Pushbullet - if sabnzbd.cfg.pushbullet_enable() and check_cat('pushbullet', job_cat): - if sabnzbd.cfg.pushbullet_apikey() and check_classes(gtype, 'pushbullet'): + if sabnzbd.cfg.pushbullet_enable() and check_cat("pushbullet", job_cat): + if sabnzbd.cfg.pushbullet_apikey() and check_classes(gtype, "pushbullet"): Thread(target=send_pushbullet, args=(title, msg, gtype)).start() # Notification script. - if sabnzbd.cfg.nscript_enable() and check_cat('nscript', job_cat): + if sabnzbd.cfg.nscript_enable() and check_cat("nscript", job_cat): if sabnzbd.cfg.nscript_script(): Thread(target=send_nscript, args=(title, msg, gtype)).start() # NTFOSD if have_ntfosd() and sabnzbd.cfg.ntfosd_enable(): - if check_classes(gtype, 'ntfosd') and check_cat('ntfosd', job_cat): + if check_classes(gtype, "ntfosd") and check_cat("ntfosd", job_cat): send_notify_osd(title, msg) @@ -166,17 +169,19 @@ def send_notification(title, msg, gtype, job_cat=None): # Ubuntu NotifyOSD Support ############################################################################## _NTFOSD = False + + def send_notify_osd(title, message): """ Send a message to NotifyOSD """ global _NTFOSD if not _HAVE_NTFOSD: - return T('Not available') # : Function is not available on this OS + return T("Not available") # : Function is not available on this OS - error = 'NotifyOSD not working' - icon = os.path.join(sabnzbd.DIR_PROG, 'sabnzbd.ico') - _NTFOSD = _NTFOSD or pynotify.init('icon-summary-body') + error = "NotifyOSD not working" + icon = os.path.join(sabnzbd.DIR_PROG, "sabnzbd.ico") + _NTFOSD = _NTFOSD or pynotify.init("icon-summary-body") if _NTFOSD: - logging.info('Send to NotifyOSD: %s / %s', title, message) + logging.info("Send to NotifyOSD: %s / %s", title, message) try: note = pynotify.Notification(title, message, icon) note.show() @@ -189,88 +194,64 @@ def send_notify_osd(title, message): return error -def ncenter_path(): - """ Return path of Notification Center tool, if it exists """ - tool = os.path.normpath(os.path.join(sabnzbd.DIR_PROG, '../Resources/SABnzbd.app/Contents/MacOS/SABnzbd')) - if os.path.exists(tool): - return tool - else: - return None - - def send_notification_center(title, msg, gtype): - """ Send message to Mountain Lion's Notification Center """ - tool = ncenter_path() - if tool: - try: - command = [tool, '-title', title, '-message', msg, '-group', T(NOTIFICATION.get(gtype, 'other'))] - proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) - output = platform_btou(proc.stdout.read()) - proc.wait() - if 'Notification delivered' in output or 'Removing previously' in output: - output = '' - except: - logging.info('Cannot run notifier "%s"', tool) - logging.debug("Traceback: ", exc_info=True) - output = 'Notifier tool crashed' - else: - output = 'Notifier app not found' - return output.strip('*\n ') - - -def hostname(host=True): - """ Return host's pretty name """ - if sabnzbd.WIN32: - sys_name = os.environ.get('computername', 'unknown') - else: - try: - sys_name = os.uname()[1] - except: - sys_name = 'unknown' - if host: - return '@%s' % sys_name.lower() - else: - return '' + """ Send message to macOS Notification Center """ + try: + NSUserNotification = objc.lookUpClass("NSUserNotification") + NSUserNotificationCenter = objc.lookUpClass("NSUserNotificationCenter") + notification = NSUserNotification.alloc().init() + notification.setTitle_(title) + notification.setSubtitle_(T(NOTIFICATION.get(gtype, "other"))) + notification.setInformativeText_(msg) + notification.setSoundName_("NSUserNotificationDefaultSoundName") + notification.setDeliveryDate_(Foundation.NSDate.dateWithTimeInterval_sinceDate_(0, Foundation.NSDate.date())) + NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification) + except: + logging.info(T("Failed to send macOS notification")) + logging.debug("Traceback: ", exc_info=True) + return T("Failed to send macOS notification") def send_prowl(title, msg, gtype, force=False, test=None): """ Send message to Prowl """ if test: - apikey = test.get('prowl_apikey') + apikey = test.get("prowl_apikey") else: apikey = sabnzbd.cfg.prowl_apikey() if not apikey: - return T('Cannot send, missing required data') + return T("Cannot send, missing required data") - title = T(NOTIFICATION.get(gtype, 'other')) - title = urllib.parse.quote(title.encode('utf8')) - msg = urllib.parse.quote(msg.encode('utf8')) - prio = get_prio(gtype, 'prowl') + title = T(NOTIFICATION.get(gtype, "other")) + title = urllib.parse.quote(title.encode("utf8")) + msg = urllib.parse.quote(msg.encode("utf8")) + prio = get_prio(gtype, "prowl") if force: prio = 0 if prio > -3: - url = 'https://api.prowlapp.com/publicapi/add?apikey=%s&application=SABnzbd' \ - '&event=%s&description=%s&priority=%d' % (apikey, title, msg, prio) + url = ( + "https://api.prowlapp.com/publicapi/add?apikey=%s&application=SABnzbd" + "&event=%s&description=%s&priority=%d" % (apikey, title, msg, prio) + ) try: urllib.request.urlopen(url) - return '' + return "" except: - logging.warning(T('Failed to send Prowl message')) + logging.warning(T("Failed to send Prowl message")) logging.info("Traceback: ", exc_info=True) - return T('Failed to send Prowl message') - return '' + return T("Failed to send Prowl message") + return "" def send_pushover(title, msg, gtype, force=False, test=None): """ Send message to pushover """ if test: - apikey = test.get('pushover_token') - userkey = test.get('pushover_userkey') - device = test.get('pushover_device') + apikey = test.get("pushover_token") + userkey = test.get("pushover_userkey") + device = test.get("pushover_device") else: apikey = sabnzbd.cfg.pushover_token() userkey = sabnzbd.cfg.pushover_userkey() @@ -278,101 +259,107 @@ def send_pushover(title, msg, gtype, force=False, test=None): emergency_retry = sabnzbd.cfg.pushover_emergency_retry() emergency_expire = sabnzbd.cfg.pushover_emergency_expire() if not apikey or not userkey: - return T('Cannot send, missing required data') + return T("Cannot send, missing required data") - title = T(NOTIFICATION.get(gtype, 'other')) - prio = get_prio(gtype, 'pushover') + title = T(NOTIFICATION.get(gtype, "other")) + prio = get_prio(gtype, "pushover") if force: prio = 1 if prio == 2: - body = { "token": apikey, - "user": userkey, - "device": device, - "title": title, - "message": msg, - "priority": prio, - "retry": emergency_retry, - "expire": emergency_expire + body = { + "token": apikey, + "user": userkey, + "device": device, + "title": title, + "message": msg, + "priority": prio, + "retry": emergency_retry, + "expire": emergency_expire, } return do_send_pushover(body) if -3 < prio < 2: - body = { "token": apikey, - "user": userkey, - "device": device, - "title": title, - "message": msg, - "priority": prio, + body = { + "token": apikey, + "user": userkey, + "device": device, + "title": title, + "message": msg, + "priority": prio, } return do_send_pushover(body) + def do_send_pushover(body): try: conn = http.client.HTTPSConnection("api.pushover.net:443") - conn.request("POST", "/1/messages.json", urllib.parse.urlencode(body), - {"Content-type": "application/x-www-form-urlencoded"}) + conn.request( + "POST", + "/1/messages.json", + urllib.parse.urlencode(body), + {"Content-type": "application/x-www-form-urlencoded"}, + ) res = conn.getresponse() if res.status != 200: - logging.error(T('Bad response from Pushover (%s): %s'), res.status, res.read()) - return T('Failed to send pushover message') + logging.error(T("Bad response from Pushover (%s): %s"), res.status, res.read()) + return T("Failed to send pushover message") else: - return '' + return "" except: - logging.warning(T('Failed to send pushover message')) + logging.warning(T("Failed to send pushover message")) logging.info("Traceback: ", exc_info=True) - return T('Failed to send pushover message') + return T("Failed to send pushover message") + def send_pushbullet(title, msg, gtype, force=False, test=None): """ Send message to Pushbullet """ if test: - apikey = test.get('pushbullet_apikey') - device = test.get('pushbullet_device') + apikey = test.get("pushbullet_apikey") + device = test.get("pushbullet_device") else: apikey = sabnzbd.cfg.pushbullet_apikey() device = sabnzbd.cfg.pushbullet_device() if not apikey: - return T('Cannot send, missing required data') + return T("Cannot send, missing required data") - title = 'SABnzbd: ' + T(NOTIFICATION.get(gtype, 'other')) + title = "SABnzbd: " + T(NOTIFICATION.get(gtype, "other")) try: - conn = http.client.HTTPSConnection('api.pushbullet.com:443') - conn.request('POST', '/v2/pushes', - json.dumps({ - 'type': 'note', - 'device': device, - 'title': title, - 'body': msg}), - headers={'Authorization': 'Bearer ' + apikey, - 'Content-type': 'application/json'}) + conn = http.client.HTTPSConnection("api.pushbullet.com:443") + conn.request( + "POST", + "/v2/pushes", + json.dumps({"type": "note", "device": device, "title": title, "body": msg}), + headers={"Authorization": "Bearer " + apikey, "Content-type": "application/json"}, + ) res = conn.getresponse() if res.status != 200: - logging.error(T('Bad response from Pushbullet (%s): %s'), res.status, res.read()) + logging.error(T("Bad response from Pushbullet (%s): %s"), res.status, res.read()) else: - logging.info('Successfully sent to Pushbullet') + logging.info("Successfully sent to Pushbullet") except: - logging.warning(T('Failed to send pushbullet message')) - logging.info('Traceback: ', exc_info=True) - return T('Failed to send pushbullet message') - return '' + logging.warning(T("Failed to send pushbullet message")) + logging.info("Traceback: ", exc_info=True) + return T("Failed to send pushbullet message") + return "" def send_nscript(title, msg, gtype, force=False, test=None): """ Run user's notification script """ if test: - script = test.get('nscript_script') - parameters = test.get('nscript_parameters') + script = test.get("nscript_script") + parameters = test.get("nscript_parameters") else: script = sabnzbd.cfg.nscript_script() parameters = sabnzbd.cfg.nscript_parameters() if not script: - return T('Cannot send, missing required data') - title = 'SABnzbd: ' + T(NOTIFICATION.get(gtype, 'other')) + return T("Cannot send, missing required data") + title = "SABnzbd: " + T(NOTIFICATION.get(gtype, "other")) - if force or check_classes(gtype, 'nscript'): + if force or check_classes(gtype, "nscript"): script_path = make_script_path(script) if script_path: output, ret = external_script(script_path, gtype, title, msg, parameters) @@ -380,10 +367,10 @@ def send_nscript(title, msg, gtype, force=False, test=None): logging.error(T('Script returned exit code %s and output "%s"') % (ret, output)) return T('Script returned exit code %s and output "%s"') % (ret, output) else: - logging.info('Successfully executed notification script ' + script_path) + logging.info("Successfully executed notification script " + script_path) else: return T('Notification script "%s" does not exist') % script_path - return '' + return "" def send_windows(title, msg, gtype): @@ -391,8 +378,7 @@ def send_windows(title, msg, gtype): try: sabnzbd.WINTRAY.sendnotification(title, msg) except: - logging.info(T('Failed to send Windows notification')) + logging.info(T("Failed to send Windows notification")) logging.debug("Traceback: ", exc_info=True) - return T('Failed to send Windows notification') + return T("Failed to send Windows notification") return None -