Add Slack Notifications.

This commit is contained in:
Brett Pemberton 2017-09-14 04:39:54 +01:00 committed by JackDandy
parent 50dfb7e490
commit c2fcf37498
7 changed files with 254 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1683,6 +1683,98 @@
</fieldset>
</div><!-- /trakt component-group //-->
<div class="component-group clearfix">
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/slack.png" alt="" title="Trakt" />
<h3><a href="http://slack.com/" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Slack</a></h3>
<p>Team communication for the 21st century.</p>
</div>
<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" class="enabler" name="use_slack" id="use_slack" #if $sickbeard.USE_SLACK then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_slack">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send Slack notifications?</span>
</label>
</div>
<div id="content_use_slack">
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Slack API Key:</span>
<input type="text" name="slack_access_token" id="slack_access_token" value="$sickbeard.SLACK_ACCESS_TOKEN" size="35" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Get your key at: <a href="https://api.slack.com/web" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">https://api.slack.com/web</a></span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Slack Channel</span>
<input type="text" name="slack_channel" id="slack_channel" value="$sickbeard.SLACK_CHANNEL" size="35" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Channel Sick Beard should send notifications to.</span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Send as User</span>
<input type="checkbox" class="enabler" name="slack_as_user" id="slack_as_user" #if $sickbeard.SLACK_AS_USER then "checked=\"checked\"" else ""# />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Send notification as your user (otherwise send as name and icon below).</span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Slack Bot Name</span>
<input type="text" name="slack_bot_name" id="slack_bot_name" value="$sickbeard.SLACK_BOT_NAME" size="35" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Name of the bot that will send the notifications.</span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Slack Bot Icon URL</span>
<input type="text" name="slack_icon_url" id="slack_icon_url" value="$sickbeard.SLACK_ICON_URL" size="35" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">URL to an image to use as the icon for this bot.</span>
</label>
</div>
<div class="field-pair">
<label for="slack_notify_onsnatch">
<span class="component-title">Notify on snatch</span>
<span class="component-desc">
<input type="checkbox" name="slack_notify_onsnatch" id="slack_notify_onsnatch" #if $sickbeard.SLACK_NOTIFY_ONSNATCH then 'checked="checked"' else ''# />
<p>send a notification when a download starts ?</p>
</span>
</label>
</div>
<div class="field-pair">
<label for="slack_notify_ondownload">
<span class="component-title">Notify on download</span>
<span class="component-desc">
<input type="checkbox" name="slack_notify_ondownload" id="slack_notify_ondownload" #if $sickbeard.SLACK_NOTIFY_ONDOWNLOAD then 'checked="checked"' else ''# />
<p>send a notification when a download finishes ?</p>
</span>
</label>
</div>
<div class="testNotification" id="testSlack-result">Click below to test.</div>
<input type="button" class="btn" value="Test Slack" id="testSlack" />
<input type="submit" class="btn config_submitter" value="Save Changes" />
</div><!-- /content_use_slack //-->
</fieldset>
</div><!-- /slack component-group //-->
<div class="component-group">
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/email.png" alt="" title="Email" />

View file

@ -434,6 +434,25 @@
});
});
$("#testSlack").click(function () {
var slack_access_token = $("#slack_access_token").val();
var slack_channel = $("#slack_channel").val();
var slack_as_user = $("#slack_as_user").attr('checked');
var slack_bot_name = $("#slack_bot_name").val();
var slack_icon_url = $("#slack_icon_url").val();
if (!slack_access_token || !slack_channel || !(slack_as_user || slack_bot_name)) {
$("#testSlack-result").html("Please fill out the necessary fields above.");
return;
}
$(this).prop("disabled", true);
$("#testSlack-result").html(loading);
$.get(sbRoot + "/home/testSlack", {'accessToken': slack_access_token, 'channel': slack_channel, 'as_user': slack_as_user, 'bot_name': slack_bot_name, 'icon_url': slack_icon_url})
.done(function (data) {
$("#testSlack-result").html(data);
$("#testSlack").prop("disabled", false);
});
});
function get_pushbullet_devices (msg) {
var pushbullet_access_token = $.trim($('#pushbullet_access_token').val());
if (!pushbullet_access_token) {

View file

@ -418,6 +418,15 @@ PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD = False
PUSHBULLET_ACCESS_TOKEN = None
PUSHBULLET_DEVICE_IDEN = None
USE_SLACK = False
SLACK_NOTIFY_ONSNATCH = False
SLACK_NOTIFY_ONDOWNLOAD = False
SLACK_ACCESS_TOKEN = None
SLACK_CHANNEL = None
SLACK_AS_USER = False
SLACK_BOT_NAME = None
SLACK_ICON_URL = None
USE_EMAIL = False
EMAIL_OLD_SUBJECTS = None
EMAIL_NOTIFY_ONSNATCH = False
@ -631,6 +640,7 @@ def initialize(console_logging=True):
USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, \
TRAKT_USE_WATCHLIST, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, \
TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
USE_SLACK, SLACK_NOTIFY_ONSNATCH, SLACK_NOTIFY_ONDOWNLOAD, SLACK_ACCESS_TOKEN, SLACK_CHANNEL, SLACK_AS_USER, SLACK_BOT_NAME, SLACK_ICON_URL, \
USE_EMAIL, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_FROM, \
EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_LIST, EMAIL_OLD_SUBJECTS
# Anime Settings
@ -640,7 +650,7 @@ def initialize(console_logging=True):
return False
for stanza in ('General', 'Blackhole', 'SABnzbd', 'NZBget', 'Emby', 'Kodi', 'XBMC', 'PLEX',
'Growl', 'Prowl', 'Twitter', 'Boxcar2', 'NMJ', 'NMJv2', 'Synology', 'SynologyNotifier',
'Growl', 'Prowl', 'Twitter', 'Slack', 'Boxcar2', 'NMJ', 'NMJv2', 'Synology', 'SynologyNotifier',
'pyTivo', 'NMA', 'Pushalot', 'Pushbullet', 'Subtitles'):
CheckSection(CFG, stanza)
@ -1033,6 +1043,15 @@ def initialize(console_logging=True):
PUSHBULLET_ACCESS_TOKEN = check_setting_str(CFG, 'Pushbullet', 'pushbullet_access_token', '')
PUSHBULLET_DEVICE_IDEN = check_setting_str(CFG, 'Pushbullet', 'pushbullet_device_iden', '')
USE_SLACK = bool(check_setting_int(CFG, 'Slack', 'use_slack', 0))
SLACK_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Slack', 'slack_notify_onsnatch', 0))
SLACK_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Slack', 'slack_notify_ondownload', 0))
SLACK_ACCESS_TOKEN = check_setting_str(CFG, 'Slack', 'slack_access_token', '')
SLACK_CHANNEL = check_setting_str(CFG, 'Slack', 'slack_channel', '')
SLACK_AS_USER = bool(check_setting_int(CFG, 'Slack', 'slack_as_user', 0))
SLACK_BOT_NAME = check_setting_str(CFG, 'Slack', 'slack_bot_name', '')
SLACK_ICON_URL = check_setting_str(CFG, 'Slack', 'slack_icon_url', '')
USE_EMAIL = bool(check_setting_int(CFG, 'Email', 'use_email', 0))
EMAIL_OLD_SUBJECTS = bool(check_setting_int(CFG, 'Email', 'email_old_subjects',
None is not EMAIL_HOST and any(EMAIL_HOST)))
@ -1821,6 +1840,16 @@ def save_config():
new_config['Pushbullet']['pushbullet_access_token'] = PUSHBULLET_ACCESS_TOKEN
new_config['Pushbullet']['pushbullet_device_iden'] = PUSHBULLET_DEVICE_IDEN
new_config['Slack'] = {}
new_config['Slack']['use_slack'] = int(USE_SLACK)
new_config['Slack']['slack_notify_onsnatch'] = int(SLACK_NOTIFY_ONSNATCH)
new_config['Slack']['slack_notify_ondownload'] = int(SLACK_NOTIFY_ONDOWNLOAD)
new_config['Slack']['slack_access_token'] = SLACK_ACCESS_TOKEN
new_config['Slack']['slack_channel'] = SLACK_CHANNEL
new_config['Slack']['slack_as_user'] = int(SLACK_AS_USER)
new_config['Slack']['slack_bot_name'] = SLACK_BOT_NAME
new_config['Slack']['slack_icon_url'] = SLACK_ICON_URL
new_config['Email'] = {}
new_config['Email']['use_email'] = int(USE_EMAIL)
new_config['Email']['email_old_subjects'] = int(EMAIL_OLD_SUBJECTS)

View file

@ -36,6 +36,7 @@ import nma
import pushalot
import pushbullet
import slack
import tweet
from lib import libtrakt
import emailnotify
@ -60,6 +61,7 @@ nma_notifier = nma.NMA_Notifier()
pushalot_notifier = pushalot.PushalotNotifier()
pushbullet_notifier = pushbullet.PushbulletNotifier()
# social
slack_notifier = slack.SlackNotifier()
twitter_notifier = tweet.TwitterNotifier()
trakt_notifier = trakt.TraktNotifier()
email_notifier = emailnotify.EmailNotifier()
@ -81,6 +83,7 @@ notifiers = [
nma_notifier,
pushalot_notifier,
pushbullet_notifier,
slack_notifier,
twitter_notifier,
trakt_notifier,
email_notifier,

View file

@ -0,0 +1,90 @@
# coding=utf-8
#
# This file is part of SickGear.
#
# Thanks to: mallen86
#
# SickGear is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# SickGear is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
import json
import sickbeard
from sickbeard import logger, common
class SlackNotifier:
def _send_to_slack(self, message, accessToken, channel, as_user, bot_name, icon_url):
SLACK_ENDPOINT = "https://slack.com/api/chat.postMessage"
data = {}
data["token"] = accessToken
data["channel"] = channel
data["username"] = bot_name
data["text"] = message
data["icon_url"] = icon_url
data["as_user"] = as_user
urlResp = sickbeard.helpers.getURL(url=SLACK_ENDPOINT, post_data=data)
if urlResp:
resp = json.loads(urlResp)
else:
return False
# if ("error" in resp):
# raise Exception(resp["error"])
if (resp["ok"] == True):
logger.log(u"Slack: Succeeded sending message.", logger.MESSAGE)
return True
logger.log(u"Slack: Failed sending message: " + resp["error"], logger.ERROR)
return False
def _notify(self, message, accessToken='', channel='', as_user='', bot_name='', icon_url='', force=False):
# suppress notifications if the notifier is disabled but the notify options are checked
if not sickbeard.USE_SLACK and not force:
return False
if not accessToken:
accessToken = sickbeard.SLACK_ACCESS_TOKEN
if not channel:
channel = sickbeard.SLACK_CHANNEL
if not as_user:
as_user = sickbeard.SLACK_AS_USER
if not bot_name:
bot_name = sickbeard.SLACK_BOT_NAME
if not icon_url:
icon_url = sickbeard.SLACK_ICON_URL
return self._send_to_slack(message, accessToken, channel, as_user, bot_name, icon_url)
##############################################################################
# Public functions
##############################################################################
def notify_snatch(self, ep_name):
if sickbeard.SLACK_NOTIFY_ONSNATCH:
self._notify(common.notifyStrings[common.NOTIFY_SNATCH] + ': ' + ep_name)
def notify_download(self, ep_name):
if sickbeard.SLACK_NOTIFY_ONDOWNLOAD:
self._notify(common.notifyStrings[common.NOTIFY_DOWNLOAD] + ': ' + ep_name)
def test_notify(self, accessToken, channel, as_user, bot_name, icon_url):
return self._notify("This is a test notification from SickGear", accessToken, channel, as_user, bot_name, icon_url, force=True)
def update_library(self, ep_obj):
pass
notifier = SlackNotifier

View file

@ -1150,6 +1150,15 @@ class Home(MainHandler):
return notifiers.pushbullet_notifier.get_devices(accessToken)
def testSlack(self, accessToken=None, channel=None, as_user=False, bot_name=None, icon_url=None):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
result = notifiers.slack_notifier.test_notify(accessToken, channel, as_user, bot_name, icon_url)
if result:
return "Slack notification succeeded. Check your Slack clients to make sure it worked"
else:
return "Error sending Slack notification"
def viewchanges(self):
t = PageTemplate(headers=self.request.headers, file='viewchanges.tmpl')
@ -5750,7 +5759,8 @@ class ConfigNotifications(Config):
use_email=None, email_notify_onsnatch=None, email_notify_ondownload=None,
email_notify_onsubtitledownload=None, email_host=None, email_port=25, email_from=None,
email_tls=None, email_user=None, email_password=None, email_list=None, email_show_list=None,
email_show=None, **kwargs):
email_show=None, use_slack=None, slack_notify_onsnatch=None, slack_notify_ondownload=None,
slack_access_token=None, slack_channel=None, slack_as_user=None, slack_bot_name=None, slack_icon_url=None, **kwargs):
results = []
@ -5889,6 +5899,15 @@ class ConfigNotifications(Config):
# sickbeard.TRAKT_REMOVE_SERIESLIST = config.checkbox_to_value(trakt_remove_serieslist)
# sickbeard.TRAKT_START_PAUSED = config.checkbox_to_value(trakt_start_paused)
sickbeard.USE_SLACK = config.checkbox_to_value(use_slack)
sickbeard.SLACK_NOTIFY_ONSNATCH = config.checkbox_to_value(slack_notify_onsnatch)
sickbeard.SLACK_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(slack_notify_ondownload)
sickbeard.SLACK_ACCESS_TOKEN = slack_access_token
sickbeard.SLACK_CHANNEL = slack_channel
sickbeard.SLACK_AS_USER = config.checkbox_to_value(slack_as_user)
sickbeard.SLACK_BOT_NAME = slack_bot_name
sickbeard.SLACK_ICON_URL = slack_icon_url
sickbeard.USE_EMAIL = config.checkbox_to_value(use_email)
sickbeard.EMAIL_NOTIFY_ONSNATCH = config.checkbox_to_value(email_notify_onsnatch)
sickbeard.EMAIL_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(email_notify_ondownload)
@ -6323,4 +6342,3 @@ class CachedImages(MainHandler):
self.set_header('Content-Type', mime_type)
with open(static_image_path, 'rb') as img:
return img.read()