Added support for custom notification script

Closes #458
This commit is contained in:
Dominique Barton
2016-03-19 17:00:48 +01:00
committed by shypike
parent 91f5eea7ba
commit ccba56e073
7 changed files with 158 additions and 5 deletions

View File

@@ -677,6 +677,78 @@
</fieldset>
</div><!-- /col1 -->
</div><!-- /section -->
<div class="section" id="nscript">
<div class="col2">
<h3>$T('section-NScript')</h3>
<table>
<tr>
<td><input type="checkbox" name="nscript_enable" id="nscript_enable" value="1" <!--#if int($nscript_enable) > 0 then 'checked="checked"' else ""#--> /></td>
<td><label for="nscript_enable"> $T('opt-nscript_enable')</label></td>
</tr>
</table>
<em>$T('explain-nscript_enable')</em>
</div><!-- /col2 -->
<div class="col1" <!--#if int($nscript_enable) > 0 then '' else 'style="display:none"'#-->>
<fieldset>
<div class="field-pair">
<label class="config" for="nscript_script">$T('opt-nscript_script')</label>
<select name="nscript_script">
<!--#for $sc in $script_list#-->
<option value="$sc" <!--#if $nscript_script.lower()==$sc.lower() then 'selected="selected"' else ""#-->>$Tspec($sc)</option>
<!--#end for#-->
</select>
<span class="desc">$T('explain-nscript_script')</span>
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_startup">$T($notify_texts['startup']).replace('/', ' / ')</label>
<input type="checkbox" name="nscript_prio_startup" id="nscript_prio_startup" value="1" <!--#if int($nscript_prio_startup) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_download">$T($notify_texts['download']) / $T('link-pause') / $T('link-resume')</label>
<input type="checkbox" name="nscript_prio_download" id="nscript_prio_download" value="1" <!--#if int($nscript_prio_download) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_pp">$T($notify_texts['pp'])</label>
<input type="checkbox" name="nscript_prio_pp" id="nscript_prio_pp" value="1" <!--#if int($nscript_prio_pp) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_complete">$T($notify_texts['complete'])</label>
<input type="checkbox" name="nscript_prio_complete" id="nscript_prio_complete" value="1" <!--#if int($nscript_prio_complete) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_failed">$T($notify_texts['failed'])</label>
<input type="checkbox" name="nscript_prio_failed" id="nscript_prio_failed" value="1" <!--#if int($nscript_prio_failed) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_queue_done">$T($notify_texts['queue_done'])</label>
<input type="checkbox" name="nscript_prio_queue_done" id="nscript_prio_queue_done" value="1" <!--#if int($nscript_prio_queue_done) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_disk_full">$T($notify_texts['disk_full'])</label>
<input type="checkbox" name="nscript_prio_disk_full" id="nscript_prio_disk_full" value="1" <!--#if int($nscript_prio_disk_full) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_warning">$T($notify_texts['warning'])</label>
<input type="checkbox" name="nscript_prio_warning" id="nscript_prio_warning" value="1" <!--#if int($nscript_prio_warning) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_error">$T($notify_texts['error'])</label>
<input type="checkbox" name="nscript_prio_error" id="nscript_prio_error" value="1" <!--#if int($nscript_prio_error) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<label class="config wide" for="nscript_prio_other">$T($notify_texts['other'])</label>
<input type="checkbox" name="nscript_prio_other" id="nscript_prio_other" value="1" <!--#if int($nscript_prio_other) > 0 then 'checked="checked"' else ""#--> />
</div>
<div class="field-pair">
<button class="btn btn-default saveButton"><span class="glyphicon glyphicon-ok"></span> $T('button-saveChanges')</button>
<button class="btn btn-default" type="button" id="test_nscript"><span class="glyphicon glyphicon-comment"></span> $T('testNotify')</button>
</div>
<div class="field-pair result-box">
<div class="alert"></div>
</div>
</fieldset>
</div><!-- /col1 -->
</div><!-- /section -->
</form>
</div><!-- /colmask -->
@@ -733,7 +805,7 @@
}
})
}
\$('#test_email, #test_notif, #test_windows, #test_pushbullet, #test_pushover, #test_prowl, #test_growl, #test_osd').click(function () {
\$('#test_email, #test_notif, #test_windows, #test_pushbullet, #test_pushover, #test_prowl, #test_growl, #test_osd, #test_nscript').click(function () {
testNotification(this)
})
});

View File

@@ -381,5 +381,12 @@ $.fn.extractFormDataTo = function(target) {
target[elem.name] = elem.value;
});
var selects = $("select", this);
selects.each(function (i,elem) {
target[elem.name] = elem.value;
});
return this;
}
}

View File

@@ -769,6 +769,11 @@ def _api_test_pushbullet(name, output, kwargs):
res = sabnzbd.notifier.send_pushbullet('SABnzbd', T('Test Notification'), 'other', force=True, test=kwargs)
return report(output, error=res)
def _api_test_nscript(name, output, kwargs):
""" API: execute a test notification script, return result """
logging.info("Executing notification script")
res = sabnzbd.notifier.send_nscript('SABnzbd', T('Test Notification'), 'other', force=True, test=kwargs)
return report(output, error=res)
def _api_undefined(name, output, kwargs):
""" API: accepts output """
@@ -924,7 +929,8 @@ _api_table = {
'test_osd': (_api_test_osd, 2),
'test_pushover': (_api_test_pushover, 2),
'test_pushbullet': (_api_test_pushbullet, 2),
'test_prowl': (_api_test_prowl, 2)
'test_prowl': (_api_test_prowl, 2),
'test_nscript': (_api_test_nscript, 2),
}
_api_queue_table = {
@@ -2153,7 +2159,7 @@ def std_time(when):
return item
def list_scripts(default=False):
def list_scripts(default=False, none=True):
""" Return a list of script names, optionally with 'Default' added """
lst = []
path = cfg.script_dir.get_path()
@@ -2165,7 +2171,8 @@ def list_scripts(default=False):
script.endswith('.py') or \
(not sabnzbd.WIN32 and os.access(script, os.X_OK) and not os.path.basename(script).startswith('.')):
lst.append(os.path.basename(script))
lst.insert(0, 'None')
if none:
lst.insert(0, 'None')
if default:
lst.insert(0, 'Default')
return lst

View File

@@ -360,6 +360,19 @@ pushbullet_prio_error = OptionNumber('pushbullet', 'pushbullet_prio_error', 0)
pushbullet_prio_queue_done = OptionNumber('pushbullet', 'pushbullet_prio_queue_done', 0)
pushbullet_prio_other = OptionNumber('pushbullet', 'pushbullet_prio_other', 0)
# [nscript]
nscript_enable = OptionBool('nscript', 'nscript_enable')
nscript_script = OptionStr('nscript', 'nscript_script')
nscript_prio_startup = OptionBool('nscript', 'nscript_prio_startup', True)
nscript_prio_download = OptionBool('nscript', 'nscript_prio_download', False)
nscript_prio_pp = OptionBool('nscript', 'nscript_prio_pp', False)
nscript_prio_complete = OptionBool('nscript', 'nscript_prio_complete', True)
nscript_prio_failed = OptionBool('nscript', 'nscript_prio_failed', True)
nscript_prio_disk_full = OptionBool('nscript', 'nscript_prio_disk_full', True)
nscript_prio_warning = OptionBool('nscript', 'nscript_prio_warning', False)
nscript_prio_error = OptionBool('nscript', 'nscript_prio_error', False)
nscript_prio_queue_done = OptionBool('nscript', 'nscript_prio_queue_done', True)
nscript_prio_other = OptionBool('nscript', 'nscript_prio_other', False)
quota_size = OptionStr('misc', 'quota_size')
quota_day = OptionStr('misc', 'quota_day')

View File

@@ -2801,6 +2801,10 @@ LIST_PUSHBULLET = ('pushbullet_enable', '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'
)
LIST_NSCRIPT = ('nscript_enable', 'nscript_script',
'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'
)
class ConfigNotify(object):
@@ -2825,6 +2829,7 @@ class ConfigNotify(object):
conf['have_growl'] = True
conf['have_ntfosd'] = sabnzbd.notifier.have_ntfosd()
conf['have_ncenter'] = sabnzbd.DARWIN_VERSION > 7 and bool(sabnzbd.notifier.ncenter_path())
conf['script_list'] = list_scripts(default=False, none=True)
for kw in LIST_EMAIL:
conf[kw] = config.get_config('misc', kw).get_string()
@@ -2845,6 +2850,8 @@ class ConfigNotify(object):
conf[kw] = config.get_config('acenter', kw)()
for kw in LIST_NTFOSD:
conf[kw] = config.get_config('ntfosd', kw)()
for kw in LIST_NSCRIPT:
conf[kw] = config.get_config('nscript', kw)()
conf['notify_texts'] = sabnzbd.notifier.NOTIFICATION
template = Template(file=os.path.join(self.__web_dir, 'config_notify.tmpl'),
@@ -2890,6 +2897,10 @@ class ConfigNotify(object):
msg = config.get_config('pushbullet', kw).set(platform_encode(kwargs.get(kw, 0)))
if msg:
return badParameterResponse(T('Incorrect value for %s: %s') % (kw, unicoder(msg)), ajax)
for kw in LIST_NSCRIPT:
msg = config.get_config('nscript', kw).set(platform_encode(kwargs.get(kw, 0)))
if msg:
return badParameterResponse(T('Incorrect value for %s: %s') % (kw, unicoder(msg)), ajax)
config.save_config()
self.__lastmail = None
@@ -2964,6 +2975,7 @@ def rss_history(url, limit=50, search=None):
return rss.write()
def rss_warnings():
""" Return an RSS feed with last warnings/errors """
rss = RSS()

View File

@@ -163,6 +163,12 @@ def send_notification(title, msg, gtype):
Thread(target=send_pushbullet, args=(title, msg, gtype)).start()
time.sleep(0.5)
# Notification script.
if sabnzbd.cfg.nscript_enable():
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)
@@ -481,6 +487,36 @@ def send_pushbullet(title, msg, gtype, force=False, test=None):
return T('Failed to send pushbullet message')
return ''
def send_nscript(title, msg, gtype, force=False, test=None):
if test:
script = test.get('nscript_script')
else:
script = sabnzbd.cfg.nscript_script()
if not script:
return T('Cannot send, missing required data')
title = u'SABnzbd: ' + Tx(NOTIFICATION.get(gtype, 'other'))
if force or check_classes(gtype, 'nscript'):
try:
script_path = os.path.join(sabnzbd.cfg.script_dir(), script)
if os.path.exists(script_path):
command = [script_path, title, msg]
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
output = proc.stdout.read()
ret = proc.wait()
if ret:
return T('Script returned exit code %s and output "%"') % (ret, output)
else:
logging.info('Successfully executed notification script ' + script)
else:
return T('Notification script "%s" does not exist') % script_path
except:
logging.warning('Failed to execute notification script ' + script)
logging.debug("Traceback: ", exc_info=True)
return T('Failed to execute notification script %s') % script
return ''
def send_windows(title, msg, gtype):
if sabnzbd.WINTRAY:
try:
@@ -490,3 +526,4 @@ def send_windows(title, msg, gtype):
logging.debug("Traceback: ", exc_info=True)
return T('Failed to send Windows notification')
return None

View File

@@ -653,6 +653,11 @@ SKIN_TEXT = {
'explain-pushbullet_apikey' : TT('Your personal Pushbullet API key (required)'), #: Pushbullet settings
'opt-pushbullet_device' : TT('Device'), #: Pushbullet settings
'explain-pushbullet_device' : TT('Device to which message should be sent'), #: Pushbullet settings
'section-NScript' : TT('Notification Script'), #: Header for Notification Script notification section
'opt-nscript_enable' : TT('Enable notification script'), #: Notification Script settings
'opt-nscript_script' : TT('Script'), #: Notification Script settings
'explain-nscript_enable' : TT('Executes a custom script'), #: Notification Scriptsettings
'explain-nscript_script' : TT('Which script should we execute for notification?'), #: Notification Scriptsettings
# Config->Cat
'explain-catTags' : TT('Use the "Groups / Indexer tags" column to map groups and tags to your categories.<br/>Wildcards are supported. Use commas to separate terms.'),