mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-23 01:43:43 +00:00
Merge branch 'release/0.11.0' into develop
This commit is contained in:
commit
2a762ae7db
6 changed files with 114 additions and 130 deletions
|
@ -1,4 +1,4 @@
|
||||||
### 0.12.0 (2015-xx-xx xx:xx:xx UTC)
|
### 0.12.0 (2015-xx-xx xx:xx:xx UTC)
|
||||||
|
|
||||||
* Change to generalize xem id fetching
|
* Change to generalize xem id fetching
|
||||||
|
|
||||||
|
@ -101,7 +101,6 @@
|
||||||
* Change position of parsed qualities to the start of log lines
|
* Change position of parsed qualities to the start of log lines
|
||||||
* Change to always display branch and commit hash on 'Help & Info' page
|
* Change to always display branch and commit hash on 'Help & Info' page
|
||||||
* Add option to create season search exceptions from editShow page
|
* Add option to create season search exceptions from editShow page
|
||||||
* Change editshow scene exceptions description
|
|
||||||
* Change sab to use requests library
|
* Change sab to use requests library
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1100,7 +1100,7 @@ def proxy_setting(proxy_setting, request_url, force=False):
|
||||||
return (False, proxy_address)[request_url_match], True
|
return (False, proxy_address)[request_url_match], True
|
||||||
|
|
||||||
|
|
||||||
def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=None, json=False):
|
def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=None, json=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a byte-string retrieved from the url provider.
|
Returns a byte-string retrieved from the url provider.
|
||||||
"""
|
"""
|
||||||
|
@ -1145,9 +1145,9 @@ def getURL(url, post_data=None, params=None, headers=None, timeout=30, session=N
|
||||||
|
|
||||||
# decide if we get or post data to server
|
# decide if we get or post data to server
|
||||||
if post_data:
|
if post_data:
|
||||||
resp = session.post(url, data=post_data, timeout=timeout)
|
resp = session.post(url, data=post_data, timeout=timeout, **kwargs)
|
||||||
else:
|
else:
|
||||||
resp = session.get(url, timeout=timeout)
|
resp = session.get(url, timeout=timeout, **kwargs)
|
||||||
|
|
||||||
if not resp.ok:
|
if not resp.ok:
|
||||||
if resp.status_code in clients.http_error_code:
|
if resp.status_code in clients.http_error_code:
|
||||||
|
|
|
@ -224,7 +224,7 @@ class NewznabProvider(generic.NZBProvider):
|
||||||
base_params['apikey'] = api_key
|
base_params['apikey'] = api_key
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
total = 0
|
total, cnt, search_url, exit_log = 0, len(results), '', False
|
||||||
|
|
||||||
for mode in search_params.keys():
|
for mode in search_params.keys():
|
||||||
for i, params in enumerate(search_params[mode]):
|
for i, params in enumerate(search_params[mode]):
|
||||||
|
@ -285,8 +285,13 @@ class NewznabProvider(generic.NZBProvider):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
break
|
break
|
||||||
|
|
||||||
# No items found or cache mode, prevent from doing another search
|
# No items found, prevent from doing another search
|
||||||
if 0 == total or 'Cache' == mode:
|
if 0 == total:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Cache mode, prevent from doing another search
|
||||||
|
if 'Cache' == mode:
|
||||||
|
exit_log = True
|
||||||
break
|
break
|
||||||
|
|
||||||
if offset != request_params['offset']:
|
if offset != request_params['offset']:
|
||||||
|
@ -295,6 +300,7 @@ class NewznabProvider(generic.NZBProvider):
|
||||||
|
|
||||||
request_params['offset'] += request_params['limit']
|
request_params['offset'] += request_params['limit']
|
||||||
if total <= request_params['offset']:
|
if total <= request_params['offset']:
|
||||||
|
exit_log = True
|
||||||
logger.log('%s item%s found that will be used for episode matching' % (total, helpers.maybe_plural(total)),
|
logger.log('%s item%s found that will be used for episode matching' % (total, helpers.maybe_plural(total)),
|
||||||
logger.DEBUG)
|
logger.DEBUG)
|
||||||
break
|
break
|
||||||
|
@ -304,15 +310,23 @@ class NewznabProvider(generic.NZBProvider):
|
||||||
logger.log('%s more item%s to fetch from a batch of up to %s items.'
|
logger.log('%s more item%s to fetch from a batch of up to %s items.'
|
||||||
% (items, helpers.maybe_plural(items), request_params['limit']), logger.DEBUG)
|
% (items, helpers.maybe_plural(items), request_params['limit']), logger.DEBUG)
|
||||||
|
|
||||||
batch_count = len(results) - cnt
|
batch_count = self._log_result(results, mode, cnt, search_url)
|
||||||
if batch_count:
|
|
||||||
self._log_search(mode, batch_count, search_url)
|
if exit_log:
|
||||||
|
self._log_result(results, mode, cnt, search_url)
|
||||||
|
exit_log = False
|
||||||
|
|
||||||
if 'tvdbid' in request_params and len(results):
|
if 'tvdbid' in request_params and len(results):
|
||||||
break
|
break
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
def _log_result(self, results, mode, cnt, url):
|
||||||
|
count = len(results) - cnt
|
||||||
|
if count:
|
||||||
|
self._log_search(mode, count, url)
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
class NewznabCache(tvcache.TVCache):
|
class NewznabCache(tvcache.TVCache):
|
||||||
|
|
||||||
|
|
114
sickbeard/sab.py
114
sickbeard/sab.py
|
@ -16,30 +16,20 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
# along with SickGear. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from six import moves
|
|
||||||
|
|
||||||
import sickbeard
|
import sickbeard
|
||||||
|
|
||||||
from lib import MultipartPostHandler
|
|
||||||
|
|
||||||
try:
|
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
from lib import simplejson as json
|
|
||||||
|
|
||||||
from sickbeard.common import USER_AGENT
|
|
||||||
from sickbeard import logger
|
from sickbeard import logger
|
||||||
from sickbeard.exceptions import ex
|
|
||||||
from sickbeard import helpers
|
|
||||||
|
|
||||||
|
|
||||||
def sendNZB(nzb):
|
def send_nzb(nzb):
|
||||||
"""
|
"""
|
||||||
Sends an NZB to SABnzbd via the API.
|
Sends an nzb to SABnzbd via the API.
|
||||||
|
|
||||||
nzb: The NZBSearchResult object to send to SAB
|
:param nzb: The NZBSearchResult object to send to SAB
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
success, result, nzb_type = True, '', 'nzb'
|
||||||
|
if nzb.resultType in ('nzb', 'nzbdata'):
|
||||||
|
|
||||||
# set up a dict with the URL params in it
|
# set up a dict with the URL params in it
|
||||||
params = {'output': 'json'}
|
params = {'output': 'json'}
|
||||||
if sickbeard.SAB_USERNAME is not None:
|
if sickbeard.SAB_USERNAME is not None:
|
||||||
|
@ -52,106 +42,96 @@ def sendNZB(nzb):
|
||||||
params['cat'] = sickbeard.SAB_CATEGORY
|
params['cat'] = sickbeard.SAB_CATEGORY
|
||||||
|
|
||||||
# use high priority if specified (recently aired episode)
|
# use high priority if specified (recently aired episode)
|
||||||
if nzb.priority == 1:
|
if 1 == nzb.priority:
|
||||||
params['priority'] = 1
|
params['priority'] = 1
|
||||||
|
|
||||||
|
kwargs = {}
|
||||||
# if it's a normal result we just pass SAB the URL
|
# if it's a normal result we just pass SAB the URL
|
||||||
if nzb.resultType == 'nzb':
|
if 'nzb' == nzb.resultType:
|
||||||
|
nzb_type = 'nzb url'
|
||||||
params['mode'] = 'addurl'
|
params['mode'] = 'addurl'
|
||||||
params['name'] = nzb.url
|
params['name'] = nzb.url
|
||||||
|
kwargs['params'] = params
|
||||||
|
|
||||||
# if we get a raw data result we want to upload it to SAB
|
# if we get a raw data result we want to upload it to SAB
|
||||||
elif nzb.resultType == 'nzbdata':
|
else:
|
||||||
|
nzb_type = 'file nzb'
|
||||||
params['mode'] = 'addfile'
|
params['mode'] = 'addfile'
|
||||||
multiPartParams = {'nzbfile': (nzb.name + '.nzb', nzb.extraInfo[0])}
|
kwargs['post_data'] = params
|
||||||
|
kwargs['files'] = {'nzbfile': ('%s.nzb' % nzb.name, nzb.extraInfo[0])}
|
||||||
|
|
||||||
url = sickbeard.SAB_HOST + 'api'
|
logger.log(u'Sending %s to SABnzbd: %s' % (nzb_type, nzb.name))
|
||||||
|
|
||||||
logger.log(u'Sending NZB to SABnzbd: %s' % nzb.name)
|
url = '%sapi' % sickbeard.SAB_HOST
|
||||||
logger.log(u'Using SABnzbd URL: %s with parameters: %s' % (url, params), logger.DEBUG)
|
logger.log(u'SABnzbd at %s sent params: %s' % (url, params), logger.DEBUG)
|
||||||
|
success, result = _get_url(url, **kwargs)
|
||||||
# if we have the URL to an NZB then we've built up the SAB API URL already so just call it
|
|
||||||
if nzb.resultType == 'nzb':
|
|
||||||
success, result = _sabURLOpenSimple(url, params)
|
|
||||||
|
|
||||||
# if we are uploading the NZB data to SAB then we need to build a little POST form and send it
|
|
||||||
elif nzb.resultType == 'nzbdata':
|
|
||||||
headers = {'User-Agent': USER_AGENT}
|
|
||||||
success, result = _sabURLOpenSimple(url, params=params, post_data=multiPartParams, headers=headers)
|
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
return False, result
|
return False
|
||||||
|
|
||||||
# do some crude parsing of the result text to determine what SAB said
|
# do some crude parsing of the result text to determine what SAB said
|
||||||
if result['status']:
|
if result.get('status'):
|
||||||
logger.log(u'NZB sent to SABnzbd successfully', logger.DEBUG)
|
logger.log(u'Success from SABnzbd using %s' % nzb_type, logger.DEBUG)
|
||||||
return True
|
return True
|
||||||
elif 'error' in result:
|
elif 'error' in result:
|
||||||
logger.log(u'NZB failed to send to SABnzbd. Return error text is: %s', logger.ERROR)
|
logger.log(u'Failed using %s with SABnzbd, response: %s' % (nzb_type, result.get('error', 'und')), logger.ERROR)
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
logger.log(u'Unknown failure sending NZB to SABnzbd. Return text is: %s' % result, logger.ERROR)
|
logger.log(u'Failure unknown using %s with SABnzbd, response: %s' % (nzb_type, result), logger.ERROR)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _checkSabResponse(result):
|
def _check_sab_response(result):
|
||||||
if len(result) == 0:
|
|
||||||
logger.log(u'No data returned from SABnzbd, NZB not sent', logger.ERROR)
|
if 0 == len(result):
|
||||||
|
logger.log('No data returned from SABnzbd, nzb not used', logger.ERROR)
|
||||||
return False, 'No data from SABnzbd'
|
return False, 'No data from SABnzbd'
|
||||||
|
|
||||||
if 'error' in result:
|
if 'error' in result:
|
||||||
logger.log(result['error'], logger.ERROR)
|
logger.log(result['error'], logger.ERROR)
|
||||||
return False, result['error']
|
return False, result['error']
|
||||||
else:
|
|
||||||
return True, result
|
return True, result
|
||||||
|
|
||||||
|
|
||||||
def _sabURLOpenSimple(url, params=None, post_data=None, headers=None):
|
def _get_url(url, params=None, **kwargs):
|
||||||
result = helpers.getURL(url, params=params, post_data=post_data, headers=headers, json=True)
|
|
||||||
if result is None:
|
result = sickbeard.helpers.getURL(url, params=params, json=True, **kwargs)
|
||||||
logger.log(u'No data returned from SABnzbd', logger.ERROR)
|
if None is result:
|
||||||
return False, u'No data returned from SABnzbd'
|
logger.log('Error, no response from SABnzbd', logger.ERROR)
|
||||||
else:
|
return False, 'Error, no response from SABnzbd'
|
||||||
return True, result
|
return True, result
|
||||||
|
|
||||||
|
|
||||||
def getSabAccesMethod(host=None, username=None, password=None, apikey=None):
|
def access_method(host):
|
||||||
url = host + 'api'
|
|
||||||
params = {u'mode': u'auth', u'output': u'json'}
|
|
||||||
|
|
||||||
success, result = _sabURLOpenSimple(url, params=params)
|
success, result = _get_url('%sapi' % host, params={'mode': 'auth', 'output': 'json'})
|
||||||
if not success:
|
if not success:
|
||||||
return False, result
|
return False, result
|
||||||
|
|
||||||
return True, result['auth']
|
return True, result['auth']
|
||||||
|
|
||||||
|
|
||||||
def testAuthentication(host=None, username=None, password=None, apikey=None):
|
def test_authentication(host=None, username=None, password=None, apikey=None):
|
||||||
"""
|
"""
|
||||||
Sends a simple API request to SAB to determine if the given connection information is connect
|
Sends a simple API request to SAB to determine if the given connection information is connect
|
||||||
|
|
||||||
host: The host where SAB is running (incl port)
|
|
||||||
username: The username to use for the HTTP request
|
|
||||||
password: The password to use for the HTTP request
|
|
||||||
apikey: The API key to provide to SAB
|
|
||||||
|
|
||||||
Returns: A tuple containing the success boolean and a message
|
Returns: A tuple containing the success boolean and a message
|
||||||
|
:param host: The host where SAB is running (incl port)
|
||||||
|
:param username: The username to use for the HTTP request
|
||||||
|
:param password: The password to use for the HTTP request
|
||||||
|
:param apikey: The API key to provide to SAB
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# build up the URL parameters
|
# build up the URL parameters
|
||||||
params = {u'mode': u'queue', u'output': u'json', u'ma_username': username, u'ma_password': password, u'apikey': apikey}
|
params = {'mode': 'queue', 'ma_username': username, 'ma_password': password, 'apikey': apikey, 'output': 'json'}
|
||||||
url = host + 'api'
|
url = '%sapi' % host
|
||||||
|
|
||||||
# send the test request
|
# send the test request
|
||||||
logger.log(u'SABnzbd test URL: %s with parameters: %s' % (url, params), logger.DEBUG)
|
logger.log(u'SABnzbd test URL: %s with parameters: %s' % (url, params), logger.DEBUG)
|
||||||
success, result = _sabURLOpenSimple(url, params=params)
|
success, result = _get_url(url, params=params)
|
||||||
if not success:
|
if not success:
|
||||||
return False, result
|
return False, result
|
||||||
|
|
||||||
# check the result and determine if it's good or not
|
# check the result and determine if it's good or not
|
||||||
success, sabText = _checkSabResponse(result)
|
success, response = _check_sab_response(result)
|
||||||
if not success:
|
if not success:
|
||||||
return False, sabText
|
return False, response
|
||||||
|
return True, 'Success'
|
||||||
return True, u'Success'
|
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ def snatch_episode(result, end_status=SNATCHED):
|
||||||
if 'blackhole' == sickbeard.NZB_METHOD:
|
if 'blackhole' == sickbeard.NZB_METHOD:
|
||||||
dl_result = _download_result(result)
|
dl_result = _download_result(result)
|
||||||
elif 'sabnzbd' == sickbeard.NZB_METHOD:
|
elif 'sabnzbd' == sickbeard.NZB_METHOD:
|
||||||
dl_result = sab.sendNZB(result)
|
dl_result = sab.send_nzb(result)
|
||||||
elif 'nzbget' == sickbeard.NZB_METHOD:
|
elif 'nzbget' == sickbeard.NZB_METHOD:
|
||||||
is_proper = True if SNATCHED_PROPER == end_status else False
|
is_proper = True if SNATCHED_PROPER == end_status else False
|
||||||
dl_result = nzbget.sendNZB(result, is_proper)
|
dl_result = nzbget.sendNZB(result, is_proper)
|
||||||
|
|
|
@ -635,19 +635,18 @@ class Home(MainHandler):
|
||||||
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
self.set_header('Cache-Control', 'max-age=0,no-cache,no-store')
|
||||||
|
|
||||||
host = config.clean_url(host)
|
host = config.clean_url(host)
|
||||||
|
connection, access_msg = sab.access_method(host)
|
||||||
|
if connection:
|
||||||
if None is not password and set('*') == set(password):
|
if None is not password and set('*') == set(password):
|
||||||
password = sickbeard.SAB_PASSWORD
|
password = sickbeard.SAB_PASSWORD
|
||||||
if None is not apikey and starify(apikey, True):
|
if None is not apikey and starify(apikey, True):
|
||||||
apikey = sickbeard.SAB_APIKEY
|
apikey = sickbeard.SAB_APIKEY
|
||||||
|
|
||||||
connection, accesMsg = sab.getSabAccesMethod(host, username, password, apikey)
|
authed, auth_msg = sab.test_authentication(host, username, password, apikey)
|
||||||
if connection:
|
|
||||||
authed, authMsg = sab.testAuthentication(host, username, password, apikey)
|
|
||||||
if authed:
|
if authed:
|
||||||
return u'Success. Connected and authenticated'
|
return u'Success. Connected %s authentication' % \
|
||||||
else:
|
('using %s' % access_msg, 'with no')['None' == auth_msg.lower()]
|
||||||
return u'Authentication failed. %s' % authMsg
|
return u'Authentication failed. %s' % auth_msg
|
||||||
else:
|
|
||||||
return u'Unable to connect to host'
|
return u'Unable to connect to host'
|
||||||
|
|
||||||
def testTorrent(self, torrent_method=None, host=None, username=None, password=None):
|
def testTorrent(self, torrent_method=None, host=None, username=None, password=None):
|
||||||
|
@ -4241,33 +4240,25 @@ class ConfigProviders(Config):
|
||||||
return newProvider.get_id() + '|' + newProvider.config_str()
|
return newProvider.get_id() + '|' + newProvider.config_str()
|
||||||
|
|
||||||
def getNewznabCategories(self, name, url, key):
|
def getNewznabCategories(self, name, url, key):
|
||||||
'''
|
"""
|
||||||
Retrieves a list of possible categories with category id's
|
Retrieves a list of possible categories with category id's
|
||||||
Using the default url/api?cat
|
Using the default url/api?cat
|
||||||
http://yournewznaburl.com/api?t=caps&apikey=yourapikey
|
http://yournewznaburl.com/api?t=caps&apikey=yourapikey
|
||||||
'''
|
"""
|
||||||
error = ''
|
|
||||||
success = False
|
|
||||||
|
|
||||||
if not name:
|
error = not name and 'Name' or not url and 'Url' or not key and 'Apikey' or ''
|
||||||
error += '\nNo Provider Name specified'
|
if error:
|
||||||
if not url:
|
error = '\nNo provider %s specified' % error
|
||||||
error += '\nNo Provider Url specified'
|
return json.dumps({'success': False, 'error': error})
|
||||||
if not key:
|
|
||||||
error += '\nNo Provider Api key specified'
|
|
||||||
|
|
||||||
if error <> '':
|
providers = dict(zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
|
||||||
return json.dumps({'success' : False, 'error': error})
|
temp_provider = newznab.NewznabProvider(name, url, key)
|
||||||
|
if None is not key and starify(key, True):
|
||||||
|
temp_provider.key = providers[temp_provider.get_id()].key
|
||||||
|
|
||||||
#Get list with Newznabproviders
|
success, tv_categories, error = temp_provider.get_newznab_categories()
|
||||||
#providerDict = dict(zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
|
|
||||||
|
|
||||||
#Get newznabprovider obj with provided name
|
return json.dumps({'success': success, 'tv_categories': tv_categories, 'error': error})
|
||||||
tempProvider= newznab.NewznabProvider(name, url, key)
|
|
||||||
|
|
||||||
success, tv_categories, error = tempProvider.get_newznab_categories()
|
|
||||||
|
|
||||||
return json.dumps({'success' : success,'tv_categories' : tv_categories, 'error' : error})
|
|
||||||
|
|
||||||
def deleteNewznabProvider(self, nnid):
|
def deleteNewznabProvider(self, nnid):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue