mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-07 02:23:38 +00:00
Fixes daily search and speed improvements
This commit is contained in:
parent
36bf98fcc5
commit
5ac3895600
7 changed files with 87 additions and 42 deletions
|
@ -50,13 +50,11 @@ class DailySearcher():
|
||||||
|
|
||||||
sql_l = []
|
sql_l = []
|
||||||
show = None
|
show = None
|
||||||
wantedEp = {}
|
|
||||||
|
|
||||||
for sqlEp in sqlResults:
|
for sqlEp in sqlResults:
|
||||||
try:
|
try:
|
||||||
if not show or int(sqlEp["showid"]) != show.indexerid:
|
if not show or int(sqlEp["showid"]) != show.indexerid:
|
||||||
show = helpers.findCertainShow(sickbeard.showList, int(sqlEp["showid"]))
|
show = helpers.findCertainShow(sickbeard.showList, int(sqlEp["showid"]))
|
||||||
wantedEp[show] = []
|
|
||||||
|
|
||||||
except exceptions.MultipleShowObjectsException:
|
except exceptions.MultipleShowObjectsException:
|
||||||
logger.log(u"ERROR: expected to find a single show matching " + sqlEp["showid"])
|
logger.log(u"ERROR: expected to find a single show matching " + sqlEp["showid"])
|
||||||
|
@ -68,7 +66,6 @@ class DailySearcher():
|
||||||
ep.status = common.SKIPPED
|
ep.status = common.SKIPPED
|
||||||
else:
|
else:
|
||||||
ep.status = common.WANTED
|
ep.status = common.WANTED
|
||||||
wantedEp[show].append(ep)
|
|
||||||
|
|
||||||
sql_l.append(ep.get_sql())
|
sql_l.append(ep.get_sql())
|
||||||
else:
|
else:
|
||||||
|
@ -78,9 +75,8 @@ class DailySearcher():
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
myDB.mass_action(sql_l)
|
myDB.mass_action(sql_l)
|
||||||
|
|
||||||
for show, episode in wantedEp.items():
|
# queue episode for daily search
|
||||||
# queue episode for daily search
|
dailysearch_queue_item = sickbeard.search_queue.DailySearchQueueItem()
|
||||||
dailysearch_queue_item = sickbeard.search_queue.DailySearchQueueItem(show, episode)
|
sickbeard.searchQueueScheduler.action.add_item(dailysearch_queue_item)
|
||||||
sickbeard.searchQueueScheduler.action.add_item(dailysearch_queue_item)
|
|
||||||
|
|
||||||
self.amActive = False
|
self.amActive = False
|
|
@ -118,7 +118,7 @@ class DBConnection(object):
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def mass_action(self, querylist, logTransaction=False):
|
def mass_action(self, querylist, logTransaction=False, fetchall=False):
|
||||||
|
|
||||||
with db_lock:
|
with db_lock:
|
||||||
# remove None types
|
# remove None types
|
||||||
|
@ -136,11 +136,11 @@ class DBConnection(object):
|
||||||
if len(qu) == 1:
|
if len(qu) == 1:
|
||||||
if logTransaction:
|
if logTransaction:
|
||||||
logger.log(qu[0], logger.DEBUG)
|
logger.log(qu[0], logger.DEBUG)
|
||||||
sqlResult.append(self.execute(qu[0]))
|
sqlResult.append(self.execute(qu[0], fetchall=fetchall))
|
||||||
elif len(qu) > 1:
|
elif len(qu) > 1:
|
||||||
if logTransaction:
|
if logTransaction:
|
||||||
logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG)
|
logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG)
|
||||||
sqlResult.append(self.execute(qu[0], qu[1]))
|
sqlResult.append(self.execute(qu[0], qu[1], fetchall=fetchall))
|
||||||
|
|
||||||
logger.log(u"Transaction with " + str(len(querylist)) + u" queries executed", logger.DEBUG)
|
logger.log(u"Transaction with " + str(len(querylist)) + u" queries executed", logger.DEBUG)
|
||||||
|
|
||||||
|
|
|
@ -203,13 +203,8 @@ class GenericProvider:
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def searchRSS(self, episode):
|
def searchRSS(self, episodes):
|
||||||
results = {}
|
return self.cache.findNeededEpisodes(episodes)
|
||||||
|
|
||||||
for ep in episode:
|
|
||||||
results.update(self.cache.findNeededEpisodes(ep))
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
def getQuality(self, item, anime=False):
|
def getQuality(self, item, anime=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -41,6 +41,7 @@ from sickbeard import failed_history
|
||||||
from sickbeard.exceptions import ex
|
from sickbeard.exceptions import ex
|
||||||
from sickbeard.providers.generic import GenericProvider
|
from sickbeard.providers.generic import GenericProvider
|
||||||
from sickbeard.blackandwhitelist import BlackAndWhiteList
|
from sickbeard.blackandwhitelist import BlackAndWhiteList
|
||||||
|
from sickbeard import common
|
||||||
|
|
||||||
def _downloadResult(result):
|
def _downloadResult(result):
|
||||||
"""
|
"""
|
||||||
|
@ -319,16 +320,60 @@ def isFirstBestMatch(result):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def searchForNeededEpisodes(show, episode):
|
def wantedEpisodes(show, fromDate):
|
||||||
|
anyQualities, bestQualities = common.Quality.splitQuality(show.quality) # @UnusedVariable
|
||||||
|
allQualities = list(set(anyQualities + bestQualities))
|
||||||
|
|
||||||
|
logger.log(u"Seeing if we need anything from " + show.name)
|
||||||
|
myDB = db.DBConnection()
|
||||||
|
|
||||||
|
if show.air_by_date:
|
||||||
|
sqlResults = myDB.select(
|
||||||
|
"SELECT ep.status, ep.season, ep.episode FROM tv_episodes ep, tv_shows show WHERE season != 0 AND ep.showid = show.indexer_id AND show.paused = 0 AND ep.airdate > ? AND ep.showid = ? AND show.air_by_date = 1",
|
||||||
|
[fromDate.toordinal(), show.indexerid])
|
||||||
|
else:
|
||||||
|
sqlResults = myDB.select(
|
||||||
|
"SELECT status, season, episode FROM tv_episodes WHERE showid = ? AND season > 0 and airdate > ?",
|
||||||
|
[show.indexerid, fromDate.toordinal()])
|
||||||
|
|
||||||
|
# check through the list of statuses to see if we want any
|
||||||
|
wanted = []
|
||||||
|
for result in sqlResults:
|
||||||
|
curCompositeStatus = int(result["status"])
|
||||||
|
curStatus, curQuality = common.Quality.splitCompositeStatus(curCompositeStatus)
|
||||||
|
|
||||||
|
if bestQualities:
|
||||||
|
highestBestQuality = max(allQualities)
|
||||||
|
else:
|
||||||
|
highestBestQuality = 0
|
||||||
|
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
epObj = show.getEpisode(int(result["season"]), int(result["episode"]))
|
||||||
|
epObj.wantedQuality = [i for i in allQualities if (i > curQuality and i != common.Quality.UNKNOWN)]
|
||||||
|
wanted.append(epObj)
|
||||||
|
|
||||||
|
return wanted
|
||||||
|
|
||||||
|
def searchForNeededEpisodes():
|
||||||
foundResults = {}
|
foundResults = {}
|
||||||
|
|
||||||
didSearch = False
|
didSearch = False
|
||||||
|
|
||||||
# build name cache for show
|
|
||||||
sickbeard.name_cache.buildNameCache(show)
|
|
||||||
|
|
||||||
origThreadName = threading.currentThread().name
|
origThreadName = threading.currentThread().name
|
||||||
|
|
||||||
|
show_list = sickbeard.showList
|
||||||
|
fromDate = datetime.date.fromordinal(1)
|
||||||
|
episodes = []
|
||||||
|
|
||||||
|
for curShow in show_list:
|
||||||
|
if curShow.paused:
|
||||||
|
continue
|
||||||
|
|
||||||
|
episodes.extend(wantedEpisodes(curShow, fromDate))
|
||||||
|
|
||||||
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_daily]
|
providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive() and x.enable_daily]
|
||||||
for curProvider in providers:
|
for curProvider in providers:
|
||||||
|
|
||||||
|
@ -336,7 +381,7 @@ def searchForNeededEpisodes(show, episode):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
curProvider.cache.updateCache()
|
curProvider.cache.updateCache()
|
||||||
curFoundResults = curProvider.searchRSS(episode)
|
curFoundResults = curProvider.searchRSS(episodes)
|
||||||
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)
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -116,8 +116,11 @@ class SearchQueue(generic_queue.GenericQueue):
|
||||||
|
|
||||||
|
|
||||||
def add_item(self, item):
|
def add_item(self, item):
|
||||||
if isinstance(item, (DailySearchQueueItem, BacklogQueueItem)) and not self.is_in_queue(item.show, item.segment):
|
if isinstance(item, DailySearchQueueItem):
|
||||||
# daily and backlog searches
|
# daily searches
|
||||||
|
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)
|
generic_queue.GenericQueue.add_item(self, item)
|
||||||
elif isinstance(item, (ManualSearchQueueItem, FailedQueueItem)) and not self.is_ep_in_queue(item.segment):
|
elif isinstance(item, (ManualSearchQueueItem, FailedQueueItem)) and not self.is_ep_in_queue(item.segment):
|
||||||
# manual and failed searches
|
# manual and failed searches
|
||||||
|
@ -126,20 +129,18 @@ class SearchQueue(generic_queue.GenericQueue):
|
||||||
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)
|
||||||
|
|
||||||
class DailySearchQueueItem(generic_queue.QueueItem):
|
class DailySearchQueueItem(generic_queue.QueueItem):
|
||||||
def __init__(self, show, segment):
|
def __init__(self):
|
||||||
generic_queue.QueueItem.__init__(self, 'Daily Search', DAILY_SEARCH)
|
generic_queue.QueueItem.__init__(self, 'Daily Search', DAILY_SEARCH)
|
||||||
self.show = show
|
|
||||||
self.segment = segment
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
generic_queue.QueueItem.run(self)
|
generic_queue.QueueItem.run(self)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.log("Beginning daily search for: [" + self.show.name + "]")
|
logger.log("Beginning daily search for new episodes")
|
||||||
foundResults = search.searchForNeededEpisodes(self.show, self.segment)
|
foundResults = search.searchForNeededEpisodes()
|
||||||
|
|
||||||
if not len(foundResults):
|
if not len(foundResults):
|
||||||
logger.log(u"No needed episodes found during daily search for: [" + self.show.name + "]")
|
logger.log(u"No needed episodes found")
|
||||||
else:
|
else:
|
||||||
for result in foundResults:
|
for result in foundResults:
|
||||||
# just use the first result for now
|
# just use the first result for now
|
||||||
|
|
|
@ -1305,6 +1305,8 @@ class TVEpisode(object):
|
||||||
|
|
||||||
self.checkForMetaFiles()
|
self.checkForMetaFiles()
|
||||||
|
|
||||||
|
self.wantedQuality = []
|
||||||
|
|
||||||
name = property(lambda self: self._name, dirty_setter("_name"))
|
name = property(lambda self: self._name, dirty_setter("_name"))
|
||||||
season = property(lambda self: self._season, dirty_setter("_season"))
|
season = property(lambda self: self._season, dirty_setter("_season"))
|
||||||
episode = property(lambda self: self._episode, dirty_setter("_episode"))
|
episode = property(lambda self: self._episode, dirty_setter("_episode"))
|
||||||
|
|
|
@ -32,6 +32,7 @@ from sickbeard.exceptions import AuthException
|
||||||
from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
from name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
||||||
from sickbeard.rssfeeds import RSSFeeds
|
from sickbeard.rssfeeds import RSSFeeds
|
||||||
from sickbeard import clients
|
from sickbeard import clients
|
||||||
|
import itertools
|
||||||
|
|
||||||
class CacheDBConnection(db.DBConnection):
|
class CacheDBConnection(db.DBConnection):
|
||||||
def __init__(self, providerName):
|
def __init__(self, providerName):
|
||||||
|
@ -279,7 +280,10 @@ class TVCache():
|
||||||
|
|
||||||
def searchCache(self, episode, manualSearch=False):
|
def searchCache(self, episode, manualSearch=False):
|
||||||
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
||||||
return neededEps[episode]
|
if len(neededEps) > 0:
|
||||||
|
return neededEps[episode]
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
def listPropers(self, date=None, delimiter="."):
|
def listPropers(self, date=None, delimiter="."):
|
||||||
myDB = self._getDB()
|
myDB = self._getDB()
|
||||||
|
@ -291,19 +295,24 @@ class TVCache():
|
||||||
return filter(lambda x: x['indexerid'] != 0, myDB.select(sql))
|
return filter(lambda x: x['indexerid'] != 0, myDB.select(sql))
|
||||||
|
|
||||||
|
|
||||||
def findNeededEpisodes(self, episode=None, manualSearch=False):
|
def findNeededEpisodes(self, episode, manualSearch=False):
|
||||||
neededEps = {}
|
neededEps = {}
|
||||||
|
cl = []
|
||||||
if episode:
|
|
||||||
neededEps[episode] = []
|
|
||||||
|
|
||||||
myDB = self._getDB()
|
myDB = self._getDB()
|
||||||
if not episode:
|
if type(episode) != list:
|
||||||
sqlResults = myDB.select("SELECT * FROM [" + self.providerID + "]")
|
|
||||||
else:
|
|
||||||
sqlResults = myDB.select(
|
sqlResults = myDB.select(
|
||||||
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?",
|
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?",
|
||||||
[episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"])
|
[episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"])
|
||||||
|
else:
|
||||||
|
for epObj in episode:
|
||||||
|
cl.append([
|
||||||
|
"SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ? "
|
||||||
|
"AND quality IN (" + ",".join([str(x) for x in epObj.wantedQuality]) + ")",
|
||||||
|
[epObj.show.indexerid, epObj.season, "%|" + str(epObj.episode) + "|%"]])
|
||||||
|
|
||||||
|
sqlResults = myDB.mass_action(cl, fetchall=True)
|
||||||
|
sqlResults = list(itertools.chain(*sqlResults))
|
||||||
|
|
||||||
# for each cache entry
|
# for each cache entry
|
||||||
for curResult in sqlResults:
|
for curResult in sqlResults:
|
||||||
|
@ -341,10 +350,7 @@ class TVCache():
|
||||||
Quality.qualityStrings[curQuality], logger.DEBUG)
|
Quality.qualityStrings[curQuality], logger.DEBUG)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if episode:
|
epObj = showObj.getEpisode(curSeason, curEp)
|
||||||
epObj = episode
|
|
||||||
else:
|
|
||||||
epObj = showObj.getEpisode(curSeason, curEp)
|
|
||||||
|
|
||||||
# build a result object
|
# build a result object
|
||||||
title = curResult["name"]
|
title = curResult["name"]
|
||||||
|
|
Loading…
Reference in a new issue