mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 00:43:37 +00:00
Add Slack Notifications.
This commit is contained in:
parent
50dfb7e490
commit
c2fcf37498
7 changed files with 254 additions and 3 deletions
BIN
gui/slick/images/notifiers/slack.png
Normal file
BIN
gui/slick/images/notifiers/slack.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -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"> </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"> </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"> </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"> </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"> </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" />
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
90
sickbeard/notifiers/slack.py
Normal file
90
sickbeard/notifiers/slack.py
Normal 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
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in a new issue