diff --git a/gui/slick/js/configNotifications.js b/gui/slick/js/configNotifications.js
index 9795fa7f..ae423a26 100644
--- a/gui/slick/js/configNotifications.js
+++ b/gui/slick/js/configNotifications.js
@@ -409,25 +409,6 @@ $(document).ready(function(){
});
});
- $('#test-nma').click(function () {
- var nmaApi = $.trim($('#nma-api').val());
- var nmaPriority = $('#nma-priority').val();
- if (!nmaApi) {
- $('#test-nma-result').html('Please fill out the necessary fields above.');
- $('#nma-api').addClass('warning');
- return;
- }
- $('#nma-api').removeClass('warning');
- $(this).prop('disabled', !0);
- $('#test-nma-result').html(loading);
- $.get(sbRoot + '/home/test_nma',
- {nma_api: nmaApi, nma_priority: nmaPriority})
- .done(function (data) {
- $('#test-nma-result').html(data);
- $('#test-nma').prop('disabled', !1);
- });
- });
-
$('#test-pushalot').click(function () {
var pushalotAuthorizationtoken = $.trim($('#pushalot-authorizationtoken').val());
if (!pushalotAuthorizationtoken) {
diff --git a/lib/pynma/__init__.py b/lib/pynma/__init__.py
deleted file mode 100644
index f884b504..00000000
--- a/lib/pynma/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/python
-
-__version__ = '1.01'
-
-from .pynma import PyNMA
diff --git a/lib/pynma/pynma.py b/lib/pynma/pynma.py
deleted file mode 100644
index e735eddd..00000000
--- a/lib/pynma/pynma.py
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/usr/bin/python
-
-from . import __version__
-from xml.dom.minidom import parseString
-
-import requests
-
-
-class PyNMA(object):
- """
- http://www.notifymyandroid.com/api.jsp
- PyNMA(apikey=None, developerkey=None)
- takes 2 optional arguments:
- - (opt) apykey: a string containing 1 key or an array of keys
- - (opt) developerkey: where you can store your developer key
- """
-
- def __init__(self, apikey=None, developerkey=None):
-
- self._developerkey = None
- self.developerkey(developerkey)
-
- self.api_server = 'https://www.notifymyandroid.com'
- self.add_path = '/publicapi/notify'
- self.user_agent = 'PyNMA/v%s' % __version__
-
- key = []
- if apikey:
- key = (apikey, [apikey])[str == type(apikey)]
-
- self._apikey = self.uniq(key)
-
- @staticmethod
- def uniq(seq):
- # Not order preserving
- return list({}.fromkeys(seq).keys())
-
- def addkey(self, key):
- """
- Add a key (register ?)
- """
- if str == type(key):
- if key not in self._apikey:
- self._apikey.append(key)
-
- elif list == type(key):
- for k in key:
- if k not in self._apikey:
- self._apikey.append(k)
-
- def delkey(self, key):
- """
- Removes a key (unregister ?)
- """
- if str == type(key):
- if key in self._apikey:
- self._apikey.remove(key)
-
- elif list == type(key):
- for k in key:
- if key in self._apikey:
- self._apikey.remove(k)
-
- def developerkey(self, developerkey):
- """
- Sets the developer key (and check it has the good length)
- """
- if str == type(developerkey) and 48 == len(developerkey):
- self._developerkey = developerkey
-
- def push(self, application='', event='', description='', url='', content_type=None, priority=0, batch_mode=False, html=False):
- """
- Pushes a message on the registered API keys.
- takes 5 arguments:
- - (req) application: application name [256]
- - (req) event: event name [1000]
- - (req) description: description [10000]
- - (opt) url: url [512]
- - (opt) contenttype: Content Type (act: None (plain text) or text/html)
- - (opt) priority: from -2 (lowest) to 2 (highest) (def:0)
- - (opt) batch_mode: call API 5 by 5 (def:False)
- - (opt) html: shortcut for content_type=text/html
-
- Warning: using batch_mode will return error only if all API keys are bad
- http://www.notifymyandroid.com/api.jsp
- """
- datas = {'application': application[:256].encode('utf8'),
- 'event': event[:1000].encode('utf8'),
- 'description': description[:10000].encode('utf8'),
- 'priority': priority}
-
- if url:
- datas['url'] = url[:2000]
-
- if self._developerkey:
- datas['developerkey'] = self._developerkey
-
- if 'text/html' == content_type or True == html: # Currently only accepted content type
- datas['content-type'] = 'text/html'
-
- results = {}
-
- if not batch_mode:
- for key in self._apikey:
- datas['apikey'] = key
- res = self.callapi('POST', self.add_path, datas)
- results[key] = res
- else:
- datas['apikey'] = ','.join(self._apikey)
- res = self.callapi('POST', self.add_path, datas)
- results[datas['apikey']] = res
-
- return results
-
- def callapi(self, method, path, args):
- headers = {'User-Agent': self.user_agent}
-
- if 'POST' == method:
- headers['Content-type'] = 'application/x-www-form-urlencoded'
-
- try:
- resp = requests.post('%s:443%s' % (self.api_server, path), data=args, headers=headers).text
- res = self._parse_response(resp)
- except Exception as e:
- res = {'type': 'pynmaerror',
- 'code': 600,
- 'message': str(e)}
- pass
-
- return res
-
- @staticmethod
- def _parse_response(response):
-
- root = parseString(response).firstChild
-
- for elem in root.childNodes:
- if elem.TEXT_NODE == elem.nodeType:
- continue
-
- if 'success' == elem.tagName:
- res = dict(list(elem.attributes.items()))
- res['message'] = ''
- res['type'] = elem.tagName
- return res
-
- if 'error' == elem.tagName:
- res = dict(list(elem.attributes.items()))
- res['message'] = elem.firstChild.nodeValue
- res['type'] = elem.tagName
- return res
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 9b229535..9731eb2d 100755
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -391,13 +391,6 @@ PROWL_NOTIFY_ONSUBTITLEDOWNLOAD = False
PROWL_API = None
PROWL_PRIORITY = '0'
-USE_NMA = False
-NMA_NOTIFY_ONSNATCH = False
-NMA_NOTIFY_ONDOWNLOAD = False
-NMA_NOTIFY_ONSUBTITLEDOWNLOAD = False
-NMA_API = None
-NMA_PRIORITY = '0'
-
USE_LIBNOTIFY = False
LIBNOTIFY_NOTIFY_ONSNATCH = False
LIBNOTIFY_NOTIFY_ONDOWNLOAD = False
@@ -671,7 +664,6 @@ def initialize(console_logging=True):
PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_PRIORITY, PUSHOVER_DEVICE, PUSHOVER_SOUND, \
USE_BOXCAR2, BOXCAR2_NOTIFY_ONSNATCH, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, \
BOXCAR2_ACCESSTOKEN, BOXCAR2_SOUND, \
- USE_NMA, NMA_NOTIFY_ONSNATCH, NMA_NOTIFY_ONDOWNLOAD, NMA_NOTIFY_ONSUBTITLEDOWNLOAD, NMA_API, NMA_PRIORITY, \
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, \
PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, \
@@ -700,7 +692,7 @@ def initialize(console_logging=True):
for stanza in ('General', 'Blackhole', 'SABnzbd', 'NZBget', 'Emby', 'Kodi', 'XBMC', 'PLEX',
'Growl', 'Prowl', 'Twitter', 'Slack', 'Discordapp', 'Boxcar2', 'NMJ', 'NMJv2',
'Synology', 'SynologyNotifier',
- 'pyTivo', 'NMA', 'Pushalot', 'Pushbullet', 'Subtitles'):
+ 'pyTivo', 'Pushalot', 'Pushbullet', 'Subtitles'):
check_section(CFG, stanza)
update_config = False
@@ -1087,13 +1079,6 @@ def initialize(console_logging=True):
PYTIVO_SHARE_NAME = check_setting_str(CFG, 'pyTivo', 'pytivo_share_name', '')
PYTIVO_TIVO_NAME = check_setting_str(CFG, 'pyTivo', 'pytivo_tivo_name', '')
- USE_NMA = bool(check_setting_int(CFG, 'NMA', 'use_nma', 0))
- NMA_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'NMA', 'nma_notify_onsnatch', 0))
- NMA_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'NMA', 'nma_notify_ondownload', 0))
- NMA_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'NMA', 'nma_notify_onsubtitledownload', 0))
- NMA_API = check_setting_str(CFG, 'NMA', 'nma_api', '')
- NMA_PRIORITY = check_setting_str(CFG, 'NMA', 'nma_priority', '0')
-
USE_PUSHALOT = bool(check_setting_int(CFG, 'Pushalot', 'use_pushalot', 0))
PUSHALOT_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Pushalot', 'pushalot_notify_onsnatch', 0))
PUSHALOT_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Pushalot', 'pushalot_notify_ondownload', 0))
@@ -1913,14 +1898,6 @@ def save_config():
new_config['Prowl']['prowl_api'] = PROWL_API
new_config['Prowl']['prowl_priority'] = PROWL_PRIORITY
- new_config['NMA'] = {}
- new_config['NMA']['use_nma'] = int(USE_NMA)
- new_config['NMA']['nma_notify_onsnatch'] = int(NMA_NOTIFY_ONSNATCH)
- new_config['NMA']['nma_notify_ondownload'] = int(NMA_NOTIFY_ONDOWNLOAD)
- new_config['NMA']['nma_notify_onsubtitledownload'] = int(NMA_NOTIFY_ONSUBTITLEDOWNLOAD)
- new_config['NMA']['nma_api'] = NMA_API
- new_config['NMA']['nma_priority'] = NMA_PRIORITY
-
new_config['Libnotify'] = {}
new_config['Libnotify']['use_libnotify'] = int(USE_LIBNOTIFY)
new_config['Libnotify']['libnotify_notify_onsnatch'] = int(LIBNOTIFY_NOTIFY_ONSNATCH)
diff --git a/sickbeard/encodingKludge.py b/sickbeard/encodingKludge.py
index e9ec28b7..67067b20 100644
--- a/sickbeard/encodingKludge.py
+++ b/sickbeard/encodingKludge.py
@@ -25,6 +25,7 @@ import sickbeard
# encodings. It tries to just use unicode, but if that fails then it tries forcing it to utf-8. Any functions
# which return something should always return unicode.
+
def fixStupidEncodings(x, silent=False):
if type(x) == str:
try:
@@ -41,7 +42,6 @@ def fixStupidEncodings(x, silent=False):
return None
-
def fixListEncodings(x):
if type(x) != list and type(x) != tuple:
return x
@@ -66,8 +66,21 @@ def fixParaLists(x):
return x
+def win_encode_unicode(x):
+ if isinstance(x, str):
+ try:
+ return x.decode('UTF-8')
+ except UnicodeDecodeError:
+ return x
+ return x
+
+
def ek(func, *args, **kwargs):
if os.name == 'nt':
+ # convert all str parameter values to unicode
+ args = tuple([x if not isinstance(x, str) else win_encode_unicode(x) for x in args])
+ kwargs = {k: x if not isinstance(x, str) else win_encode_unicode(x) for k, x in
+ kwargs.iteritems()}
result = func(*args, **kwargs)
else:
result = func(*[callPeopleStupid(x) if type(x) in (str, unicode) else fixParaLists(x) for x in args], **kwargs)
diff --git a/sickbeard/notifiers/__init__.py b/sickbeard/notifiers/__init__.py
index 1ff173c1..4c9c7e08 100644
--- a/sickbeard/notifiers/__init__.py
+++ b/sickbeard/notifiers/__init__.py
@@ -32,7 +32,6 @@ import pushbullet
import pushover
import growl
import prowl
-import nma
from . import libnotify
from lib import libtrakt
@@ -68,7 +67,6 @@ class NotifierFactory(object):
PUSHOVER=pushover.PushoverNotifier,
GROWL=growl.GrowlNotifier,
PROWL=prowl.ProwlNotifier,
- NMA=nma.NMANotifier,
LIBNOTIFY=libnotify.LibnotifyNotifier,
# social
diff --git a/sickbeard/notifiers/nma.py b/sickbeard/notifiers/nma.py
deleted file mode 100644
index 3ed63278..00000000
--- a/sickbeard/notifiers/nma.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import sickbeard
-from sickbeard.notifiers.generic import Notifier
-
-from lib.pynma import pynma
-
-
-class NMANotifier(Notifier):
-
- def _notify(self, title, body, nma_api=None, nma_priority=None, **kwargs):
-
- nma_api = self._choose(nma_api, sickbeard.NMA_API)
- nma_priority = self._choose(nma_priority, sickbeard.NMA_PRIORITY)
-
- batch = False
-
- p = pynma.PyNMA()
- keys = nma_api.split(',')
- p.addkey(keys)
-
- if 1 < len(keys):
- batch = True
-
- self._log_debug('Sending notice with priority=%s, batch=%s' % (nma_priority, batch))
- response = p.push('SickGear', title, body, priority=nma_priority, batch_mode=batch)
-
- result = False
- try:
- if u'200' != response[nma_api][u'code']:
- self._log_error('Notification failed')
- else:
- result = True
- except (StandardError, Exception):
- pass
-
- return result
-
-
-notifier = NMANotifier
diff --git a/sickbeard/search.py b/sickbeard/search.py
index d8266aab..6538ddc7 100644
--- a/sickbeard/search.py
+++ b/sickbeard/search.py
@@ -707,9 +707,9 @@ def search_providers(show, episodes, manual_search=False, torrent_only=False, tr
best_season_result.provider.providerType), logger.DEBUG)
my_db = db.DBConnection()
- sql = 'SELECT episode FROM tv_episodes WHERE showid = %s AND (season IN (%s))' %\
+ sql = 'SELECT season, episode FROM tv_episodes WHERE showid = %s AND (season IN (%s))' %\
(show.indexerid, ','.join([str(x.season) for x in episodes]))
- ep_nums = [int(x['episode']) for x in my_db.select(sql)]
+ ep_nums = [(int(x['season']), int(x['episode'])) for x in my_db.select(sql)]
logger.log(u'Executed query: [%s]' % sql)
logger.log(u'Episode list: %s' % ep_nums, logger.DEBUG)
@@ -717,11 +717,10 @@ def search_providers(show, episodes, manual_search=False, torrent_only=False, tr
all_wanted = True
any_wanted = False
for ep_num in ep_nums:
- for season in set([x.season for x in episodes]):
- if not show.wantEpisode(season, ep_num, season_qual):
- all_wanted = False
- else:
- any_wanted = True
+ if not show.wantEpisode(ep_num[0], ep_num[1], season_qual):
+ all_wanted = False
+ else:
+ any_wanted = True
# if we need every ep in the season and there's nothing better then just download this and
# be done with it (unless single episodes are preferred)
@@ -730,8 +729,7 @@ def search_providers(show, episodes, manual_search=False, torrent_only=False, tr
(best_season_result.provider.providerType, best_season_result.name))
ep_objs = []
for ep_num in ep_nums:
- for season in set([x.season for x in episodes]):
- ep_objs.append(show.getEpisode(season, ep_num))
+ ep_objs.append(show.getEpisode(ep_num[0], ep_num[1]))
best_season_result.episodes = ep_objs
return [best_season_result]
@@ -770,8 +768,7 @@ def search_providers(show, episodes, manual_search=False, torrent_only=False, tr
u'the episodes that you do not want to "don\'t download"')
ep_objs = []
for ep_num in ep_nums:
- for season in set([x.season for x in episodes]):
- ep_objs.append(show.getEpisode(season, ep_num))
+ ep_objs.append(show.getEpisode(ep_num[0], ep_num[1]))
best_season_result.episodes = ep_objs
ep_num = MULTI_EP_RESULT
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index c30bd6d2..d7ae9a77 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -1450,14 +1450,6 @@ class Home(MainHandler):
return notifiers.NotifierFactory().get('PROWL').test_notify(prowl_api, prowl_priority)
- def test_nma(self, nma_api=None, nma_priority=0):
- self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
-
- if None is not nma_api and starify(nma_api, True):
- nma_api = sickbeard.NMA_API
-
- return notifiers.NotifierFactory().get('NMA').test_notify(nma_api, nma_priority)
-
def test_libnotify(self, *args, **kwargs):
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
@@ -3298,7 +3290,7 @@ class NewHomeAddShows(Home):
if not file_list:
try:
file_list = ek.ek(os.listdir, root_dir)
- except:
+ except (StandardError, Exception):
continue
for cur_file in file_list:
@@ -6605,8 +6597,6 @@ class ConfigNotifications(Config):
growl_notify_onsubtitledownload=None, growl_host=None, growl_password=None,
use_prowl=None, prowl_notify_onsnatch=None, prowl_notify_ondownload=None,
prowl_notify_onsubtitledownload=None, prowl_api=None, prowl_priority=0,
- use_nma=None, nma_notify_onsnatch=None, nma_notify_ondownload=None,
- nma_notify_onsubtitledownload=None, nma_api=None, nma_priority=0,
use_libnotify=None, libnotify_notify_onsnatch=None, libnotify_notify_ondownload=None,
libnotify_notify_onsubtitledownload=None,
# use_pushalot=None, pushalot_notify_onsnatch=None, pushalot_notify_ondownload=None,
@@ -6820,15 +6810,6 @@ class ConfigNotifications(Config):
sickbeard.PYTIVO_SHARE_NAME = pytivo_share_name
sickbeard.PYTIVO_TIVO_NAME = pytivo_tivo_name
- sickbeard.USE_NMA = config.checkbox_to_value(use_nma)
- sickbeard.NMA_NOTIFY_ONSNATCH = config.checkbox_to_value(nma_notify_onsnatch)
- sickbeard.NMA_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(nma_notify_ondownload)
- sickbeard.NMA_NOTIFY_ONSUBTITLEDOWNLOAD = config.checkbox_to_value(nma_notify_onsubtitledownload)
- key = nma_api.strip()
- if not starify(key, True):
- sickbeard.NMA_API = key
- sickbeard.NMA_PRIORITY = nma_priority
-
# sickbeard.USE_PUSHALOT = config.checkbox_to_value(use_pushalot)
# sickbeard.PUSHALOT_NOTIFY_ONSNATCH = config.checkbox_to_value(pushalot_notify_onsnatch)
# sickbeard.PUSHALOT_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(pushalot_notify_ondownload)