From 7333d19e1c343dd03292d5736f40900cf9d11ef5 Mon Sep 17 00:00:00 2001 From: Safihre Date: Sat, 15 Jul 2017 22:22:20 +0200 Subject: [PATCH] Notifications selection based on Categories Closes #716 --- interfaces/Config/templates/config_notify.tmpl | 106 ++++++++++++++------- .../Config/templates/staticcfg/css/style.css | 3 +- sabnzbd/cfg.py | 11 ++- sabnzbd/emailer.py | 4 + sabnzbd/interface.py | 19 ++-- sabnzbd/notifier.py | 35 ++++--- sabnzbd/nzbqueue.py | 2 +- sabnzbd/postproc.py | 8 +- sabnzbd/urlgrabber.py | 2 +- 9 files changed, 127 insertions(+), 63 deletions(-) diff --git a/interfaces/Config/templates/config_notify.tmpl b/interfaces/Config/templates/config_notify.tmpl index dc81274..ad51be6 100644 --- a/interfaces/Config/templates/config_notify.tmpl +++ b/interfaces/Config/templates/config_notify.tmpl @@ -13,6 +13,18 @@ + +
0 then '' else 'style="display:none"'#-->> +
+ $T('affectedCat')
+ +
+ +
@@ -20,7 +32,15 @@

$T('cmenu-email')

-
+
0 then '' else 'style="display:none"'#-->> + $T('affectedCat')
+ +
+
@@ -79,8 +99,8 @@
-
-
+ +
@@ -91,7 +111,7 @@ -
+
0 then '' else 'style="display:none"'#-->>
$show_notify_checkboxes('ncenter') @@ -103,8 +123,8 @@
- - + +
@@ -116,7 +136,8 @@ -
+ $show_cat_box('acenter') +
0 then '' else 'style="display:none"'#-->>
$show_notify_checkboxes('acenter') @@ -128,8 +149,8 @@
- - + +
@@ -141,7 +162,8 @@ -
+ $show_cat_box('ntfosd') +
0 then '' else 'style="display:none"'#-->>
$show_notify_checkboxes('ntfosd') @@ -153,8 +175,8 @@
- - + +
@@ -165,7 +187,8 @@ -
+ $show_cat_box('growl') +
0 then '' else 'style="display:none"'#-->>
@@ -187,8 +210,8 @@
-
- + +

$T('section-Prowl')

@@ -199,7 +222,8 @@ $T('explain-prowl_enable') -
+ $show_cat_box('prowl') +
0 then '' else 'style="display:none"'#-->>
@@ -231,8 +255,8 @@
-
- + +
@@ -244,7 +268,8 @@ $T('explain-pushover_enable') -
+ $show_cat_box('pushover') +
0 then '' else 'style="display:none"'#-->>
@@ -286,8 +311,8 @@
-
- + +

$T('section-Pushbullet')

@@ -298,7 +323,8 @@ $T('explain-pushbullet_enable') -
+ $show_cat_box('pushbullet') +
0 then '' else 'style="display:none"'#-->>
@@ -322,19 +348,20 @@
-
- + +
-

$T('section-NScript')

- - - - - -
0 then 'checked="checked"' else ""#--> />
- $T('explain-nscript_enable') -
+

$T('section-NScript')

+ + + + + +
0 then 'checked="checked"' else ""#--> />
+ $T('explain-nscript_enable') + $show_cat_box('nscript') +
0 then '' else 'style="display:none"'#-->>
@@ -360,8 +387,8 @@
-
- + + @@ -374,11 +401,20 @@ \$('.col2 input[name$="enable"]').change(function() { if(this.checked) { \$(this).parents('.section').find('.col1').show() + \$(this).parents('.col2').find('.col2-cats').show() } else { \$(this).parents('.section').find('.col1').hide() + \$(this).parents('.col2').find('.col2-cats').hide() } \$('form').submit() }) + \$('#email_endjob').change(function() { + if(\$(this).val() > 0) { + \$(this).parents('.section').find('.col2-cats').show() + } else { + \$(this).parents('.section').find('.col2-cats').hide() + } + }) /** Testing functions diff --git a/interfaces/Config/templates/staticcfg/css/style.css b/interfaces/Config/templates/staticcfg/css/style.css index 57b0117..7333b6f 100644 --- a/interfaces/Config/templates/staticcfg/css/style.css +++ b/interfaces/Config/templates/staticcfg/css/style.css @@ -137,7 +137,8 @@ input[type="checkbox"]+.desc { font-style: italic; padding: 0 1px; } -.col2 p { +.col2 p, +.col2-cats { font-size: 12px; color: #666; margin: 1em 0; diff --git a/sabnzbd/cfg.py b/sabnzbd/cfg.py index e5fc1eb..7fcc738 100644 --- a/sabnzbd/cfg.py +++ b/sabnzbd/cfg.py @@ -74,6 +74,7 @@ email_endjob = OptionNumber('misc', 'email_endjob', 0, 0, 2) email_full = OptionBool('misc', 'email_full', False) email_dir = OptionDir('misc', 'email_dir', create=True) email_rss = OptionBool('misc', 'email_rss', False) +email_cats = OptionList('misc', 'email_cats', ['*']) version_check = OptionNumber('misc', 'check_new_rel', 1) autobrowser = OptionBool('misc', 'auto_browser', True) @@ -172,7 +173,7 @@ movie_categories = OptionList('misc', 'movie_categories', ['movies']) enable_date_sorting = OptionBool('misc', 'enable_date_sorting', False) date_sort_string = OptionStr('misc', 'date_sort_string') -date_categories = OptionStr('misc', 'date_categories', ['tv']) +date_categories = OptionList('misc', 'date_categories', ['tv']) configlock = OptionBool('misc', 'config_lock', 0) @@ -245,6 +246,7 @@ fixed_ports = OptionBool('misc', 'fixed_ports', False) # [ncenter] ncenter_enable = OptionBool('ncenter', 'ncenter_enable', sabnzbd.DARWIN) +ncenter_cats = OptionList('ncenter', 'ncenter_cats', ['*']) ncenter_prio_startup = OptionBool('ncenter', 'ncenter_prio_startup', True) ncenter_prio_download = OptionBool('ncenter', 'ncenter_prio_download', False) ncenter_prio_pp = OptionBool('ncenter', 'ncenter_prio_pp', False) @@ -259,6 +261,7 @@ ncenter_prio_other = OptionBool('ncenter', 'ncenter_prio_other', False) # [acenter] acenter_enable = OptionBool('acenter', 'acenter_enable', sabnzbd.WIN32) +acenter_cats = OptionList('acenter', 'acenter_cats', ['*']) acenter_prio_startup = OptionBool('acenter', 'acenter_prio_startup', False) acenter_prio_download = OptionBool('acenter', 'acenter_prio_download', False) acenter_prio_pp = OptionBool('acenter', 'acenter_prio_pp', False) @@ -273,6 +276,7 @@ acenter_prio_other = OptionBool('acenter', 'acenter_prio_other', False) # [ntfosd] ntfosd_enable = OptionBool('ntfosd', 'ntfosd_enable', not sabnzbd.WIN32 and not sabnzbd.DARWIN) +ntfosd_cats = OptionList('ntfosd', 'ntfosd_cats', ['*']) ntfosd_prio_startup = OptionBool('ntfosd', 'ntfosd_prio_startup', True) ntfosd_prio_download = OptionBool('ntfosd', 'ntfosd_prio_download', False) ntfosd_prio_pp = OptionBool('ntfosd', 'ntfosd_prio_pp', False) @@ -287,6 +291,7 @@ ntfosd_prio_other = OptionBool('ntfosd', 'ntfosd_prio_other', False) # [growl] growl_enable = OptionBool('growl', 'growl_enable', False) +growl_cats = OptionList('growl', 'growl_cats', ['*']) growl_server = OptionStr('growl', 'growl_server') growl_password = OptionPassword('growl', 'growl_password') growl_prio_startup = OptionBool('growl', 'growl_prio_startup', True) @@ -303,6 +308,7 @@ growl_prio_other = OptionBool('growl', 'growl_prio_other', False) # [prowl] prowl_enable = OptionBool('prowl', 'prowl_enable', False) +prowl_cats = OptionList('prowl', 'prowl_cats', ['*']) prowl_apikey = OptionStr('prowl', 'prowl_apikey') prowl_prio_startup = OptionNumber('prowl', 'prowl_prio_startup', -3) prowl_prio_download = OptionNumber('prowl', 'prowl_prio_download', -3) @@ -321,6 +327,7 @@ pushover_token = OptionStr('pushover', 'pushover_token') pushover_userkey = OptionStr('pushover', 'pushover_userkey') pushover_device = OptionStr('pushover', 'pushover_device') pushover_enable = OptionBool('pushover', 'pushover_enable') +pushover_cats = OptionList('pushover', 'pushover_cats', ['*']) pushover_prio_startup = OptionNumber('pushover', 'pushover_prio_startup', -3) pushover_prio_download = OptionNumber('pushover', 'pushover_prio_download', -2) pushover_prio_pp = OptionNumber('pushover', 'pushover_prio_pp', -3) @@ -335,6 +342,7 @@ pushover_prio_other = OptionNumber('pushover', 'pushover_prio_other', -3) # [pushbullet] pushbullet_enable = OptionBool('pushbullet', 'pushbullet_enable') +pushbullet_cats = OptionList('pushbullet', 'pushbullet_cats', ['*']) pushbullet_apikey = OptionStr('pushbullet', 'pushbullet_apikey') pushbullet_device = OptionStr('pushbullet', 'pushbullet_device') pushbullet_prio_startup = OptionNumber('pushbullet', 'pushbullet_prio_startup', 0) @@ -351,6 +359,7 @@ pushbullet_prio_other = OptionNumber('pushbullet', 'pushbullet_prio_other', 0) # [nscript] nscript_enable = OptionBool('nscript', 'nscript_enable') +nscript_cats = OptionList('nscript', 'nscript_cats', ['*']) nscript_script = OptionStr('nscript', 'nscript_script') nscript_parameters = OptionStr('nscript', 'nscript_parameters') nscript_prio_startup = OptionBool('nscript', 'nscript_prio_startup', True) diff --git a/sabnzbd/emailer.py b/sabnzbd/emailer.py index 99ddaee..686a83e 100644 --- a/sabnzbd/emailer.py +++ b/sabnzbd/emailer.py @@ -29,6 +29,7 @@ from sabnzbd.constants import * import sabnzbd from sabnzbd.misc import to_units, split_host, time_format from sabnzbd.encoding import EmailFilter +from sabnzbd.notifier import check_cat import sabnzbd.cfg as cfg @@ -216,6 +217,9 @@ def send_with_template(prefix, parm, test=None): def endjob(filename, cat, status, path, bytes, fail_msg, stages, script, script_output, script_ret, test=None): """ Send end-of-job email """ + # Is it allowed? + if not check_cat('email', cat): + return None # Translate the stage names tr = sabnzbd.api.Ttemplate diff --git a/sabnzbd/interface.py b/sabnzbd/interface.py index 007e2f8..ebe3142 100644 --- a/sabnzbd/interface.py +++ b/sabnzbd/interface.py @@ -2695,39 +2695,39 @@ def GetRssLog(feed): ############################################################################## LIST_EMAIL = ( - 'email_endjob', 'email_full', + 'email_endjob', 'email_cats', 'email_full', 'email_server', 'email_to', 'email_from', 'email_account', 'email_pwd', 'email_dir', 'email_rss' ) -LIST_GROWL = ('growl_enable', 'growl_server', 'growl_password', +LIST_GROWL = ('growl_enable', 'growl_cats', 'growl_server', 'growl_password', 'growl_prio_startup', 'growl_prio_download', 'growl_prio_pp', 'growl_prio_complete', 'growl_prio_failed', 'growl_prio_disk_full', 'growl_prio_warning', 'growl_prio_error', 'growl_prio_queue_done', 'growl_prio_other', 'growl_prio_new_login') -LIST_NCENTER = ('ncenter_enable', +LIST_NCENTER = ('ncenter_enable', 'ncenter_cats', 'ncenter_prio_startup', 'ncenter_prio_download', 'ncenter_prio_pp', 'ncenter_prio_complete', 'ncenter_prio_failed', 'ncenter_prio_disk_full', 'ncenter_prio_warning', 'ncenter_prio_error', 'ncenter_prio_queue_done', 'ncenter_prio_other', 'ncenter_prio_new_login') -LIST_ACENTER = ('acenter_enable', +LIST_ACENTER = ('acenter_enable', 'acenter_cats', 'acenter_prio_startup', 'acenter_prio_download', 'acenter_prio_pp', 'acenter_prio_complete', 'acenter_prio_failed', 'acenter_prio_disk_full', 'acenter_prio_warning', 'acenter_prio_error', 'acenter_prio_queue_done', 'acenter_prio_other', 'acenter_prio_new_login') -LIST_NTFOSD = ('ntfosd_enable', +LIST_NTFOSD = ('ntfosd_enable', 'ntfosd_cats', 'ntfosd_prio_startup', 'ntfosd_prio_download', 'ntfosd_prio_pp', 'ntfosd_prio_complete', 'ntfosd_prio_failed', 'ntfosd_prio_disk_full', 'ntfosd_prio_warning', 'ntfosd_prio_error', 'ntfosd_prio_queue_done', 'ntfosd_prio_other', 'ntfosd_prio_new_login') -LIST_PROWL = ('prowl_enable', 'prowl_apikey', +LIST_PROWL = ('prowl_enable', 'prowl_cats', 'prowl_apikey', 'prowl_prio_startup', 'prowl_prio_download', 'prowl_prio_pp', 'prowl_prio_complete', 'prowl_prio_failed', 'prowl_prio_disk_full', 'prowl_prio_warning', 'prowl_prio_error', 'prowl_prio_queue_done', 'prowl_prio_other', 'prowl_prio_new_login') -LIST_PUSHOVER = ('pushover_enable', 'pushover_token', 'pushover_userkey', 'pushover_device', +LIST_PUSHOVER = ('pushover_enable', 'pushover_cats', 'pushover_token', 'pushover_userkey', 'pushover_device', 'pushover_prio_startup', 'pushover_prio_download', 'pushover_prio_pp', 'pushover_prio_complete', 'pushover_prio_failed', 'pushover_prio_disk_full', 'pushover_prio_warning', 'pushover_prio_error', 'pushover_prio_queue_done', 'pushover_prio_other', 'pushover_prio_new_login') -LIST_PUSHBULLET = ('pushbullet_enable', 'pushbullet_apikey', 'pushbullet_device', +LIST_PUSHBULLET = ('pushbullet_enable', 'pushbullet_cats', 'pushbullet_apikey', 'pushbullet_device', 'pushbullet_prio_startup', 'pushbullet_prio_download', 'pushbullet_prio_pp', 'pushbullet_prio_complete', 'pushbullet_prio_failed', 'pushbullet_prio_disk_full', 'pushbullet_prio_warning', 'pushbullet_prio_error', 'pushbullet_prio_queue_done', 'pushbullet_prio_other', 'pushbullet_prio_new_login') -LIST_NSCRIPT = ('nscript_enable', 'nscript_script', 'nscript_parameters', +LIST_NSCRIPT = ('nscript_enable', 'nscript_cats', 'nscript_script', 'nscript_parameters', 'nscript_prio_startup', 'nscript_prio_download', 'nscript_prio_pp', 'nscript_prio_complete', 'nscript_prio_failed', 'nscript_prio_disk_full', 'nscript_prio_warning', 'nscript_prio_error', 'nscript_prio_queue_done', 'nscript_prio_other', 'nscript_prio_new_login') @@ -2749,6 +2749,7 @@ class ConfigNotify(object): conf = build_header(sabnzbd.WEB_DIR_CONFIG) conf['my_home'] = sabnzbd.DIR_HOME + conf['categories'] = list_cats(False) conf['lastmail'] = self.__lastmail conf['have_growl'] = True conf['have_ntfosd'] = sabnzbd.notifier.have_ntfosd() diff --git a/sabnzbd/notifier.py b/sabnzbd/notifier.py index 9000f07..f1de981 100644 --- a/sabnzbd/notifier.py +++ b/sabnzbd/notifier.py @@ -120,7 +120,7 @@ def check_classes(gtype, section): def get_prio(gtype, section): - """ Check if `gtype` is enabled in `section` """ + """ Check prio of `gtype` in `section` """ try: return sabnzbd.config.get_config(section, '%s_prio_%s' % (section, gtype))() except TypeError: @@ -128,20 +128,32 @@ def get_prio(gtype, section): return -1000 -def send_notification(title, msg, gtype): +def check_cat(section, job_cat): + """ Check if `job_cat` is enabled in `section`. * = All """ + if not job_cat: + return True + try: + section_cats = sabnzbd.config.get_config(section, '%s_cats' % section)() + return ('*' in section_cats or job_cat in section_cats) + except TypeError: + logging.debug('Incorrect Notify option %s:%s_prio_%s', section, section, gtype) + return False + + +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'): + 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'): + if check_classes(gtype, 'acenter') and check_cat('acenter', job_cat): send_windows(title, msg, gtype) # Growl - if sabnzbd.cfg.growl_enable() and check_classes(gtype, 'growl'): + if sabnzbd.cfg.growl_enable() and check_classes(gtype, 'growl') and check_cat('growl', job_cat): if _HAVE_CLASSIC_GROWL and not sabnzbd.cfg.growl_server(): return send_local_growl(title, msg, gtype) else: @@ -149,32 +161,33 @@ def send_notification(title, msg, gtype): time.sleep(0.5) # Prowl - if sabnzbd.cfg.prowl_enable(): + 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() time.sleep(0.5) # Pushover - if sabnzbd.cfg.pushover_enable(): + 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() time.sleep(0.5) # Pushbullet - if sabnzbd.cfg.pushbullet_enable(): + 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() time.sleep(0.5) # Notification script. - if sabnzbd.cfg.nscript_enable(): + 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() time.sleep(0.5) # NTFOSD - if have_ntfosd() and sabnzbd.cfg.ntfosd_enable() and check_classes(gtype, 'ntfosd'): - send_notify_osd(title, msg) + if have_ntfosd() and sabnzbd.cfg.ntfosd_enable(): + if check_classes(gtype, 'ntfosd') and check_cat('ntfosd', job_cat): + send_notify_osd(title, msg) def reset_growl(): diff --git a/sabnzbd/nzbqueue.py b/sabnzbd/nzbqueue.py index f868e7e..50fa65c 100644 --- a/sabnzbd/nzbqueue.py +++ b/sabnzbd/nzbqueue.py @@ -398,7 +398,7 @@ class NzbQueue(object): self.save(nzo) if not (quiet or nzo.status in ('Fetching',)): - notifier.send_notification(T('NZB added to queue'), nzo.filename, 'download') + notifier.send_notification(T('NZB added to queue'), nzo.filename, 'download', nzo.cat) if not quiet and cfg.auto_sort(): self.sort_by_avg_age() diff --git a/sabnzbd/postproc.py b/sabnzbd/postproc.py index ba33ddf..df7660e 100644 --- a/sabnzbd/postproc.py +++ b/sabnzbd/postproc.py @@ -500,7 +500,7 @@ def process_job(nzo): logging.info("Traceback: ", exc_info=True) crash_msg = T('see logfile') nzo.fail_msg = T('PostProcessing was aborted (%s)') % unicoder(crash_msg) - notifier.send_notification(T('Download Failed'), filename, 'failed') + notifier.send_notification(T('Download Failed'), filename, 'failed', nzo.cat) nzo.status = Status.FAILED par_error = True all_ok = False @@ -538,10 +538,10 @@ def process_job(nzo): # Show final status in history if all_ok: - notifier.send_notification(T('Download Completed'), filename, 'complete') + notifier.send_notification(T('Download Completed'), filename, 'complete', nzo.cat) nzo.status = Status.COMPLETED else: - notifier.send_notification(T('Download Failed'), filename, 'failed') + notifier.send_notification(T('Download Failed'), filename, 'failed', nzo.cat) nzo.status = Status.FAILED # Log the overall time taken for postprocessing @@ -623,7 +623,7 @@ def is_parfile(fn): def parring(nzo, workdir): """ Perform par processing. Returns: (par_error, re_add) """ filename = nzo.final_name - notifier.send_notification(T('Post-processing'), filename, 'pp') + notifier.send_notification(T('Post-processing'), filename, 'pp', nzo.cat) logging.info('Starting verification and repair of %s', filename) # Get verification status of sets diff --git a/sabnzbd/urlgrabber.py b/sabnzbd/urlgrabber.py index 82122c9..d2bc60d 100644 --- a/sabnzbd/urlgrabber.py +++ b/sabnzbd/urlgrabber.py @@ -361,7 +361,7 @@ def bad_fetch(nzo, url, msg='', content=False): nzo.fail_msg = msg - notifier.send_notification(T('URL Fetching failed; %s') % '', '%s\n%s' % (msg, url), 'other') + notifier.send_notification(T('URL Fetching failed; %s') % '', '%s\n%s' % (msg, url), 'other', nzo.cat) if cfg.email_endjob() > 0: emailer.badfetch_mail(msg, url)