Browse Source

Replace Telegram notififier "Send icon" with "Send show image"

Add Telegram notifier option "Send quietly" to mute client notification sound.
Refactor notifier parameters, notify_snatch, notify_download, notify_subtitle_download.
tags/release_0.25.1
JackDandy 5 years ago
parent
commit
534d023cb0
  1. 2
      CHANGES.md
  2. 17
      gui/slick/interfaces/default/config_notifications.tmpl
  3. 5
      gui/slick/js/configNotifications.js
  4. 16
      sickbeard/__init__.py
  5. 14
      sickbeard/notifiers/__init__.py
  6. 19
      sickbeard/notifiers/emailnotify.py
  7. 19
      sickbeard/notifiers/generic.py
  8. 4
      sickbeard/notifiers/nmj.py
  9. 4
      sickbeard/notifiers/nmjv2.py
  10. 57
      sickbeard/notifiers/telegram.py
  11. 5
      sickbeard/postProcessor.py
  12. 1
      sickbeard/processTV.py
  13. 2
      sickbeard/search.py
  14. 2
      sickbeard/tv.py
  15. 9
      sickbeard/webserve.py

2
CHANGES.md

@ -78,6 +78,8 @@
* Change add fallback to premiered year to lookup browse card show
* Change display % after rating value only if value is numeric
* Change add fallback to remove a premiered year to lookup browse card show
* Replace Telegram notififier "Send icon" with "Send show image"
* Add Telegram notifier option "Send quietly" to mute client notification sound
### 0.21.37 (2020-05-30 12:00:00 UTC)

17
gui/slick/interfaces/default/config_notifications.tmpl

@ -1928,11 +1928,20 @@
</label>
</div>
<div class="field-pair">
<label for="telegram-send-icon">
<span class="component-title">Send icon image</span>
<label for="telegram-send-image">
<span class="component-title">Send with image</span>
<span class="component-desc">
<input type="checkbox" name="telegram_send_icon" id="telegram-send-icon"#if $sg_var('TELEGRAM_SEND_ICON') then 'checked="checked"' else ''#>
<p>send icon image before the notification</p>
<input type="checkbox" name="telegram_send_image" id="telegram-send-image"#if $sg_var('TELEGRAM_SEND_IMAGE') then 'checked="checked"' else ''#>
<p>send show image with notification</p>
</span>
</label>
</div>
<div class="field-pair">
<label for="telegram-quiet">
<span class="component-title">Send quietly</span>
<span class="component-desc">
<input type="checkbox" name="telegram_quiet" id="telegram-quiet"#if $sg_var('TELEGRAM_QUIET') then 'checked="checked"' else ''#>
<p>mute client notification sound</p>
</span>
</label>
</div>

5
gui/slick/js/configNotifications.js

@ -511,7 +511,8 @@ $(document).ready(function(){
});
$('#test-telegram').click(function () {
var telegramSendIcon = $('#telegram-send-icon').prop('checked'),
var telegramSendImage = $('#telegram-send-image').prop('checked'),
telegramQuiet = $('#telegram-quiet').prop('checked'),
accessToken = '#telegram-access-token', telegramAccessToken = $(accessToken).val().replace(/\s/g, ''),
chatid = '#telegram-chatid', telegramChatid = $(chatid).val().replace(/\s/g, '');
@ -523,7 +524,7 @@ $(document).ready(function(){
$(this).prop('disabled', !0);
$('#test-telegram-result').html(loading);
$.getJSON(sbRoot + '/home/test-telegram',
{send_icon: telegramSendIcon, access_token: telegramAccessToken, chatid: telegramChatid})
{send_icon: telegramSendImage, access_token: telegramAccessToken, chatid: telegramChatid, quiet: telegramQuiet})
.done(function (JSONdata) {
$('#test-telegram-result').html(JSONdata.result);
if ('' === telegramChatid) {

16
sickbeard/__init__.py

@ -468,7 +468,8 @@ USE_TELEGRAM = False
TELEGRAM_NOTIFY_ONSNATCH = False
TELEGRAM_NOTIFY_ONDOWNLOAD = False
TELEGRAM_NOTIFY_ONSUBTITLEDOWNLOAD = False
TELEGRAM_SEND_ICON = True
TELEGRAM_SEND_IMAGE = True
TELEGRAM_QUIET = False
TELEGRAM_ACCESS_TOKEN = None
TELEGRAM_CHATID = None
@ -734,7 +735,7 @@ def init_stage_1(console_logging):
USE_GITTER, GITTER_NOTIFY_ONSNATCH, GITTER_NOTIFY_ONDOWNLOAD, GITTER_NOTIFY_ONSUBTITLEDOWNLOAD,\
GITTER_ROOM, GITTER_ACCESS_TOKEN, \
USE_TELEGRAM, TELEGRAM_NOTIFY_ONSNATCH, TELEGRAM_NOTIFY_ONDOWNLOAD, TELEGRAM_NOTIFY_ONSUBTITLEDOWNLOAD, \
TELEGRAM_SEND_ICON, TELEGRAM_ACCESS_TOKEN, TELEGRAM_CHATID, \
TELEGRAM_SEND_IMAGE, TELEGRAM_QUIET, TELEGRAM_ACCESS_TOKEN, TELEGRAM_CHATID, \
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
@ -1199,7 +1200,8 @@ def init_stage_1(console_logging):
TELEGRAM_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Telegram', 'telegram_notify_ondownload', 0))
TELEGRAM_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(
CFG, 'Telegram', 'telegram_notify_onsubtitledownload', 0))
TELEGRAM_SEND_ICON = bool(check_setting_int(CFG, 'Telegram', 'telegram_send_icon', 1))
TELEGRAM_SEND_IMAGE = bool(check_setting_int(CFG, 'Telegram', 'telegram_send_image', 1))
TELEGRAM_QUIET = bool(check_setting_int(CFG, 'Telegram', 'telegram_quiet', 0))
TELEGRAM_ACCESS_TOKEN = check_setting_str(CFG, 'Telegram', 'telegram_access_token', '')
TELEGRAM_CHATID = check_setting_str(CFG, 'Telegram', 'telegram_chatid', '')
@ -2099,7 +2101,8 @@ def save_config():
]),
('Telegram', [
('use_%s', int(USE_TELEGRAM)),
('send_icon', int(TELEGRAM_SEND_ICON)),
('send_image', int(TELEGRAM_SEND_IMAGE)),
('quiet', int(TELEGRAM_QUIET)),
('access_token', TELEGRAM_ACCESS_TOKEN),
('chatid', TELEGRAM_CHATID),
]),
@ -2119,8 +2122,9 @@ def save_config():
new_config[cfg] = {}
for (k, v) in filter_iter(lambda arg: any([arg[1]]) or (
# allow saving where item value default is non-zero but 0 is a required setting value
cfg_lc in ('kodi', 'xbmc', 'synoindex', 'nzbget', 'torrent') and arg[0] in ('always_on', 'priority')
or (arg[0] == 'label_var' and 'rtorrent' == new_config['General']['torrent_method'])), items):
cfg_lc in ('kodi', 'xbmc', 'synoindex', 'nzbget', 'torrent', 'telegram')
and arg[0] in ('always_on', 'priority', 'send_image'))
or ('rtorrent' == new_config['General']['torrent_method'] and 'label_var' == arg[0]), items):
k = '%s' in k and (k % cfg_lc) or (cfg_lc + '_' + k)
# correct for cases where keys are named in an inconsistent manner to parent stanza
k = k.replace('blackhole_', '').replace('sabnzbd_', 'sab_')

14
sickbeard/notifiers/__init__.py

@ -122,19 +122,19 @@ class NotifierFactory(object):
yield self.get(n)
def notify_snatch(ep_name):
def notify_snatch(ep_obj):
for n in NotifierFactory().get_enabled('onsnatch'):
n.notify_snatch(ep_name)
n.notify_snatch(ep_obj)
def notify_download(ep_name):
def notify_download(ep_obj):
for n in NotifierFactory().get_enabled('ondownload'):
n.notify_download(ep_name)
n.notify_download(ep_obj)
def notify_subtitle_download(ep_name, lang):
def notify_subtitle_download(ep_obj, lang):
for n in NotifierFactory().get_enabled('onsubtitledownload'):
n.notify_subtitle_download(ep_name, lang)
n.notify_subtitle_download(ep_obj, lang)
def notify_git_update(new_version=''):
@ -143,7 +143,7 @@ def notify_git_update(new_version=''):
n.notify_git_update(new_version)
def notify_update_library(ep_obj, flush_q=None):
def notify_update_library(ep_obj, flush_q=False):
if not flush_q or sickbeard.QUEUE_UPDATE_LIBRARY:

19
sickbeard/notifiers/emailnotify.py

@ -148,39 +148,40 @@ class EmailNotifier(Notifier):
return self._choose(('Success, notification sent.',
'Failed to send notification: %s' % self.last_err)[not r], r)
def notify_snatch(self, ep_name, title=None):
def notify_snatch(self, ep_obj, title=None, **kwargs):
"""
Send a notification that an episode was snatched
:param ep_name: The name of the episode that was snatched
:param ep_obj: The snatched episode
:param title: The title of the notification (optional)
"""
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Snatched' or title or notify_strings['snatch']
self._notify(title, ep_name)
# noinspection PyProtectedMember
self._notify(title, self.pretty_name(ep_obj))
def notify_download(self, ep_name, title=None):
def notify_download(self, ep_obj, title=None, **kwargs):
"""
Send a notification that an episode was downloaded
:param ep_name: The name of the episode that was downloaded
:param ep_obj: The downloaded episode
:param title: The title of the notification (optional)
"""
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Downloaded' or title or notify_strings['download']
self._notify(title, ep_name)
self._notify(title, self.pretty_name(ep_obj))
def notify_subtitle_download(self, ep_name, lang, title=None):
def notify_subtitle_download(self, ep_obj, lang, title=None, **kwargs):
"""
Send a notification that a subtitle was downloaded
:param ep_name: The name of the episode that was downloaded
:param ep_obj: The downloaded episode
:param lang: Subtitle language
:param title: The title of the notification (optional)
"""
title = sickbeard.EMAIL_OLD_SUBJECTS and 'Subtitle Downloaded' or title or notify_strings['subtitle_download']
self._notify(title, ep_name, '%s ' % lang, '</b></p>\n<p>Language: <b>%s' % lang)
self._notify(title, ep_obj.pretty_name(), '%s ' % lang, '</b></p>\n<p>Language: <b>%s' % lang)
notifier = EmailNotifier

19
sickbeard/notifiers/generic.py

@ -111,7 +111,7 @@ class BaseNotifier(object):
@staticmethod
def _body_only(title, body):
# don't use title with updates or testing, as only one str is used
return body if 'SickGear' in title else '%s: %s' % (title, body.replace('#: ', '# '))
return body if 'SickGear' in title else u'%s: %s' % (title, body.replace('#: ', '# '))
class Notifier(BaseNotifier):
@ -121,14 +121,19 @@ class Notifier(BaseNotifier):
r = self._pre_notify('test_title', notify_strings['test_body'] % (self.name + ' notifier'), *args, **kwargs)
return (r, (('Success, notification sent.', 'Failed to send notification.')[not r]))[r in (True, False)]
def notify_snatch(self, ep_name, **kwargs):
self._pre_notify('snatch', ep_name, **kwargs)
@staticmethod
def pretty_name(ep_obj):
# noinspection PyProtectedMember
return ('%s%s' % (ep_obj.pretty_name(), ep_obj._format_pattern(' - %QN'))).replace(' - N-A', '')
def notify_snatch(self, ep_obj, **kwargs):
self._pre_notify('snatch', self.pretty_name(ep_obj), ep_obj=ep_obj, **kwargs)
def notify_download(self, ep_name, **kwargs):
self._pre_notify('download', ep_name, **kwargs)
def notify_download(self, ep_obj, **kwargs):
self._pre_notify('download', self.pretty_name(ep_obj), ep_obj=ep_obj, **kwargs)
def notify_subtitle_download(self, ep_name, lang, **kwargs):
self._pre_notify('subtitle_download', '%s : %s' % (ep_name, lang), **kwargs)
def notify_subtitle_download(self, ep_obj, lang, **kwargs):
self._pre_notify('subtitle_download', '%s : %s' % (ep_obj.pretty_name(), lang), ep_obj=ep_obj, **kwargs)
def notify_git_update(self, new_version='??', **kwargs):
self._pre_notify('git_updated', notify_strings['git_updated_text'] + new_version, **kwargs)

4
sickbeard/notifiers/nmj.py

@ -167,10 +167,10 @@ class NMJNotifier(BaseNotifier):
# notify_snatch() Not implemented: Start the scanner when snatched does not make sense
# notify_git_update() Not implemented, no reason to start scanner
def notify_download(self):
def notify_download(self, *args, **kwargs):
self._notify()
def notify_subtitle_download(self):
def notify_subtitle_download(self, *args, **kwargs):
self._notify()

4
sickbeard/notifiers/nmjv2.py

@ -181,10 +181,10 @@ class NMJv2Notifier(BaseNotifier):
# notify_snatch() Not implemented: Start the scanner when snatched does not make sense
# notify_git_update() Not implemented, no reason to start scanner
def notify_download(self):
def notify_download(self, *args, **kwargs):
self._notify()
def notify_subtitle_download(self):
def notify_subtitle_download(self, *args, **kwargs):
self._notify()

57
sickbeard/notifiers/telegram.py

@ -14,15 +14,20 @@
#
# You should have received a copy of the GNU General Public License
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
import os
import re
from ..common import USER_AGENT
from .generic import Notifier
import sickbeard
# noinspection PyPep8Naming
import encodingKludge as ek
from exceptions_helper import ex
from lib.apprise.plugins.NotifyTelegram import NotifyTelegram
import sickbeard
from sickbeard.image_cache import ImageCache
from sg_helpers import get_url
class TelegramNotifier(Notifier):
@ -30,22 +35,38 @@ class TelegramNotifier(Notifier):
def __init__(self):
super(TelegramNotifier, self).__init__()
def _notify(self, title, body, send_icon='', access_token='', chatid='', **kwargs):
def _notify(self, title, body, send_icon='', quiet=False, access_token='', chatid='', ep_obj=None, **kwargs):
result = None
cid = ''
use_icon = bool(self._choose(send_icon, sickbeard.TELEGRAM_SEND_ICON))
use_icon = bool(self._choose(send_icon, sickbeard.TELEGRAM_SEND_IMAGE))
quiet = bool(self._choose(quiet, sickbeard.TELEGRAM_QUIET))
access_token = self._choose(access_token, sickbeard.TELEGRAM_ACCESS_TOKEN)
cid = self._choose(chatid, sickbeard.TELEGRAM_CHATID)
try:
tg = NotifyTelegram(
bot_token=self._choose(access_token, sickbeard.TELEGRAM_ACCESS_TOKEN),
targets=self._choose(chatid, sickbeard.TELEGRAM_CHATID),
include_image=use_icon
)
cid = chatid or isinstance(tg.targets, list) and 1 == len(tg.targets) and tg.targets[0] or ''
msg = self._body_only(('' if not title else u'<b>%s</b>' % title), body)
msg = msg.replace(u'<b>%s</b>: ' % title, u'<b>%s:</b>\r\n' % ('SickGear ' + title, title)[use_icon])
# HTML spaces (&nbsp;) and tabs (&emsp;) aren't supported
# See https://core.telegram.org/bots/api#html-style
msg = re.sub('(?i)&nbsp;?', ' ', msg)
# Tabs become 3 spaces
msg = re.sub('(?i)&emsp;?', ' ', msg)
if use_icon:
tg.icon_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick',
'images', 'ico', 'apple-touch-icon-76x76.png')
tg.image_size = '72x72'
result = tg.send(body, title=title)
image_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick', 'images', 'banner_thumb.jpg')
if not self._testing:
show_obj = ep_obj.show_obj
banner_path = ImageCache().banner_thumb_path(show_obj.tvid, show_obj.prodid)
if ek.ek(os.path.isfile, banner_path):
image_path = banner_path
with open(image_path, 'rb') as f:
response = self.post('sendPhoto', access_token, cid, quiet,
dict(files={'photo': ('image.png', f)}, post_data=dict(caption=msg)))
else:
response = self.post('sendMessage', access_token, cid, quiet, dict(post_data=dict(text=msg)))
result = response and response.get('ok') or False
except (BaseException, Exception) as e:
if 'No chat_id' in ex(e):
result = 'a chat id is not set, and a msg has not been sent to the bot to auto detect one.'
@ -57,5 +78,11 @@ class TelegramNotifier(Notifier):
result=self._choose(('Successful test notice sent.',
'Error sending notification, %s' % result)[True is not result], result))
@staticmethod
def post(action, access_token, cid, quiet, params):
params.update(dict(headers={'User-Agent': USER_AGENT}, verify=True, json=True))
params['post_data'].update(dict(chat_id=cid, parse_mode='HTML', disable_notification=quiet))
return get_url('https://api.telegram.org/bot%s/%s' % (access_token, action), **params)
notifier = TelegramNotifier

5
sickbeard/postProcessor.py

@ -1245,11 +1245,10 @@ class PostProcessor(object):
history.log_download(ep_obj, self.file_path, new_ep_quality, self.release_group, anime_version)
# send notifications
# noinspection PyProtectedMember
notifiers.notify_download(ep_obj._format_pattern('%SN - %Sx%0E - %EN - %QN'))
notifiers.notify_download(ep_obj)
# trigger library updates
notifiers.notify_update_library(ep_obj=ep_obj)
notifiers.notify_update_library(ep_obj)
# disabled due to security alert... https://github.com/clinton-hall/nzbToMedia/issues/1721
# self._run_extra_scripts(ep_obj)

1
sickbeard/processTV.py

@ -29,7 +29,6 @@ import re
import shutil
import stat
import sys
import time
# noinspection PyPep8Naming
import encodingKludge as ek

2
sickbeard/search.py

@ -195,7 +195,7 @@ def snatch_episode(result, end_status=SNATCHED):
sql_l.append(item)
if cur_ep_obj.status not in Quality.DOWNLOADED:
notifiers.notify_snatch(cur_ep_obj._format_pattern('%SN - %Sx%0E - %EN - %QN'))
notifiers.notify_snatch(cur_ep_obj)
update_imdb_data = update_imdb_data and cur_ep_obj.show_obj.load_imdb_info()

2
sickbeard/tv.py

@ -2149,7 +2149,7 @@ class TVEpisode(TVEpisodeBase):
logger.log('%s: Downloaded %s subtitles for episode %sx%s' %
(self.show_obj.tvid_prodid, subtitleList, self.season, self.episode), logger.DEBUG)
notifiers.notify_subtitle_download(self.pretty_name(), subtitleList)
notifiers.notify_subtitle_download(self, subtitleList)
else:
logger.log('%s: No subtitles downloaded for episode %sx%s'

9
sickbeard/webserve.py

@ -1787,11 +1787,11 @@ class Home(MainHandler):
return notifiers.NotifierFactory().get('GITTER').test_notify(
room_name=room_name, access_token=access_token)
def test_telegram(self, send_icon=False, access_token=None, chatid=None):
def test_telegram(self, send_icon=False, access_token=None, chatid=None, quiet=False):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
r = notifiers.NotifierFactory().get('TELEGRAM').test_notify(
send_icon=bool(config.checkbox_to_value(send_icon)), access_token=access_token, chatid=chatid)
send_icon=bool(config.checkbox_to_value(send_icon)), access_token=access_token, chatid=chatid, quiet=quiet)
return json.dumps(r)
def test_email(self, host=None, port=None, smtp_from=None, use_tls=None, user=None, pwd=None, to=None):
@ -7822,7 +7822,7 @@ class ConfigNotifications(Config):
gitter_notify_onsubtitledownload=None, gitter_access_token=None, gitter_room=None,
use_telegram=None, telegram_notify_onsnatch=None, telegram_notify_ondownload=None,
telegram_notify_onsubtitledownload=None, telegram_access_token=None, telegram_chatid=None,
telegram_send_icon=None,
telegram_send_image=None, telegram_quiet=None,
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,
@ -7984,7 +7984,8 @@ class ConfigNotifications(Config):
sickbeard.TELEGRAM_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(telegram_notify_onsubtitledownload)
sickbeard.TELEGRAM_ACCESS_TOKEN = telegram_access_token
sickbeard.TELEGRAM_CHATID = telegram_chatid
sickbeard.TELEGRAM_SEND_ICON = config.checkbox_to_value(telegram_send_icon)
sickbeard.TELEGRAM_SEND_IMAGE = config.checkbox_to_value(telegram_send_image)
sickbeard.TELEGRAM_QUIET = config.checkbox_to_value(telegram_quiet)
sickbeard.USE_EMAIL = config.checkbox_to_value(use_email)
sickbeard.EMAIL_NOTIFY_ONSNATCH = config.checkbox_to_value(email_notify_onsnatch)

Loading…
Cancel
Save