mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-07 10:33:38 +00:00
Fixes for post-processing issues.
Improvements made to caches for overall performance boost and more accurate matches. Misc bug fixes applied.
This commit is contained in:
parent
9f2a6dad5d
commit
9d191f6999
10 changed files with 215 additions and 187 deletions
|
@ -38,7 +38,7 @@ from sickbeard import searchCurrent, searchBacklog, showUpdater, versionChecker,
|
||||||
from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler, show_name_helpers
|
from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler, show_name_helpers
|
||||||
from sickbeard import logger
|
from sickbeard import logger
|
||||||
from sickbeard import naming
|
from sickbeard import naming
|
||||||
from sickbeard import scene_numbering
|
from sickbeard import scene_numbering, scene_exceptions, name_cache
|
||||||
from indexers.indexer_api import indexerApi
|
from indexers.indexer_api import indexerApi
|
||||||
from indexers.indexer_exceptions import indexer_shownotfound, indexer_exception, indexer_error, indexer_episodenotfound, \
|
from indexers.indexer_exceptions import indexer_shownotfound, indexer_exception, indexer_error, indexer_episodenotfound, \
|
||||||
indexer_attributenotfound, indexer_seasonnotfound, indexer_userabort, indexerExcepts
|
indexer_attributenotfound, indexer_seasonnotfound, indexer_userabort, indexerExcepts
|
||||||
|
|
|
@ -105,9 +105,9 @@ class FailedProcessor(object):
|
||||||
return exception
|
return exception
|
||||||
|
|
||||||
for show_name in show_names:
|
for show_name in show_names:
|
||||||
found_info = helpers.searchDBForShow(show_name)
|
found_info = helpers.get_show_by_name(show_name)
|
||||||
if found_info is not None:
|
if found_info is not None:
|
||||||
return (found_info[1])
|
return (found_info.indexerid)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,13 @@ from sickbeard.common import USER_AGENT, mediaExtensions, subtitleExtensions, XM
|
||||||
from sickbeard import db
|
from sickbeard import db
|
||||||
from sickbeard import encodingKludge as ek
|
from sickbeard import encodingKludge as ek
|
||||||
from sickbeard import notifiers
|
from sickbeard import notifiers
|
||||||
from sickbeard import exceptions
|
|
||||||
from lib import subliminal
|
from lib import subliminal
|
||||||
|
|
||||||
urllib._urlopener = classes.SickBeardURLopener()
|
urllib._urlopener = classes.SickBeardURLopener()
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
|
||||||
|
|
||||||
def indentXML(elem, level=0):
|
def indentXML(elem, level=0):
|
||||||
'''
|
'''
|
||||||
Does our pretty printing, makes Matt very happy
|
Does our pretty printing, makes Matt very happy
|
||||||
|
@ -191,11 +191,13 @@ def getURL(url, post_data=None, headers=None, params=None, timeout=30, json=Fals
|
||||||
proxies = {
|
proxies = {
|
||||||
"http": sickbeard.PROXY_SETTING,
|
"http": sickbeard.PROXY_SETTING,
|
||||||
"https": sickbeard.PROXY_SETTING,
|
"https": sickbeard.PROXY_SETTING,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = session.get(url, params=params, data=post_data, headers=dict(zip(it, it)), proxies=proxies, timeout=timeout, verify=False)
|
r = session.get(url, params=params, data=post_data, headers=dict(zip(it, it)), proxies=proxies,
|
||||||
|
timeout=timeout, verify=False)
|
||||||
else:
|
else:
|
||||||
r = session.get(url, params=params, data=post_data, headers=dict(zip(it, it)), timeout=timeout, verify=False)
|
r = session.get(url, params=params, data=post_data, headers=dict(zip(it, it)), timeout=timeout,
|
||||||
|
verify=False)
|
||||||
except requests.HTTPError, e:
|
except requests.HTTPError, e:
|
||||||
logger.log(u"HTTP error " + str(e.errno) + " while loading URL " + url, logger.WARNING)
|
logger.log(u"HTTP error " + str(e.errno) + " while loading URL " + url, logger.WARNING)
|
||||||
return None
|
return None
|
||||||
|
@ -288,28 +290,14 @@ def searchDBForShow(regShowName):
|
||||||
yearRegex = "([^()]+?)\s*(\()?(\d{4})(?(2)\))$"
|
yearRegex = "([^()]+?)\s*(\()?(\d{4})(?(2)\))$"
|
||||||
|
|
||||||
for showName in showNames:
|
for showName in showNames:
|
||||||
|
# if we didn't get exactly one result then try again with the year stripped off if possible
|
||||||
show = get_show_by_name(showName, sickbeard.showList)
|
match = re.match(yearRegex, showName)
|
||||||
if show:
|
if match and match.group(1):
|
||||||
sqlResults = myDB.select("SELECT * FROM tv_shows WHERE show_name LIKE ? OR show_name LIKE ?",
|
logger.log(u"Unable to match original name but trying to manually strip and specify show year",
|
||||||
[show.name, show.name])
|
logger.DEBUG)
|
||||||
else:
|
sqlResults = myDB.select(
|
||||||
sqlResults = myDB.select("SELECT * FROM tv_shows WHERE show_name LIKE ? OR show_name LIKE ?",
|
"SELECT * FROM tv_shows WHERE (show_name LIKE ? OR show_name LIKE ?) AND startyear = ?",
|
||||||
[showName, showName])
|
[match.group(1) + '%', match.group(1) + '%', match.group(3)])
|
||||||
|
|
||||||
if len(sqlResults) == 1:
|
|
||||||
return (int(sqlResults[0]["indexer"]), int(sqlResults[0]["indexer_id"]), sqlResults[0]["show_name"])
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
# if we didn't get exactly one result then try again with the year stripped off if possible
|
|
||||||
match = re.match(yearRegex, showName)
|
|
||||||
if match and match.group(1):
|
|
||||||
logger.log(u"Unable to match original name but trying to manually strip and specify show year",
|
|
||||||
logger.DEBUG)
|
|
||||||
sqlResults = myDB.select(
|
|
||||||
"SELECT * FROM tv_shows WHERE (show_name LIKE ? OR show_name LIKE ?) AND startyear = ?",
|
|
||||||
[match.group(1) + '%', match.group(1) + '%', match.group(3)])
|
|
||||||
|
|
||||||
if len(sqlResults) == 0:
|
if len(sqlResults) == 0:
|
||||||
logger.log(u"Unable to match a record in the DB for " + showName, logger.DEBUG)
|
logger.log(u"Unable to match a record in the DB for " + showName, logger.DEBUG)
|
||||||
|
@ -320,9 +308,6 @@ def searchDBForShow(regShowName):
|
||||||
else:
|
else:
|
||||||
return (int(sqlResults[0]["indexer"]), int(sqlResults[0]["indexer_id"]), sqlResults[0]["show_name"])
|
return (int(sqlResults[0]["indexer"]), int(sqlResults[0]["indexer_id"]), sqlResults[0]["show_name"])
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
|
def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
|
||||||
showNames = list(set([re.sub('[. -]', ' ', regShowName), regShowName]))
|
showNames = list(set([re.sub('[. -]', ' ', regShowName), regShowName]))
|
||||||
|
|
||||||
|
@ -330,7 +315,7 @@ def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
|
||||||
for indexer in sickbeard.indexerApi().indexers if not indexer else [int(indexer)]:
|
for indexer in sickbeard.indexerApi().indexers if not indexer else [int(indexer)]:
|
||||||
# Query Indexers for each search term and build the list of results
|
# Query Indexers for each search term and build the list of results
|
||||||
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
||||||
if ui:lINDEXER_API_PARMS['custom_ui'] = ui
|
if ui: lINDEXER_API_PARMS['custom_ui'] = ui
|
||||||
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
|
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
|
||||||
|
|
||||||
for name in showNames:
|
for name in showNames:
|
||||||
|
@ -354,6 +339,7 @@ def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
def sizeof_fmt(num):
|
def sizeof_fmt(num):
|
||||||
'''
|
'''
|
||||||
>>> sizeof_fmt(2)
|
>>> sizeof_fmt(2)
|
||||||
|
@ -430,11 +416,13 @@ def symlink(src, dst):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
if ctypes.windll.kernel32.CreateSymbolicLinkW(unicode(dst), unicode(src), 1 if os.path.isdir(src) else 0) in [0,1280]:
|
if ctypes.windll.kernel32.CreateSymbolicLinkW(unicode(dst), unicode(src), 1 if os.path.isdir(src) else 0) in [0,
|
||||||
|
1280]:
|
||||||
raise ctypes.WinError()
|
raise ctypes.WinError()
|
||||||
else:
|
else:
|
||||||
os.symlink(src, dst)
|
os.symlink(src, dst)
|
||||||
|
|
||||||
|
|
||||||
def moveAndSymlinkFile(srcFile, destFile):
|
def moveAndSymlinkFile(srcFile, destFile):
|
||||||
try:
|
try:
|
||||||
ek.ek(os.rename, srcFile, destFile)
|
ek.ek(os.rename, srcFile, destFile)
|
||||||
|
@ -652,7 +640,7 @@ def fixSetGroupID(childPath):
|
||||||
except OSError:
|
except OSError:
|
||||||
logger.log(
|
logger.log(
|
||||||
u"Failed to respect the set-group-ID bit on the parent directory for %s (setting group ID %i)" % (
|
u"Failed to respect the set-group-ID bit on the parent directory for %s (setting group ID %i)" % (
|
||||||
childPath, parentGID), logger.ERROR)
|
childPath, parentGID), logger.ERROR)
|
||||||
|
|
||||||
|
|
||||||
def sanitizeSceneName(name, ezrss=False):
|
def sanitizeSceneName(name, ezrss=False):
|
||||||
|
@ -944,21 +932,58 @@ def _check_against_names(name, show):
|
||||||
|
|
||||||
for showName in showNames:
|
for showName in showNames:
|
||||||
nameFromList = full_sanitizeSceneName(showName)
|
nameFromList = full_sanitizeSceneName(showName)
|
||||||
#logger.log(u"Comparing names: '"+nameFromList+"' vs '"+nameInQuestion+"'", logger.DEBUG)
|
|
||||||
if nameFromList == nameInQuestion:
|
if nameFromList == nameInQuestion:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_show_by_name(name, showList, useIndexer=False):
|
def get_show_by_name(name, useIndexer=False):
|
||||||
if showList:
|
in_cache = False
|
||||||
for show in showList:
|
foundResult = None
|
||||||
if _check_against_names(name, show):
|
|
||||||
logger.log(u"Matched " + name + " in the showlist to the show " + show.name, logger.DEBUG)
|
logger.log(
|
||||||
return show
|
u"Checking the cahe for:" + str(name),
|
||||||
|
logger.DEBUG)
|
||||||
|
|
||||||
|
cacheResult = sickbeard.name_cache.retrieveNameFromCache(name)
|
||||||
|
if cacheResult:
|
||||||
|
in_cache = True
|
||||||
|
foundResult = findCertainShow(sickbeard.showList, cacheResult)
|
||||||
|
logger.log(
|
||||||
|
u"Cache lookup found Indexer ID:" + repr(
|
||||||
|
foundResult.indexerid) + ", using that for " + name,
|
||||||
|
logger.DEBUG)
|
||||||
|
|
||||||
|
if not foundResult:
|
||||||
|
logger.log(
|
||||||
|
u"Checking the showlist for:" + str(name),
|
||||||
|
logger.DEBUG)
|
||||||
|
|
||||||
|
for show in sickbeard.showList:
|
||||||
|
if _check_against_names(name, show):
|
||||||
|
logger.log(
|
||||||
|
u"Showlist lookup found Indexer ID:" + str(show.indexerid) + ", using that for " + name,
|
||||||
|
logger.DEBUG)
|
||||||
|
foundResult = show
|
||||||
|
|
||||||
|
if not foundResult:
|
||||||
|
logger.log(
|
||||||
|
u"Checking the database for show:" + str(name),
|
||||||
|
logger.DEBUG)
|
||||||
|
|
||||||
|
dbResult = searchDBForShow(name)
|
||||||
|
if dbResult:
|
||||||
|
foundResult = findCertainShow(sickbeard.showList, dbResult[1])
|
||||||
|
logger.log(
|
||||||
|
u"Database lookup found Indexer ID:" + str(
|
||||||
|
foundResult.indexerid) + ", using that for " + name, logger.DEBUG)
|
||||||
|
|
||||||
|
if not foundResult and useIndexer:
|
||||||
|
logger.log(
|
||||||
|
u"Checking the Indexers for:" + str(name),
|
||||||
|
logger.DEBUG)
|
||||||
|
|
||||||
if useIndexer:
|
|
||||||
for indexer in sickbeard.indexerApi().indexers:
|
for indexer in sickbeard.indexerApi().indexers:
|
||||||
try:
|
try:
|
||||||
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
|
||||||
|
@ -967,14 +992,21 @@ def get_show_by_name(name, showList, useIndexer=False):
|
||||||
|
|
||||||
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
|
t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
|
||||||
showObj = t[name]
|
showObj = t[name]
|
||||||
except:continue
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
if showObj:
|
if showObj:
|
||||||
showResult = findCertainShow(sickbeard.showList, int(showObj["id"]))
|
foundResult = findCertainShow(sickbeard.showList, int(showObj["id"]))
|
||||||
if showResult is not None:
|
if foundResult:
|
||||||
return showResult
|
logger.log(
|
||||||
|
u"Indexer lookup found Indexer ID:" + str(
|
||||||
|
foundResult.indexerid) + ", using that for " + name, logger.DEBUG)
|
||||||
|
|
||||||
return None
|
# 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)
|
||||||
|
|
||||||
|
return foundResult
|
||||||
|
|
||||||
def is_hidden_folder(folder):
|
def is_hidden_folder(folder):
|
||||||
"""
|
"""
|
||||||
|
@ -995,6 +1027,7 @@ def real_path(path):
|
||||||
"""
|
"""
|
||||||
return ek.ek(os.path.normpath, ek.ek(os.path.normcase, ek.ek(os.path.realpath, path)))
|
return ek.ek(os.path.normpath, ek.ek(os.path.normcase, ek.ek(os.path.realpath, path)))
|
||||||
|
|
||||||
|
|
||||||
def validateShow(show, season=None, episode=None):
|
def validateShow(show, season=None, episode=None):
|
||||||
indexer_lang = show.lang
|
indexer_lang = show.lang
|
||||||
|
|
||||||
|
|
|
@ -21,21 +21,21 @@ import os.path
|
||||||
import re
|
import re
|
||||||
import regexes
|
import regexes
|
||||||
import sickbeard
|
import sickbeard
|
||||||
import calendar
|
|
||||||
|
|
||||||
from sickbeard import logger, helpers, scene_numbering
|
from sickbeard import logger, helpers, scene_numbering
|
||||||
|
from dateutil import parser
|
||||||
|
|
||||||
class NameParser(object):
|
class NameParser(object):
|
||||||
ALL_REGEX = 0
|
ALL_REGEX = 0
|
||||||
NORMAL_REGEX = 1
|
NORMAL_REGEX = 1
|
||||||
SPORTS_REGEX = 2
|
SPORTS_REGEX = 2
|
||||||
|
|
||||||
def __init__(self, file_name=True, regexMode=0):
|
def __init__(self, file_name=True, regexMode=1):
|
||||||
|
|
||||||
self.file_name = file_name
|
self.file_name = file_name
|
||||||
self.regexMode = regexMode
|
self.regexMode = regexMode
|
||||||
self.compiled_regexes = []
|
self.compiled_regexes = []
|
||||||
self._compile_regexes(regexMode)
|
self._compile_regexes(self.regexMode)
|
||||||
|
|
||||||
def clean_series_name(self, series_name):
|
def clean_series_name(self, series_name):
|
||||||
"""Cleans up series name by removing any . and _
|
"""Cleans up series name by removing any . and _
|
||||||
|
@ -125,6 +125,14 @@ class NameParser(object):
|
||||||
else:
|
else:
|
||||||
result.episode_numbers = [ep_num]
|
result.episode_numbers = [ep_num]
|
||||||
|
|
||||||
|
if 'sports_event_date' in named_groups:
|
||||||
|
sports_event_date = match.group('sports_event_date')
|
||||||
|
if sports_event_date:
|
||||||
|
try:
|
||||||
|
result.sports_event_date = parser.parse(sports_event_date, fuzzy=True).date()
|
||||||
|
except ValueError, e:
|
||||||
|
raise InvalidNameException(e.message)
|
||||||
|
|
||||||
if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
|
if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
|
||||||
year = int(match.group('air_year'))
|
year = int(match.group('air_year'))
|
||||||
month = int(match.group('air_month'))
|
month = int(match.group('air_month'))
|
||||||
|
@ -232,6 +240,7 @@ class NameParser(object):
|
||||||
|
|
||||||
# sports event title
|
# sports event title
|
||||||
final_result.sports_event_title = self._combine_results(file_name_result, dir_name_result, 'sports_event_title')
|
final_result.sports_event_title = self._combine_results(file_name_result, dir_name_result, 'sports_event_title')
|
||||||
|
final_result.sports_event_date = self._combine_results(file_name_result, dir_name_result, 'sports_event_date')
|
||||||
|
|
||||||
if not final_result.air_date:
|
if not final_result.air_date:
|
||||||
final_result.season_number = self._combine_results(file_name_result, dir_name_result, 'season_number')
|
final_result.season_number = self._combine_results(file_name_result, dir_name_result, 'season_number')
|
||||||
|
@ -265,6 +274,7 @@ class ParseResult(object):
|
||||||
original_name,
|
original_name,
|
||||||
series_name=None,
|
series_name=None,
|
||||||
sports_event_title=None,
|
sports_event_title=None,
|
||||||
|
sports_event_date=None,
|
||||||
season_number=None,
|
season_number=None,
|
||||||
episode_numbers=None,
|
episode_numbers=None,
|
||||||
extra_info=None,
|
extra_info=None,
|
||||||
|
@ -287,6 +297,7 @@ class ParseResult(object):
|
||||||
self.air_date = air_date
|
self.air_date = air_date
|
||||||
|
|
||||||
self.sports_event_title = sports_event_title
|
self.sports_event_title = sports_event_title
|
||||||
|
self.sports_event_date = sports_event_date
|
||||||
|
|
||||||
self.which_regex = None
|
self.which_regex = None
|
||||||
|
|
||||||
|
@ -308,6 +319,8 @@ class ParseResult(object):
|
||||||
return False
|
return False
|
||||||
if self.sports_event_title != other.sports_event_title:
|
if self.sports_event_title != other.sports_event_title:
|
||||||
return False
|
return False
|
||||||
|
if self.sports_event_date != other.sports_event_date:
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -326,6 +339,7 @@ class ParseResult(object):
|
||||||
to_return += str(self.air_date)
|
to_return += str(self.air_date)
|
||||||
if self.sports:
|
if self.sports:
|
||||||
to_return += str(self.sports_event_title)
|
to_return += str(self.sports_event_title)
|
||||||
|
to_return += str(self.sports_event_date)
|
||||||
|
|
||||||
if self.extra_info:
|
if self.extra_info:
|
||||||
to_return += ' - ' + self.extra_info
|
to_return += ' - ' + self.extra_info
|
||||||
|
@ -344,12 +358,12 @@ class ParseResult(object):
|
||||||
if len(self.episode_numbers) == 0: return self # need at least one episode
|
if len(self.episode_numbers) == 0: return self # need at least one episode
|
||||||
|
|
||||||
# convert scene numbered releases before storing to cache
|
# convert scene numbered releases before storing to cache
|
||||||
indexer_id = helpers.searchDBForShow(self.series_name)
|
showObj = helpers.get_show_by_name(self.series_name)
|
||||||
if indexer_id:
|
if showObj:
|
||||||
new_episode_numbers = []
|
new_episode_numbers = []
|
||||||
new_season_numbers = []
|
new_season_numbers = []
|
||||||
for epNo in self.episode_numbers:
|
for epNo in self.episode_numbers:
|
||||||
(s, e) = scene_numbering.get_indexer_numbering(indexer_id, self.season_number, epNo)
|
(s, e) = scene_numbering.get_indexer_numbering(showObj.indexerid, self.season_number, epNo)
|
||||||
new_episode_numbers.append(e)
|
new_episode_numbers.append(e)
|
||||||
new_season_numbers.append(s)
|
new_season_numbers.append(s)
|
||||||
|
|
||||||
|
@ -380,7 +394,7 @@ class ParseResult(object):
|
||||||
air_by_date = property(_is_air_by_date)
|
air_by_date = property(_is_air_by_date)
|
||||||
|
|
||||||
def _is_sports(self):
|
def _is_sports(self):
|
||||||
if self.sports_event_title:
|
if self.sports_event_title or self.sports_event_date:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
sports = property(_is_sports)
|
sports = property(_is_sports)
|
||||||
|
|
|
@ -187,14 +187,15 @@ ep_regexes = [
|
||||||
]
|
]
|
||||||
|
|
||||||
sports_regexs = [
|
sports_regexs = [
|
||||||
('sports_event_mma',
|
|
||||||
# Show.Name.123.Event.23rd.Nov.2010.Source.Quality.Etc-Group
|
('sports_standard',
|
||||||
'''
|
# Sports.Name.2010.11.23.Source.Quality.Etc-Group
|
||||||
^(?P<series_name>.+?)[. _-]+
|
# Sports.Name.23rd.Nov.2010.Source.Quality.Etc-Group
|
||||||
(?P<sports_event_title>\d{3}.+[. _-]vs[. _-].+?)[. _-]+
|
'''
|
||||||
((?![. _-]+\d{2})(.*?)(?:\d{4}[. _-]+))?
|
^(?P<series_name>.+?)[. _-]+
|
||||||
([. _-]*(?P<extra_info>.+?)((?<![. _-])
|
(?P<sports_event_date>(\d{4}[. _-]+\d{2}[. _-]+\d{2})|(\d{2}\w{2}[. _-]+\w+[. _-]+\d{4}))
|
||||||
(?<!WEB)-(?P<release_group>[^- ]+))?)?$
|
[. _-]*((?P<extra_info>.+?)((?<![. _-])(?<!WEB)
|
||||||
'''
|
-(?P<release_group>[^- ]+))?)?$
|
||||||
|
'''
|
||||||
),
|
),
|
||||||
]
|
]
|
|
@ -506,43 +506,10 @@ class PostProcessor(object):
|
||||||
|
|
||||||
# for each possible interpretation of that scene name
|
# for each possible interpretation of that scene name
|
||||||
for cur_name in name_list:
|
for cur_name in name_list:
|
||||||
self._log(u"Checking cache for " + cur_name, logger.DEBUG)
|
showObj = helpers.get_show_by_name(parse_result.series_name)
|
||||||
cache_id = name_cache.retrieveNameFromCache(parse_result.series_name)
|
if showObj:
|
||||||
if cache_id:
|
|
||||||
self._log(u"Cache lookup got a Indexer ID " + str(cache_id) + ", using that", logger.DEBUG)
|
|
||||||
_finalize(parse_result)
|
_finalize(parse_result)
|
||||||
return (cache_id, season, episodes)
|
return (showObj.indexerid, season, episodes)
|
||||||
|
|
||||||
# for each possible interpretation of that scene name
|
|
||||||
for cur_name in name_list:
|
|
||||||
self._log(u"Checking scene exceptions for a match on " + cur_name, logger.DEBUG)
|
|
||||||
scene_id = scene_exceptions.get_scene_exception_by_name(cur_name)
|
|
||||||
if scene_id:
|
|
||||||
self._log(u"Scene exception lookup got a Indexer ID " + str(scene_id) + ", using that", logger.DEBUG)
|
|
||||||
_finalize(parse_result)
|
|
||||||
return (scene_id, season, episodes)
|
|
||||||
|
|
||||||
# see if we can find the name directly in the DB, if so use it
|
|
||||||
for cur_name in name_list:
|
|
||||||
self._log(u"Looking up " + cur_name + u" in the DB", logger.DEBUG)
|
|
||||||
db_result = helpers.searchDBForShow(cur_name)
|
|
||||||
if db_result:
|
|
||||||
self._log(u"Lookup successful, using " + sickbeard.indexerApi(db_result[0]).name + " id " + str(
|
|
||||||
db_result[1]),
|
|
||||||
logger.DEBUG)
|
|
||||||
_finalize(parse_result)
|
|
||||||
return (int(db_result[1]), season, episodes)
|
|
||||||
|
|
||||||
# see if we can find the name on the Indexer
|
|
||||||
for cur_name in name_list:
|
|
||||||
foundInfo = helpers.searchIndexerForShowID(cur_name, ui=classes.ShowListUI)
|
|
||||||
if foundInfo:
|
|
||||||
indexer_id = foundInfo[1]
|
|
||||||
self._log(
|
|
||||||
u"Lookup successful, using " + sickbeard.indexerApi(self.indexer).name + " id " + str(indexer_id),
|
|
||||||
logger.DEBUG)
|
|
||||||
_finalize(parse_result)
|
|
||||||
return (indexer_id, season, episodes)
|
|
||||||
|
|
||||||
_finalize(parse_result)
|
_finalize(parse_result)
|
||||||
return to_return
|
return to_return
|
||||||
|
|
|
@ -59,9 +59,11 @@ class EZRSSProvider(generic.TorrentProvider):
|
||||||
|
|
||||||
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
def getSearchResults(self, show, season, ep_objs, seasonSearch=False, manualSearch=False):
|
||||||
|
|
||||||
|
self.show = show
|
||||||
|
|
||||||
results = {}
|
results = {}
|
||||||
|
|
||||||
if self.show.air_by_date or self.show.sports:
|
if show.air_by_date or show.sports:
|
||||||
logger.log(self.name + u" doesn't support air-by-date or sports backloging because of limitations on their RSS search.",
|
logger.log(self.name + u" doesn't support air-by-date or sports backloging because of limitations on their RSS search.",
|
||||||
logger.WARNING)
|
logger.WARNING)
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -38,6 +38,7 @@ from lib.hachoir_parser import createParser
|
||||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException
|
from sickbeard.name_parser.parser import NameParser, InvalidNameException
|
||||||
from sickbeard.common import Quality
|
from sickbeard.common import Quality
|
||||||
|
|
||||||
|
|
||||||
class GenericProvider:
|
class GenericProvider:
|
||||||
NZB = "nzb"
|
NZB = "nzb"
|
||||||
TORRENT = "torrent"
|
TORRENT = "torrent"
|
||||||
|
@ -56,7 +57,8 @@ class GenericProvider:
|
||||||
|
|
||||||
self.session = requests.session()
|
self.session = requests.session()
|
||||||
self.session.verify = False
|
self.session.verify = False
|
||||||
self.session.headers.update({'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36'})
|
self.session.headers.update({
|
||||||
|
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36'})
|
||||||
|
|
||||||
|
|
||||||
def getID(self):
|
def getID(self):
|
||||||
|
@ -132,7 +134,8 @@ class GenericProvider:
|
||||||
logger.log(u"Error loading " + self.name + " URL: " + url, logger.ERROR)
|
logger.log(u"Error loading " + self.name + " URL: " + url, logger.ERROR)
|
||||||
return None
|
return None
|
||||||
elif 'error' in f.feed:
|
elif 'error' in f.feed:
|
||||||
logger.log(u"Newznab ERROR:[%s] CODE:[%s]" % (f.feed['error']['description'], f.feed['error']['code']), logger.DEBUG)
|
logger.log(u"Newznab ERROR:[%s] CODE:[%s]" % (f.feed['error']['description'], f.feed['error']['code']),
|
||||||
|
logger.DEBUG)
|
||||||
return None
|
return None
|
||||||
elif not f.entries:
|
elif not f.entries:
|
||||||
logger.log(u"No items found on " + self.name + " using URL: " + url, logger.WARNING)
|
logger.log(u"No items found on " + self.name + " using URL: " + url, logger.WARNING)
|
||||||
|
@ -253,7 +256,7 @@ class GenericProvider:
|
||||||
self.show = show
|
self.show = show
|
||||||
|
|
||||||
regexMode = 0
|
regexMode = 0
|
||||||
if show.sports:
|
if self.show.sports:
|
||||||
regexMode = 2
|
regexMode = 2
|
||||||
|
|
||||||
for ep_obj in ep_objs:
|
for ep_obj in ep_objs:
|
||||||
|
@ -280,7 +283,7 @@ class GenericProvider:
|
||||||
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
|
logger.log(u"Unable to parse the filename " + title + " into a valid episode", logger.WARNING)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not show.air_by_date:
|
if not (self.show.air_by_date, self.show.sports):
|
||||||
# this check is meaningless for non-season searches
|
# this check is meaningless for non-season searches
|
||||||
if (parse_result.season_number is not None and parse_result.season_number != season) or (
|
if (parse_result.season_number is not None and parse_result.season_number != season) or (
|
||||||
parse_result.season_number is None and season != 1):
|
parse_result.season_number is None and season != 1):
|
||||||
|
@ -293,16 +296,27 @@ class GenericProvider:
|
||||||
actual_episodes = parse_result.episode_numbers
|
actual_episodes = parse_result.episode_numbers
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if show.air_by_date and not parse_result.air_by_date:
|
if self.show.air_by_date and not parse_result.air_by_date:
|
||||||
logger.log(
|
logger.log(
|
||||||
u"This is supposed to be an air-by-date search but the result " + title + " didn't parse as one, skipping it",
|
u"This is supposed to be an air-by-date search but the result " + title + " didn't parse as one, skipping it",
|
||||||
logger.DEBUG)
|
logger.DEBUG)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if self.show.sports and not parse_result.sports_event_date:
|
||||||
|
logger.log(
|
||||||
|
u"This is supposed to be an sports-event-date search but the result " + title + " didn't parse as one, skipping it",
|
||||||
|
logger.DEBUG)
|
||||||
|
continue
|
||||||
|
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
if parse_result.air_by_date:
|
if parse_result.air_by_date:
|
||||||
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
sql_results = myDB.select(
|
||||||
[show.indexerid, parse_result.air_date.toordinal()])
|
"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:
|
if len(sql_results) != 1:
|
||||||
logger.log(
|
logger.log(
|
||||||
|
@ -316,8 +330,8 @@ class GenericProvider:
|
||||||
# make sure we want the episode
|
# make sure we want the episode
|
||||||
wantEp = True
|
wantEp = True
|
||||||
for epNo in actual_episodes:
|
for epNo in actual_episodes:
|
||||||
epObj = show.getEpisode(actual_season, epNo)
|
epObj = self.show.getEpisode(actual_season, epNo)
|
||||||
if not epObj or not show.wantEpisode(epObj.season, epObj.episode, quality, manualSearch=manualSearch):
|
if not epObj or not self.show.wantEpisode(epObj.season, epObj.episode, quality, manualSearch=manualSearch):
|
||||||
wantEp = False
|
wantEp = False
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -351,13 +365,13 @@ class GenericProvider:
|
||||||
parse_result.episode_numbers), logger.DEBUG)
|
parse_result.episode_numbers), logger.DEBUG)
|
||||||
elif len(epObjs) == 0:
|
elif len(epObjs) == 0:
|
||||||
epNum = SEASON_RESULT
|
epNum = SEASON_RESULT
|
||||||
result.extraInfo = [show]
|
result.extraInfo = [self.show]
|
||||||
logger.log(u"Separating full season result to check for later", logger.DEBUG)
|
logger.log(u"Separating full season result to check for later", logger.DEBUG)
|
||||||
|
|
||||||
if epNum in results:
|
if epNum in results:
|
||||||
results[epNum].append(result)
|
results[epNum].append(result)
|
||||||
else:
|
else:
|
||||||
results = {epNum:[result]}
|
results = {epNum: [result]}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
|
@ -193,92 +193,67 @@ class TVCache():
|
||||||
def _addCacheEntry(self, name, url, quality=None):
|
def _addCacheEntry(self, name, url, quality=None):
|
||||||
|
|
||||||
cacheDB = self._getDB()
|
cacheDB = self._getDB()
|
||||||
parse_result = None
|
|
||||||
indexer_id = None
|
|
||||||
season = None
|
season = None
|
||||||
episodes = None
|
episodes = None
|
||||||
from_cache = False
|
|
||||||
|
|
||||||
# if we don't have complete info then parse the filename to get it
|
# if we don't have complete info then parse the filename to get it
|
||||||
while(True):
|
try:
|
||||||
try:
|
myParser = NameParser()
|
||||||
myParser = NameParser()
|
parse_result = myParser.parse(name).convert()
|
||||||
parse_result = myParser.parse(name).convert()
|
except InvalidNameException:
|
||||||
except InvalidNameException:
|
logger.log(u"Unable to parse the filename " + name + " into a valid episode", logger.DEBUG)
|
||||||
logger.log(u"Unable to parse the filename " + name + " into a valid episode", logger.DEBUG)
|
return None
|
||||||
|
|
||||||
|
if not parse_result:
|
||||||
|
logger.log(u"Giving up because I'm unable to parse this name: " + name, logger.DEBUG)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not parse_result.series_name:
|
||||||
|
logger.log(u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG)
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
showObj = helpers.get_show_by_name(parse_result.series_name)
|
||||||
|
if showObj is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not parse_result:
|
myDB = db.DBConnection()
|
||||||
logger.log(u"Giving up because I'm unable to parse this name: " + name, logger.DEBUG)
|
if showObj.air_by_date:
|
||||||
return None
|
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||||
|
[showObj.indexerid, parse_result.air_date.toordinal()])
|
||||||
|
if sql_results > 0:
|
||||||
|
season = int(sql_results[0]["season"])
|
||||||
|
episodes = [int(sql_results[0]["episode"])]
|
||||||
|
elif showObj.sports:
|
||||||
|
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||||
|
[showObj.indexerid, parse_result.sports_event_date.toordinal()])
|
||||||
|
|
||||||
if not parse_result.series_name:
|
if sql_results > 0:
|
||||||
logger.log(u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG)
|
season = int(sql_results[0]["season"])
|
||||||
return None
|
episodes = [int(sql_results[0]["episode"])]
|
||||||
|
else:
|
||||||
|
season = parse_result.season_number
|
||||||
|
episodes = parse_result.episode_numbers
|
||||||
|
|
||||||
logger.log(
|
if season and episodes:
|
||||||
u"Checking the cache for show:" + str(parse_result.series_name),
|
# store episodes as a seperated string
|
||||||
logger.DEBUG)
|
episodeText = "|" + "|".join(map(str, episodes)) + "|"
|
||||||
|
|
||||||
# remember if the cache lookup worked or not so we know whether we should bother updating it later
|
# get the current timestamp
|
||||||
cache_id = name_cache.retrieveNameFromCache(parse_result.series_name)
|
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
|
||||||
if cache_id:
|
|
||||||
logger.log(u"Cache lookup found Indexer ID:" + repr(indexer_id) + ", using that for " + parse_result.series_name, logger.DEBUG)
|
|
||||||
from_cache = True
|
|
||||||
indexer_id = cache_id
|
|
||||||
break
|
|
||||||
|
|
||||||
# if the cache failed, try looking up the show name in the database
|
# get quality of release
|
||||||
logger.log(
|
if quality is None:
|
||||||
u"Checking the database for show:" + str(parse_result.series_name),
|
quality = Quality.sceneQuality(name)
|
||||||
logger.DEBUG)
|
|
||||||
|
|
||||||
showResult = helpers.searchDBForShow(parse_result.series_name)
|
if not isinstance(name, unicode):
|
||||||
if showResult:
|
name = unicode(name, 'utf-8')
|
||||||
logger.log(
|
|
||||||
u"Database lookup found Indexer ID:" + str(showResult[1]) + ", using that for " + parse_result.series_name, logger.DEBUG)
|
|
||||||
indexer_id = showResult[1]
|
|
||||||
break
|
|
||||||
|
|
||||||
# if we didn't find a Indexer ID return None
|
cacheDB.action(
|
||||||
if indexer_id:
|
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
|
||||||
# add to name cache if we didn't get it from the cache
|
[name, season, episodeText, showObj.indexerid, url, curTimestamp, quality])
|
||||||
if not from_cache:
|
except:
|
||||||
name_cache.addNameToCache(parse_result.series_name, indexer_id)
|
return
|
||||||
|
|
||||||
# if the show isn't in out database then return None
|
|
||||||
try:
|
|
||||||
showObj = helpers.findCertainShow(sickbeard.showList, indexer_id)
|
|
||||||
myDB = db.DBConnection()
|
|
||||||
if parse_result.air_by_date:
|
|
||||||
sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
|
||||||
[showObj.indexerid, parse_result.air_date.toordinal()])
|
|
||||||
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)) + "|"
|
|
||||||
|
|
||||||
# get the current timestamp
|
|
||||||
curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))
|
|
||||||
|
|
||||||
# get quality of release
|
|
||||||
if quality is None:
|
|
||||||
quality = Quality.sceneQuality(name)
|
|
||||||
|
|
||||||
if not isinstance(name, unicode):
|
|
||||||
name = unicode(name, 'utf-8')
|
|
||||||
|
|
||||||
cacheDB.action(
|
|
||||||
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
|
|
||||||
[name, season, episodeText, indexer_id, url, curTimestamp, quality])
|
|
||||||
except:
|
|
||||||
return
|
|
||||||
|
|
||||||
def searchCache(self, episode, manualSearch=False):
|
def searchCache(self, episode, manualSearch=False):
|
||||||
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
neededEps = self.findNeededEpisodes(episode, manualSearch)
|
||||||
|
|
|
@ -28,7 +28,7 @@ sys.path.append(os.path.abspath('../lib'))
|
||||||
|
|
||||||
import test_lib as test
|
import test_lib as test
|
||||||
import sickbeard
|
import sickbeard
|
||||||
from sickbeard.helpers import sanitizeSceneName
|
from sickbeard.helpers import get_show_by_name
|
||||||
from sickbeard.tv import TVShow
|
from sickbeard.tv import TVShow
|
||||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException
|
from sickbeard.name_parser.parser import NameParser, InvalidNameException
|
||||||
|
|
||||||
|
@ -65,6 +65,28 @@ class XEMBasicTests(test.SickbeardTestDBCase):
|
||||||
print scene_parsse_results1
|
print scene_parsse_results1
|
||||||
print scene_parsse_results2
|
print scene_parsse_results2
|
||||||
|
|
||||||
|
sports_release = 'UFC.168.Weidman.vs.Silva.II.28th.Dec.2013.HDTV.x264-Sir.Paul'
|
||||||
|
try:
|
||||||
|
myParser = NameParser(False, 2)
|
||||||
|
parse_result = myParser.parse(sports_release)
|
||||||
|
|
||||||
|
test = sickbeard.show_name_helpers.allPossibleShowNames(parse_result.series_name)
|
||||||
|
show = get_show_by_name(parse_result.series_name)
|
||||||
|
if show:
|
||||||
|
sql_results = test.db.DBConnection().select(
|
||||||
|
"SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
|
||||||
|
[show.indexerid, parse_result.sports_event_date.toordinal()])
|
||||||
|
|
||||||
|
actual_season = int(sql_results[0]["season"])
|
||||||
|
actual_episodes = [int(sql_results[0]["episode"])]
|
||||||
|
|
||||||
|
print actual_season
|
||||||
|
print actual_episodes
|
||||||
|
except InvalidNameException:
|
||||||
|
print(u"Unable to parse the filename " + scene_release + " into a valid episode")
|
||||||
|
|
||||||
|
print scene_parsse_results1
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print "=================="
|
print "=================="
|
||||||
print "STARTING - XEM Scene Numbering TESTS"
|
print "STARTING - XEM Scene Numbering TESTS"
|
||||||
|
|
Loading…
Reference in a new issue