def _test_sceneToNormalShowNames(self, name, expected): result = sceneHelpers.sceneToNormalShowNames(name) self.assertTrue(len(set(expected).intersection(set(result))) == len(expected)) dot_result = sceneHelpers.sceneToNormalShowNames(name.replace(' ','.')) dot_expected = [x.replace(' ','.') for x in expected] self.assertTrue(len(set(dot_expected).intersection(set(dot_result))) == len(dot_expected))
def _test_sceneToNormalShowNames(self, name, expected): result = sceneHelpers.sceneToNormalShowNames(name) self.assertTrue( len(set(expected).intersection(set(result))) == len(expected)) dot_result = sceneHelpers.sceneToNormalShowNames(name.replace( ' ', '.')) dot_expected = [x.replace(' ', '.') for x in expected] self.assertTrue( len(set(dot_expected).intersection(set(dot_result))) == len( dot_expected))
def processFile(fileName, downloadDir=None, nzbName=None, multi_file=False): returnStr = '' folderName = None if downloadDir != None: folderName = downloadDir.split(os.path.sep)[-1] returnStr += logHelper(u"Processing file "+fileName+" (with folder name "+str(folderName)+" and NZB name "+str(nzbName)+")", logger.DEBUG) finalNameList = [] for curName in (fileName, folderName, nzbName): if curName != None: for curSceneName in sceneHelpers.sceneToNormalShowNames(curName): if curSceneName not in finalNameList: finalNameList.append(curSceneName) showResults = None result = None tvdb_id = None season = None episodes = [] # first try looking up every name in our history for curName in finalNameList: historyResult = findInHistory(curName) if historyResult: returnStr += logHelper(u"Result from history: "+str(historyResult)+" from "+curName, logger.DEBUG) (tvdb_id, season, episodes) = historyResult showResults = helpers.findCertainShow(sickbeard.showList, tvdb_id) break # if we're parsing a multi-file folder then the folder name doesn't reflect the correct episode so ignore it if multi_file and episodes: returnStr += logHelper(u"Multi-file dir "+downloadDir+" doesn't reflect all episode names, only using name & season", logger.DEBUG) episodes = [] # if that didn't work then try manually parsing and searching them on TVDB for curName in finalNameList: # if we already have the info from the history then don't bother with this if tvdb_id != None and season != None and episodes != []: break # if we're doing a multi-file dir and we already got the tvdb_id/season but no episodes then assume it's right and carry it forward # otherwise, reset it every time if not (tvdb_id and season and not episodes and multi_file): tvdb_id = None season = None episodes = [] try: returnStr += logHelper(u"Attempting to parse name "+curName, logger.DEBUG) myParser = FileParser(curName) result = myParser.parse() season = result.seasonnumber if result.seasonnumber != None else 1 episodes = result.episodenumbers returnStr += logHelper(u"Ended up with season "+str(season)+" and episodes "+str(episodes), logger.DEBUG) except tvnamer_exceptions.InvalidFilename: returnStr += logHelper(u"Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not result.seriesname: returnStr += logHelper(u"Filename "+curName+" has no series name, unable to use this name for processing", logger.DEBUG) continue if not episodes: returnStr += logHelper(u"Unable to find an episode number in the filename "+curName+", skipping", logger.DEBUG) continue # reverse-lookup the scene exceptions returnStr += logHelper(u"Checking scene exceptions for "+result.seriesname, logger.DEBUG) sceneID = None for exceptionID in sceneExceptions: for curException in sceneExceptions[exceptionID]: if result.seriesname == curException: sceneID = exceptionID break if sceneID: returnStr += logHelper(u"Scene exception lookup got tvdb id "+str(sceneID)+", using that", logger.DEBUG) break if sceneID: tvdb_id = sceneID showObj = None try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) # get the tvdb object from either the scene exception ID or the series name if tvdb_id: returnStr += logHelper(u"Looking up ID "+str(tvdb_id)+" on TVDB", logger.DEBUG) showObj = t[tvdb_id] else: returnStr += logHelper(u"Looking up name "+result.seriesname+" on TVDB", logger.DEBUG) showObj = t[result.seriesname] returnStr += logHelper(u"Got tvdb_id "+str(showObj["id"])+" and series name "+showObj["seriesname"].decode('utf-8')+" from TVDB", logger.DEBUG) showInfo = (int(showObj["id"]), showObj["seriesname"]) except (tvdb_exceptions.tvdb_exception, IOError), e: returnStr += logHelper(u"Unable to look up show on TVDB: "+str(e).decode('utf-8'), logger.DEBUG) returnStr += logHelper(u"Looking up show in DB instead", logger.DEBUG) showInfo = helpers.searchDBForShow(result.seriesname) if showInfo: tvdb_id = showInfo[0] if showInfo and season == None: myDB = db.DBConnection() numseasonsSQlResult = myDB.select("SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0", [tvdb_id]) numseasons = numseasonsSQlResult[0][0] if numseasons == 1 and season == None: returnStr += logHelper(u"Don't have a season number, but this show appears to only have 1 season, setting seasonnumber to 1...", logger.DEBUG) season = 1 # if it is an air-by-date show and we successfully found it on TVDB, convert the date into a season/episode if season == -1 and showObj: returnStr += logHelper(u"Looks like this is an air-by-date show, attempting to parse...", logger.DEBUG) try: epObj = showObj.airedOn(episodes[0])[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound, e: returnStr += logHelper(u"Unable to find episode with date "+str(episodes[0])+" for show "+showObj["seriesname"]+", skipping", logger.DEBUG) continue
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. Returns a (tvdb_id, season, [episodes]) tuple. The first two may be None and episodes may be [] if none were found. """ logger.log(u"Analyzing name "+repr(name)) to_return = (None, None, []) if not name: return to_return # parse the name to break it into show name, season, and episode np = NameParser(file) parse_result = np.parse(name) self._log("Parsed "+name+" into "+str(parse_result).decode('utf-8'), logger.DEBUG) if parse_result.air_by_date: season = -1 episodes = [parse_result.air_date] else: season = parse_result.season_number episodes = parse_result.episode_numbers to_return = (None, season, episodes) # do a scene reverse-lookup to get a list of all possible names name_list = sceneHelpers.sceneToNormalShowNames(parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group if parse_result.extra_info: self.is_proper = re.search('(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # 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) for exceptionID in common.sceneExceptions: # for each exception name for curException in common.sceneExceptions[exceptionID]: if cur_name.lower() in (curException.lower(), sceneHelpers.sanitizeSceneName(curException).lower().replace('.',' ')): self._log(u"Scene exception lookup got tvdb id "+str(exceptionID)+u", using that", logger.DEBUG) _finalize(parse_result) return (exceptionID, 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 tvdb id "+str(db_result[0]), logger.DEBUG) _finalize(parse_result) return (int(db_result[0]), season, episodes) # see if we can find the name with a TVDB lookup for cur_name in name_list: try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) self._log(u"Looking up name "+cur_name+u" on TVDB", logger.DEBUG) showObj = t[cur_name] except (tvdb_exceptions.tvdb_exception), e: # if none found, search on all languages try: # There's gotta be a better way of doing this but we don't wanna # change the language value elsewhere ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy() ltvdb_api_parms['search_all_languages'] = True t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **ltvdb_api_parms) self._log(u"Looking up name "+cur_name+u" in all languages on TVDB", logger.DEBUG) showObj = t[cur_name] except (tvdb_exceptions.tvdb_exception, IOError), e: pass continue
def processFile(fileName, downloadDir=None, nzbName=None): returnStr = '' folderName = None if downloadDir != None: folderName = downloadDir.split(os.path.sep)[-1] returnStr += logHelper("Processing file "+fileName+" (with folder name "+str(folderName)+" and NZB name "+str(nzbName)+")", logger.DEBUG) finalNameList = [] for curName in (fileName, folderName, nzbName): if curName != None: for curSceneName in sceneHelpers.sceneToNormalShowNames(curName): if curSceneName not in finalNameList: finalNameList.append(curSceneName) showResults = None result = None tvdb_id = None season = None episodes = [] # first try looking up every name in our history for curName in finalNameList: historyResult = findInHistory(curName) if historyResult: returnStr += logHelper("Result from history: "+str(historyResult)+" from "+curName, logger.DEBUG) (tvdb_id, season, episode) = historyResult episodes = [episode] showResults = helpers.findCertainShow(sickbeard.showList, tvdb_id) break # if that didn't work then try manually parsing and searching them on TVDB for curName in finalNameList: # if we already have the info from the history then don't bother with this if tvdb_id != None and season != None and episodes != []: break # set all search stuff to defaults so we don't carry results over from the last iteration tvdb_id = None season = None episodes = [] try: returnStr += logHelper("Attempting to parse name "+curName, logger.DEBUG) myParser = FileParser(curName) result = myParser.parse() season = result.seasonnumber episodes = result.episodenumbers except tvnamer_exceptions.InvalidFilename: returnStr += logHelper("Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not result.seriesname: returnStr += logHelper("Filename "+curName+" has no series name, unable to use this name for processing", logger.DEBUG) continue if not episodes: returnStr += logHelper("Unable to find an episode number in the filename "+curName+", skipping", logger.DEBUG) continue # reverse-lookup the scene exceptions sceneID = None for exceptionID in sceneExceptions: if curName == sceneExceptions[exceptionID]: sceneID = exceptionID break try: returnStr += logHelper("Looking up name "+result.seriesname+" on TVDB", logger.DEBUG) t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) # get the tvdb object from either the scene exception ID or the series name if sceneID: showObj = t[sceneID] else: showObj = t[result.seriesname] showInfo = (int(showObj["id"]), showObj["seriesname"]) except (tvdb_exceptions.tvdb_exception, IOError), e: returnStr += logHelper("Unable to look up show on TVDB: "+str(e), logger.DEBUG) returnStr += logHelper("Looking up show in DB instead", logger.DEBUG) showInfo = helpers.searchDBForShow(result.seriesname) if showInfo: tvdb_id = showInfo[0] # if it is an air-by-date show and we successfully found it on TVDB, convert the date into a season/episode if season == -1 and showObj: try: epObj = showObj.airedOn(episodes[0])[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound, e: returnStr += logHelper("Unable to find episode with date "+str(episodes[0])+" for show "+showObj["seriesname"]+", skipping", logger.DEBUG) continue
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. Returns a (tvdb_id, season, [episodes]) tuple. The first two may be None and episodes may be [] if none were found. """ logger.log(u"Analyzing name " + repr(name)) to_return = (None, None, []) if not name: return to_return # parse the name to break it into show name, season, and episode np = NameParser(file) parse_result = np.parse(name) self._log( "Parsed " + name + " into " + str(parse_result).decode('utf-8'), logger.DEBUG) if parse_result.air_by_date: season = -1 episodes = [parse_result.air_date] else: season = parse_result.season_number episodes = parse_result.episode_numbers to_return = (None, season, episodes) # do a scene reverse-lookup to get a list of all possible names name_list = sceneHelpers.sceneToNormalShowNames( parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group if parse_result.extra_info: self.is_proper = re.search( '(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # 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) for exceptionID in common.sceneExceptions: # for each exception name for curException in common.sceneExceptions[exceptionID]: if cur_name.lower() in (curException.lower(), sceneHelpers.sanitizeSceneName( curException).lower().replace( '.', ' ')): self._log( u"Scene exception lookup got tvdb id " + str(exceptionID) + u", using that", logger.DEBUG) _finalize(parse_result) return (exceptionID, 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 tvdb id " + str(db_result[0]), logger.DEBUG) _finalize(parse_result) return (int(db_result[0]), season, episodes) # see if we can find the name with a TVDB lookup for cur_name in name_list: try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) self._log(u"Looking up name " + cur_name + u" on TVDB", logger.DEBUG) showObj = t[cur_name] except (tvdb_exceptions.tvdb_exception), e: # if none found, search on all languages try: # There's gotta be a better way of doing this but we don't wanna # change the language value elsewhere ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy() ltvdb_api_parms['search_all_languages'] = True t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **ltvdb_api_parms) self._log( u"Looking up name " + cur_name + u" in all languages on TVDB", logger.DEBUG) showObj = t[cur_name] except (tvdb_exceptions.tvdb_exception, IOError), e: pass continue