def convert(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 # convert scene numbered releases before storing to cache indexer_id = helpers.searchDBForShow(self.series_name) if indexer_id: new_episode_numbers = [] new_season_numbers = [] for epNo in self.episode_numbers: (s, e) = scene_numbering.get_indexer_numbering(indexer_id, self.season_number, epNo) new_episode_numbers.append(e) new_season_numbers.append(s) # need to do a quick sanity check here. It's possible that we now have episodes # from more than one season (by tvdb numbering), and this is just too much # for sickbeard, so we'd need to flag it. new_season_numbers = list(set(new_season_numbers)) # remove duplicates if len(new_season_numbers) > 1: raise InvalidNameException("Scene numbering results episodes from " "seasons %s, (i.e. more than one) and " "sickbeard does not support this. " "Sorry." % (str(new_season_numbers))) # I guess it's possible that we'd have duplicate episodes too, so lets # eliminate them new_episode_numbers = list(set(new_episode_numbers)) new_episode_numbers.sort() self.episode_numbers = new_episode_numbers self.season_number = new_season_numbers[0] return self
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 helpers.sceneToNormalShowNames(curName): if curSceneName not in finalNameList: finalNameList.append(curSceneName) showResults = None result = None for curName in finalNameList: try: returnStr += logHelper("Attempting to parse name "+curName, logger.DEBUG) myParser = FileParser(curName) result = myParser.parse() 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 try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) showObj = t[result.seriesname] showInfo = (int(showObj["id"]), showObj["seriesname"]) except (tvdb_exceptions.tvdb_exception, IOError), e: returnStr += logHelper("TVDB didn't respond, trying to look up the show in the DB instead: "+str(e), logger.DEBUG) showInfo = helpers.searchDBForShow(result.seriesname) # if we didn't get anything from TVDB or the DB then try the next option if showInfo == None: continue # find the show in the showlist try: showResults = helpers.findCertainShow(sickbeard.showList, showInfo[0]) except exceptions.MultipleShowObjectsException: raise #TODO: later I'll just log this, for now I want to know about it ASAP if showResults != None: returnStr += logHelper("Found the show in our list, continuing", logger.DEBUG) break
def _get_show_id(self, series_name): """Find and return show ID by searching exceptions, then DB""" show_names = show_name_helpers.sceneToNormalShowNames(series_name) logger.log(u"show_names: " + str(show_names), logger.DEBUG) for show_name in show_names: exception = scene_exceptions.get_scene_exception_by_name(show_name) if exception is not None: return exception for show_name in show_names: found_info = helpers.searchDBForShow(show_name) if found_info is not None: return (found_info[0]) return None
def _get_show_id(self, series_name): """Find and return show ID by searching exceptions, then DB""" show_names = show_name_helpers.sceneToNormalShowNames(series_name) logger.log(u"show_names: " + str(show_names), logger.DEBUG) for show_name in show_names: exception = scene_exceptions.get_scene_exception_by_name(show_name) if exception is not None: return exception for show_name in show_names: found_info = helpers.searchDBForShow(show_name) if found_info is not None: return(found_info[1]) return None
def convert(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 # convert scene numbered releases before storing to cache indexer_id = helpers.searchDBForShow(self.series_name) if indexer_id: new_episode_numbers = [] new_season_numbers = [] for epNo in self.episode_numbers: (s, e) = scene_numbering.get_indexer_numbering( indexer_id, self.season_number, epNo) new_episode_numbers.append(e) new_season_numbers.append(s) # need to do a quick sanity check here. It's possible that we now have episodes # from more than one season (by tvdb numbering), and this is just too much # for sickbeard, so we'd need to flag it. new_season_numbers = list( set(new_season_numbers)) # remove duplicates if len(new_season_numbers) > 1: raise InvalidNameException( "Scene numbering results episodes from " "seasons %s, (i.e. more than one) and " "sickbeard does not support this. " "Sorry." % (str(new_season_numbers))) # I guess it's possible that we'd have duplicate episodes too, so lets # eliminate them new_episode_numbers = list(set(new_episode_numbers)) new_episode_numbers.sort() self.episode_numbers = new_episode_numbers self.season_number = new_season_numbers[0] return self
def _addCacheEntry(self, name, url, season=None, episodes=None, indexer_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName, True) except InvalidNameException: logger.log( u"Unable to parse the filename " + curName + " into a valid episode", logger.DEBUG) continue 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 indexer_lang = None if indexer_id: # if we have only the indexer_id, use the database showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) if showObj: self.indexer = int(showObj.indexer) indexer_lang = showObj.lang else: logger.log( u"We were given a Indexer ID " + str(indexer_id) + " but it doesn't match a show we have in our list, so leaving indexer_id empty", logger.DEBUG) indexer_id = 0 # if no indexerID then fill out as much info as possible by searching the show name if not indexer_id: # check the name cache and see if we already know what show this is logger.log( u"Checking the cache to see if we already know the Indexer ID of " + parse_result.series_name, logger.DEBUG) indexer_id = name_cache.retrieveNameFromCache( parse_result.series_name) # remember if the cache lookup worked or not so we know whether we should bother updating it later if indexer_id == None: logger.log( u"No cache results returned, continuing on with the search", logger.DEBUG) from_cache = False else: logger.log( u"Cache lookup found " + repr(indexer_id) + ", using that", logger.DEBUG) from_cache = True # if the cache failed, try looking up the show name in the database if indexer_id == None: logger.log(u"Trying to look the show up in the show database", logger.DEBUG) showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: logger.log( u"" + parse_result.series_name + " was found to be show " + showResult[2] + " (" + str(showResult[1]) + ") in our DB.", logger.DEBUG) indexer_id = showResult[1] # if the DB lookup fails then do a comprehensive regex search if indexer_id == None: logger.log( u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if show_name_helpers.isGoodResult(name, curShow, False): logger.log( u"Successfully matched " + name + " to " + curShow.name + " with regex", logger.DEBUG) indexer_id = curShow.indexerid indexer_lang = curShow.lang break # if indexer_id was anything but None (0 or a number) then if not from_cache: name_cache.addNameToCache(parse_result.series_name, indexer_id) # if we came out with indexer_id = None it means we couldn't figure it out at all, just use 0 for that if indexer_id == None: indexer_id = 0 # if we found the show then retrieve the show object if indexer_id: try: showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) except (MultipleShowObjectsException): showObj = None if showObj: self.indexer = int(showObj.indexer) indexer_lang = showObj.lang # if we weren't provided with season/episode information then get it from the name that we parsed if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if (parse_result.air_by_date or parse_result.sports) and indexer_id: try: lINDEXER_API_PARMS = sickbeard.indexerApi( self.indexer).api_params.copy() if not (indexer_lang == "" or indexer_lang == "en" or indexer_lang == None): lINDEXER_API_PARMS['language'] = indexer_lang t = sickbeard.indexerApi( self.indexer).indexer(**lINDEXER_API_PARMS) epObj = None if parse_result.air_by_date: epObj = t[indexer_id].airedOn(parse_result.air_date)[0] elif parse_result.sports: epObj = t[indexer_id].airedOn(parse_result.sports_date)[0] if epObj is None: return None season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except sickbeard.indexer_episodenotfound: logger.log( u"Unable to find episode with date " + str(parse_result.air_date) + " for show " + parse_result.series_name + ", skipping", logger.WARNING) return None except sickbeard.indexer_error, e: logger.log( u"Unable to contact " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e), logger.WARNING) return None
def doIt(downloaderDir, nzbName=None): returnStr = "" downloadDir = '' # if they passed us a real dir then assume it's the one we want if os.path.isdir(downloaderDir): downloadDir = os.path.abspath(downloaderDir) # if they've got a download dir configured then use it elif sickbeard.TV_DOWNLOAD_DIR != '' and os.path.isdir(sickbeard.TV_DOWNLOAD_DIR): downloadDir = os.path.join(sickbeard.TV_DOWNLOAD_DIR, os.path.abspath(downloaderDir).split(os.path.sep)[-1]) returnStr += logHelper("Trying to use folder "+downloadDir, logger.DEBUG) # if we didn't find a real dir then quit if not os.path.isdir(downloadDir): returnStr += logHelper("Unable to figure out what folder to process. If your downloader and Sick Beard aren't on the same PC make sure you fill out your TV download dir in the config.", logger.DEBUG) return returnStr myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_shows") for sqlShow in sqlResults: if downloadDir.startswith(os.path.abspath(sqlShow["location"])+os.sep): returnStr += logHelper("You're trying to post process a show that's already been moved to its show dir", logger.ERROR) return returnStr returnStr += logHelper("Final folder name is " + downloadDir, logger.DEBUG) # TODO: check if it's failed and deal with it if it is if downloadDir.startswith('_FAILED_'): returnStr += logHelper("The directory name indicates it failed to extract, cancelling", logger.DEBUG) return returnStr # find the file we're dealing with biggest_file = findMainFile(downloadDir) if biggest_file == None: returnStr += logHelper("Unable to find the biggest file - is this really a TV download?", logger.DEBUG) return returnStr returnStr += logHelper("The biggest file in the dir is: " + biggest_file, logger.DEBUG) # use file name, folder name, and NZB name (in that order) to try to figure out the episode info result = None nameList = [downloadDir.split(os.path.sep)[-1], biggest_file] if nzbName != None: nameList.append(nzbName) showResults = None for curName in nameList: try: myParser = FileParser(curName) result = myParser.parse() except tvnamer_exceptions.InvalidFilename: returnStr += logHelper("Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, lastTimeout=sickbeard.LAST_TVDB_TIMEOUT, **sickbeard.TVDB_API_PARMS) showObj = t[result.seriesname] showInfo = (int(showObj["id"]), showObj["seriesname"]) except (tvdb_exceptions.tvdb_exception, IOError), e: returnStr += logHelper("TVDB didn't respond, trying to look up the show in the DB instead", logger.DEBUG) showInfo = helpers.searchDBForShow(result.seriesname) # if we didn't get anything from TVDB or the DB then try the next option if showInfo == None: continue # find the show in the showlist try: showResults = helpers.findCertainShow(sickbeard.showList, showInfo[0]) except exceptions.MultipleShowObjectsException: raise #TODO: later I'll just log this, for now I want to know about it ASAP if showResults != None: returnStr += logHelper("Found the show in our list, continuing", logger.DEBUG) break
def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() epInfo = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = FileParser(curName) epInfo = myParser.parse() except tvnamer_exceptions.InvalidFilename: logger.log("Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not epInfo: logger.log("Giving up because I'm unable to figure out what show/etc this is: "+name, logger.DEBUG) return False if not epInfo.seriesname: logger.log("No series name retrieved from "+name+", unable to cache it", logger.DEBUG) return False # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid else: logger.log("We were given a TVDB id "+str(tvdb_id)+" but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow(sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid else: logger.log("We were given a TVRage id "+str(tvrage_id)+" but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: showResult = helpers.searchDBForShow(epInfo.seriesname) if showResult: logger.log(epInfo.seriesname+" was found to be show "+showResult[1]+" ("+str(showResult[0])+") in our DB.", logger.DEBUG) tvdb_id = showResult[0] showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if not showObj: logger.log("This should never have happened, post a bug about this!", logger.ERROR) raise Exception("BAD STUFF HAPPENED") tvrage_id = showObj.tvrid if not season: season = epInfo.seasonnumber if not episodes: episodes = epInfo.episodenumbers episodeText = "|"+"|".join(map(str, episodes))+"|" # get the current timestamp curTimestamp = int(time.mktime(datetime.datetime.today().timetuple())) if not quality: # if we don't know what quality it is and it looks like itouch quality, skip it if "itouch" in name.lower(): return False elif any(x in name.lower() for x in ("720p", "1080p", "x264")): quality = HD elif any(x in name.lower() for x in ("xvid", "divx")): quality = SD else: logger.log("Unable to figure out the quality of "+name+", assuming SD", logger.DEBUG) quality = SD myDB.action("INSERT INTO "+self.providerName+" (name, season, episodes, tvrid, tvdbid, url, time, quality) VALUES (?,?,?,?,?,?,?,?)", [name, season, episodeText, tvrage_id, tvdb_id, url, curTimestamp, quality])
def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName) except InvalidNameException: logger.log(u"Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not parse_result: logger.log(u"Giving up because I'm unable to parse this name: "+name, logger.DEBUG) return False if not parse_result.series_name: logger.log(u"No series name retrieved from "+name+", unable to cache it", logger.DEBUG) return False tvdb_lang = None # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid tvdb_lang = showObj.lang else: logger.log(u"We were given a TVDB id "+str(tvdb_id)+" but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow(sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid tvdb_lang = showObj.lang else: logger.log(u"We were given a TVRage id "+str(tvrage_id)+" but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: # check the name cache and see if we already know what show this is logger.log(u"Checking the cache to see if we already know the tvdb id of "+parse_result.series_name, logger.DEBUG) tvdb_id = name_cache.retrieveNameFromCache(parse_result.series_name) # remember if the cache lookup worked or not so we know whether we should bother updating it later if tvdb_id == None: logger.log(u"No cache results returned, continuing on with the search", logger.DEBUG) from_cache = False else: logger.log(u"Cache lookup found "+repr(tvdb_id)+", using that", logger.DEBUG) from_cache = True # if the cache failed, try looking up the show name in the database if tvdb_id == None: logger.log(u"Trying to look the show up in the show database", logger.DEBUG) showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: logger.log(parse_result.series_name+" was found to be show "+showResult[1]+" ("+str(showResult[0])+") in our DB.", logger.DEBUG) tvdb_id = showResult[0] # if the DB lookup fails then do a comprehensive regex search if tvdb_id == None: logger.log(u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if show_name_helpers.isGoodResult(name, curShow, False): logger.log(u"Successfully matched "+name+" to "+curShow.name+" with regex", logger.DEBUG) tvdb_id = curShow.tvdbid tvdb_lang = curShow.lang break # if tvdb_id was anything but None (0 or a number) then if not from_cache: name_cache.addNameToCache(parse_result.series_name, tvdb_id) # if we came out with tvdb_id = None it means we couldn't figure it out at all, just use 0 for that if tvdb_id == None: tvdb_id = 0 # if we found the show then retrieve the show object if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid tvdb_lang = showObj.lang # if we weren't provided with season/episode information then get it from the name that we parsed if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if parse_result.air_by_date and tvdb_id: 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() if not (tvdb_lang == "" or tvdb_lang == "en" or tvdb_lang == None): ltvdb_api_parms['language'] = tvdb_lang t = tvdb_api.Tvdb(**ltvdb_api_parms) epObj = t[tvdb_id].airedOn(parse_result.air_date)[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound: logger.log(u"Unable to find episode with date "+str(parse_result.air_date)+" for show "+parse_result.series_name+", skipping", logger.WARNING) return False except tvdb_exceptions.tvdb_error, e: logger.log(u"Unable to contact TVDB: "+ex(e), logger.WARNING) return False
def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() epInfo = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = FileParser(curName) epInfo = myParser.parse() except tvnamer_exceptions.InvalidFilename: logger.log("Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not epInfo: logger.log("Giving up because I'm unable to figure out what show/etc this is: "+name, logger.DEBUG) return False if not epInfo.seriesname: logger.log("No series name retrieved from "+name+", unable to cache it", logger.DEBUG) return False # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid else: logger.log("We were given a TVDB id "+str(tvdb_id)+" but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow(sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid else: logger.log("We were given a TVRage id "+str(tvrage_id)+" but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: showResult = helpers.searchDBForShow(epInfo.seriesname) if showResult: logger.log(epInfo.seriesname+" was found to be show "+showResult[1]+" ("+str(showResult[0])+") in our DB.", logger.DEBUG) tvdb_id = showResult[0] showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if not showObj: logger.log("This should never have happened, post a bug about this!", logger.ERROR) raise Exception("BAD STUFF HAPPENED") tvrage_id = showObj.tvrid if not season: season = epInfo.seasonnumber if not episodes: episodes = epInfo.episodenumbers # if we have an air-by-date show then get the real season/episode numbers if season == -1 and tvdb_id: try: t = tvdb_api.Tvdb(**sickbeard.TVDB_API_PARMS) epObj = t[tvdb_id].airedOn(episodes[0])[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound, e: logger.log("Unable to find episode with date "+str(episodes[0])+" for show "+epInfo.seriesname+", skipping", logger.WARNING) return False
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 _addCacheEntry(self, name, url, quality=None): indexerid = None in_cache = False # if we don't have complete info then parse the filename to get it try: myParser = NameParser() parse_result = myParser.parse(name).convert() except InvalidNameException: 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 cacheResult = sickbeard.name_cache.retrieveNameFromCache(parse_result.series_name) if cacheResult: in_cache = True indexerid = int(cacheResult) if not indexerid: showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: indexerid = int(showResult[0]) showObj = None if indexerid: showObj = helpers.findCertainShow(sickbeard.showList, indexerid) if not showObj: logger.log(u"No match for show: [" + parse_result.series_name + "], not caching ...", logger.DEBUG) return None season = episodes = None if parse_result.air_by_date or parse_result.sports: myDB = db.DBConnection() airdate = parse_result.air_date.toordinal() or parse_result.sports_event_date.toordinal() sql_results = myDB.select( "SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?", [indexerid, showObj.indexer, airdate]) if sql_results > 0: season = int(sql_results[0]["season"]) episodes = [int(sql_results[0]["episode"])] else: season = parse_result.season_number if parse_result.season_number != None else 1 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') logger.log(u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG) if not in_cache: sickbeard.name_cache.addNameToCache(parse_result.series_name, indexerid) return [ "INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)", [name, season, episodeText, indexerid, url, curTimestamp, quality]]
class ProperFinder(): def __init__(self): self.amActive = False self.updateInterval = datetime.timedelta(hours=1) check_propers_interval = {'15m': 15, '45m': 45, '90m': 90, '4h': 4*60, 'daily': 24*60} for curInterval in ('15m', '45m', '90m', '4h', 'daily'): if sickbeard.CHECK_PROPERS_INTERVAL == curInterval: self.updateInterval = datetime.timedelta(minutes = check_propers_interval[curInterval]) def run(self, force=False): if not sickbeard.DOWNLOAD_PROPERS: return # look for propers every night at 1 AM updateTime = datetime.time(hour=1) logger.log(u"Checking proper time", logger.DEBUG) hourDiff = datetime.datetime.today().time().hour - updateTime.hour dayDiff = (datetime.date.today() - self._get_lastProperSearch()).days if sickbeard.CHECK_PROPERS_INTERVAL == "daily" and not force: # if it's less than an interval after the update time then do an update if not (hourDiff >= 0 and hourDiff < self.updateInterval.seconds / 3600 or dayDiff >= 1): return logger.log(u"Beginning the search for new propers") self.amActive = True propers = self._getProperList() if propers: self._downloadPropers(propers) self._set_lastProperSearch(datetime.datetime.today().toordinal()) msg = u"Completed the search for new propers, next check " if sickbeard.CHECK_PROPERS_INTERVAL == "daily": logger.log(u"%sat 1am tomorrow" % msg) else: logger.log(u"%sin ~%s" % (msg, sickbeard.CHECK_PROPERS_INTERVAL)) self.amActive = False def _getProperList(self): propers = {} # for each provider get a list of the origThreadName = threading.currentThread().name providers = [x for x in sickbeard.providers.sortedProviderList() if x.isActive()] for curProvider in providers: threading.currentThread().name = origThreadName + " :: [" + curProvider.name + "]" search_date = datetime.datetime.today() - datetime.timedelta(days=2) logger.log(u"Searching for any new PROPER releases from " + curProvider.name) try: curPropers = curProvider.findPropers(search_date) except exceptions.AuthException, e: logger.log(u"Authentication error: " + ex(e), logger.ERROR) continue # if they haven't been added by a different provider than add the proper to the list for x in curPropers: name = self._genericName(x.name) if not name in propers: logger.log(u"Found new proper: " + x.name, logger.DEBUG) x.provider = curProvider propers[name] = x # reset thread name back to original threading.currentThread().name = origThreadName # take the list of unique propers and get it sorted by sortedPropers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True) finalPropers = [] for curProper in sortedPropers: in_cache = False try: myParser = NameParser(False) 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 not parse_result.series_name: continue cacheResult = sickbeard.name_cache.retrieveNameFromCache(parse_result.series_name) if cacheResult: in_cache = True curProper.indexerid = int(cacheResult) elif cacheResult == 0: return None if not curProper.indexerid: showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: curProper.indexerid = int(showResult[0]) if not curProper.indexerid: for curShow in sickbeard.showList: if show_name_helpers.isGoodResult(curProper.name, curShow, False): curProper.indexerid = curShow.indexerid break showObj = None if curProper.indexerid: showObj = helpers.findCertainShow(sickbeard.showList, curProper.indexerid) if not showObj: sickbeard.name_cache.addNameToCache(parse_result.series_name, 0) continue if not in_cache: sickbeard.name_cache.addNameToCache(parse_result.series_name, curProper.indexerid) # scene numbering -> indexer numbering parse_result = parse_result.convert(showObj) if not parse_result.episode_numbers: logger.log( u"Ignoring " + curProper.name + " because it's for a full season rather than specific episode", logger.DEBUG) continue # populate our Proper instance if parse_result.air_by_date or parse_result.sports: curProper.season = -1 curProper.episode = parse_result.air_date or parse_result.sports_event_date else: curProper.season = parse_result.season_number if parse_result.season_number != None else 1 curProper.episode = parse_result.episode_numbers[0] curProper.quality = Quality.nameQuality(curProper.name) # for each show in our list for curShow in sickbeard.showList: genericName = self._genericName(parse_result.series_name) # get the scene name masks sceneNames = set(show_name_helpers.makeSceneShowSearchStrings(curShow)) # for each scene name mask for curSceneName in sceneNames: # if it matches if genericName == self._genericName(curSceneName): logger.log( u"Successful match! Result " + parse_result.series_name + " matched to show " + curShow.name, logger.DEBUG) # set the indexerid in the db to the show's indexerid curProper.indexerid = curShow.indexerid # set the indexer in the db to the show's indexer curProper.indexer = curShow.indexer # since we found it, break out break # if we found something in the inner for loop break out of this one if curProper.indexerid != -1: break if not show_name_helpers.filterBadReleases(curProper.name): logger.log(u"Proper " + curProper.name + " isn't a valid scene release that we want, igoring it", logger.DEBUG) continue showObj = helpers.findCertainShow(sickbeard.showList, curProper.indexerid) if not showObj: logger.log(u"Unable to find the show with indexerID " + str(curProper.indexerid), logger.ERROR) continue if showObj.rls_ignore_words and search.filter_release_name(curProper.name, showObj.rls_ignore_words): logger.log(u"Ignoring " + curProper.name + " based on ignored words filter: " + showObj.rls_ignore_words, logger.MESSAGE) continue if showObj.rls_require_words and not search.filter_release_name(curProper.name, showObj.rls_require_words): logger.log(u"Ignoring " + curProper.name + " based on required words filter: " + showObj.rls_require_words, logger.MESSAGE) continue # if we have an air-by-date show then get the real season/episode numbers if (parse_result.air_by_date or parse_result.sports_event_date) and curProper.indexerid: logger.log( u"Looks like this is an air-by-date or sports show, attempting to convert the date to season/episode", logger.DEBUG) airdate = curProper.episode.toordinal() myDB = db.DBConnection() sql_result = myDB.select( "SELECT season, episode FROM tv_episodes WHERE showid = ? and indexer = ? and airdate = ?", [curProper.indexerid, curProper.indexer, airdate]) if sql_result: curProper.season = int(sql_result[0][0]) curProper.episodes = [int(sql_result[0][1])] else: logger.log(u"Unable to find episode with date " + str( curProper.episode) + " for show " + parse_result.series_name + ", skipping", logger.WARNING) continue # check if we actually want this proper (if it's the right quality) sqlResults = db.DBConnection().select( "SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", [curProper.indexerid, curProper.season, curProper.episode]) if not sqlResults: continue oldStatus, oldQuality = Quality.splitCompositeStatus(int(sqlResults[0]["status"])) # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones) if oldStatus not in (DOWNLOADED, SNATCHED) or oldQuality != curProper.quality: continue # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers if curProper.indexerid != -1 and (curProper.indexerid, curProper.season, curProper.episode) not in map( operator.attrgetter('indexerid', 'season', 'episode'), finalPropers): logger.log(u"Found a proper that we need: " + str(curProper.name)) finalPropers.append(curProper) return finalPropers
def _addCacheEntry(self, name, url, season=None, episodes=None, indexer_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName) except InvalidNameException: logger.log(u"Unable to parse the filename " + curName + " into a valid episode", logger.DEBUG) continue 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 indexer_lang = None if indexer_id: # if we have only the indexer_id, use the database showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) if showObj: self.indexer = int(showObj.indexer) indexer_lang = showObj.lang else: logger.log(u"We were given a Indexer ID " + str(indexer_id) + " but it doesn't match a show we have in our list, so leaving indexer_id empty",logger.DEBUG) indexer_id = 0 # if no indexerID then fill out as much info as possible by searching the show name if not indexer_id: from_cache = False # check the name cache and see if we already know what show this is logger.log( u"Checking the cache for Indexer ID of " + parse_result.series_name, logger.DEBUG) # remember if the cache lookup worked or not so we know whether we should bother updating it later indexer_id = name_cache.retrieveNameFromCache(parse_result.series_name) if indexer_id: logger.log(u"Cache lookup found " + repr(indexer_id) + ", using that", logger.DEBUG) from_cache = True # if the cache failed, try looking up the show name in the database if not indexer_id: logger.log( u"Checking the database for Indexer ID of " + str(parse_result.series_name), logger.DEBUG) showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: logger.log( u"" + parse_result.series_name + " was found to be show " + showResult[2] + " (" + str( showResult[1]) + ") in our DB.", logger.DEBUG) indexer_id = showResult[1] # if the database failed, try looking up the show name from scene exceptions list if not indexer_id: logger.log( u"Checking the scene exceptions list for Indexer ID of " + parse_result.series_name, logger.DEBUG) sceneResult = sickbeard.scene_exceptions.get_scene_exception_by_name(parse_result.series_name) if sceneResult: logger.log( u"" + str(parse_result.series_name) + " was found in scene exceptions list with Indexer ID: " + str(sceneResult), logger.DEBUG) indexer_id = sceneResult # if the DB lookup fails then do a comprehensive regex search if not indexer_id: logger.log( u"Checking the shows list for Indexer ID of " + str(parse_result.series_name), logger.DEBUG) for curShow in sickbeard.showList: if show_name_helpers.isGoodResult(name, curShow, False): logger.log(u"Successfully matched " + name + " to " + curShow.name + " from shows list", logger.DEBUG) indexer_id = curShow.indexerid indexer_lang = curShow.lang break # if the database failed, try looking up the show name from scene exceptions list if not indexer_id: logger.log( u"Checking Indexers for Indexer ID of " + parse_result.series_name, logger.DEBUG) # check indexers try:indexerResult = helpers.searchIndexerForShowID(parse_result.series_name) except:indexerResult = None if indexerResult: logger.log( u"" + str(parse_result.series_name) + " was found on " + str(sickbeard.indexerApi(indexerResult[0]).name) + " with Indexer ID: " + str(indexerResult[1]), logger.DEBUG) indexer_id = indexerResult[1] # if indexer_id was anything but None (0 or a number) then if not from_cache: name_cache.addNameToCache(parse_result.series_name, indexer_id) # if we came out with indexer_id = None it means we couldn't figure it out at all, just use 0 for that if indexer_id == None: indexer_id = 0 # if we found the show then retrieve the show object if indexer_id: try: showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) except (MultipleShowObjectsException): showObj = None if showObj: self.indexer = int(showObj.indexer) indexer_lang = showObj.lang # if we weren't provided with season/episode information then get it from the name that we parsed if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if (parse_result.air_by_date or parse_result.sports) and indexer_id: try: lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() if not (indexer_lang == "" or indexer_lang == "en" or indexer_lang == None): lINDEXER_API_PARMS['language'] = indexer_lang t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) epObj = None if parse_result.air_by_date: epObj = t[indexer_id].airedOn(parse_result.air_date)[0] elif parse_result.sports: epObj = t[indexer_id].airedOn(parse_result.sports_date)[0] if epObj is None: return None season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except sickbeard.indexer_episodenotfound: logger.log(u"Unable to find episode with date " + str( parse_result.air_date) + " for show " + parse_result.series_name + ", skipping", logger.WARNING) return None except sickbeard.indexer_error, e: logger.log(u"Unable to contact " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e), logger.WARNING) return None
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) 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 trimprefix = ['^sof-','^euhd-','^amb-','^itg-','^idtv-','^zzgtv-','^itn-','^tcpa-','^tvp-'] for regex in trimprefix: name = re.sub(regex, "", name) # 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 = show_name_helpers.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) scene_id = scene_exceptions.get_scene_exception_by_name(cur_name) if scene_id: self._log(u"Scene exception lookup got tvdb id "+str(scene_id)+u", 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 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): # 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): pass continue except (IOError): continue self._log(u"Lookup successful, using tvdb id "+str(showObj["id"]), logger.DEBUG) _finalize(parse_result) return (int(showObj["id"]), season, episodes) _finalize(parse_result) return to_return
def test_searchDBForShow(self): self.assertIsNone(helpers.searchDBForShow('Testing Show')) TvShow(show_name='Testing Show').save(force_insert=True) self.assertIsNotNone(helpers.searchDBForShow('Testing Show'))
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 helpers.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 # reverse-lookup the scene exceptions sceneID = None for exceptionID in sceneExceptions: if curName == sceneExceptions[exceptionID]: sceneID = exceptionID break try: if result.seriesname == "CSI": result.seriesname = "CSI: Crime Scene Investigation" returnStr += logHelper("Override CSI to CSI: Crime Scene Investigation", logger.DEBUG) 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 we couldn't get the necessary info from either of the above methods, try the next name if tvdb_id == None or season == None or episodes == []: continue # find the show in the showlist try: showResults = helpers.findCertainShow(sickbeard.showList, showInfo[0]) except exceptions.MultipleShowObjectsException: raise #TODO: later I'll just log this, for now I want to know about it ASAP if showResults != None: returnStr += logHelper("Found the show in our list, continuing", logger.DEBUG) break
def _addCacheEntry(self, name, url): cacheDB = self._getDB() parse_result = None from_cache = False indexer_id = None # if we don't have complete info then parse the filename to get it while (True): try: myParser = NameParser() parse_result = myParser.parse(name) except InvalidNameException: 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 logger.log( u"Checking the cahe for show:" + str(parse_result.series_name), logger.DEBUG) # remember if the cache lookup worked or not so we know whether we should bother updating it later cache_id = name_cache.retrieveNameFromCache( parse_result.series_name) 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 logger.log( u"Checking the database for show:" + str(parse_result.series_name), logger.DEBUG) showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: 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 if not indexer_id: return None # if the show isn't in out database then return None try: showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) except: return None if not showObj: return None # if we weren't provided with season/episode information then get it from the name that we parsed season = None episodes = None 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"])] elif parse_result.sports: sql_results = myDB.select( "SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", [showObj.indexerid, parse_result.sports_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 not (season and episodes): return None # convert scene numbered releases before storing to cache convertedEps = {} for curEp in episodes: epObj = showObj.getEpisode(season, curEp, sceneConvert=True) if not epObj: return None if not epObj.season in convertedEps: convertedEps[epObj.season] = [] convertedEps[epObj.season].append(epObj.episode) # get the current timestamp curTimestamp = int(time.mktime(datetime.datetime.today().timetuple())) # get quality of release quality = Quality.sceneQuality(name) if not isinstance(name, unicode): name = unicode(name, 'utf-8') for season, episodes in convertedEps.items(): episodeText = "|" + "|".join(map(str, episodes)) + "|" cacheDB.action( "INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)", [ name, season, episodeText, indexer_id, url, curTimestamp, quality ])
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) 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 trimprefix = [ '^sof-', '^euhd-', '^amb-', '^itg-', '^idtv-', '^zzgtv-', '^itn-', '^tcpa-', '^tvp-' ] for regex in trimprefix: name = re.sub(regex, "", name) # 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 = show_name_helpers.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) scene_id = scene_exceptions.get_scene_exception_by_name(cur_name) if scene_id: self._log( u"Scene exception lookup got tvdb id " + str(scene_id) + u", 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 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): # 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): pass continue except (IOError): continue self._log( u"Lookup successful, using tvdb id " + str(showObj["id"]), logger.DEBUG) _finalize(parse_result) return (int(showObj["id"]), season, episodes) _finalize(parse_result) return to_return
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) Returns a (indexer_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 = show_name_helpers.sceneToNormalShowNames(parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group # remember whether it's a proper if parse_result.extra_info: self.is_proper = re.search('(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # if the result is complete then remember that for later if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group: test_name = os.path.basename(name) if test_name == self.nzb_name: self.good_results[self.NZB_NAME] = True elif test_name == self.folder_name: self.good_results[self.FOLDER_NAME] = True elif test_name == self.file_name: self.good_results[self.FILE_NAME] = True else: logger.log(u"Nothing was good, found " + repr(test_name) + " and wanted either " + repr( self.nzb_name) + ", " + repr(self.folder_name) + ", or " + repr(self.file_name)) else: logger.log(u"Parse result not sufficient(all following have to be set). Will not save release name", logger.DEBUG) logger.log("Parse result(series_name): " + str(parse_result.series_name), logger.DEBUG) logger.log("Parse result(season_number): " + str(parse_result.season_number), logger.DEBUG) logger.log("Parse result(episode_numbers): " + str(parse_result.episode_numbers), logger.DEBUG) logger.log("Parse result(release_group): " + str(parse_result.release_group), logger.DEBUG) # 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, self.indexer) 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) return to_return
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 _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 _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName) except InvalidNameException: logger.log( u"Unable to parse the filename " + curName + " into a valid episode", logger.DEBUG) continue if not parse_result: logger.log( u"Giving up because I'm unable to parse this name: " + name, logger.DEBUG) return False if not parse_result.series_name: logger.log( u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG) return False # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid tvdb_lang = showObj.lang else: logger.log( u"We were given a TVDB id " + str(tvdb_id) + " but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow( sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid tvdb_lang = showObj.lang else: logger.log( u"We were given a TVRage id " + str(tvrage_id) + " but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: logger.log( parse_result.series_name + " was found to be show " + showResult[1] + " (" + str(showResult[0]) + ") in our DB.", logger.DEBUG) tvdb_id = showResult[0] else: logger.log( u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if sceneHelpers.isGoodResult(name, curShow, False): logger.log( u"Successfully matched " + name + " to " + curShow.name + " with regex", logger.DEBUG) tvdb_id = curShow.tvdbid tvdb_lang = curShow.lang break if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if not showObj: logger.log( u"This should never have happened, post a bug about this!", logger.ERROR) raise Exception("BAD STUFF HAPPENED") tvrage_id = showObj.tvrid tvdb_lang = showObj.lang if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if parse_result.air_by_date and tvdb_id: 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() if not (tvdb_lang == "" or tvdb_lang == "en" or tvdb_lang == None): ltvdb_api_parms['language'] = tvdb_lang t = tvdb_api.Tvdb(**ltvdb_api_parms) epObj = t[tvdb_id].airedOn(parse_result.air_date)[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound, e: logger.log( u"Unable to find episode with date " + str(parse_result.air_date) + " for show " + parse_result.series_name + ", skipping", logger.WARNING) return False
def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName) except InvalidNameException: logger.log( u"Unable to parse the filename " + curName + " into a valid episode", logger.DEBUG) continue if not parse_result: logger.log( u"Giving up because I'm unable to parse this name: " + name, logger.DEBUG) return False if not parse_result.series_name: logger.log( u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG) return False tvdb_lang = None # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid tvdb_lang = showObj.lang else: logger.log( u"We were given a TVDB id " + str(tvdb_id) + " but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow( sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid tvdb_lang = showObj.lang else: logger.log( u"We were given a TVRage id " + str(tvrage_id) + " but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: # check the name cache and see if we already know what show this is logger.log( u"Checking the cache to see if we already know the tvdb id of " + parse_result.series_name, logger.DEBUG) tvdb_id = name_cache.retrieveNameFromCache( parse_result.series_name) # remember if the cache lookup worked or not so we know whether we should bother updating it later if tvdb_id == None: logger.log( u"No cache results returned, continuing on with the search", logger.DEBUG) from_cache = False else: logger.log( u"Cache lookup found " + repr(tvdb_id) + ", using that", logger.DEBUG) from_cache = True # if the cache failed, try looking up the show name in the database if tvdb_id == None: logger.log( u"Trying to look the show up in the show database", logger.DEBUG) showResult = helpers.searchDBForShow( parse_result.series_name) if showResult: logger.log( parse_result.series_name + " was found to be show " + showResult[1] + " (" + str(showResult[0]) + ") in our DB.", logger.DEBUG) tvdb_id = showResult[0] # if the DB lookup fails then do a comprehensive regex search if tvdb_id == None: logger.log( u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if show_name_helpers.isGoodResult( name, curShow, False): logger.log( u"Successfully matched " + name + " to " + curShow.name + " with regex", logger.DEBUG) tvdb_id = curShow.tvdbid tvdb_lang = curShow.lang break # if tvdb_id was anything but None (0 or a number) then if not from_cache: name_cache.addNameToCache(parse_result.series_name, tvdb_id) # if we came out with tvdb_id = None it means we couldn't figure it out at all, just use 0 for that if tvdb_id == None: tvdb_id = 0 # if we found the show then retrieve the show object if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid tvdb_lang = showObj.lang # if we weren't provided with season/episode information then get it from the name that we parsed if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if parse_result.air_by_date and tvdb_id: 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() if not (tvdb_lang == "" or tvdb_lang == "en" or tvdb_lang == None): ltvdb_api_parms['language'] = tvdb_lang t = tvdb_api.Tvdb(**ltvdb_api_parms) epObj = t[tvdb_id].airedOn(parse_result.air_date)[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound: logger.log( u"Unable to find episode with date " + str(parse_result.air_date) + " for show " + parse_result.series_name + ", skipping", logger.WARNING) return False except tvdb_exceptions.tvdb_error, e: logger.log(u"Unable to contact TVDB: " + ex(e), logger.WARNING) return False
def get_show_by_name(self, name, showList, fileName, useTvdb=False): if not name: self._log(u"Not trying to get the tvdbid. No name given", logger.DEBUG) return None self._log(u"Trying to get the tvdbid for " + name, logger.DEBUG) name_orig = name name = helpers.sanitizeSceneName(name) cacheDB = db.DBConnection('cache.db') cacheDB.action("DELETE FROM scene_names WHERE tvdb_id = ?", [0]) self._log(u"Checking the cache to see if we allready know the tvdb_id of " + name, logger.DEBUG) tvdb_id = sickbeard.name_cache.retrieveNameFromCache(name) if tvdb_id is None: from_cache = False self._log(u"No cache results returned, continuing on with the search", logger.DEBUG) else: logger.log(u"Cache lookup found "+repr(tvdb_id)+", using that", logger.DEBUG) from_cache = True #checking scene exception list if tvdb_id is None: if name in sickbeard.scene_exceptions.exception_tvdb: self._log(u"Found " + name + " in the exception list", logger.DEBUG) tvdb_id = sickbeard.scene_exceptions.exception_tvdb[name] else: self._log(u"Did NOT find " + name + " in the exception list", logger.DEBUG) # if the cache failed, try looking up the show name in the database if tvdb_id is None: logger.log(u"Trying to look up the show in the show database", logger.DEBUG) showResult = helpers.searchDBForShow(name_orig) if showResult: logger.log(name+" was found to be show "+showResult[1]+" ("+str(showResult[0])+") in our DB.", logger.DEBUG) tvdb_id = showResult[0] # if the DB lookup fails then do a comprehensive regex search if tvdb_id is None: logger.log(u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if sickbeard.show_name_helpers.isGoodResult(fileName, curShow): logger.log(u"Successfully matched "+fileName+" to "+curShow.name+" with regex", logger.DEBUG) tvdb_id = curShow.tvdbid break if tvdb_id is None and useTvdb: try: t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS) showObj = t[name] except (tvdb_exceptions.tvdb_exception): # 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) showObj = t[name] except (tvdb_exceptions.tvdb_exception, IOError): pass return None except (IOError): return None else: tvdb_id = int(showObj["id"]) #if show: # return show # if tvdb_id was anything but None (0 or a number) then if not from_cache: if tvdb_id > 0: sickbeard.name_cache.addNameToCache(name, tvdb_id) # if we came out with tvdb_id = None it means we couldn't figure it out at all, just use 0 for that if tvdb_id is None: tvdb_id = 0 if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: return showObj return None
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) Returns a (indexer_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 = show_name_helpers.sceneToNormalShowNames( parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group # remember whether it's a proper if parse_result.extra_info: self.is_proper = re.search( '(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # if the result is complete then remember that for later if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group: test_name = os.path.basename(name) if test_name == self.nzb_name: self.good_results[self.NZB_NAME] = True elif test_name == self.folder_name: self.good_results[self.FOLDER_NAME] = True elif test_name == self.file_name: self.good_results[self.FILE_NAME] = True else: logger.log(u"Nothing was good, found " + repr(test_name) + " and wanted either " + repr(self.nzb_name) + ", " + repr(self.folder_name) + ", or " + repr(self.file_name)) else: logger.log( u"Parse result not sufficient(all following have to be set). Will not save release name", logger.DEBUG) logger.log( "Parse result(series_name): " + str(parse_result.series_name), logger.DEBUG) logger.log( "Parse result(season_number): " + str(parse_result.season_number), logger.DEBUG) logger.log( "Parse result(episode_numbers): " + str(parse_result.episode_numbers), logger.DEBUG) logger.log( "Parse result(release_group): " + str(parse_result.release_group), logger.DEBUG) # 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, self.indexer) 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) return to_return
def _addCacheEntry(self, name, url): cacheDB = self._getDB() parse_result = None from_cache = False indexer_id = None # if we don't have complete info then parse the filename to get it while(True): try: myParser = NameParser() parse_result = myParser.parse(name) except InvalidNameException: 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 logger.log( u"Checking the cahe for show:" + str(parse_result.series_name), logger.DEBUG) # remember if the cache lookup worked or not so we know whether we should bother updating it later cache_id = name_cache.retrieveNameFromCache(parse_result.series_name) 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 logger.log( u"Checking the database for show:" + str(parse_result.series_name), logger.DEBUG) showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: 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 if not indexer_id: return None # if the show isn't in out database then return None try:showObj = helpers.findCertainShow(sickbeard.showList, indexer_id) except:return None if not showObj: return None # if we weren't provided with season/episode information then get it from the name that we parsed season = None episodes = None 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"])] elif parse_result.sports: sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?", [showObj.indexerid, parse_result.sports_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 not (season and episodes): return None # convert scene numbered releases before storing to cache convertedEps = {} for curEp in episodes: epObj = showObj.getEpisode(season, curEp, sceneConvert=True) if not epObj: return None if not epObj.season in convertedEps: convertedEps[epObj.season] = [] convertedEps[epObj.season].append(epObj.episode) # get the current timestamp curTimestamp = int(time.mktime(datetime.datetime.today().timetuple())) # get quality of release quality = Quality.sceneQuality(name) if not isinstance(name, unicode): name = unicode(name, 'utf-8') for season, episodes in convertedEps.items(): episodeText = "|" + "|".join(map(str, episodes)) + "|" cacheDB.action( "INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)", [name, season, episodeText, indexer_id, url, curTimestamp, quality])
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) 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 = show_name_helpers.sceneToNormalShowNames(parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group # remember whether it's a proper if parse_result.extra_info: self.is_proper = re.search('(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # if the result is complete then remember that for later if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group: test_name = os.path.basename(name) if test_name == self.nzb_name: self.good_results[self.NZB_NAME] = True elif test_name == self.folder_name: self.good_results[self.FOLDER_NAME] = True elif test_name == self.file_name: self.good_results[self.FILE_NAME] = True else: logger.log(u"Nothing was good, found "+repr(test_name)+" and wanted either "+repr(self.nzb_name)+", "+repr(self.folder_name)+", or "+repr(self.file_name)) else: logger.log("Parse result not suficent(all folowing have to be set). will not save release name", logger.DEBUG) logger.log("Parse result(series_name): " + str(parse_result.series_name), logger.DEBUG) logger.log("Parse result(season_number): " + str(parse_result.season_number), logger.DEBUG) logger.log("Parse result(episode_numbers): " + str(parse_result.episode_numbers), logger.DEBUG) logger.log("Parse result(release_group): " + str(parse_result.release_group), logger.DEBUG) # 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 tvdb id "+str(scene_id)+u", 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 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): # 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): pass continue except (IOError): continue self._log(u"Lookup successful, using tvdb id "+str(showObj["id"]), logger.DEBUG) _finalize(parse_result) return (int(showObj["id"]), season, episodes) _finalize(parse_result) return to_return
def _addCacheEntry(self, name, url, season=None, episodes=None, tvdb_id=0, tvrage_id=0, quality=None, extraNames=[]): myDB = self._getDB() parse_result = None # if we don't have complete info then parse the filename to get it for curName in [name] + extraNames: try: myParser = NameParser() parse_result = myParser.parse(curName) except InvalidNameException: logger.log(u"Unable to parse the filename "+curName+" into a valid episode", logger.DEBUG) continue if not parse_result: logger.log(u"Giving up because I'm unable to parse this name: "+name, logger.DEBUG) return False if not parse_result.series_name: logger.log(u"No series name retrieved from "+name+", unable to cache it", logger.DEBUG) return False # if we need tvdb_id or tvrage_id then search the DB for them if not tvdb_id or not tvrage_id: # if we have only the tvdb_id, use the database if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if showObj: tvrage_id = showObj.tvrid else: logger.log(u"We were given a TVDB id "+str(tvdb_id)+" but it doesn't match a show we have in our list, so leaving tvrage_id empty", logger.DEBUG) tvrage_id = 0 # if we have only a tvrage_id then use the database elif tvrage_id: showObj = helpers.findCertainTVRageShow(sickbeard.showList, tvrage_id) if showObj: tvdb_id = showObj.tvdbid else: logger.log(u"We were given a TVRage id "+str(tvrage_id)+" but it doesn't match a show we have in our list, so leaving tvdb_id empty", logger.DEBUG) tvdb_id = 0 # if they're both empty then fill out as much info as possible by searching the show name else: showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: logger.log(parse_result.series_name+" was found to be show "+showResult[1]+" ("+str(showResult[0])+") in our DB.", logger.DEBUG) tvdb_id = showResult[0] else: logger.log(u"Couldn't figure out a show name straight from the DB, trying a regex search instead", logger.DEBUG) for curShow in sickbeard.showList: if sceneHelpers.isGoodResult(name, curShow, False): logger.log(u"Successfully matched "+name+" to "+curShow.name+" with regex", logger.DEBUG) tvdb_id = curShow.tvdbid break if tvdb_id: showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id) if not showObj: logger.log(u"This should never have happened, post a bug about this!", logger.ERROR) raise Exception("BAD STUFF HAPPENED") tvrage_id = showObj.tvrid if not season: season = parse_result.season_number if parse_result.season_number != None else 1 if not episodes: episodes = parse_result.episode_numbers # if we have an air-by-date show then get the real season/episode numbers if parse_result.air_by_date and tvdb_id: try: t = tvdb_api.Tvdb(**sickbeard.TVDB_API_PARMS) epObj = t[tvdb_id].airedOn(parse_result.air_date)[0] season = int(epObj["seasonnumber"]) episodes = [int(epObj["episodenumber"])] except tvdb_exceptions.tvdb_episodenotfound, e: logger.log(u"Unable to find episode with date "+str(parse_result.air_date)+" for show "+parse_result.series_name+", skipping", logger.WARNING) return False
def _analyze_name(self, name, file=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) 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 = show_name_helpers.sceneToNormalShowNames( parse_result.series_name) if not name_list: return (None, season, episodes) def _finalize(parse_result): self.release_group = parse_result.release_group # remember whether it's a proper if parse_result.extra_info: self.is_proper = re.search( '(^|[\. _-])(proper|repack)([\. _-]|$)', parse_result.extra_info, re.I) != None # if the result is complete then remember that for later if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group: test_name = os.path.basename(name) if test_name == self.nzb_name: self.good_results[self.NZB_NAME] = True elif test_name == self.folder_name: self.good_results[self.FOLDER_NAME] = True elif test_name == self.file_name: self.good_results[self.FILE_NAME] = True else: logger.log(u"Nothing was good, found " + repr(test_name) + " and wanted either " + repr(self.nzb_name) + ", " + repr(self.folder_name) + ", or " + repr(self.file_name)) else: logger.log( "Parse result not suficent(all folowing have to be set). will not save release name", logger.DEBUG) logger.log( "Parse result(series_name): " + str(parse_result.series_name), logger.DEBUG) logger.log( "Parse result(season_number): " + str(parse_result.season_number), logger.DEBUG) logger.log( "Parse result(episode_numbers): " + str(parse_result.episode_numbers), logger.DEBUG) logger.log( "Parse result(release_group): " + str(parse_result.release_group), logger.DEBUG) # 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 tvdb id " + str(scene_id) + u", 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 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): # 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): pass continue except (IOError): continue self._log( u"Lookup successful, using tvdb id " + str(showObj["id"]), logger.DEBUG) _finalize(parse_result) return (int(showObj["id"]), season, episodes) _finalize(parse_result) return to_return
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_name=True): """ Takes a name and tries to figure out a show, season, and episode from it. name: A string which we want to analyze to determine show info from (unicode) Returns a (tvdb_id, season, [episodes], quality) tuple. tvdb_id, season, quality may be None and episodes may be []. if none were found. """ logger.log(u"Analyzing name " + repr(name)) to_return = (None, None, [], None) if not name: return to_return name = helpers.remove_non_release_groups(helpers.remove_extension(name)) # parse the name to break it into show name, season, and episode np = NameParser(False) parse_result = np.parse(name) self._log(u"Parsed " + name + " into " + str(parse_result).decode('utf-8', 'xmlcharrefreplace'), 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, None) # do a scene reverse-lookup to get a list of all possible names name_list = show_name_helpers.sceneToNormalShowNames(parse_result.series_name) if not name_list: return (None, season, episodes, None) # try finding name in DB 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) self._finalize(parse_result) return (int(db_result[0]), season, episodes, None) # try finding name in scene exceptions 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 tvdb id " + str(scene_id) + u", using that", logger.DEBUG) self._finalize(parse_result) return (scene_id, season, episodes, None) # try finding name on TVDB 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): # 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): pass continue except (IOError): continue self._log(u"Lookup successful, using tvdb id " + str(showObj["id"]), logger.DEBUG) self._finalize(parse_result) return (int(showObj["id"]), season, episodes, None) self._finalize(parse_result) return to_return
def _addCacheEntry(self, name, url, quality=None): indexerid = None in_cache = False # if we don't have complete info then parse the filename to get it try: myParser = NameParser() parse_result = myParser.parse(name) except InvalidNameException: 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 cacheResult = sickbeard.name_cache.retrieveNameFromCache( parse_result.series_name) if cacheResult: in_cache = True indexerid = int(cacheResult) elif cacheResult == 0: return None if not indexerid: showResult = helpers.searchDBForShow(parse_result.series_name) if showResult: indexerid = int(showResult[0]) if not indexerid: for curShow in sickbeard.showList: if show_name_helpers.isGoodResult(name, curShow, False): indexerid = curShow.indexerid break showObj = None if indexerid: showObj = helpers.findCertainShow(sickbeard.showList, indexerid) if not showObj: logger.log( u"No match for show: [" + parse_result.series_name + "], not caching ...", logger.DEBUG) sickbeard.name_cache.addNameToCache(parse_result.series_name, 0) return None # scene -> indexer numbering parse_result = parse_result.convert(showObj) season = episodes = None if parse_result.air_by_date or parse_result.sports: myDB = db.DBConnection() airdate = parse_result.air_date.toordinal( ) or parse_result.sports_event_date.toordinal() sql_results = myDB.select( "SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?", [indexerid, showObj.indexer, airdate]) if sql_results > 0: season = int(sql_results[0]["season"]) episodes = [int(sql_results[0]["episode"])] else: season = parse_result.season_number if parse_result.season_number != None else 1 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') logger.log( u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG) if not in_cache: sickbeard.name_cache.addNameToCache(parse_result.series_name, indexerid) return [ "INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)", [ name, season, episodeText, indexerid, url, curTimestamp, quality ] ]