Merge branch 'release/v3.1.0'

This commit is contained in:
echel0n 2014-11-22 19:59:42 -08:00
commit b181233f61
12 changed files with 44 additions and 85 deletions

View File

@ -167,7 +167,7 @@
<tr>
<th>Airdate</th>
<th>Show</th>
<th class="nowrap">Next Ep</th>
<th nowrap="nowrap">Next Ep</th>
<th>Next Ep Name</th>
<th>Network</th>
<th>Quality</th>
@ -206,17 +206,17 @@
<!-- start $cur_result['show_name'] //-->
<tr class="$show_div">
## forced to use a div to wrap airdate, the column sort went crazy with a span
<td align="center" class="nowrap">
<td align="center" nowrap="nowrap">
<div class="${fuzzydate}">$sbdatetime.sbdatetime.sbfdatetime($cur_result['localtime']).decode($sickbeard.SYS_ENCODING)</div><span class="sort_data">$time.mktime($cur_result['localtime'].timetuple())</span>
</td>
<td class="tvShow"><a href="$sbRoot/home/displayShow?show=${cur_result['showid']}">$cur_result['show_name']</a>
<td class="tvShow" nowrap="nowrap"><a href="$sbRoot/home/displayShow?show=${cur_result['showid']}">$cur_result['show_name']</a>
#if int($cur_result['paused']):
<span class="pause">[paused]</span>
#end if
</td>
<td class="nowrap" align="center">
<td nowrap="nowrap" align="center">
<%= 'S%02iE%02i' % (int(cur_result['season']), int(cur_result['episode'])) %>
</td>

View File

@ -120,9 +120,9 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
<span class="component-desc">
#set $provider_config_list = []
#for $curProvider in $sickbeard.providers.sortedProviderList():
#if $curProvider.providerType == $GenericProvider.NZB and not $sickbeard.USE_NZBS:
#if $curProvider.providerType == $GenericProvider.NZB and (not $sickbeard.USE_NZBS or not $curProvider.isEnabled()):
#continue
#elif $curProvider.providerType == $GenericProvider.TORRENT and not $sickbeard.USE_TORRENTS:
#elif $curProvider.providerType == $GenericProvider.TORRENT and ( not $sickbeard.USE_TORRENTS or not $curProvider.isEnabled()):
#continue
#end if
$provider_config_list.append($curProvider)

View File

@ -1,67 +1,24 @@
from urllib2 import Request, urlopen, HTTPError, URLError
import base64
from sha import new as sha1
try:
import json
except ImportError:
from lib import simplejson as json
import hashlib
import requests
def TraktCall(method, api, username=None, password=None, data={}):
"""
A generic method for communicating with trakt. Uses the method and data provided along
with the auth info to send the command.
method: The URL to use at trakt, relative, no leading slash.
api: The API string to provide to trakt
username: The username to use when logging in
password: The unencrypted password to use when logging in
Returns: A boolean representing success
"""
#logger.log("trakt: Call method " + method, logger.DEBUG)
base_url = 'http://api.trakt.tv/'
# if the API isn't given then it failed
if not api:
return None
# replace the API string with what we found
method = method.replace("%API%", api)
# make the full url
url = 'https://api.trakt.tv/' + method
# take the URL params and make a json object out of them
encoded_data = json.JSONEncoder().encode(data)
request = Request(url, encoded_data)
# if the username isn't given then it failed
# if username and password given then encode password with sha1
auth = None
if username and password:
pwdsha1 = sha1(password).hexdigest()
base64string = base64.encodestring('%s:%s' % (username, pwdsha1)).replace('\n', '')
request.add_header("Accept", "*/*")
request.add_header("User-Agent", "CPython/2.7.5 Unknown/Unknown")
request.add_header("Authorization", "Basic %s" % base64string)
auth = (username, hashlib.sha1(password.encode('utf-8')).hexdigest())
# request the URL from trakt and parse the result as json
try:
#logger.log("trakt: Calling method http://api.trakt.tv/" + method + ", with data" + encoded_data, logger.DEBUG)
stream = urlopen(request).read()
# check if results are valid
if stream == '[]':
resp = 'NULL'
else:
resp = json.JSONDecoder().decode(stream)
if ("error" in resp):
raise Exception(resp["error"])
except (IOError):
#logger.log("trakt: Failed calling method", logger.ERROR)
resp = requests.get(base_url + method.replace("%API%", api), auth=auth, data=data).json()
if isinstance(resp, dict) and resp.get('status', False) == 'failure':
raise Exception(resp.get('error', 'Unknown Error'))
except:
return None
#logger.log("trakt: Failed calling method", logger.ERROR)
return resp

View File

@ -155,7 +155,7 @@ def get_scene_exception_by_name_multiple(show_name):
if out:
return out
return (None, None)
return [(None, None)]
def retrieve_exceptions():

View File

@ -167,7 +167,7 @@ def snatchEpisode(result, endStatus=SNATCHED):
sql_l.append(curEpObj.get_sql())
if curEpObj.status not in Quality.DOWNLOADED:
notifiers.notify_snatch(curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN'))
notifiers.notify_snatch(curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
if len(sql_l) > 0:
myDB = db.DBConnection()

View File

@ -53,14 +53,14 @@ class TraktChecker():
def findShow(self, indexer, indexerid):
library = TraktCall("user/library/shows/all.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
if library == 'NULL':
logger.log(u"No shows found in your library, aborting library update", logger.DEBUG)
return
if not library:
logger.log(u"Could not connect to trakt service, aborting library check", logger.ERROR)
return
if not len(library):
logger.log(u"No shows found in your library, aborting library update", logger.DEBUG)
return
return filter(lambda x: int(indexerid) in [int(x['tvdb_id']) or 0, int(x['tvrage_id'])] or 0, library)
def syncLibrary(self):
@ -106,14 +106,14 @@ class TraktChecker():
logger.log(u"Starting trakt show watchlist check", logger.DEBUG)
watchlist = TraktCall("user/watchlist/shows.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
if watchlist == 'NULL':
logger.log(u"No shows found in your watchlist, aborting watchlist update", logger.DEBUG)
return
if not watchlist:
logger.log(u"Could not connect to trakt service, aborting watchlist update", logger.ERROR)
return
if not len(watchlist):
logger.log(u"No shows found in your watchlist, aborting watchlist update", logger.DEBUG)
return
for show in watchlist:
indexer = int(sickbeard.TRAKT_DEFAULT_INDEXER)
if indexer == 2:
@ -140,14 +140,14 @@ class TraktChecker():
logger.log(u"Starting trakt episode watchlist check", logger.DEBUG)
watchlist = TraktCall("user/watchlist/episodes.json/%API%/" + sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_API, sickbeard.TRAKT_USERNAME, sickbeard.TRAKT_PASSWORD)
if watchlist == 'NULL':
logger.log(u"No episodes found in your watchlist, aborting watchlist update", logger.DEBUG)
return
if not watchlist:
logger.log(u"Could not connect to trakt service, aborting watchlist update", logger.ERROR)
return
if not len(watchlist):
logger.log(u"No shows found in your watchlist, aborting watchlist update", logger.DEBUG)
return
for show in watchlist:
indexer = int(sickbeard.TRAKT_DEFAULT_INDEXER)
if indexer == 2:

View File

@ -618,23 +618,19 @@ class SourceUpdateManager(UpdateManager):
# try to get newest commit hash and commits behind directly by comparing branch and current commit
if self._cur_commit_hash:
branch_compared = sickbeard.gh.compare(base=self.branch, head=self._cur_commit_hash)
if 'base_commit' in branch_compared:
self._newest_commit_hash = branch_compared['base_commit']['sha']
if 'behind_by' in branch_compared:
self._num_commits_behind = int(branch_compared['behind_by'])
self._newest_commit_hash = branch_compared.base_commit.sha
self._num_commits_behind = branch_compared.behind_by
# fall back and iterate over last 100 (items per page in gh_api) commits
if not self._newest_commit_hash:
for curCommit in sickbeard.gh.get_commits():
if not self._newest_commit_hash:
self._newest_commit_hash = curCommit['sha']
self._newest_commit_hash = curCommit.sha
if not self._cur_commit_hash:
break
if curCommit['sha'] == self._cur_commit_hash:
if curCommit.sha == self._cur_commit_hash:
break
# when _cur_commit_hash doesn't match anything _num_commits_behind == 100

View File

@ -163,7 +163,7 @@ class Api(webserve.MainHandler):
def _out_as_json(self, dict):
self.set_header("Content-Type", "application/json")
try:
out = json.dumps(dict, indent=self.intent, sort_keys=True)
out = json.dumps(dict, indent=self.intent,ensure_ascii=False,sort_keys=True)
if 'jsonp' in self.request.query_arguments:
out = self.request.arguments['jsonp'] + '(' + out + ');' # wrap with JSONP call if requested
@ -2313,7 +2313,7 @@ class CMD_ShowSeasons(ApiCall):
myDB = db.DBConnection(row_type="dict")
if self.season == None:
sqlResults = myDB.select("SELECT name, episode, airdate, status, season FROM tv_episodes WHERE showid = ?",
sqlResults = myDB.select("SELECT name, episode, airdate, status, release_name, season, location, file_size, subtitles FROM tv_episodes WHERE showid = ?",
[self.indexerid])
seasons = {}
for row in sqlResults:
@ -2332,7 +2332,7 @@ class CMD_ShowSeasons(ApiCall):
else:
sqlResults = myDB.select(
"SELECT name, episode, airdate, status FROM tv_episodes WHERE showid = ? AND season = ?",
"SELECT name, episode, airdate, status, location, file_size, release_name, subtitles FROM tv_episodes WHERE showid = ? AND season = ?",
[self.indexerid, self.season])
if len(sqlResults) is 0:
return _responds(RESULT_FAILURE, msg="Season not found")

View File

@ -2,7 +2,9 @@ import unittest
import sys
import os.path
sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib'))
from sickbeard import common

View File

@ -3,6 +3,7 @@ import unittest
import test_lib as test
import sys, os.path
sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib'))

View File

@ -2,7 +2,9 @@ import unittest
import test_lib as test
import sys, os.path
sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib'))
from sickbeard import show_name_helpers, scene_exceptions, common, name_cache
@ -105,7 +107,7 @@ class SceneExceptionTestCase(test.SickbeardTestDBCase):
self.assertEqual(scene_exceptions.get_scene_exception_by_name('Carlos 2010'), (164451, -1))
def test_sceneExceptionByNameEmpty(self):
self.assertEqual(scene_exceptions.get_scene_exception_by_name('nothing useful'), None)
self.assertEqual(scene_exceptions.get_scene_exception_by_name('nothing useful'), (None, None))
def test_sceneExceptionsResetNameCache(self):
# clear the exceptions

View File

@ -25,6 +25,7 @@ import sqlite3
import sys
import os.path
sys.path.append(os.path.abspath('..'))
sys.path.append(os.path.abspath('../lib'))