1
0
mirror of https://github.com/moparisthebest/SickRage synced 2024-12-12 19:12:26 -05:00

Fixed failed download handling.

Improved search queue code.
This commit is contained in:
echel0n 2014-09-06 21:36:23 -07:00
parent 6ce43c7782
commit 59675f27ac
11 changed files with 104 additions and 120 deletions

View File

@ -64,10 +64,8 @@ class FailedProcessor(object):
logger.log(u" - " + str(parsed.release_group), logger.DEBUG) logger.log(u" - " + str(parsed.release_group), logger.DEBUG)
logger.log(u" - " + str(parsed.air_date), logger.DEBUG) logger.log(u" - " + str(parsed.air_date), logger.DEBUG)
segment = {parsed.season_number: []}
for episode in parsed.episode_numbers: for episode in parsed.episode_numbers:
epObj = parsed.show.getEpisode(parsed.season_number, episode) segment = parsed.show.getEpisode(parsed.season_number, episode)
segment[parsed.season_number].append(epObj)
cur_failed_queue_item = search_queue.FailedQueueItem(parsed.show, segment) cur_failed_queue_item = search_queue.FailedQueueItem(parsed.show, segment)
sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item) sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item)

View File

@ -60,7 +60,7 @@ class EZRSSProvider(generic.TorrentProvider):
return quality return quality
def findSearchResults(self, show, season, episodes, search_mode, manualSearch=False): def findSearchResults(self, show, episodes, search_mode, manualSearch=False):
self.show = show self.show = show
@ -71,7 +71,7 @@ class EZRSSProvider(generic.TorrentProvider):
logger.WARNING) logger.WARNING)
return results return results
results = generic.TorrentProvider.findSearchResults(self, show, season, episodes, search_mode, manualSearch) results = generic.TorrentProvider.findSearchResults(self, show, episodes, search_mode, manualSearch)
return results return results

View File

@ -248,7 +248,7 @@ class GenericProvider:
return title, url return title, url
def findSearchResults(self, show, season, episodes, search_mode, manualSearch=False): def findSearchResults(self, show, episodes, search_mode, manualSearch=False):
self._checkAuth() self._checkAuth()
self.show = show self.show = show

View File

@ -55,8 +55,8 @@ class NyaaProvider(generic.TorrentProvider):
quality = Quality.sceneQuality(title) quality = Quality.sceneQuality(title)
return quality return quality
def findSearchResults(self, show, season, episodes, search_mode, manualSearch=False): def findSearchResults(self, show, episodes, search_mode, manualSearch=False):
return generic.TorrentProvider.findSearchResults(self, show, season, episodes, search_mode, manualSearch) return generic.TorrentProvider.findSearchResults(self, show, episodes, search_mode, manualSearch)
def _get_season_search_strings(self, ep_obj): def _get_season_search_strings(self, ep_obj):
return show_name_helpers.makeSceneShowSearchStrings(self.show) return show_name_helpers.makeSceneShowSearchStrings(self.show)

View File

@ -390,22 +390,12 @@ def searchForNeededEpisodes():
return foundResults.values() return foundResults.values()
def searchProviders(show, season, episodes, manualSearch=False): def searchProviders(show, episodes, manualSearch=False):
foundResults = {} foundResults = {}
finalResults = [] finalResults = []
didSearch = False didSearch = False
# build name cache for show
sickbeard.name_cache.buildNameCache(show)
# check if we want to search for season packs instead of just season/episode
seasonSearch = False
if not manualSearch:
seasonEps = show.getAllEpisodes(season)
if len(seasonEps) == len(episodes):
seasonSearch = True
origThreadName = threading.currentThread().name origThreadName = threading.currentThread().name
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_backlog] providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_backlog]
@ -417,23 +407,21 @@ def searchProviders(show, season, episodes, manualSearch=False):
threading.currentThread().name = origThreadName + " :: [" + curProvider.name + "]" threading.currentThread().name = origThreadName + " :: [" + curProvider.name + "]"
foundResults[curProvider.name] = {} foundResults[curProvider.name] = {}
searchCount = 0
search_mode = 'eponly' searchCount = 0
if seasonSearch and curProvider.search_mode == 'sponly':
search_mode = curProvider.search_mode search_mode = curProvider.search_mode
while(True): while(True):
searchCount += 1 searchCount += 1
if search_mode == 'sponly': if search_mode == 'eponly':
logger.log(u"Searching for " + show.name + " Season " + str(season) + " pack") logger.log(u"Performing episode search for " + show.name)
else: else:
logger.log(u"Searching for episodes we need from " + show.name + " Season " + str(season)) logger.log(u"Performing season pack search for " + show.name)
try: try:
curProvider.cache.updateCache() curProvider.cache.updateCache()
searchResults = curProvider.findSearchResults(show, season, episodes, search_mode, manualSearch) searchResults = curProvider.findSearchResults(show, episodes, search_mode, manualSearch)
except exceptions.AuthException, e: except exceptions.AuthException, e:
logger.log(u"Authentication error: " + ex(e), logger.ERROR) logger.log(u"Authentication error: " + ex(e), logger.ERROR)
break break

View File

@ -99,12 +99,13 @@ class BacklogSearcher:
segments = self._get_segments(curShow, fromDate) segments = self._get_segments(curShow, fromDate)
if len(segments): for season, segment in segments.items():
backlog_queue_item = search_queue.BacklogQueueItem(curShow, segments) self.currentSearchInfo = {'title': self.show.name + " Season " + str(season)}
backlog_queue_item = search_queue.BacklogQueueItem(curShow, segment)
sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) # @UndefinedVariable sickbeard.searchQueueScheduler.action.add_item(backlog_queue_item) # @UndefinedVariable
else: else:
logger.log(u"Nothing needs to be downloaded for " + str(curShow.name) + ", skipping this season", logger.log(u"Nothing needs to be downloaded for " + str(curShow.name) + ", skipping",logger.DEBUG)
logger.DEBUG)
# don't consider this an actual backlog search if we only did recent eps # don't consider this an actual backlog search if we only did recent eps
# or if we only did certain shows # or if we only did certain shows

View File

@ -49,6 +49,12 @@ class SearchQueue(generic_queue.GenericQueue):
return True return True
return False return False
def is_ep_in_queue(self, ep_obj):
for cur_item in self.queue:
if isinstance(cur_item, (ManualSearchQueueItem, FailedQueueItem)) and cur_item.ep_obj == ep_obj:
return True
return False
def pause_backlog(self): def pause_backlog(self):
self.min_priority = generic_queue.QueuePriorities.HIGH self.min_priority = generic_queue.QueuePriorities.HIGH
@ -72,13 +78,21 @@ class SearchQueue(generic_queue.GenericQueue):
return False return False
def add_item(self, item): def add_item(self, item):
if isinstance(item, DailySearchQueueItem) or ( if isinstance(item, DailySearchQueueItem):
isinstance(item, (BacklogQueueItem, ManualSearchQueueItem, FailedQueueItem)) and not self.is_in_queue( # daily searches
item.show, item.segment)): generic_queue.GenericQueue.add_item(self, item)
elif isinstance(item, BacklogQueueItem) and not self.is_in_queue(item.show, item.segment):
# backlog searches
generic_queue.GenericQueue.add_item(self, item)
elif isinstance(item, (ManualSearchQueueItem, FailedQueueItem)) and not self.is_ep_in_queue(item.segment):
# manual and failed searches
generic_queue.GenericQueue.add_item(self, item) generic_queue.GenericQueue.add_item(self, item)
else: else:
logger.log(u"Not adding item, it's already in the queue", logger.DEBUG) logger.log(u"Not adding item, it's already in the queue", logger.DEBUG)
return
# build name cache for show
sickbeard.name_cache.buildNameCache(item.show)
class DailySearchQueueItem(generic_queue.QueueItem): class DailySearchQueueItem(generic_queue.QueueItem):
def __init__(self): def __init__(self):
@ -123,7 +137,7 @@ class ManualSearchQueueItem(generic_queue.QueueItem):
try: try:
logger.log("Beginning manual search for [" + self.segment.prettyName() + "]") logger.log("Beginning manual search for [" + self.segment.prettyName() + "]")
searchResult = search.searchProviders(self.show, self.segment.season, [self.segment], True) searchResult = search.searchProviders(self.show, [self.segment], True)
if searchResult: if searchResult:
# just use the first result for now # just use the first result for now
@ -161,14 +175,8 @@ class BacklogQueueItem(generic_queue.QueueItem):
generic_queue.QueueItem.run(self) generic_queue.QueueItem.run(self)
try: try:
for season in self.segment:
sickbeard.searchBacklog.BacklogSearcher.currentSearchInfo = {
'title': self.show.name + " Season " + str(season)}
wantedEps = self.segment[season]
logger.log("Beginning backlog search for [" + self.show.name + "]") logger.log("Beginning backlog search for [" + self.show.name + "]")
searchResult = search.searchProviders(self.show, season, wantedEps, False) searchResult = search.searchProviders(self.show, self.segment, False)
if searchResult: if searchResult:
for result in searchResult: for result in searchResult:
@ -199,20 +207,18 @@ class FailedQueueItem(generic_queue.QueueItem):
generic_queue.QueueItem.run(self) generic_queue.QueueItem.run(self)
try: try:
for season, episodes in self.segment.items(): logger.log(u"Marking episode as bad: [" + self.segment.prettyName() + "]")
for epObj in episodes: failed_history.markFailed(self.segment)
logger.log(u"Marking episode as bad: [" + epObj.prettyName() + "]")
failed_history.markFailed(epObj)
(release, provider) = failed_history.findRelease(epObj) (release, provider) = failed_history.findRelease(self.segment)
if release: if release:
failed_history.logFailed(release) failed_history.logFailed(release)
history.logFailed(epObj, release, provider) history.logFailed(self.segment, release, provider)
failed_history.revertEpisode(epObj) failed_history.revertEpisode(self.segment)
logger.log("Beginning failed download search for [" + epObj.prettyName() + "]") logger.log("Beginning failed download search for [" + self.segment.prettyName() + "]")
searchResult = search.searchProviders(self.show, season, [epObj], True) searchResult = search.searchProviders(self.show, [self.segment], True)
if searchResult: if searchResult:
for result in searchResult: for result in searchResult:
@ -223,7 +229,7 @@ class FailedQueueItem(generic_queue.QueueItem):
# give the CPU a break # give the CPU a break
time.sleep(common.cpu_presets[sickbeard.CPU_PRESET]) time.sleep(common.cpu_presets[sickbeard.CPU_PRESET])
else: else:
logger.log(u"No valid episode found to retry for [" + epObj.prettyName() + "]") logger.log(u"No valid episode found to retry for [" + self.segment.prettyName() + "]")
except Exception: except Exception:
logger.log(traceback.format_exc(), logger.DEBUG) logger.log(traceback.format_exc(), logger.DEBUG)

View File

@ -31,7 +31,6 @@ from lib.trakt import *
class TraktChecker(): class TraktChecker():
def __init__(self): def __init__(self):
self.todoWanted = [] self.todoWanted = []
self.todoBacklog = []
def run(self, force=False): def run(self, force=False):
try: try:
@ -207,7 +206,7 @@ class TraktChecker():
epObj = show.getEpisode(int(s), int(e)) epObj = show.getEpisode(int(s), int(e))
if epObj: if epObj:
ep_segment = {} segments = {}
with epObj.lock: with epObj.lock:
if epObj.status != SKIPPED: if epObj.status != SKIPPED:
@ -217,35 +216,27 @@ class TraktChecker():
# figure out what segment the episode is in and remember it so we can backlog it # figure out what segment the episode is in and remember it so we can backlog it
if epObj.season in ep_segment: if epObj.season in ep_segment:
ep_segment[epObj.season].append(epObj) segments[epObj.season].append(epObj)
else: else:
ep_segment[epObj.season] = [epObj] segments[epObj.season] = [epObj]
epObj.status = WANTED epObj.status = WANTED
epObj.saveToDB() epObj.saveToDB()
backlog = (show, ep_segment) for season, segment in segments.items():
if self.todoBacklog.count(backlog) == 0: cur_backlog_queue_item = search_queue.BacklogQueueItem(show, segment[1])
self.todoBacklog.append(backlog) sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item)
logger.log(u"Starting backlog for " + show.name + " season " + str(
season) + " because some eps were set to wanted")
def manageNewShow(self, show): def manageNewShow(self, show):
episodes = [i for i in self.todoWanted if i[0] == show.indexerid] episodes = [i for i in self.todoWanted if i[0] == show.indexerid]
for episode in episodes: for episode in episodes:
self.todoWanted.remove(episode) self.todoWanted.remove(episode)
if episode[1] == -1 and sickbeard.TRAKT_START_PAUSED: if episode[1] == -1 and sickbeard.TRAKT_START_PAUSED:
show.paused = 1 show.paused = 1
continue continue
self.setEpisodeToWanted(show, episode[1], episode[2]) self.setEpisodeToWanted(show, episode[1], episode[2])
self.startBacklog(show)
def startBacklog(self, show):
segments = [i for i in self.todoBacklog if i[0] == show]
for segment in segments:
cur_backlog_queue_item = search_queue.BacklogQueueItem(show, segment[1])
sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item)
for season in segment[1]:
logger.log(u"Starting backlog for " + show.name + " season " + str(
season) + " because some eps were set to wanted")
self.todoBacklog.remove(segment)

View File

@ -341,9 +341,6 @@ class TVCache():
Quality.qualityStrings[curQuality], logger.DEBUG) Quality.qualityStrings[curQuality], logger.DEBUG)
continue continue
# build name cache for show
sickbeard.name_cache.buildNameCache(showObj)
if episode: if episode:
epObj = episode epObj = episode
else: else:

View File

@ -969,7 +969,7 @@ class CMD_EpisodeSetStatus(ApiCall):
ep_results = [] ep_results = []
failure = False failure = False
start_backlog = False start_backlog = False
ep_segment = {} segments = {}
sql_l = [] sql_l = []
for epObj in ep_list: for epObj in ep_list:
@ -977,9 +977,9 @@ class CMD_EpisodeSetStatus(ApiCall):
if self.status == WANTED: if self.status == WANTED:
# figure out what episodes are wanted so we can backlog them # figure out what episodes are wanted so we can backlog them
if epObj.season in ep_segment: if epObj.season in ep_segment:
ep_segment[epObj.season].append(epObj) segments[epObj.season].append(epObj)
else: else:
ep_segment[epObj.season] = [epObj] segments[epObj.season] = [epObj]
# don't let them mess up UNAIRED episodes # don't let them mess up UNAIRED episodes
if epObj.status == UNAIRED: if epObj.status == UNAIRED:
@ -1009,11 +1009,13 @@ class CMD_EpisodeSetStatus(ApiCall):
extra_msg = "" extra_msg = ""
if start_backlog: if start_backlog:
cur_backlog_queue_item = search_queue.BacklogQueueItem(showObj, ep_segment) for season, segment in segments.items():
cur_backlog_queue_item = search_queue.BacklogQueueItem(showObj, segment)
sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item) #@UndefinedVariable sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item) #@UndefinedVariable
for season in ep_segment:
logger.log(u"API :: Starting backlog for " + showObj.name + " season " + str( logger.log(u"API :: Starting backlog for " + showObj.name + " season " + str(
season) + " because some episodes were set to WANTED") season) + " because some episodes were set to WANTED")
extra_msg = " Backlog started" extra_msg = " Backlog started"
if failure: if failure:

View File

@ -4121,7 +4121,7 @@ class Home(MainHandler):
else: else:
return self._genericMessage("Error", errMsg) return self._genericMessage("Error", errMsg)
segment = {} segments = {}
if eps is not None: if eps is not None:
sql_l = [] sql_l = []
@ -4138,10 +4138,10 @@ class Home(MainHandler):
if int(status) in [WANTED, FAILED]: if int(status) in [WANTED, FAILED]:
# figure out what episodes are wanted so we can backlog them # figure out what episodes are wanted so we can backlog them
if epObj.season in segment: if epObj.season in segments:
segment[epObj.season].append(epObj) segments[epObj.season].append(epObj)
else: else:
segment[epObj.season] = [epObj] segments[epObj.season] = [epObj]
with epObj.lock: with epObj.lock:
# don't let them mess up UNAIRED episodes # don't let them mess up UNAIRED episodes
@ -4175,30 +4175,34 @@ class Home(MainHandler):
if int(status) == WANTED: if int(status) == WANTED:
msg = "Backlog was automatically started for the following seasons of <b>" + showObj.name + "</b>:<br />" msg = "Backlog was automatically started for the following seasons of <b>" + showObj.name + "</b>:<br />"
for season in segment:
msg += "<li>Season " + str(season) + "</li>"
logger.log(u"Sending backlog for " + showObj.name + " season " + str(
season) + " because some eps were set to wanted")
msg += "</ul>"
for season, segment in segments.items():
cur_backlog_queue_item = search_queue.BacklogQueueItem(showObj, segment) cur_backlog_queue_item = search_queue.BacklogQueueItem(showObj, segment)
sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item) # @UndefinedVariable sickbeard.searchQueueScheduler.action.add_item(cur_backlog_queue_item) # @UndefinedVariable
if segment: msg += "<li>Season " + str(season) + "</li>"
logger.log(u"Sending backlog for " + showObj.name + " season " + str(
season) + " because some eps were set to wanted")
msg += "</ul>"
if segments:
ui.notifications.message("Backlog started", msg) ui.notifications.message("Backlog started", msg)
if int(status) == FAILED: if int(status) == FAILED:
msg = "Retrying Search was automatically started for the following season of <b>" + showObj.name + "</b>:<br />" msg = "Retrying Search was automatically started for the following season of <b>" + showObj.name + "</b>:<br />"
for season in segment:
msg += "<li>Season " + str(season) + "</li>"
logger.log(u"Retrying Search for " + showObj.name + " season " + str(
season) + " because some eps were set to failed")
msg += "</ul>"
for season, segment in segments.items():
cur_failed_queue_item = search_queue.FailedQueueItem(showObj, segment) cur_failed_queue_item = search_queue.FailedQueueItem(showObj, segment)
sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item) # @UndefinedVariable sickbeard.searchQueueScheduler.action.add_item(cur_failed_queue_item) # @UndefinedVariable
if segment: msg += "<li>Season " + str(season) + "</li>"
logger.log(u"Retrying Search for " + showObj.name + " season " + str(
season) + " because some eps were set to failed")
msg += "</ul>"
if segments:
ui.notifications.message("Retry Search started", msg) ui.notifications.message("Retry Search started", msg)
if direct: if direct:
@ -4440,11 +4444,8 @@ class Home(MainHandler):
if isinstance(ep_obj, str): if isinstance(ep_obj, str):
return json.dumps({'result': 'failure'}) return json.dumps({'result': 'failure'})
# create failed segment
segment = {season: [ep_obj]}
# make a queue item for it and put it on the queue # make a queue item for it and put it on the queue
ep_queue_item = search_queue.FailedQueueItem(ep_obj.show, segment) ep_queue_item = search_queue.FailedQueueItem(ep_obj.show, ep_obj)
sickbeard.searchQueueScheduler.action.add_item(ep_queue_item) # @UndefinedVariable sickbeard.searchQueueScheduler.action.add_item(ep_queue_item) # @UndefinedVariable
# wait until the queue item tells us whether it worked or not # wait until the queue item tells us whether it worked or not