mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 00:43:37 +00:00
Major changes made to search code, tvcache code, and name parser
This commit is contained in:
parent
4b5fa9582a
commit
d5f183c171
25 changed files with 333 additions and 459 deletions
|
@ -206,6 +206,8 @@ class Proper:
|
|||
self.indexerid = -1
|
||||
self.season = -1
|
||||
self.episode = -1
|
||||
self.scene_season = -1
|
||||
self.scene_episode = -1
|
||||
|
||||
def __str__(self):
|
||||
return str(self.date) + " " + self.name + " " + str(self.season) + "x" + str(self.episode) + " of " + str(
|
||||
|
|
|
@ -27,7 +27,7 @@ from sickbeard import encodingKludge as ek
|
|||
from sickbeard.name_parser.parser import NameParser, InvalidNameException
|
||||
|
||||
MIN_DB_VERSION = 9 # oldest db version we support migrating from
|
||||
MAX_DB_VERSION = 30
|
||||
MAX_DB_VERSION = 31
|
||||
|
||||
class MainSanityCheck(db.DBSanityCheck):
|
||||
def check(self):
|
||||
|
@ -35,6 +35,7 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||
self.fix_duplicate_shows()
|
||||
self.fix_duplicate_episodes()
|
||||
self.fix_orphan_episodes()
|
||||
self.fix_scene_numbering()
|
||||
|
||||
def fix_duplicate_shows(self):
|
||||
|
||||
|
@ -124,6 +125,29 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||
self.connection.action("CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate)")
|
||||
|
||||
|
||||
def fix_scene_numbering(self):
|
||||
ql = []
|
||||
|
||||
sqlResults = self.connection.select(
|
||||
"SELECT showid, indexerid, indexer, episode_id, season, episode FROM tv_episodes WHERE scene_season = 0 OR scene_episode = 0")
|
||||
|
||||
for epResult in sqlResults:
|
||||
logger.log(
|
||||
u"Repairing any scene numbering issues for showid: " + str(epResult["showid"]) + u" season: " + str(
|
||||
epResult["season"]) + u" episode: " + str(epResult["episode"]), logger.DEBUG)
|
||||
|
||||
scene_season, scene_episode = sickbeard.scene_numbering.get_scene_numbering(epResult["showid"],
|
||||
epResult["indexer"],
|
||||
epResult["season"],
|
||||
epResult["episode"])
|
||||
|
||||
ql.append(["UPDATE tv_episodes SET scene_season = ? WHERE indexerid = ?", [scene_season, epResult["indexerid"]]])
|
||||
ql.append(
|
||||
["UPDATE tv_episodes SET scene_episode = ? WHERE indexerid = ?", [scene_episode, epResult["indexerid"]]])
|
||||
|
||||
self.connection.mass_action(ql)
|
||||
|
||||
|
||||
def backupDatabase(version):
|
||||
logger.log(u"Backing up database before upgrade")
|
||||
if not helpers.backupVersionedFile(db.dbFilename(), version):
|
||||
|
@ -746,3 +770,19 @@ class AddSportsOption(AddRequireAndIgnoreWords):
|
|||
self.connection.mass_action(ql)
|
||||
|
||||
self.incDBVersion()
|
||||
|
||||
class AddSceneNumberingToTvEpisodes(AddSportsOption):
|
||||
def test(self):
|
||||
return self.checkDBVersion() >= 31
|
||||
|
||||
def execute(self):
|
||||
backupDatabase(31)
|
||||
|
||||
logger.log(u"Adding column scene_season and scene_episode to tvepisodes")
|
||||
if not self.hasColumn("tv_episodes", "scene_season"):
|
||||
self.addColumn("tv_episodes", "scene_season", "NUMERIC", "0")
|
||||
|
||||
if not self.hasColumn("tv_episodes", "scene_episode"):
|
||||
self.addColumn("tv_episodes", "scene_episode", "NUMERIC", "0")
|
||||
|
||||
self.incDBVersion()
|
|
@ -54,7 +54,7 @@ class FailedProcessor(object):
|
|||
|
||||
parser = NameParser(False)
|
||||
try:
|
||||
parsed = parser.parse(releaseName).convert()
|
||||
parsed = parser.parse(releaseName)
|
||||
except InvalidNameException:
|
||||
self._log(u"Error: release name is invalid: " + releaseName, logger.WARNING)
|
||||
raise exceptions.FailedProcessingFailed()
|
||||
|
@ -68,16 +68,20 @@ class FailedProcessor(object):
|
|||
logger.log(u" - " + str(parsed.air_date), logger.DEBUG)
|
||||
logger.log(u" - " + str(parsed.sports_event_date), logger.DEBUG)
|
||||
|
||||
self._show_obj = parsed.show
|
||||
self._show_obj = sickbeard.helpers.get_show_by_name(parsed.series_name)
|
||||
if self._show_obj is None:
|
||||
self._log(
|
||||
u"Could not create show object. Either the show hasn't been added to SickBeard, or it's still loading (if SB was restarted recently)",
|
||||
logger.WARNING)
|
||||
raise exceptions.FailedProcessingFailed()
|
||||
|
||||
episodes = []
|
||||
for episode in parsed.episode_numbers:
|
||||
cur_failed_queue_item = search_queue.FailedQueueItem(self._show_obj, {parsed.season_number: episode})
|
||||
sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item)
|
||||
epObj = self._show_obj.getEpisode(parsed.season_number, episode)
|
||||
episodes.append(epObj)
|
||||
|
||||
cur_failed_queue_item = search_queue.FailedQueueItem(self._show_obj, episodes)
|
||||
sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -306,7 +306,9 @@ def searchDBForShow(regShowName):
|
|||
logger.log(u"Multiple results for " + showName + " in the DB, unable to match show name", logger.DEBUG)
|
||||
continue
|
||||
else:
|
||||
return (int(sqlResults[0]["indexer"]), int(sqlResults[0]["indexer_id"]), sqlResults[0]["show_name"])
|
||||
return int(sqlResults[0]["indexer_id"])
|
||||
|
||||
return
|
||||
|
||||
def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
|
||||
showNames = list(set([re.sub('[. -]', ' ', regShowName), regShowName]))
|
||||
|
@ -942,79 +944,37 @@ def _check_against_names(name, show):
|
|||
return False
|
||||
|
||||
|
||||
def get_show_by_name(name, checkIndexers=False):
|
||||
if not sickbeard.showList: return
|
||||
|
||||
def get_show_by_name(name):
|
||||
showObj = None
|
||||
in_cache = False
|
||||
foundResult = None
|
||||
|
||||
logger.log(
|
||||
u"Checking the cache for:" + str(name),
|
||||
logger.DEBUG)
|
||||
if not sickbeard.showList:
|
||||
return
|
||||
|
||||
cacheResult = sickbeard.name_cache.retrieveNameFromCache(name)
|
||||
if cacheResult:
|
||||
foundResult = findCertainShow(sickbeard.showList, cacheResult)
|
||||
if foundResult:
|
||||
in_cache = True
|
||||
logger.log(
|
||||
u"Cache lookup found Indexer ID:" + repr(
|
||||
foundResult.indexerid) + ", using that for " + name,
|
||||
logger.DEBUG)
|
||||
indexerid = sickbeard.name_cache.retrieveNameFromCache(name)
|
||||
if indexerid or indexerid == 0:
|
||||
in_cache = True
|
||||
|
||||
if not foundResult:
|
||||
logger.log(
|
||||
u"Checking the database for:" + str(name),
|
||||
logger.DEBUG)
|
||||
showNames = list(set(sickbeard.show_name_helpers.sceneToNormalShowNames(name)))
|
||||
for showName in showNames if not in_cache else []:
|
||||
try:
|
||||
showObj = [x for x in sickbeard.showList if _check_against_names(showName, x)][0]
|
||||
indexerid = showObj.indexerid
|
||||
except:
|
||||
indexerid = 0
|
||||
|
||||
dbResult = searchDBForShow(name)
|
||||
if dbResult:
|
||||
foundResult = findCertainShow(sickbeard.showList, dbResult[1])
|
||||
if foundResult:
|
||||
logger.log(
|
||||
u"Database lookup found Indexer ID:" + str(
|
||||
foundResult.indexerid) + ", using that for " + name, logger.DEBUG)
|
||||
|
||||
if not foundResult:
|
||||
logger.log(
|
||||
u"Checking the scene exceptions list for:" + str(name),
|
||||
logger.DEBUG)
|
||||
|
||||
for show in sickbeard.showList:
|
||||
if _check_against_names(name, show):
|
||||
logger.log(
|
||||
u"Scene exceptions lookup found Indexer ID:" + str(show.indexerid) + ", using that for " + name,
|
||||
logger.DEBUG)
|
||||
foundResult = show
|
||||
|
||||
if not foundResult and checkIndexers:
|
||||
logger.log(
|
||||
u"Checking the Indexers for:" + str(name),
|
||||
logger.DEBUG)
|
||||
|
||||
for indexer in sickbeard.indexerApi().indexers:
|
||||
try:
|
||||
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
||||
lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
|
||||
lINDEXER_API_PARMS['search_all_languages'] = True
|
||||
|
||||
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
|
||||
showObj = t[name]
|
||||
except:
|
||||
continue
|
||||
|
||||
if showObj:
|
||||
foundResult = findCertainShow(sickbeard.showList, int(showObj[0]['id']))
|
||||
if foundResult:
|
||||
logger.log(
|
||||
u"Indexers lookup found Indexer ID:" + str(
|
||||
foundResult.indexerid) + ", using that for " + name, logger.DEBUG)
|
||||
if indexerid:
|
||||
break
|
||||
|
||||
# add to name cache if we didn't get it from the cache
|
||||
if foundResult and not in_cache:
|
||||
sickbeard.name_cache.addNameToCache(name, foundResult.indexerid)
|
||||
if not in_cache:
|
||||
sickbeard.name_cache.addNameToCache(name, indexerid if indexerid else 0)
|
||||
|
||||
return foundResult
|
||||
if indexerid:
|
||||
logger.log(u"Found Indexer ID:[" + repr(indexerid) + "], using that for [" + name + "}",logger.DEBUG)
|
||||
if not showObj:
|
||||
showObj = [x for x in sickbeard.showList if x.indexerid == indexerid][0]
|
||||
return showObj
|
||||
|
||||
def is_hidden_folder(folder):
|
||||
"""
|
||||
|
|
|
@ -20,7 +20,7 @@ from sickbeard import db
|
|||
from sickbeard.helpers import sanitizeSceneName
|
||||
|
||||
|
||||
def addNameToCache(name, indexer_id):
|
||||
def addNameToCache(name, indexer_id=0):
|
||||
"""
|
||||
Adds the show & tvdb id to the scene_names table in cache.db.
|
||||
|
||||
|
@ -28,11 +28,10 @@ def addNameToCache(name, indexer_id):
|
|||
indexer_id: the TVDB and TVRAGE id that this show should be cached with (can be None/0 for unknown)
|
||||
"""
|
||||
|
||||
if indexer_id:
|
||||
# standardize the name we're using to account for small differences in providers
|
||||
name = sanitizeSceneName(name)
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
cacheDB.action("INSERT INTO scene_names (indexer_id, name) VALUES (?, ?)", [indexer_id, name])
|
||||
# standardize the name we're using to account for small differences in providers
|
||||
name = sanitizeSceneName(name)
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
cacheDB.action("INSERT INTO scene_names (indexer_id, name) VALUES (?, ?)", [indexer_id, name])
|
||||
|
||||
|
||||
def retrieveNameFromCache(name):
|
||||
|
@ -53,7 +52,6 @@ def retrieveNameFromCache(name):
|
|||
if cache_results:
|
||||
return int(cache_results[0]["indexer_id"])
|
||||
|
||||
|
||||
def clearCache():
|
||||
"""
|
||||
Deletes all "unknown" entries from the cache (names with indexer_id of 0).
|
||||
|
|
|
@ -106,11 +106,6 @@ class NameParser(object):
|
|||
result.series_name = match.group('series_name')
|
||||
if result.series_name:
|
||||
result.series_name = self.clean_series_name(result.series_name)
|
||||
name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(result.series_name)
|
||||
for name in name_list:
|
||||
result.show = helpers.get_show_by_name(name)
|
||||
if result.show:
|
||||
break
|
||||
|
||||
if 'season_num' in named_groups:
|
||||
tmp_season = int(match.group('season_num'))
|
||||
|
@ -245,8 +240,6 @@ class NameParser(object):
|
|||
# parse the dirname for extra info if needed
|
||||
dir_name_result = self._parse_string(dir_name)
|
||||
|
||||
final_result.show = self._combine_results(file_name_result, dir_name_result, 'show')
|
||||
|
||||
# build the ParseResult object
|
||||
final_result.air_date = self._combine_results(file_name_result, dir_name_result, 'air_date')
|
||||
|
||||
|
@ -323,8 +316,6 @@ class ParseResult(object):
|
|||
if not other:
|
||||
return False
|
||||
|
||||
if self.show != other.show:
|
||||
return False
|
||||
if self.series_name != other.series_name:
|
||||
return False
|
||||
if self.season_number != other.season_number:
|
||||
|
@ -376,11 +367,14 @@ class ParseResult(object):
|
|||
return to_return.encode('utf-8')
|
||||
|
||||
def convert(self):
|
||||
if not self.show: return self
|
||||
if self.air_by_date: return self # scene numbering does not apply to air-by-date
|
||||
if self.season_number == None: return self # can't work without a season
|
||||
if len(self.episode_numbers) == 0: return self # need at least one episode
|
||||
|
||||
self.show = helpers.get_show_by_name(self.series_name)
|
||||
if not self.show:
|
||||
return self
|
||||
|
||||
new_episode_numbers = []
|
||||
new_season_numbers = []
|
||||
for epNo in self.episode_numbers:
|
||||
|
|
|
@ -114,7 +114,7 @@ def splitResult(result):
|
|||
# parse the season ep name
|
||||
try:
|
||||
np = NameParser(False)
|
||||
parse_result = np.parse(result.name).convert()
|
||||
parse_result = np.parse(result.name)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + result.name + " into a valid episode", logger.WARNING)
|
||||
return False
|
||||
|
@ -133,7 +133,7 @@ def splitResult(result):
|
|||
# parse the name
|
||||
try:
|
||||
np = NameParser(False)
|
||||
parse_result = np.parse(newNZB).convert()
|
||||
parse_result = np.parse(newNZB)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + newNZB + " into a valid episode", logger.WARNING)
|
||||
return False
|
||||
|
|
|
@ -484,7 +484,7 @@ class PostProcessor(object):
|
|||
|
||||
# parse the name to break it into show name, season, and episode
|
||||
np = NameParser(file)
|
||||
parse_result = np.parse(name).convert()
|
||||
parse_result = np.parse(name)
|
||||
|
||||
self._log("Parsed " + name + " into " + str(parse_result).decode('utf-8'), logger.DEBUG)
|
||||
|
||||
|
@ -625,7 +625,7 @@ class PostProcessor(object):
|
|||
# now that we've figured out which episode this file is just load it manually
|
||||
try:
|
||||
# convert scene numbered release and load episode from database
|
||||
curEp = show_obj.getEpisode(season, cur_episode)
|
||||
curEp = show_obj.getEpisode(scene_season=season, scene_episode=cur_episode)
|
||||
except exceptions.EpisodeNotFoundException, e:
|
||||
self._log(u"Unable to create episode: " + ex(e), logger.DEBUG)
|
||||
raise exceptions.PostProcessingFailed()
|
||||
|
|
|
@ -100,17 +100,11 @@ class ProperFinder():
|
|||
# parse the file name
|
||||
try:
|
||||
myParser = NameParser(False)
|
||||
parse_result = myParser.parse(curProper.name).convert()
|
||||
parse_result = myParser.parse(curProper.name)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + curProper.name + " into a valid episode", logger.DEBUG)
|
||||
continue
|
||||
|
||||
# if we can't find the show then there's nothing we can really do
|
||||
if not parse_result.show:
|
||||
logger.log(u"This show isn't in your list, skipping ...",
|
||||
logger.DEBUG)
|
||||
continue
|
||||
|
||||
if not parse_result.episode_numbers:
|
||||
logger.log(
|
||||
u"Ignoring " + curProper.name + " because it's for a full season rather than specific episode",
|
||||
|
@ -122,8 +116,8 @@ class ProperFinder():
|
|||
curProper.season = -1
|
||||
curProper.episode = parse_result.air_date
|
||||
else:
|
||||
curProper.season = parse_result.season_number if parse_result.season_number != None else 1
|
||||
curProper.episode = parse_result.episode_numbers[0]
|
||||
curProper.scene_season = parse_result.season_number if parse_result.season_number != None else 1
|
||||
curProper.scene_episode = parse_result.episode_numbers[0]
|
||||
|
||||
curProper.quality = Quality.nameQuality(curProper.name)
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ class DTTProvider(generic.TorrentProvider):
|
|||
quality = Quality.sceneQuality(url)
|
||||
return quality
|
||||
|
||||
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
||||
return generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch)
|
||||
def getSearchResults(self, show, season, episodes, seasonSearch=False, manualSearch=False):
|
||||
return generic.TorrentProvider.getSearchResults(self, show, season, episodes, seasonSearch, manualSearch)
|
||||
|
||||
def _dtt_show_id(self, show_name):
|
||||
return sanitizeSceneName(show_name).replace('.', '-').lower()
|
||||
|
|
|
@ -57,7 +57,7 @@ class EZRSSProvider(generic.TorrentProvider):
|
|||
|
||||
return quality
|
||||
|
||||
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
||||
def getSearchResults(self, show, season, episodes, seasonSearch=False, manualSearch=False):
|
||||
|
||||
self.show = show
|
||||
|
||||
|
@ -68,7 +68,7 @@ class EZRSSProvider(generic.TorrentProvider):
|
|||
logger.WARNING)
|
||||
return results
|
||||
|
||||
results = generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch)
|
||||
results = generic.TorrentProvider.getSearchResults(self, show, season, episodes, seasonSearch, manualSearch)
|
||||
|
||||
return results
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ class GenericProvider:
|
|||
|
||||
return (title, url)
|
||||
|
||||
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
||||
def findSearchResults(self, show, season, episodes, manualSearch=False):
|
||||
|
||||
self._checkAuth()
|
||||
self.show = show
|
||||
|
@ -255,133 +255,86 @@ class GenericProvider:
|
|||
itemList = []
|
||||
results = {}
|
||||
|
||||
useDate = False
|
||||
if self.show.air_by_date or self.show.sports:
|
||||
useDate = True
|
||||
for epObj in episodes:
|
||||
cacheResult = self.cache.searchCache(epObj, manualSearch)
|
||||
if len(cacheResult):
|
||||
return cacheResult
|
||||
|
||||
for ep_obj in ep_objs:
|
||||
logger.log(u'Searching "%s" for "%s" as "%s"' % (self.name, ep_obj.prettyName(), ep_obj.scene_prettyName()))
|
||||
logger.log(u'Searching "%s" for "%s" as "%s"' % (self.name, epObj.prettyName(), epObj.scene_prettyName()))
|
||||
for curString in self._get_episode_search_strings(epObj):
|
||||
itemList += self._doSearch(curString)
|
||||
|
||||
if seasonSearch:
|
||||
for curString in self._get_season_search_strings(ep_obj):
|
||||
itemList += self._doSearch(curString)
|
||||
else:
|
||||
for curString in self._get_episode_search_strings(ep_obj):
|
||||
itemList += self._doSearch(curString)
|
||||
for item in itemList:
|
||||
|
||||
for item in itemList:
|
||||
(title, url) = self._get_title_and_url(item)
|
||||
|
||||
(title, url) = self._get_title_and_url(item)
|
||||
quality = self.getQuality(item)
|
||||
|
||||
quality = self.getQuality(item)
|
||||
|
||||
# parse the file name
|
||||
try:
|
||||
myParser = NameParser(False)
|
||||
parse_result = myParser.parse(title).convert()
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
|
||||
continue
|
||||
|
||||
if not useDate:
|
||||
# this check is meaningless for non-season searches
|
||||
if (parse_result.season_number is not None and parse_result.season_number != season) or (
|
||||
parse_result.season_number is None and season != 1):
|
||||
logger.log(u"The result " + title + " doesn't seem to be a valid episode for season " + str(
|
||||
season) + ", ignoring", logger.DEBUG)
|
||||
# parse the file name
|
||||
try:
|
||||
myParser = NameParser(False)
|
||||
parse_result = myParser.parse(title)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
|
||||
continue
|
||||
|
||||
if manualSearch and (
|
||||
parse_result.season_number != season or ep_objs[0].episode not in parse_result.episode_numbers):
|
||||
logger.log(u"Episode " + title + " isn't " + str(season) + "x" + str(
|
||||
ep_objs[0].episode) + ", skipping it", logger.DEBUG)
|
||||
continue
|
||||
|
||||
# we just use the existing info for normal searches
|
||||
actual_season = season if manualSearch else parse_result.season_number
|
||||
actual_episodes = [ep_objs[0].episode] if manualSearch else parse_result.episode_numbers
|
||||
else:
|
||||
if not (parse_result.air_by_date or parse_result.sports):
|
||||
logger.log(
|
||||
u"This is supposed to be a date search but the result " + title + " didn't parse as one, skipping it",
|
||||
logger.DEBUG)
|
||||
continue
|
||||
|
||||
if manualSearch and ((parse_result.air_date != ep_objs[0].airdate and parse_result.air_by_date) or (
|
||||
parse_result.sports_event_date != ep_objs[0].airdate and parse_result.sports)):
|
||||
logger.log(u"Episode " + title + " didn't air on " + str(ep_objs[0].airdate) + ", skipping it",
|
||||
logger.DEBUG)
|
||||
continue
|
||||
|
||||
if not manualSearch:
|
||||
myDB = db.DBConnection()
|
||||
if parse_result.air_by_date:
|
||||
sql_results = myDB.select(
|
||||
"SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||
[self.show.indexerid, parse_result.air_date.toordinal()])
|
||||
elif parse_result.sports:
|
||||
sql_results = myDB.select(
|
||||
"SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||
[self.show.indexerid, parse_result.sports_event_date.toordinal()])
|
||||
|
||||
if len(sql_results) != 1:
|
||||
logger.log(
|
||||
u"Tried to look up the date for the episode " + title + " but the database didn't give proper results, skipping it",
|
||||
logger.WARNING)
|
||||
if not (self.show.air_by_date or self.show.sports):
|
||||
if not (self.show.air_by_date or self.show.sports):
|
||||
if (parse_result.season_number != season or epObj.episode not in parse_result.episode_numbers):
|
||||
logger.log(u"Episode " + title + " isn't " + str(season) + "x" + str(
|
||||
epObj.episode) + ", skipping it", logger.DEBUG)
|
||||
continue
|
||||
|
||||
actual_season = season if manualSearch else int(sql_results[0]["season"])
|
||||
actual_episodes = [ep_objs[0].episode] if manualSearch else [int(sql_results[0]["episode"])]
|
||||
else:
|
||||
if not (parse_result.air_by_date or parse_result.sports):
|
||||
logger.log(
|
||||
u"This is supposed to be a date search but the result " + title + " didn't parse as one, skipping it",
|
||||
logger.DEBUG)
|
||||
continue
|
||||
|
||||
if ((parse_result.air_date != epObj.airdate and parse_result.air_by_date) or (
|
||||
parse_result.sports_event_date != epObj.airdate and parse_result.sports)):
|
||||
logger.log(u"Episode " + title + " didn't air on " + str(epObj.airdate) + ", skipping it",
|
||||
logger.DEBUG)
|
||||
continue
|
||||
|
||||
# make sure we want the episode
|
||||
epObj = None
|
||||
wantEp = True
|
||||
for epNo in actual_episodes:
|
||||
epObj = self.show.getEpisode(actual_season, epNo)
|
||||
if not epObj or not self.show.wantEpisode(epObj.season, epObj.episode, quality,manualSearch=manualSearch):
|
||||
wantEp = False
|
||||
break
|
||||
# make sure we want the episode
|
||||
if not self.show.wantEpisode(epObj.season, epObj.episode, quality, manualSearch=manualSearch):
|
||||
logger.log(
|
||||
u"Ignoring result " + title + " because we don't want an episode that is " + Quality.qualityStrings[
|
||||
quality], logger.DEBUG)
|
||||
continue
|
||||
|
||||
if not epObj:
|
||||
logger.log(u"Ignoring result " + title + " because episode scene info is invalid.")
|
||||
continue
|
||||
logger.log(u"Found result " + title + " at " + url, logger.DEBUG)
|
||||
|
||||
if not wantEp:
|
||||
logger.log(
|
||||
u"Ignoring result " + title + " because we don't want an episode that is " + Quality.qualityStrings[
|
||||
quality], logger.DEBUG)
|
||||
continue
|
||||
# make a result object
|
||||
epObjs = [epObj]
|
||||
|
||||
logger.log(u"Found result " + title + " at " + url, logger.DEBUG)
|
||||
result = self.getResult(epObjs)
|
||||
result.url = url
|
||||
result.name = title
|
||||
result.quality = quality
|
||||
result.provider = self
|
||||
result.content = None
|
||||
|
||||
# make a result object
|
||||
epObjs = [epObj]
|
||||
if len(epObjs) == 1:
|
||||
epNum = epObjs[0].episode
|
||||
logger.log(u"Single episode result.", logger.DEBUG)
|
||||
elif len(epObjs) > 1:
|
||||
epNum = MULTI_EP_RESULT
|
||||
logger.log(u"Separating multi-episode result to check for later - result contains episodes: " + str(
|
||||
parse_result.episode_numbers), logger.DEBUG)
|
||||
elif len(epObjs) == 0:
|
||||
epNum = SEASON_RESULT
|
||||
result.extraInfo = [self.show]
|
||||
logger.log(u"Separating full season result to check for later", logger.DEBUG)
|
||||
|
||||
result = self.getResult(epObjs)
|
||||
result.url = url
|
||||
result.name = title
|
||||
result.quality = quality
|
||||
result.provider = self
|
||||
result.content = None
|
||||
if epNum in results:
|
||||
results[epNum].append(result)
|
||||
else:
|
||||
results[epNum] = [result]
|
||||
|
||||
if len(epObjs) == 1:
|
||||
epNum = epObjs[0].episode
|
||||
elif len(epObjs) > 1:
|
||||
epNum = MULTI_EP_RESULT
|
||||
logger.log(u"Separating multi-episode result to check for later - result contains episodes: " + str(
|
||||
parse_result.episode_numbers), logger.DEBUG)
|
||||
elif len(epObjs) == 0:
|
||||
epNum = SEASON_RESULT
|
||||
result.extraInfo = [self.show]
|
||||
logger.log(u"Separating full season result to check for later", logger.DEBUG)
|
||||
|
||||
if epNum in results:
|
||||
results[epNum].append(result)
|
||||
else:
|
||||
results = {epNum: [result]}
|
||||
|
||||
return results
|
||||
return results
|
||||
|
||||
def findPropers(self, search_date=None):
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ class HDBitsProvider(generic.TorrentProvider):
|
|||
# parse the file name
|
||||
try:
|
||||
myParser = NameParser()
|
||||
parse_result = myParser.parse(title).convert()
|
||||
parse_result = myParser.parse(title)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
|
||||
continue
|
||||
|
|
|
@ -148,7 +148,7 @@ class KATProvider(generic.TorrentProvider):
|
|||
|
||||
try:
|
||||
myParser = NameParser()
|
||||
parse_result = myParser.parse(fileName).convert()
|
||||
parse_result = myParser.parse(fileName)
|
||||
except InvalidNameException:
|
||||
return None
|
||||
|
||||
|
|
|
@ -113,13 +113,14 @@ class NewznabProvider(generic.NZBProvider):
|
|||
# search
|
||||
params['q'] = helpers.sanitizeSceneName(self.show.name)
|
||||
|
||||
date_str = str(ep_obj.airdate)
|
||||
if self.show.air_by_date:
|
||||
date_str = str(ep_obj.airdate)
|
||||
params['season'] = date_str.partition('-')[0]
|
||||
params['ep'] = date_str.partition('-')[2].replace('-', '/')
|
||||
elif self.show.sports:
|
||||
date_str = str(ep_obj.airdate)
|
||||
params['season'] = date_str.partition('-')[0]
|
||||
params['ep'] = date_str.partition('-')[0]
|
||||
params['ep'] = date_str.partition('-')[2].replace('-', '/')
|
||||
else:
|
||||
params['season'] = ep_obj.scene_season
|
||||
params['ep'] = ep_obj.scene_episode
|
||||
|
|
|
@ -54,8 +54,8 @@ class NyaaProvider(generic.TorrentProvider):
|
|||
quality = Quality.sceneQuality(title)
|
||||
return quality
|
||||
|
||||
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
||||
results = generic.TorrentProvider.getSearchResults(self, show, season, ep_objs, seasonSearch, manualSearch)
|
||||
def getSearchResults(self, show, season, episodes, seasonSearch=False, manualSearch=False):
|
||||
results = generic.TorrentProvider.getSearchResults(self, show, season, episodes, seasonSearch, manualSearch)
|
||||
return results
|
||||
|
||||
def _get_season_search_strings(self, ep_obj):
|
||||
|
|
|
@ -157,7 +157,7 @@ class ThePirateBayProvider(generic.TorrentProvider):
|
|||
|
||||
try:
|
||||
myParser = NameParser()
|
||||
parse_result = myParser.parse(fileName).convert()
|
||||
parse_result = myParser.parse(fileName)
|
||||
except InvalidNameException:
|
||||
return None
|
||||
|
||||
|
|
|
@ -33,14 +33,13 @@ import sickbeard
|
|||
|
||||
from sickbeard import logger
|
||||
from sickbeard import db
|
||||
from sickbeard import helpers
|
||||
from sickbeard.exceptions import ex
|
||||
from lib import requests
|
||||
|
||||
MAX_XEM_AGE_SECS = 86400 # 1 day
|
||||
|
||||
|
||||
def get_scene_numbering(indexer_id, season, episode, fallback_to_xem=True):
|
||||
def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=True):
|
||||
"""
|
||||
Returns a tuple, (season, episode), with the scene numbering (if there is one),
|
||||
otherwise returns the xem numbering (if fallback_to_xem is set), otherwise
|
||||
|
@ -56,28 +55,24 @@ def get_scene_numbering(indexer_id, season, episode, fallback_to_xem=True):
|
|||
if indexer_id is None or season is None or episode is None:
|
||||
return (season, episode)
|
||||
|
||||
result = find_scene_numbering(indexer_id, season, episode)
|
||||
result = find_scene_numbering(indexer_id, indexer, season, episode)
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
if fallback_to_xem:
|
||||
xem_result = find_xem_numbering(indexer_id, season, episode)
|
||||
xem_result = find_xem_numbering(indexer_id, indexer, season, episode)
|
||||
if xem_result:
|
||||
return xem_result
|
||||
return (season, episode)
|
||||
|
||||
|
||||
def find_scene_numbering(indexer_id, season, episode):
|
||||
def find_scene_numbering(indexer_id, indexer, season, episode):
|
||||
"""
|
||||
Same as get_scene_numbering(), but returns None if scene numbering is not set
|
||||
"""
|
||||
if indexer_id is None or season is None or episode is None:
|
||||
return (season, episode)
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return (season, episode)
|
||||
indexer = showObj.indexer
|
||||
|
||||
myDB = db.DBConnection()
|
||||
|
||||
rows = myDB.select(
|
||||
|
@ -87,7 +82,7 @@ def find_scene_numbering(indexer_id, season, episode):
|
|||
return (int(rows[0]["scene_season"]), int(rows[0]["scene_episode"]))
|
||||
|
||||
|
||||
def get_indexer_numbering(indexer_id, sceneSeason, sceneEpisode, fallback_to_xem=True):
|
||||
def get_indexer_numbering(indexer_id, indexer, sceneSeason, sceneEpisode, fallback_to_xem=True):
|
||||
"""
|
||||
Returns a tuple, (season, episode) with the TVDB and TVRAGE numbering for (sceneSeason, sceneEpisode)
|
||||
(this works like the reverse of get_scene_numbering)
|
||||
|
@ -95,10 +90,6 @@ def get_indexer_numbering(indexer_id, sceneSeason, sceneEpisode, fallback_to_xem
|
|||
if indexer_id is None or sceneSeason is None or sceneEpisode is None:
|
||||
return (sceneSeason, sceneEpisode)
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return (sceneSeason, sceneEpisode)
|
||||
indexer = showObj.indexer
|
||||
|
||||
myDB = db.DBConnection()
|
||||
|
||||
rows = myDB.select(
|
||||
|
@ -108,11 +99,11 @@ def get_indexer_numbering(indexer_id, sceneSeason, sceneEpisode, fallback_to_xem
|
|||
return (int(rows[0]["season"]), int(rows[0]["episode"]))
|
||||
else:
|
||||
if fallback_to_xem:
|
||||
return get_indexer_numbering_for_xem(indexer_id, sceneSeason, sceneEpisode)
|
||||
return get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode)
|
||||
return (sceneSeason, sceneEpisode)
|
||||
|
||||
|
||||
def get_scene_numbering_for_show(indexer_id):
|
||||
def get_scene_numbering_for_show(indexer_id, indexer):
|
||||
"""
|
||||
Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings
|
||||
for an entire show. Both the keys and values of the dict are tuples.
|
||||
|
@ -121,10 +112,6 @@ def get_scene_numbering_for_show(indexer_id):
|
|||
if indexer_id is None:
|
||||
return {}
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return {}
|
||||
indexer = showObj.indexer
|
||||
|
||||
myDB = db.DBConnection()
|
||||
|
||||
rows = myDB.select(
|
||||
|
@ -137,7 +124,7 @@ def get_scene_numbering_for_show(indexer_id):
|
|||
return result
|
||||
|
||||
|
||||
def set_scene_numbering(indexer_id, season, episode, sceneSeason=None, sceneEpisode=None):
|
||||
def set_scene_numbering(indexer_id, indexer, season, episode, sceneSeason=None, sceneEpisode=None):
|
||||
"""
|
||||
Set scene numbering for a season/episode.
|
||||
To clear the scene numbering, leave both sceneSeason and sceneEpisode as None.
|
||||
|
@ -146,10 +133,6 @@ def set_scene_numbering(indexer_id, season, episode, sceneSeason=None, sceneEpis
|
|||
if indexer_id is None or season is None or episode is None:
|
||||
return
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return
|
||||
indexer = showObj.indexer
|
||||
|
||||
myDB = db.DBConnection()
|
||||
|
||||
# sanity
|
||||
|
@ -167,7 +150,7 @@ def set_scene_numbering(indexer_id, season, episode, sceneSeason=None, sceneEpis
|
|||
[indexer, indexer_id, season, episode, sceneSeason, sceneEpisode])
|
||||
|
||||
|
||||
def find_xem_numbering(indexer_id, season, episode):
|
||||
def find_xem_numbering(indexer_id, indexer, season, episode):
|
||||
"""
|
||||
Returns the scene numbering, as retrieved from xem.
|
||||
Refreshes/Loads as needed.
|
||||
|
@ -180,12 +163,8 @@ def find_xem_numbering(indexer_id, season, episode):
|
|||
if indexer_id is None or season is None or episode is None:
|
||||
return None
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return None
|
||||
indexer = showObj.indexer
|
||||
|
||||
if _xem_refresh_needed(indexer_id):
|
||||
_xem_refresh(indexer_id)
|
||||
if _xem_refresh_needed(indexer_id, indexer):
|
||||
_xem_refresh(indexer_id, indexer)
|
||||
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
rows = cacheDB.select(
|
||||
|
@ -197,7 +176,7 @@ def find_xem_numbering(indexer_id, season, episode):
|
|||
return None
|
||||
|
||||
|
||||
def get_indexer_numbering_for_xem(indexer_id, sceneSeason, sceneEpisode):
|
||||
def get_indexer_numbering_for_xem(indexer_id, indexer, sceneSeason, sceneEpisode):
|
||||
"""
|
||||
Reverse of find_xem_numbering: lookup a tvdb season and episode using scene numbering
|
||||
|
||||
|
@ -209,12 +188,8 @@ def get_indexer_numbering_for_xem(indexer_id, sceneSeason, sceneEpisode):
|
|||
if indexer_id is None or sceneSeason is None or sceneEpisode is None:
|
||||
return None
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return None
|
||||
indexer = showObj.indexer
|
||||
|
||||
if _xem_refresh_needed(indexer_id):
|
||||
_xem_refresh(indexer_id)
|
||||
if _xem_refresh_needed(indexer_id, indexer):
|
||||
_xem_refresh(indexer_id, indexer)
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
rows = cacheDB.select(
|
||||
"SELECT season, episode FROM xem_numbering WHERE indexer = ? and indexer_id = ? and scene_season = ? and scene_episode = ?",
|
||||
|
@ -225,7 +200,7 @@ def get_indexer_numbering_for_xem(indexer_id, sceneSeason, sceneEpisode):
|
|||
return (sceneSeason, sceneEpisode)
|
||||
|
||||
|
||||
def _xem_refresh_needed(indexer_id):
|
||||
def _xem_refresh_needed(indexer_id, indexer):
|
||||
"""
|
||||
Is a refresh needed on a show?
|
||||
|
||||
|
@ -235,10 +210,6 @@ def _xem_refresh_needed(indexer_id):
|
|||
if indexer_id is None:
|
||||
return False
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return False
|
||||
indexer = showObj.indexer
|
||||
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
rows = cacheDB.select("SELECT last_refreshed FROM xem_refresh WHERE indexer = ? and indexer_id = ?",
|
||||
[indexer, indexer_id])
|
||||
|
@ -248,7 +219,7 @@ def _xem_refresh_needed(indexer_id):
|
|||
return True
|
||||
|
||||
|
||||
def _xem_refresh(indexer_id):
|
||||
def _xem_refresh(indexer_id, indexer):
|
||||
"""
|
||||
Refresh data from xem for a tv show
|
||||
|
||||
|
@ -257,10 +228,6 @@ def _xem_refresh(indexer_id):
|
|||
if indexer_id is None:
|
||||
return
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return
|
||||
indexer = showObj.indexer
|
||||
|
||||
try:
|
||||
logger.log(
|
||||
u'Looking up XEM scene mapping for show %s on %s' % (indexer_id, sickbeard.indexerApi(indexer).name,),
|
||||
|
@ -311,7 +278,7 @@ def _xem_refresh(indexer_id):
|
|||
return None
|
||||
|
||||
|
||||
def get_xem_numbering_for_show(indexer_id):
|
||||
def get_xem_numbering_for_show(indexer_id, indexer):
|
||||
"""
|
||||
Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings
|
||||
for an entire show. Both the keys and values of the dict are tuples.
|
||||
|
@ -320,12 +287,8 @@ def get_xem_numbering_for_show(indexer_id):
|
|||
if indexer_id is None:
|
||||
return {}
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return {}
|
||||
indexer = showObj.indexer
|
||||
|
||||
if _xem_refresh_needed(indexer_id):
|
||||
_xem_refresh(indexer_id)
|
||||
if _xem_refresh_needed(indexer_id, indexer):
|
||||
_xem_refresh(indexer_id, indexer)
|
||||
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
|
||||
|
@ -340,7 +303,7 @@ def get_xem_numbering_for_show(indexer_id):
|
|||
return result
|
||||
|
||||
|
||||
def get_xem_numbering_for_season(indexer_id, season):
|
||||
def get_xem_numbering_for_season(indexer_id, indexer, season):
|
||||
"""
|
||||
Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings
|
||||
for an entire show. Both the keys and values of the dict are tuples.
|
||||
|
@ -349,17 +312,13 @@ def get_xem_numbering_for_season(indexer_id, season):
|
|||
if indexer_id is None or season is None:
|
||||
return {}
|
||||
|
||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
||||
if showObj is None: return {}
|
||||
indexer = showObj.indexer
|
||||
|
||||
if _xem_refresh_needed(indexer_id):
|
||||
_xem_refresh(indexer_id)
|
||||
if _xem_refresh_needed(indexer_id, indexer):
|
||||
_xem_refresh(indexer_id, indexer)
|
||||
|
||||
cacheDB = db.DBConnection('cache.db')
|
||||
|
||||
rows = cacheDB.select(
|
||||
'SELECT season, scene_season FROM xem_numbering WHERE indexer = ? and indexer_id = ? AND season = ? ORDER BY season, [indexer, indexer_id, season]')
|
||||
'SELECT season, scene_season FROM xem_numbering WHERE indexer = ? and indexer_id = ? AND season = ? ORDER BY season', [indexer, indexer_id, season])
|
||||
|
||||
result = {}
|
||||
if rows:
|
||||
|
|
|
@ -184,8 +184,6 @@ def searchForNeededEpisodes():
|
|||
if not curProvider.isActive():
|
||||
continue
|
||||
|
||||
curFoundResults = {}
|
||||
|
||||
try:
|
||||
curFoundResults = curProvider.searchRSS()
|
||||
except exceptions.AuthException, e:
|
||||
|
@ -365,62 +363,33 @@ def filterSearchResults(show, results):
|
|||
|
||||
return foundResults
|
||||
|
||||
def searchProviders(show, season, episode=None, manualSearch=False):
|
||||
def searchProviders(show, season, episodes, manualSearch=False):
|
||||
logger.log(u"Searching for stuff we need from " + show.name + " season " + str(season))
|
||||
foundResults = {}
|
||||
|
||||
didSearch = False
|
||||
seasonSearch = False
|
||||
|
||||
# gather all episodes for season and then pick out the wanted episodes and compare to determin if we want whole season or just a few episodes
|
||||
if episode is None:
|
||||
seasonEps = show.getAllEpisodes(season)
|
||||
wantedEps = [x for x in seasonEps if show.getOverview(x.status) in (Overview.WANTED, Overview.QUAL)]
|
||||
if len(seasonEps) == len(wantedEps):
|
||||
seasonSearch = True
|
||||
else:
|
||||
ep_obj = show.getEpisode(season, episode)
|
||||
wantedEps = [ep_obj]
|
||||
|
||||
for curProvider in providers.sortedProviderList():
|
||||
if not curProvider.isActive():
|
||||
continue
|
||||
|
||||
# update cache
|
||||
if manualSearch:
|
||||
curProvider.cache.updateCache()
|
||||
try:
|
||||
curResults = curProvider.findSearchResults(show, season, episodes, manualSearch)
|
||||
except exceptions.AuthException, e:
|
||||
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
||||
continue
|
||||
except Exception, e:
|
||||
logger.log(u"Error while searching " + curProvider.name + ", skipping: " + ex(e), logger.ERROR)
|
||||
logger.log(traceback.format_exc(), logger.DEBUG)
|
||||
continue
|
||||
|
||||
# search cache first for wanted episodes
|
||||
for ep_obj in wantedEps:
|
||||
curResults = curProvider.cache.searchCache(ep_obj, manualSearch)
|
||||
curResults = filterSearchResults(show, curResults)
|
||||
if len(curResults):
|
||||
foundResults.update(curResults)
|
||||
logger.log(u"Cache results: " + repr(foundResults), logger.DEBUG)
|
||||
didSearch = True
|
||||
# finished searching this provider successfully
|
||||
didSearch = True
|
||||
|
||||
if not len(foundResults):
|
||||
for curProvider in providers.sortedProviderList():
|
||||
if not curProvider.isActive():
|
||||
continue
|
||||
|
||||
try:
|
||||
curResults = curProvider.getSearchResults(show, season, wantedEps, seasonSearch, manualSearch)
|
||||
except exceptions.AuthException, e:
|
||||
logger.log(u"Authentication error: " + ex(e), logger.ERROR)
|
||||
continue
|
||||
except Exception, e:
|
||||
logger.log(u"Error while searching " + curProvider.name + ", skipping: " + ex(e), logger.ERROR)
|
||||
logger.log(traceback.format_exc(), logger.DEBUG)
|
||||
continue
|
||||
|
||||
# finished searching this provider successfully
|
||||
didSearch = True
|
||||
|
||||
curResults = filterSearchResults(show, curResults)
|
||||
if len(curResults):
|
||||
foundResults.update(curResults)
|
||||
logger.log(u"Provider search results: " + str(foundResults), logger.DEBUG)
|
||||
curResults = filterSearchResults(show, curResults)
|
||||
if len(curResults):
|
||||
foundResults.update(curResults)
|
||||
logger.log(u"Provider search results: " + str(foundResults), logger.DEBUG)
|
||||
|
||||
if not didSearch:
|
||||
logger.log(u"No NZB/Torrent providers found or enabled in the sickbeard config. Please check your settings.",
|
||||
|
|
|
@ -96,7 +96,6 @@ class BacklogSearcher:
|
|||
# get separate lists of the season/date shows
|
||||
#season_shows = [x for x in show_list if not x.air_by_date]
|
||||
air_by_date_shows = [x for x in show_list if x.air_by_date]
|
||||
sports_shows = [x for x in show_list if x.sports]
|
||||
|
||||
# figure out how many segments of air by date shows we're going to do
|
||||
air_by_date_segments = []
|
||||
|
@ -105,12 +104,6 @@ class BacklogSearcher:
|
|||
|
||||
logger.log(u"Air-by-date segments: " + str(air_by_date_segments), logger.DEBUG)
|
||||
|
||||
sports_segments = []
|
||||
for cur_id in [x.indexerid for x in sports_shows]:
|
||||
sports_segments += self._get_sports_segments(cur_id, fromDate)
|
||||
|
||||
logger.log(u"Sports segments: " + str(sports_segments), logger.DEBUG)
|
||||
|
||||
#totalSeasons = float(len(numSeasonResults) + len(air_by_date_segments))
|
||||
#numSeasonsDone = 0.0
|
||||
|
||||
|
@ -122,10 +115,8 @@ class BacklogSearcher:
|
|||
|
||||
if curShow.air_by_date:
|
||||
segments = [x[1] for x in self._get_air_by_date_segments(curShow.indexerid, fromDate)]
|
||||
elif curShow.sports:
|
||||
segments = self._get_sports_segments(curShow.indexerid, fromDate)
|
||||
else:
|
||||
segments = self._get_season_segments(curShow.indexerid, fromDate)
|
||||
segments = self._get_segments(curShow.indexerid, fromDate)
|
||||
|
||||
for cur_segment in segments:
|
||||
|
||||
|
@ -133,12 +124,12 @@ class BacklogSearcher:
|
|||
|
||||
backlog_queue_item = search_queue.BacklogQueueItem(curShow, cur_segment)
|
||||
|
||||
if not backlog_queue_item.wantSeason:
|
||||
if backlog_queue_item.wantedEpisodes:
|
||||
sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) #@UndefinedVariable
|
||||
else:
|
||||
logger.log(
|
||||
u"Nothing in season " + str(cur_segment) + " needs to be downloaded, skipping this season",
|
||||
logger.DEBUG)
|
||||
else:
|
||||
sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) #@UndefinedVariable
|
||||
|
||||
# don't consider this an actual backlog search if we only did recent eps
|
||||
# or if we only did certain shows
|
||||
|
@ -167,11 +158,12 @@ class BacklogSearcher:
|
|||
self._lastBacklog = lastBacklog
|
||||
return self._lastBacklog
|
||||
|
||||
def _get_season_segments(self, indexer_id, fromDate):
|
||||
def _get_segments(self, indexer_id, fromDate):
|
||||
myDB = db.DBConnection()
|
||||
sqlResults = myDB.select(
|
||||
"SELECT DISTINCT(season) as season FROM tv_episodes WHERE showid = ? AND season > 0 and airdate > ?",
|
||||
[indexer_id, fromDate.toordinal()])
|
||||
|
||||
return [int(x["season"]) for x in sqlResults]
|
||||
|
||||
def _get_air_by_date_segments(self, indexer_id, fromDate):
|
||||
|
@ -194,12 +186,6 @@ class BacklogSearcher:
|
|||
|
||||
return air_by_date_segments
|
||||
|
||||
def _get_sports_segments(self, indexer_id, fromDate):
|
||||
myDB = db.DBConnection()
|
||||
sqlResults = myDB.select(
|
||||
"SELECT DISTINCT(season) as season FROM tv_episodes WHERE showid = ? AND season > 0 and airdate > ?",
|
||||
[indexer_id, fromDate.toordinal()])
|
||||
return [int(x["season"]) for x in sqlResults]
|
||||
|
||||
def _set_lastBacklog(self, when):
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ class SearchQueue(generic_queue.GenericQueue):
|
|||
def add_item(self, item):
|
||||
if isinstance(item, RSSSearchQueueItem):
|
||||
generic_queue.GenericQueue.add_item(self, item)
|
||||
# don't do duplicates
|
||||
elif isinstance(item, BacklogQueueItem) and not self.is_in_queue(item.show, item.segment):
|
||||
generic_queue.GenericQueue.add_item(self, item)
|
||||
elif isinstance(item, ManualSearchQueueItem) and not self.is_ep_in_queue(item.ep_obj):
|
||||
|
@ -93,7 +92,7 @@ class ManualSearchQueueItem(generic_queue.QueueItem):
|
|||
|
||||
logger.log("Beginning manual search for " + self.ep_obj.prettyName())
|
||||
|
||||
foundResults = search.searchProviders(self.ep_obj.show, self.ep_obj.season, self.ep_obj.episode, manualSearch=True)
|
||||
foundResults = search.searchProviders(self.ep_obj.show, self.ep_obj.season, [self.ep_obj], manualSearch=True)
|
||||
result = False
|
||||
|
||||
if not foundResults:
|
||||
|
@ -186,6 +185,7 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||
|
||||
self.show = show
|
||||
self.segment = segment
|
||||
self.wantedEpisodes = []
|
||||
|
||||
logger.log(u"Seeing if we need any episodes from " + self.show.name + " season " + str(self.segment))
|
||||
|
||||
|
@ -193,7 +193,7 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||
|
||||
# see if there is anything in this season worth searching for
|
||||
if not self.show.air_by_date:
|
||||
statusResults = myDB.select("SELECT status FROM tv_episodes WHERE showid = ? AND season = ?",
|
||||
statusResults = myDB.select("SELECT status, episode FROM tv_episodes WHERE showid = ? AND season = ?",
|
||||
[self.show.indexerid, self.segment])
|
||||
else:
|
||||
season_year, season_month = map(int, self.segment.split('-'))
|
||||
|
@ -206,17 +206,17 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||
max_date = datetime.date(season_year, season_month + 1, 1) - datetime.timedelta(days=1)
|
||||
|
||||
statusResults = myDB.select(
|
||||
"SELECT status FROM tv_episodes WHERE showid = ? AND airdate >= ? AND airdate <= ?",
|
||||
"SELECT status, episode FROM tv_episodes WHERE showid = ? AND airdate >= ? AND airdate <= ?",
|
||||
[self.show.indexerid, min_date.toordinal(), max_date.toordinal()])
|
||||
|
||||
anyQualities, bestQualities = common.Quality.splitQuality(self.show.quality) #@UnusedVariable
|
||||
self.wantSeason = self._need_any_episodes(statusResults, bestQualities)
|
||||
self.wantedEpisodes = self._need_any_episodes(statusResults, bestQualities)
|
||||
|
||||
def execute(self):
|
||||
|
||||
generic_queue.QueueItem.execute(self)
|
||||
|
||||
results = search.searchProviders(self.show, self.segment)
|
||||
results = search.searchProviders(self.show, self.segment, self.wantedEpisodes)
|
||||
|
||||
# download whatever we find
|
||||
for curResult in results:
|
||||
|
@ -226,13 +226,13 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||
self.finish()
|
||||
|
||||
def _need_any_episodes(self, statusResults, bestQualities):
|
||||
|
||||
wantSeason = False
|
||||
wantedEpisodes = []
|
||||
|
||||
# check through the list of statuses to see if we want any
|
||||
for curStatusResult in statusResults:
|
||||
curCompositeStatus = int(curStatusResult["status"])
|
||||
curStatus, curQuality = common.Quality.splitCompositeStatus(curCompositeStatus)
|
||||
episode = int(curStatusResult["episode"])
|
||||
|
||||
if bestQualities:
|
||||
highestBestQuality = max(bestQualities)
|
||||
|
@ -242,44 +242,45 @@ class BacklogQueueItem(generic_queue.QueueItem):
|
|||
# if we need a better one then say yes
|
||||
if (curStatus in (common.DOWNLOADED, common.SNATCHED, common.SNATCHED_PROPER,
|
||||
common.SNATCHED_BEST) and curQuality < highestBestQuality) or curStatus == common.WANTED:
|
||||
wantSeason = True
|
||||
break
|
||||
epObj = self.show.getEpisode(self.segment,episode)
|
||||
wantedEpisodes.append(epObj)
|
||||
|
||||
return wantSeason
|
||||
return wantedEpisodes
|
||||
|
||||
|
||||
class FailedQueueItem(generic_queue.QueueItem):
|
||||
def __init__(self, show, segment):
|
||||
def __init__(self, show, episodes):
|
||||
generic_queue.QueueItem.__init__(self, 'Retry', MANUAL_SEARCH)
|
||||
self.priority = generic_queue.QueuePriorities.HIGH
|
||||
self.thread_name = 'RETRY-' + str(show.indexerid)
|
||||
|
||||
self.show = show
|
||||
self.segment = segment
|
||||
self.episodes = episodes
|
||||
|
||||
self.success = None
|
||||
|
||||
def execute(self):
|
||||
generic_queue.QueueItem.execute(self)
|
||||
|
||||
for season, episode in self.segment.iteritems():
|
||||
epObj = self.show.getEpisode(season, episode)
|
||||
episodes = []
|
||||
|
||||
(release, provider) = failed_history.findRelease(self.show, season, episode)
|
||||
for epObj in episodes:
|
||||
(release, provider) = failed_history.findRelease(self.show, epObj.season, epObj.episode)
|
||||
if release:
|
||||
logger.log(u"Marking release as bad: " + release)
|
||||
failed_history.markFailed(self.show, season, episode)
|
||||
failed_history.markFailed(self.show, epObj.season, epObj.episode)
|
||||
failed_history.logFailed(release)
|
||||
history.logFailed(self.show.indexerid, season, episode, epObj.status, release, provider)
|
||||
history.logFailed(self.show.indexerid, epObj.season, epObj.episode, epObj.status, release, provider)
|
||||
|
||||
failed_history.revertEpisode(self.show, season, episode)
|
||||
failed_history.revertEpisode(self.show, epObj.season, epObj.episode)
|
||||
episodes.append(epObj)
|
||||
|
||||
# get search results
|
||||
results = search.searchProviders(self.show, season, episode)
|
||||
# get search results
|
||||
results = search.searchProviders(self.show, episodes[0].season, episodes)
|
||||
|
||||
# download whatever we find
|
||||
for curResult in results:
|
||||
self.success = search.snatchEpisode(curResult)
|
||||
time.sleep(5)
|
||||
# download whatever we find
|
||||
for curResult in results:
|
||||
self.success = search.snatchEpisode(curResult)
|
||||
time.sleep(5)
|
||||
|
||||
self.finish()
|
||||
|
|
|
@ -139,7 +139,7 @@ class TVShow(object):
|
|||
sql_selection = sql_selection + " FROM tv_episodes tve WHERE showid = " + str(self.indexerid)
|
||||
|
||||
if season is not None:
|
||||
if not self.air_by_date and not self.sports:
|
||||
if not self.air_by_date:
|
||||
sql_selection = sql_selection + " AND season = " + str(season)
|
||||
else:
|
||||
segment_year, segment_month = map(int, str(season).split('-'))
|
||||
|
@ -1128,15 +1128,26 @@ def dirty_setter(attr_name):
|
|||
|
||||
|
||||
class TVEpisode(object):
|
||||
def __init__(self, show, season, episode, file=""):
|
||||
# Convert season/episode to XEM scene numbering
|
||||
scene_season, scene_episode = sickbeard.scene_numbering.get_scene_numbering(show.indexerid, season, episode)
|
||||
def __init__(self, show, season=None, episode=None, scene_season=None, scene_episode=None, file=""):
|
||||
# convert from indexer numbering <-> scene numerbing and back again once we have correct season and episode numbers
|
||||
if season and episode:
|
||||
self._scene_season, self._scene_episode = sickbeard.scene_numbering.get_scene_numbering(show.indexerid,
|
||||
show.indexer,
|
||||
season, episode)
|
||||
self._season, self._episode = sickbeard.scene_numbering.get_indexer_numbering(show.indexerid, show.indexer,
|
||||
self._scene_season,
|
||||
self._scene_episode)
|
||||
|
||||
# convert from scene numbering <-> indexer numbering and back again once we have correct season and episode numbers
|
||||
elif scene_season and scene_episode:
|
||||
self._season, self._episode = sickbeard.scene_numbering.get_indexer_numbering(show.indexerid, show.indexer,
|
||||
scene_season,
|
||||
scene_episode)
|
||||
self._scene_season, self._scene_episode = sickbeard.scene_numbering.get_scene_numbering(show.indexerid,
|
||||
show.indexer,
|
||||
self._season,
|
||||
self._episode)
|
||||
self._name = ""
|
||||
self._season = season
|
||||
self._episode = episode
|
||||
self._scene_season = scene_season
|
||||
self._scene_episode = scene_episode
|
||||
self._description = ""
|
||||
self._subtitles = list()
|
||||
self._subtitles_searchcount = 0
|
||||
|
@ -1161,7 +1172,7 @@ class TVEpisode(object):
|
|||
|
||||
self.lock = threading.Lock()
|
||||
|
||||
self.specifyEpisode(self.season, self.episode)
|
||||
self.specifyEpisode(self.season, self.episode, self.scene_season, self.scene_episode)
|
||||
|
||||
self.relatedEps = []
|
||||
|
||||
|
@ -1299,9 +1310,9 @@ class TVEpisode(object):
|
|||
# if either setting has changed return true, if not return false
|
||||
return oldhasnfo != self.hasnfo or oldhastbn != self.hastbn
|
||||
|
||||
def specifyEpisode(self, season, episode):
|
||||
def specifyEpisode(self, season, episode, scene_season, scene_episode):
|
||||
|
||||
sqlResult = self.loadFromDB(season, episode)
|
||||
sqlResult = self.loadFromDB(season, episode, scene_season, scene_episode)
|
||||
|
||||
if not sqlResult:
|
||||
# only load from NFO if we didn't load from DB
|
||||
|
@ -1316,7 +1327,7 @@ class TVEpisode(object):
|
|||
# if we tried loading it from NFO and didn't find the NFO, try the Indexers
|
||||
if self.hasnfo == False:
|
||||
try:
|
||||
result = self.loadFromIndexer(season, episode)
|
||||
result = self.loadFromIndexer(season, episode, scene_season, scene_episode)
|
||||
except exceptions.EpisodeDeletedException:
|
||||
result = False
|
||||
|
||||
|
@ -1325,7 +1336,7 @@ class TVEpisode(object):
|
|||
raise exceptions.EpisodeNotFoundException(
|
||||
"Couldn't find episode " + str(season) + "x" + str(episode))
|
||||
|
||||
def loadFromDB(self, season, episode):
|
||||
def loadFromDB(self, season, episode, scene_season, scene_episode):
|
||||
|
||||
logger.log(
|
||||
str(self.show.indexerid) + u": Loading episode details from DB for episode " + str(season) + "x" + str(
|
||||
|
@ -1345,9 +1356,11 @@ class TVEpisode(object):
|
|||
#NAMEIT logger.log(u"AAAAA from" + str(self.season)+"x"+str(self.episode) + " -" + self.name + " to " + str(sqlResults[0]["name"]))
|
||||
if sqlResults[0]["name"]:
|
||||
self.name = sqlResults[0]["name"]
|
||||
|
||||
self.season = season
|
||||
self.episode = episode
|
||||
|
||||
self.scene_season = scene_season
|
||||
self.scene_episode = scene_episode
|
||||
self.description = sqlResults[0]["description"]
|
||||
if not self.description:
|
||||
self.description = ""
|
||||
|
@ -1379,13 +1392,18 @@ class TVEpisode(object):
|
|||
self.dirty = False
|
||||
return True
|
||||
|
||||
def loadFromIndexer(self, season=None, episode=None, cache=True, tvapi=None, cachedSeason=None):
|
||||
def loadFromIndexer(self, season=None, episode=None, scene_season=None, scene_episode=None, cache=True, tvapi=None, cachedSeason=None):
|
||||
|
||||
if season is None:
|
||||
season = self.season
|
||||
if episode is None:
|
||||
episode = self.episode
|
||||
|
||||
if scene_season is None:
|
||||
scene_season = self.scene_season
|
||||
if scene_episode is None:
|
||||
scene_episode = self.scene_episode
|
||||
|
||||
logger.log(str(self.show.indexerid) + u": Loading episode details from " + sickbeard.indexerApi(
|
||||
self.show.indexer).name + " for episode " + str(season) + "x" + str(episode), logger.DEBUG)
|
||||
|
||||
|
@ -1676,11 +1694,11 @@ class TVEpisode(object):
|
|||
|
||||
# use a custom update/insert method to get the data into the DB
|
||||
return [
|
||||
"INSERT OR REPLACE INTO tv_episodes (episode_id, indexerid, indexer, name, description, subtitles, subtitles_searchcount, subtitles_lastsearch, airdate, hasnfo, hastbn, status, location, file_size, release_name, is_proper, showid, season, episode) VALUES ((SELECT episode_id FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
|
||||
"INSERT OR REPLACE INTO tv_episodes (episode_id, indexerid, indexer, name, description, subtitles, subtitles_searchcount, subtitles_lastsearch, airdate, hasnfo, hastbn, status, location, file_size, release_name, is_proper, showid, season, episode) VALUES ((SELECT episode_id FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ? AND scene_season = ? AND scene_episode = ?),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
|
||||
[self.show.indexerid, self.season, self.episode, self.indexerid, self.indexer, self.name, self.description,
|
||||
",".join([sub for sub in self.subtitles]), self.subtitles_searchcount, self.subtitles_lastsearch,
|
||||
self.airdate.toordinal(), self.hasnfo, self.hastbn, self.status, self.location, self.file_size,
|
||||
self.release_name, self.is_proper, self.show.indexerid, self.season, self.episode]]
|
||||
self.release_name, self.is_proper, self.show.indexerid, self.season, self.episode, self.scene_season, self.scene_episode]]
|
||||
|
||||
def saveToDB(self, forceSave=False):
|
||||
"""
|
||||
|
@ -1714,7 +1732,9 @@ class TVEpisode(object):
|
|||
"location": self.location,
|
||||
"file_size": self.file_size,
|
||||
"release_name": self.release_name,
|
||||
"is_proper": self.is_proper}
|
||||
"is_proper": self.is_proper,
|
||||
"scene_season": self.scene_season,
|
||||
"scene_episode": self.scene_episode}
|
||||
controlValueDict = {"showid": self.show.indexerid,
|
||||
"season": self.season,
|
||||
"episode": self.episode}
|
||||
|
@ -1748,16 +1768,6 @@ class TVEpisode(object):
|
|||
|
||||
return self._format_pattern('%SN - %XMSx%0XME - %EN')
|
||||
|
||||
def sports_prettyName(self):
|
||||
"""
|
||||
Returns the name of this episode in a "pretty" human-readable format. Used for logging
|
||||
and notifications and such.
|
||||
|
||||
Returns: A string representing the episode's name and season/ep numbers
|
||||
"""
|
||||
|
||||
return self._format_pattern('%SN - %A-D - %EN')
|
||||
|
||||
def _ep_name(self):
|
||||
"""
|
||||
Returns the name of the episode to use during renaming. Combines the names of related episodes.
|
||||
|
|
|
@ -56,14 +56,6 @@ class CacheDBConnection(db.DBConnection):
|
|||
if str(e) != "table lastUpdate already exists":
|
||||
raise
|
||||
|
||||
# Clear out records missing there Indexer IDs
|
||||
try:
|
||||
sql = "DELETE FROM [" + providerName + "] WHERE indexerid is NULL or indexerid is 0"
|
||||
self.connection.execute(sql)
|
||||
self.connection.commit()
|
||||
except:
|
||||
pass
|
||||
|
||||
class TVCache():
|
||||
def __init__(self, provider):
|
||||
|
||||
|
@ -113,15 +105,15 @@ class TVCache():
|
|||
|
||||
if self._checkAuth(data):
|
||||
items = data.entries
|
||||
cl = []
|
||||
ql = []
|
||||
for item in items:
|
||||
ci = self._parseItem(item)
|
||||
if ci is not None:
|
||||
cl.append(ci)
|
||||
qi = self._parseItem(item)
|
||||
if qi is not None:
|
||||
ql.append(qi)
|
||||
|
||||
if len(cl) > 0:
|
||||
if len(ql):
|
||||
myDB = self._getDB()
|
||||
myDB.mass_action(cl)
|
||||
myDB.mass_action(ql)
|
||||
|
||||
else:
|
||||
raise AuthException(
|
||||
|
@ -192,14 +184,13 @@ class TVCache():
|
|||
|
||||
def _addCacheEntry(self, name, url, quality=None):
|
||||
|
||||
cacheDB = self._getDB()
|
||||
season = None
|
||||
episodes = None
|
||||
|
||||
# if we don't have complete info then parse the filename to get it
|
||||
try:
|
||||
myParser = NameParser()
|
||||
parse_result = myParser.parse(name).convert()
|
||||
parse_result = myParser.parse(name)
|
||||
except InvalidNameException:
|
||||
logger.log(u"Unable to parse the filename " + name + " into a valid episode", logger.DEBUG)
|
||||
return None
|
||||
|
@ -212,42 +203,41 @@ class TVCache():
|
|||
logger.log(u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG)
|
||||
return None
|
||||
|
||||
if not parse_result.show:
|
||||
logger.log(u"Couldn't find a show in our databases matching " + name + ", unable to cache it", logger.DEBUG)
|
||||
if not helpers.get_show_by_name(parse_result.series_name):
|
||||
logger.log(u"Could not find a show matching " + parse_result.series_name + " in the database, skipping ...", logger.DEBUG)
|
||||
return None
|
||||
|
||||
try:
|
||||
if parse_result.air_by_date:
|
||||
myDB = db.DBConnection()
|
||||
if parse_result.show.air_by_date:
|
||||
airdate = parse_result.sports_event_date.toordinal() if parse_result.show.sports else parse_result.air_date.toordinal()
|
||||
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||
[parse_result.show.indexerid, airdate])
|
||||
if sql_results > 0:
|
||||
season = int(sql_results[0]["season"])
|
||||
episodes = [int(sql_results[0]["episode"])]
|
||||
else:
|
||||
season = parse_result.season_number
|
||||
episodes = parse_result.episode_numbers
|
||||
|
||||
if season and episodes:
|
||||
# store episodes as a seperated string
|
||||
episodeText = "|" + "|".join(map(str, episodes)) + "|"
|
||||
airdate = parse_result.air_date.toordinal()
|
||||
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?",
|
||||
[parse_result.show.indexerid, parse_result.show.indexer, airdate])
|
||||
if sql_results > 0:
|
||||
season = int(sql_results[0]["season"])
|
||||
episodes = [int(sql_results[0]["episode"])]
|
||||
else:
|
||||
season = parse_result.season_number
|
||||
episodes = parse_result.episode_numbers
|
||||
|
||||
# get the current timestamp
|
||||
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
|
||||
if season and episodes:
|
||||
# store episodes as a seperated string
|
||||
episodeText = "|" + "|".join(map(str, episodes)) + "|"
|
||||
|
||||
# get quality of release
|
||||
if quality is None:
|
||||
quality = Quality.sceneQuality(name)
|
||||
# get the current timestamp
|
||||
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
|
||||
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name, 'utf-8')
|
||||
# get quality of release
|
||||
if quality is None:
|
||||
quality = Quality.sceneQuality(name)
|
||||
|
||||
cacheDB.action(
|
||||
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
|
||||
[name, season, episodeText, parse_result.show.indexerid, url, curTimestamp, quality])
|
||||
except:
|
||||
return
|
||||
if not isinstance(name, unicode):
|
||||
name = unicode(name, 'utf-8')
|
||||
|
||||
|
||||
logger.log(u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG)
|
||||
return ["INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
|
||||
[name, season, episodeText, parse_result.show.indexerid, url, curTimestamp, quality]]
|
||||
|
||||
def searchCache(self, episode, manualSearch=False):
|
||||
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
||||
|
@ -275,7 +265,7 @@ class TVCache():
|
|||
else:
|
||||
sqlResults = myDB.select(
|
||||
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?",
|
||||
[episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"])
|
||||
[episode.show.indexerid, episode.scene_season, "%|" + str(episode.scene_episode) + "|%"])
|
||||
|
||||
# for each cache entry
|
||||
for curResult in sqlResults:
|
||||
|
|
|
@ -2833,8 +2833,8 @@ class Home:
|
|||
|
||||
#t.all_scene_exceptions = list(set((get_scene_exceptions(showObj.indexerid) or []) + (get_custom_exceptions(showObj.indexerid) or [])))
|
||||
t.all_scene_exceptions = get_scene_exceptions(showObj.indexerid)
|
||||
t.scene_numbering = get_scene_numbering_for_show(showObj.indexerid)
|
||||
t.xem_numbering = get_xem_numbering_for_show(showObj.indexerid)
|
||||
t.scene_numbering = get_scene_numbering_for_show(showObj.indexerid, showObj.indexer)
|
||||
t.xem_numbering = get_xem_numbering_for_show(showObj.indexerid, showObj.indexer)
|
||||
|
||||
return _munge(t)
|
||||
|
||||
|
@ -3404,7 +3404,7 @@ class Home:
|
|||
|
||||
set_scene_numbering(show, forSeason, forEpisode, sceneSeason, sceneEpisode)
|
||||
|
||||
sn = get_scene_numbering(show, forSeason, forEpisode)
|
||||
sn = get_scene_numbering(show, ep_obj.indexer, forSeason, forEpisode)
|
||||
if sn:
|
||||
(result['sceneSeason'], result['sceneEpisode']) = sn
|
||||
else:
|
||||
|
@ -3421,7 +3421,7 @@ class Home:
|
|||
return json.dumps({'result': 'failure'})
|
||||
|
||||
# make a queue item for it and put it on the queue
|
||||
ep_queue_item = search_queue.FailedQueueItem(ep_obj.show, {ep_obj.season: ep_obj.episode})
|
||||
ep_queue_item = search_queue.FailedQueueItem(ep_obj.show, [ep_obj])
|
||||
sickbeard.searchQueueScheduler.action.add_item(ep_queue_item) # @UndefinedVariable
|
||||
|
||||
# wait until the queue item tells us whether it worked or not
|
||||
|
|
|
@ -33,6 +33,21 @@ from sickbeard.name_parser.parser import NameParser
|
|||
from sickbeard.tv import TVShow
|
||||
|
||||
class XEMBasicTests(test.SickbeardTestDBCase):
|
||||
def loadShowsFromDB(self):
|
||||
"""
|
||||
Populates the showList with shows from the database
|
||||
"""
|
||||
|
||||
myDB = test.db.DBConnection()
|
||||
sqlResults = myDB.select("SELECT * FROM tv_shows")
|
||||
|
||||
for sqlShow in sqlResults:
|
||||
try:
|
||||
curShow = TVShow(int(sqlShow["indexer"]), int(sqlShow["indexer_id"]))
|
||||
sickbeard.showList.append(curShow)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def loadFromDB(self):
|
||||
"""
|
||||
Populates the showList with shows from the database
|
||||
|
@ -49,9 +64,7 @@ class XEMBasicTests(test.SickbeardTestDBCase):
|
|||
print "There was an error creating the show"
|
||||
|
||||
def test_formating(self):
|
||||
self.loadFromDB()
|
||||
|
||||
release = "d:\\Downloads\\newdownload\\2.Broke.Girls.S03E10.And.the.First.Day.of.School.720p.WEB-DL.DD5.1.H.264-BS.mkv"
|
||||
release = "UFC.172.26th.April.2014.HDTV.x264.720p-Sir.Paul[rartv]"
|
||||
# parse the name to break it into show name, season, and episode
|
||||
np = NameParser(file)
|
||||
parse_result = np.parse(release).convert()
|
||||
|
|
Loading…
Reference in a new issue