def get_show(self, name, tryIndexers=False): if not sickrage.showList: return showObj = None fromCache = False if not name: return showObj try: # check cache for show cache = sickrage.NAMECACHE.retrieveNameFromCache(name) if cache: fromCache = True showObj = findCertainShow(sickrage.showList, int(cache)) # try indexers if not showObj and tryIndexers: showObj = findCertainShow(sickrage.showList, searchIndexerForShowID(full_sanitizeSceneName(name), ui=ShowListUI)[2]) # try scene exceptions if not showObj: ShowID = get_scene_exception_by_name(name)[0] if ShowID: showObj = findCertainShow(sickrage.showList, int(ShowID)) # add show to cache if showObj and not fromCache: sickrage.NAMECACHE.addNameToCache(name, showObj.indexerid) except Exception as e: sickrage.LOGGER.debug("Error when attempting to find show: %s in SiCKRAGE. Error: %r " % (name, repr(e))) return showObj
def updateShows(self): sickrage.app.log.debug("SHOW_WATCHLIST::CHECK::START - Trakt Show Watchlist") if not len(self.ShowWatchlist): sickrage.app.log.debug("No shows found in your watchlist, aborting watchlist update") return for key, show in self.ShowWatchlist.items(): # get traktID and indexerID values trakt_id, indexer_id = key try: # determine indexer = IndexerApi().indexersByTraktID[trakt_id] except KeyError: continue if trakt_id == IndexerApi(indexer).trakt_id: if int(sickrage.app.config.trakt_method_add) != 2: self.addDefaultShow(indexer, indexer_id, show.title, SKIPPED) else: self.addDefaultShow(indexer, indexer_id, show.title, WANTED) if int(sickrage.app.config.trakt_method_add) == 1: newShow = findCertainShow(indexer_id) if newShow is not None: setEpisodeToWanted(newShow, 1, 1) else: self.todoWanted.append((indexer_id, 1, 1)) sickrage.app.log.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Show Watchlist")
def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, fallback_to_xem=True): """ Returns a tuple, (season, episode), with the scene numbering (if there is one), otherwise returns the xem numbering (if fallback_to_xem is set), otherwise returns the TVDB numbering. (so the return values will always be set) :param indexer_id: int ;param absolute_number: int :param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering :return: (int, int) a tuple with (season, episode) """ if indexer_id is None or absolute_number is None: return absolute_number indexer_id = int(indexer_id) indexer = int(indexer) showObj = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) if showObj and not showObj.is_scene: return absolute_number result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number) if result: return result else: if fallback_to_xem: xem_result = find_xem_absolute_numbering(indexer_id, indexer, absolute_number) if xem_result: return xem_result return absolute_number
def findPropers(self, search_date=datetime.datetime.today()): results = [] sqlResults = main_db.MainDB().select( 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + ' AND (e.status IN (' + ','.join([str(x) for x in Quality.DOWNLOADED]) + ')' + ' OR (e.status IN (' + ','.join([str(x) for x in Quality.SNATCHED]) + ')))' ) if not sqlResults: return [] for sqlshow in sqlResults: self.show = findCertainShow(sickrage.srCore.SHOWLIST, int(sqlshow["showid"])) if self.show: curEp = self.show.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"])) searchStrings = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK') for searchString in searchStrings: for item in self.search(searchString): title, url = self._get_title_and_url(item) if re.match(r'.*(REPACK|PROPER).*', title, re.I): results.append(Proper(title, url, datetime.datetime.today(), self.show)) return results
def addDefaultShow(indexer, indexer_id, name, status): """ Adds a new show with the default settings """ if not findCertainShow(sickrage.srCore.SHOWLIST, int(indexer_id)): sickrage.srCore.srLogger.info("Adding show " + str(indexer_id)) root_dirs = sickrage.srCore.srConfig.ROOT_DIRS.split('|') try: location = root_dirs[int(root_dirs[0]) + 1] except Exception: location = None if location: showPath = os.path.join(location, sanitizeFileName(name)) dir_exists = makeDir(showPath) if not dir_exists: sickrage.srCore.srLogger.warning("Unable to create the folder %s , can't add the show" % showPath) return else: chmodAsParent(showPath) sickrage.srCore.SHOWQUEUE.addShow(int(indexer), int(indexer_id), showPath, default_status=status, quality=int(sickrage.srCore.srConfig.QUALITY_DEFAULT), flatten_folders=int(sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT), paused=sickrage.srCore.srConfig.TRAKT_START_PAUSED, default_status_after=status, archive=sickrage.srCore.srConfig.ARCHIVE_DEFAULT) else: sickrage.srCore.srLogger.warning("There was an error creating the show, no root directory setting found") return
def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute_number=None, sceneSeason=None, sceneEpisode=None, sceneAbsolute=None): """ Set scene numbering for a season/episode. To clear the scene numbering, leave both sceneSeason and sceneEpisode as None. """ if indexer_id is None: return indexer_id = int(indexer_id) indexer = int(indexer) if season and episode: main_db.MainDB().action( "INSERT OR IGNORE INTO scene_numbering (indexer, indexer_id, season, episode) VALUES (?,?,?,?)", [indexer, indexer_id, season, episode]) main_db.MainDB().action( "UPDATE scene_numbering SET scene_season = ?, scene_episode = ? WHERE indexer = ? AND indexer_id = ? AND season = ? AND episode = ?", [sceneSeason, sceneEpisode, indexer, indexer_id, season, episode]) elif absolute_number: main_db.MainDB().action( "INSERT OR IGNORE INTO scene_numbering (indexer, indexer_id, absolute_number) VALUES (?,?,?)", [indexer, indexer_id, absolute_number]) main_db.MainDB().action( "UPDATE scene_numbering SET scene_absolute_number = ? WHERE indexer = ? AND indexer_id = ? AND absolute_number = ?", [sceneAbsolute, indexer, indexer_id, absolute_number]) # Reload data from DB so that cache and db are in sync show = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) show.flushEpisodes()
def updateShows(self): sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::START - Trakt Show Watchlist") if not len(self.ShowWatchlist): sickrage.srCore.srLogger.debug("No shows found in your watchlist, aborting watchlist update") return indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER) trakt_id = srIndexerApi(indexer).config['trakt_id'] for show_el in self.ShowWatchlist[trakt_id]: indexer_id = int(str(show_el)) show = self.ShowWatchlist[trakt_id][show_el] # LOGGER.debug(u"Checking Show: %s %s %s" % (trakt_id, indexer_id, show['title'])) if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) != 2: self.addDefaultShow(indexer, indexer_id, show['title'], SKIPPED) else: self.addDefaultShow(indexer, indexer_id, show['title'], WANTED) if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) == 1: newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) if newShow is not None: setEpisodeToWanted(newShow, 1, 1) else: self.todoWanted.append((indexer_id, 1, 1)) sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Show Watchlist")
def get_scene_numbering(indexer_id, indexer, season, episode, fallback_to_xem=True): """ Returns a tuple, (season, episode), with the scene numbering (if there is one), otherwise returns the xem numbering (if fallback_to_xem is set), otherwise returns the TVDB numbering. (so the return values will always be set) :param indexer_id: int :param season: int :param episode: int :param fallback_to_xem: bool If set (the default), check xem for matches if there is no local scene numbering :return: (int, int) a tuple with (season, episode) """ if indexer_id is None or season is None or episode is None: return season, episode showObj = findCertainShow(sickrage.showList, int(indexer_id)) if showObj and not showObj.is_scene: return season, episode result = find_scene_numbering(int(indexer_id), int(indexer), season, episode) if result: return result else: if fallback_to_xem: xem_result = find_xem_numbering(int(indexer_id), int(indexer), season, episode) if xem_result: return xem_result return season, episode
def addDefaultShow(indexer, indexer_id, name, status): """ Adds a new show with the default settings """ if not findCertainShow(int(indexer_id)): sickrage.app.log.info("Adding show " + str(indexer_id)) root_dirs = sickrage.app.config.root_dirs.split('|') try: location = root_dirs[int(root_dirs[0]) + 1] except Exception: location = None if location: showPath = os.path.join(location, sanitizeFileName(name)) dir_exists = makeDir(showPath) if not dir_exists: sickrage.app.log.warning("Unable to create the folder %s , can't add the show" % showPath) return else: chmod_as_parent(showPath) sickrage.app.show_queue.addShow(int(indexer), int(indexer_id), showPath, default_status=status, quality=int(sickrage.app.config.quality_default), flatten_folders=int(sickrage.app.config.flatten_folders_default), paused=sickrage.app.config.trakt_start_paused, default_status_after=status, skip_downloaded=sickrage.app.config.skip_downloaded_default) else: sickrage.app.log.warning( "There was an error creating the show, no root directory setting found") return
def set_scene_numbering(indexer_id, indexer, season=0, episode=0, absolute_number=0, sceneSeason=0, sceneEpisode=0, sceneAbsolute=0): """ Set scene numbering for a season/episode. To clear the scene numbering, leave both sceneSeason and sceneEpisode as None. """ if indexer_id is None: return indexer_id = int(indexer_id) indexer = int(indexer) if season and episode: dbData = [x for x in sickrage.app.main_db.get_many('scene_numbering', indexer_id) if x['index'] == indexer and x['season'] == season and x['episode'] == episode] if len(dbData): dbData[0]['scene_season'] = sceneSeason dbData[0]['scene_episode'] = sceneEpisode sickrage.app.main_db.update(dbData[0]) else: sickrage.app.main_db.insert({ '_t': 'scene_numbering', 'indexer': indexer, 'indexer_id': indexer_id, 'season': season, 'episode': episode, 'scene_season': sceneSeason, 'scene_episode': sceneEpisode, 'absolute_number': absolute_number, 'scene_absolute_number': sceneAbsolute }) elif absolute_number: dbData = [x for x in sickrage.app.main_db.get_many('scene_numbering', indexer_id) if x['index'] == indexer and x['absolute_number'] == absolute_number] if len(dbData): dbData[0]['scene_absolute_number'] = sceneAbsolute sickrage.app.main_db.update(dbData[0]) else: sickrage.app.main_db.insert({ '_t': 'scene_numbering', 'indexer': indexer, 'indexer_id': indexer_id, 'season': season, 'episode': episode, 'scene_season': sceneSeason, 'scene_episode': sceneEpisode, 'absolute_number': absolute_number, 'scene_absolute_number': sceneAbsolute }) # Reload data from DB so that cache and db are in sync show = findCertainShow(indexer_id) show.flush_episodes()
def addCacheEntry(self, name, url, parse_result=None, indexer_id=0): # check if we passed in a parsed result or should we try and create one if not parse_result: # create showObj from indexer_id if available showObj = None if indexer_id: showObj = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) try: myParser = NameParser(showObj=showObj) parse_result = myParser.parse(name) if not parse_result: return except (InvalidShowException, InvalidNameException): sickrage.srCore.srLogger.debug("RSS ITEM:[{}] IGNORED!".format(name)) return if not parse_result.series_name: return # if we made it this far then lets add the parsed result to cache for usager later on season = parse_result.season_number if parse_result.season_number 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 quality = parse_result.quality # get release group release_group = parse_result.release_group # get version version = parse_result.version if not len([x for x in sickrage.srCore.cacheDB.db.get_many('providers', self.providerID, with_doc=True) if x['doc']['url'] == url]): sickrage.srCore.cacheDB.db.insert({ '_t': 'providers', 'provider': self.providerID, 'name': name, 'season': season, 'episodes': episodeText, 'indexerid': parse_result.show.indexerid, 'url': url, 'time': curTimestamp, 'quality': quality, 'release_group': release_group, 'version': version }) sickrage.srCore.srLogger.debug("RSS ITEM:[%s] ADDED!", name)
def get_show(self): """ :return: The show object associated with ``self.indexer_id`` or ``None`` """ try: return findCertainShow(self.indexer_id) except MultipleShowObjectsException: return None
def get_show(self, name): show = None show_id = None show_names = [name] if not all([name, sickrage.app.showlist]): return show, show_id def cache_lookup(term): return sickrage.app.name_cache.get(term) def scene_exception_lookup(term): return get_scene_exception_by_name(term)[0] def showlist_lookup(term): try: return search_showlist_by_name(term).indexerid except MultipleShowObjectsException: return None show_names.append(strip_accents(name)) show_names.append(strip_accents(name).replace("'", " ")) for show_name in set(show_names): lookup_list = [ lambda: cache_lookup(show_name), lambda: scene_exception_lookup(show_name), lambda: showlist_lookup(show_name), ] # lookup show id for lookup in lookup_list: try: show_id = int(lookup()) if show_id == 0: continue sickrage.app.name_cache.put(show_name, show_id) if not show: if self.validate_show: show = findCertainShow(show_id) else: from sickrage.core.tv.show import TVShow show = TVShow(1, show_id) except Exception: pass if show_id is None: # ignore show name by caching it with a indexerid of 0 sickrage.app.name_cache.put(show_name, 0) return show, show_id or 0
def searchForShowID(self, regShowName, showid=None, ui=ShowListUI): """ Contacts indexer to check for information on shows by showid :param regShowName: Name of show :param showid: Which indexer ID to look for :param ui: Custom UI for indexer use :return: """ showNames = [re.sub('[. -]', ' ', regShowName)] # Query Indexers for each search term and build the list of results # Query Indexers for each search term and build the list of results lINDEXER_API_PARMS = self.api_params.copy() if ui is not None: lINDEXER_API_PARMS['custom_ui'] = ui t = self.indexer(**lINDEXER_API_PARMS) for name in showNames: sickrage.srCore.srLogger.debug("Trying to find " + name + " on " + self.name) try: search = t[showid] if showid else t[name] except Exception: continue try: seriesname = search[0]['seriesname'] except Exception: seriesname = None try: series_id = search[0]['id'] except Exception: series_id = None if not (seriesname and series_id): continue ShowObj = findCertainShow(sickrage.srCore.SHOWLIST, int(series_id)) # Check if we can find the show in our list (if not, it's not the right show) if (showid is None) and (ShowObj is not None) and (ShowObj.indexerid == int(series_id)): return seriesname, self.indexerID, int(series_id) elif (showid is not None) and (int(showid) == int(series_id)): return seriesname, self.indexerID, int(showid) return None, None, None
def _addCacheEntry(self, name, url, parse_result=None, indexer_id=0): # check if we passed in a parsed result or should we try and create one if not parse_result: # create showObj from indexer_id if available showObj = None if indexer_id: showObj = findCertainShow(sickrage.showList, indexer_id) try: myParser = NameParser(showObj=showObj) parse_result = myParser.parse(name) except InvalidNameException: sickrage.LOGGER.debug("Unable to parse the filename " + name + " into a valid episode") return None except InvalidShowException: sickrage.LOGGER.debug("Unable to parse the filename " + name + " into a valid show") return None if not parse_result or not parse_result.series_name: return None # if we made it this far then lets add the parsed result to cache for usager later on season = parse_result.season_number if parse_result.season_number 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 quality = parse_result.quality # get release group release_group = parse_result.release_group # get version version = parse_result.version sickrage.LOGGER.debug("Added RSS item: [" + name + "] to cache: [" + self.providerID + "]") return [ "INSERT OR IGNORE INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality, release_group, version) VALUES (?,?,?,?,?,?,?,?,?)", [name, season, episodeText, parse_result.show.indexerid, url, curTimestamp, quality, release_group, version]]
def get_show(self, name, tryIndexers=False): if not sickrage.srCore.SHOWLIST: return showObj = None fromCache = False if not name: return showObj try: # check cache for show cache = sickrage.srCore.NAMECACHE.get(name) if cache: fromCache = True showObj = findCertainShow(sickrage.srCore.SHOWLIST, int(cache)) # try indexers if not showObj and tryIndexers: showObj = findCertainShow(sickrage.srCore.SHOWLIST, srIndexerApi().searchForShowID(full_sanitizeSceneName(name))[2]) # try scene exceptions if not showObj: ShowID = get_scene_exception_by_name(name)[0] if ShowID: showObj = findCertainShow(sickrage.srCore.SHOWLIST, int(ShowID)) # add show to cache if showObj and not fromCache: sickrage.srCore.NAMECACHE.put(name, showObj.indexerid) except Exception as e: sickrage.srCore.srLogger.debug( "Error when attempting to find show: %s in SiCKRAGE. Error: %r " % (name, repr(e))) return showObj
def get_episodes_list(epids, showid=None): if epids is None or len(epids) == 0: return [] query = "SELECT * FROM tv_episodes WHERE indexerid in (%s)" % (",".join(['?'] * len(epids)),) params = epids if showid is not None: query += " AND showid = ?" params.append(showid) eplist = [] for curEp in main_db.MainDB().select(query, params): curshowobj = findCertainShow(sickrage.showList, int(curEp[b"showid"])) eplist += [curshowobj.getEpisode(int(curEp[b"season"]), int(curEp[b"episode"]))] return eplist
def test_unaired(self): count = 0 for episode in sickrage.app.main_db.all('tv_episodes'): if all([episode['status'] == UNAIRED, episode['season'] > 0, episode['airdate'] > 1]): count += 1 show = helpers.findCertainShow(int(episode["showid"])) ep = TVEpisode(show, 1, episode['episode']) ep.indexerid = episode['episode'] ep.name = "test episode {}".format(episode['episode']) ep.airdate = datetime.date.fromordinal(733832) ep.status = UNAIRED ep.save_to_db() self.assertEqual(count, 3)
def new_episode_finder(): curDate = datetime.date.today() curDate += datetime.timedelta(days=1) curTime = datetime.datetime.now(sickrage.app.tz) show = None for episode in sickrage.app.main_db.all('tv_episodes'): if not all([episode['status'] == UNAIRED, episode['season'] > 0, episode['airdate'] > 1]): continue if not show or int(episode["showid"]) != show.indexerid: show = helpers.findCertainShow(int(episode["showid"])) # for when there is orphaned series in the database but not loaded into our showlist if not show or show.paused: continue air_date = datetime.date.fromordinal(episode['airdate']) air_date += datetime.timedelta(days=show.search_delay) if not curDate.toordinal() >= air_date.toordinal(): continue if show.airs and show.network: # This is how you assure it is always converted to local time air_time = sickrage.app.tz_updater.parse_date_time(episode['airdate'], show.airs, show.network).astimezone(sickrage.app.tz) # filter out any episodes that haven't started airing yet, # but set them to the default status while they are airing # so they are snatched faster if air_time > curTime: continue ep_obj = show.get_episode(int(episode['season']), int(episode['episode'])) with ep_obj.lock: ep_obj.status = show.default_ep_status if ep_obj.season else SKIPPED sickrage.app.log.info('Setting status ({status}) for show airing today: {name} {special}'.format( name=ep_obj.pretty_name(), status=statusStrings[ep_obj.status], special='(specials are not supported)' if not ep_obj.season else '', )) ep_obj.save_to_db()
def find_propers(self, search_date=datetime.datetime.today()): results = [] for show in [s['doc'] for s in sickrage.srCore.mainDB.db.all('tv_shows', with_doc=True)]: for episode in [e['doc'] for e in sickrage.srCore.mainDB.db.get_many('tv_episodes', show['indexer_id'], with_doc=True)]: if episode['airdate'] >= str(search_date.toordinal()) \ and episode['status'] in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_BEST: self.show = findCertainShow(sickrage.srCore.SHOWLIST, int(episode["showid"])) if not show: continue curEp = show.getEpisode(int(episode["season"]), int(episode["episode"])) for term in self.proper_strings: searchString = self._get_episode_search_strings(curEp, add_string=term) for item in self.search(searchString[0]): title, url = self._get_title_and_url(item) results.append(Proper(title, url, datetime.datetime.today(), self.show)) return results
def updateEpisodes(self): """ Sets episodes to wanted that are in trakt watchlist """ sickrage.app.log.debug("SHOW_WATCHLIST::CHECK::START - Trakt Episode Watchlist") if not len(self.EpisodeWatchlist): sickrage.app.log.debug("No episode found in your watchlist, aborting episode update") return managed_show = [] for key, show in self.EpisodeWatchlist.items(): # get traktID and indexerID values trakt_id, indexer_id = key try: # determine indexer = IndexerApi().indexersByTraktID[trakt_id] except KeyError: continue newShow = findCertainShow(indexer_id) try: if newShow is None: if indexer_id not in managed_show: self.addDefaultShow(indexer, indexer_id, show.title, SKIPPED) managed_show.append(indexer_id) for season_number, season in show.seasons.items(): for episode_number, _ in season.episodes.items(): self.todoWanted.append((int(indexer_id), int(season_number), int(episode_number))) else: if newShow.indexer == indexer: for season_number, season in show.seasons.items(): for episode_number, _ in season.episodes.items(): setEpisodeToWanted(newShow, int(season_number), int(episode_number)) except TypeError: sickrage.app.log.debug("Could not parse the output from trakt for %s " % show.title) sickrage.app.log.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Episode Watchlist")
def updateEpisodes(self): """ Sets episodes to wanted that are in trakt watchlist """ sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::START - Trakt Episode Watchlist") if not len(self.EpisodeWatchlist): sickrage.srCore.srLogger.debug("No episode found in your watchlist, aborting episode update") return managed_show = [] indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER) trakt_id = srIndexerApi(indexer).config['trakt_id'] for show_el in self.EpisodeWatchlist[trakt_id]: indexer_id = int(show_el) show = self.EpisodeWatchlist[trakt_id][show_el] newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) try: if newShow is None: if indexer_id not in managed_show: self.addDefaultShow(indexer, indexer_id, show['title'], SKIPPED) managed_show.append(indexer_id) for season_el in show['seasons']: season = int(season_el) for episode_el in show['seasons'][season_el]['episodes']: self.todoWanted.append((indexer_id, season, int(episode_el))) else: if newShow.indexer == indexer: for season_el in show['seasons']: season = int(season_el) for episode_el in show['seasons'][season_el]['episodes']: setEpisodeToWanted(newShow, season, int(episode_el)) except TypeError: sickrage.srCore.srLogger.debug("Could not parse the output from trakt for %s " % show["title"]) sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Episode Watchlist")
def get_show(self, name): show = None show_id = 0 fromCache = False if not all([name, sickrage.app.showlist]): return show, show_id try: # check cache for show cache = sickrage.app.name_cache.get(name) if cache: fromCache = True show_id = cache # try indexers if not show_id and self.tryIndexers: try: show_id1 = int(IndexerApi().searchForShowID(full_sanitizeSceneName(name))[2]) show_id2 = int(srTraktAPI()['search'].query(full_sanitizeSceneName(name), 'show')[0].ids['tvdb']) show_id = (show_id, show_id1)[show_id1 == show_id2] except Exception: pass # try scene exceptions if not show_id: try: show_id = get_scene_exception_by_name(name)[0] except Exception: pass # create show object show = findCertainShow(sickrage.app.showlist, int(show_id)) if show_id else None # add show to cache if show and not fromCache: sickrage.app.name_cache.put(name, show.indexerid) except Exception as e: sickrage.app.log.debug( "Error when attempting to find show: %s in SiCKRAGE. Error: %r " % (name, repr(e))) return show, show_id or 0
def find_propers(self, search_date=datetime.datetime.today()): results = [] dbData = [] for show in [s['doc'] for s in sickrage.srCore.mainDB.db.all('tv_shows', with_doc=True)]: for episode in [e['doc'] for e in sickrage.srCore.mainDB.db.get_many('tv_episodes', show['indexer_id'], with_doc=True)]: if episode['airdate'] >= str(search_date.toordinal()) \ and episode['status'] in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_BEST: self.show = findCertainShow(sickrage.srCore.SHOWLIST, int(show["showid"])) if not self.show: continue curEp = self.show.getEpisode(int(episode["season"]), int(episode["episode"])) searchStrings = self._get_episode_search_strings(curEp, add_string='PROPER|REPACK') for searchString in searchStrings: for item in self.search(searchString): title, url = self._get_title_and_url(item) if re.match(r'.*(REPACK|PROPER).*', title, re.I): results += [Proper(title, url, datetime.datetime.today(), self.show)] return results
def findPropers(self, search_date=datetime.datetime.today()): results = [] sqlResults = main_db.MainDB().select( 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate FROM tv_episodes AS e' + ' INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id)' + ' WHERE e.airdate >= ' + str(search_date.toordinal()) + ' AND e.status IN (' + ','.join( [str(x) for x in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_BEST]) + ')' ) for sqlshow in sqlResults or []: show = findCertainShow(sickrage.srCore.SHOWLIST, int(sqlshow["showid"])) if show: curEp = show.getEpisode(int(sqlshow["season"]), int(sqlshow["episode"])) for term in self.proper_strings: searchString = self._get_episode_search_strings(curEp, add_string=term) for item in self.search(searchString[0]): title, url = self._get_title_and_url(item) results.append(Proper(title, url, datetime.datetime.today(), show)) return results
def run(self, force=False): if self.amActive: return self.amActive = True if len(getEnabledServiceList()) < 1: sickrage.LOGGER.warning( 'Not enough services selected. At least 1 service is required to search subtitles in the background' ) return sickrage.LOGGER.info('Checking for subtitles') # get episodes on which we want subtitles # criteria is: # - show subtitles = 1 # - episode subtitles != config wanted languages or 'und' (depends on config multi) # - search count < 2 and diff(airdate, now) > 1 week : now -> 1d # - search count < 7 and diff(airdate, now) <= 1 week : now -> 4h -> 8h -> 16h -> 1d -> 1d -> 1d today = datetime.date.today().toordinal() # you have 5 minutes to understand that one. Good luck sqlResults = main_db.MainDB().select( 'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.subtitles, ' + 'e.subtitles_searchcount AS searchcount, e.subtitles_lastsearch AS lastsearch, e.location, (? - e.airdate) AS airdate_daydiff ' + 'FROM tv_episodes AS e INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id) ' + 'WHERE s.subtitles = 1 AND e.subtitles NOT LIKE (?) ' + 'AND (e.subtitles_searchcount <= 2 OR (e.subtitles_searchcount <= 7 AND airdate_daydiff <= 7)) ' + 'AND e.location != ""', [today, wantedLanguages(True)]) if len(sqlResults) == 0: sickrage.LOGGER.info('No subtitles to download') return rules = self._getRules() now = datetime.datetime.now() for epToSub in sqlResults: if not os.path.isfile(epToSub[b'location']): sickrage.LOGGER.debug('Episode file does not exist, cannot download subtitles for episode %dx%d of show %s' % ( epToSub[b'season'], epToSub[b'episode'], epToSub[b'show_name'])) continue # http://bugs.python.org/issue7980#msg221094 # I dont think this needs done here, but keeping to be safe datetime.datetime.strptime('20110101', '%Y%m%d') if ( (epToSub[b'airdate_daydiff'] > 7 and epToSub[ b'searchcount'] < 2 and now - datetime.datetime.strptime( epToSub[b'lastsearch'], dateTimeFormat) > datetime.timedelta( hours=rules['old'][epToSub[b'searchcount']])) or ( epToSub[b'airdate_daydiff'] <= 7 and epToSub[b'searchcount'] < 7 and now - datetime.datetime.strptime( epToSub[b'lastsearch'], dateTimeFormat) > datetime.timedelta ( hours=rules[b'new'][epToSub[b'searchcount']] ) ) ): sickrage.LOGGER.debug('Downloading subtitles for episode %dx%d of show %s' % ( epToSub[b'season'], epToSub[b'episode'], epToSub[b'show_name'])) showObj = findCertainShow(sickrage.showList, int(epToSub[b'showid'])) if not showObj: sickrage.LOGGER.debug('Show not found') return epObj = showObj.getEpisode(int(epToSub[b"season"]), int(epToSub[b"episode"])) if isinstance(epObj, str): sickrage.LOGGER.debug('Episode not found') return existing_subtitles = epObj.subtitles try: epObj.downloadSubtitles() except Exception as e: sickrage.LOGGER.debug('Unable to find subtitles') sickrage.LOGGER.debug(str(e)) return newSubtitles = frozenset(epObj.subtitles).difference(existing_subtitles) if newSubtitles: sickrage.LOGGER.info('Downloaded subtitles for S%02dE%02d in %s' % ( epToSub[b"season"], epToSub[b"episode"], ', '.join(newSubtitles))) self.amActive = False
def run(self): sickrage.srCore.srLogger.info( "Started adding show {} from show dir: {}".format( self.show_name, self.showDir)) index_name = srIndexerApi(self.indexer).name # make sure the Indexer IDs are valid try: lINDEXER_API_PARMS = srIndexerApi(self.indexer).api_params.copy() lINDEXER_API_PARMS[ 'language'] = self.lang or sickrage.srCore.srConfig.INDEXER_DEFAULT_LANGUAGE sickrage.srCore.srLogger.info("{}: {}".format( index_name, repr(lINDEXER_API_PARMS))) t = srIndexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) s = t[self.indexer_id] if not s: return self._finishEarly() # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show if not getattr(s, 'seriesname'): sickrage.srCore.srLogger.error( "Show in {} has no name on {}, probably the wrong language used to search with" .format(self.showDir, index_name)) sickrage.srCore.srNotifications.error( "Unable to add show", "Show in {} has no name on {}, probably the wrong language. Delete .nfo and add manually in the correct language" .format(self.showDir, index_name)) return self._finishEarly() # if the show has no episodes/seasons if not len(s): sickrage.srCore.srLogger.error( "Show " + str(s['seriesname']) + " is on " + str(srIndexerApi(self.indexer).name) + " but contains no season/episode data.") sickrage.srCore.srNotifications.error( "Unable to add show", "Show " + str(s['seriesname']) + " is on " + str(srIndexerApi(self.indexer).name) + " but contains no season/episode data.") return self._finishEarly() except Exception as e: sickrage.srCore.srLogger.error( "{}: Error while loading information from indexer {}. Error: {}" .format(self.indexer_id, index_name, e.message)) sickrage.srCore.srNotifications.error( "Unable to add show", "Unable to look up the show in {} on {} using ID {}, not using the NFO. Delete .nfo and try adding manually again." .format(self.showDir, index_name, self.indexer_id)) if sickrage.srCore.srConfig.USE_TRAKT: trakt_id = srIndexerApi(self.indexer).config['trakt_id'] trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.TRAKT_TIMEOUT) title = self.showDir.split("/")[-1] data = {'shows': [{'title': title, 'ids': {}}]} if trakt_id == 'tvdb_id': data['shows'][0]['ids']['tvdb'] = self.indexer_id else: data['shows'][0]['ids']['tvrage'] = self.indexer_id trakt_api.traktRequest("sync/watchlist/remove", data, method='POST') return self._finishEarly() try: self.show = TVShow(self.indexer, self.indexer_id, self.lang) self.show.loadFromIndexer(cache=False) # set up initial values self.show.location = self.showDir self.show.subtitles = self.subtitles or sickrage.srCore.srConfig.SUBTITLES_DEFAULT self.show.subtitles_sr_metadata = self.subtitles_sr_metadata self.show.quality = self.quality or sickrage.srCore.srConfig.QUALITY_DEFAULT self.show.flatten_folders = self.flatten_folders or sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT self.show.anime = self.anime or sickrage.srCore.srConfig.ANIME_DEFAULT self.show.scene = self.scene or sickrage.srCore.srConfig.SCENE_DEFAULT self.show.archive_firstmatch = self.archive or sickrage.srCore.srConfig.ARCHIVE_DEFAULT self.show.paused = self.paused or False # set up default new/missing episode status sickrage.srCore.srLogger.info( "Setting all current episodes to the specified default status: " + str(self.default_status)) self.show.default_ep_status = self.default_status if self.show.anime: self.show.release_groups = BlackAndWhiteList( self.show.indexerid) if self.blacklist: self.show.release_groups.set_black_keywords(self.blacklist) if self.whitelist: self.show.release_groups.set_white_keywords(self.whitelist) # # be smartish about this # if self.show.genre and "talk show" in self.show.genre.lower(): # self.show.air_by_date = 1 # if self.show.genre and "documentary" in self.show.genre.lower(): # self.show.air_by_date = 0 # if self.show.classification and "sports" in self.show.classification.lower(): # self.show.sports = 1 except indexer_exception as e: sickrage.srCore.srLogger.error( "Unable to add show due to an error with " + srIndexerApi(self.indexer).name + ": {}".format(e.message)) if self.show: sickrage.srCore.srNotifications.error( "Unable to add " + str(self.show.name) + " due to an error with " + srIndexerApi(self.indexer).name + "") else: sickrage.srCore.srNotifications.error( "Unable to add show due to an error with " + srIndexerApi(self.indexer).name + "") return self._finishEarly() except MultipleShowObjectsException: sickrage.srCore.srLogger.warning( "The show in " + self.showDir + " is already in your show list, skipping") sickrage.srCore.srNotifications.error( 'Show skipped', "The show in " + self.showDir + " is already in your show list") return self._finishEarly() except Exception as e: sickrage.srCore.srLogger.error( "Error trying to add show: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) raise self._finishEarly() try: sickrage.srCore.srLogger.debug( "Attempting to retrieve show info from IMDb") self.show.loadIMDbInfo() except Exception as e: sickrage.srCore.srLogger.error( "Error loading IMDb info: {}".format(e.message)) try: self.show.saveToDB() except Exception as e: sickrage.srCore.srLogger.error( "Error saving the show to the database: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) raise self._finishEarly() # add it to the show list if not findCertainShow(sickrage.srCore.SHOWLIST, self.indexer_id): sickrage.srCore.SHOWLIST.append(self.show) try: self.show.loadEpisodesFromIndexer() except Exception as e: sickrage.srCore.srLogger.error( "Error with " + srIndexerApi(self.show.indexer).name + ", not creating episode list: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) try: self.show.loadEpisodesFromDir() except Exception as e: sickrage.srCore.srLogger.debug( "Error searching dir for episodes: {}".format(e.message)) sickrage.srCore.srLogger.debug(traceback.format_exc()) # if they set default ep status to WANTED then run the backlog to search for episodes if self.show.default_ep_status == WANTED: sickrage.srCore.srLogger.info( "Launching backlog for this show since its episodes are WANTED" ) sickrage.srCore.BACKLOGSEARCHER.searchBacklog([self.show]) self.show.writeMetadata() self.show.updateMetadata() self.show.populateCache() if sickrage.srCore.srConfig.USE_TRAKT: # if there are specific episodes that need to be added by trakt sickrage.srCore.TRAKTSEARCHER.manageNewShow(self.show) # add show to trakt.tv library if sickrage.srCore.srConfig.TRAKT_SYNC: sickrage.srCore.TRAKTSEARCHER.addShowToTraktLibrary(self.show) if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST: sickrage.srCore.srLogger.info("update watchlist") sickrage.srCore.notifiersDict['trakt'].update_watchlist( show_obj=self.show) # Load XEM data to DB for show xem_refresh(self.show.indexerid, self.show.indexer, force=True) # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering. if not self.scene and get_xem_numbering_for_show( self.show.indexerid, self.show.indexer): self.show.scene = 1 self.show.default_ep_status = self.default_status_after self.show.saveToDB() sickrage.srCore.NAMECACHE.build(self.show) self.finish() sickrage.srCore.srLogger.info( "Finished adding show {} from show dir: {}".format( self.show_name, self.showDir))
def addCacheEntry(self, name, url, parse_result=None, indexer_id=0): # check if we passed in a parsed result or should we try and create one if not parse_result: # create showObj from indexer_id if available showObj = None if indexer_id: showObj = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) try: myParser = NameParser(showObj=showObj) parse_result = myParser.parse(name) if not parse_result: return except (InvalidShowException, InvalidNameException): sickrage.srCore.srLogger.debug( "RSS ITEM:[{}] IGNORED!".format(name)) return if not parse_result.series_name: return # if we made it this far then lets add the parsed result to cache for usager later on season = parse_result.season_number if parse_result.season_number 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 quality = parse_result.quality # get release group release_group = parse_result.release_group # get version version = parse_result.version if not len([ x for x in sickrage.srCore.cacheDB.db.get_many( 'providers', self.providerID, with_doc=True) if x['doc']['url'] == url ]): sickrage.srCore.cacheDB.db.insert({ '_t': 'providers', 'provider': self.providerID, 'name': name, 'season': season, 'episodes': episodeText, 'indexerid': parse_result.show.indexerid, 'url': url, 'time': curTimestamp, 'quality': quality, 'release_group': release_group, 'version': version }) sickrage.srCore.srLogger.debug("RSS ITEM:[%s] ADDED!", name)
def search_cache(self, episode=None, manualSearch=False, downCurQuality=False): neededEps = {} if not episode: dbData = [ x['doc'] for x in sickrage.srCore.cacheDB.db.get_many( 'providers', self.providerID, with_doc=True) ] else: dbData = [ x['doc'] for x in sickrage.srCore.cacheDB.db.get_many( 'providers', self.providerID, with_doc=True) if x['doc']['indexerid'] == episode.show.indexerid and x['doc']['season'] == episode.season and "|" + str(episode.episode) + "|" in x['doc']['episodes'] ] # for each cache entry for curResult in dbData: # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult["name"]): continue # get the show object, or if it's not one of our shows then ignore it showObj = findCertainShow(sickrage.srCore.SHOWLIST, int(curResult["indexerid"])) if not showObj: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not showObj.is_anime: sickrage.srCore.srLogger.debug("" + str(showObj.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult["season"]) if curSeason == -1: continue curEp = curResult["episodes"].split("|")[1] if not curEp: continue curEp = int(curEp) curQuality = int(curResult["quality"]) curReleaseGroup = curResult["release_group"] curVersion = curResult["version"] # if the show says we want that episode then add it to the list if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch, downCurQuality): sickrage.srCore.srLogger.info( "Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[curQuality]) continue epObj = showObj.getEpisode(curSeason, curEp) # build a result object title = curResult["name"] url = curResult["url"] sickrage.srCore.srLogger.info("Found result " + title + " at " + url) result = self.provider.getResult([epObj]) result.show = showObj result.url = url result.name = title result.quality = curQuality result.release_group = curReleaseGroup result.version = curVersion result.content = None result.size = self.provider._get_size(url) result.files = self.provider._get_files(url) # add it to the list if epObj not in neededEps: neededEps[epObj.episode] = [result] else: neededEps[epObj.episode].append(result) # datetime stamp this search so cache gets cleared self.last_search = datetime.datetime.today() return neededEps
def run(self, force=False): if self.amActive or sickrage.app.developer: return self.amActive = True # set thread name threading.currentThread().setName(self.name) if len(sickrage.subtitles.getEnabledServiceList()) < 1: sickrage.app.log.warning( 'Not enough services selected. At least 1 service is required to search subtitles in the background' ) return sickrage.app.log.info('Checking for subtitles') # get episodes on which we want subtitles # criteria is: # - show subtitles = 1 # - episode subtitles != config wanted languages or 'und' (depends on config multi) # - search count < 2 and diff(airdate, now) > 1 week : now -> 1d # - search count < 7 and diff(airdate, now) <= 1 week : now -> 4h -> 8h -> 16h -> 1d -> 1d -> 1d today = datetime.date.today().toordinal() results = [] for s in [s['doc'] for s in sickrage.app.main_db.db.all('tv_shows', with_doc=True)]: for e in [e['doc'] for e in sickrage.app.main_db.db.get_many('tv_episodes', s['indexer_id'], with_doc=True) if s['subtitles'] == 1 and e['doc']['location'] != '' and e['doc']['subtitles'] not in sickrage.subtitles.wanted_languages() and (e['doc']['subtitles_searchcount'] <= 2 or ( e['doc']['subtitles_searchcount'] <= 7 and (today - e['doc']['airdate'])))]: results += [{ 'show_name': s['show_name'], 'showid': e['showid'], 'season': e['season'], 'episode': e['episode'], 'status': e['status'], 'subtitles': e['subtitles'], 'searchcount': e['subtitles_searchcount'], 'lastsearch': e['subtitles_lastsearch'], 'location': e['location'], 'airdate_daydiff': (today - e['airdate']) }] if len(results) == 0: sickrage.app.log.info('No subtitles to download') return rules = self._getRules() now = datetime.datetime.now() for epToSub in results: if not os.path.isfile(epToSub['location']): sickrage.app.log.debug( 'Episode file does not exist, cannot download subtitles for episode %dx%d of show %s' % ( epToSub['season'], epToSub['episode'], epToSub['show_name'])) continue # http://bugs.python.org/issue7980#msg221094 # I dont think this needs done here, but keeping to be safe datetime.datetime.strptime('20110101', '%Y%m%d') if ( (epToSub['airdate_daydiff'] > 7 and epToSub[ 'searchcount'] < 2 and now - datetime.datetime.strptime( epToSub['lastsearch'], dateTimeFormat) > datetime.timedelta( hours=rules['old'][epToSub['searchcount']])) or ( epToSub['airdate_daydiff'] <= 7 and epToSub['searchcount'] < 7 and now - datetime.datetime.strptime( epToSub['lastsearch'], dateTimeFormat) > datetime.timedelta ( hours=rules['new'][epToSub['searchcount']] ) ) ): sickrage.app.log.debug('Downloading subtitles for episode %dx%d of show %s' % ( epToSub['season'], epToSub['episode'], epToSub['show_name'])) showObj = findCertainShow(sickrage.app.showlist, int(epToSub['showid'])) if not showObj: sickrage.app.log.debug('Show not found') return epObj = showObj.getEpisode(int(epToSub["season"]), int(epToSub["episode"])) if isinstance(epObj, str): sickrage.app.log.debug('Episode not found') return existing_subtitles = epObj.subtitles try: epObj.downloadSubtitles() except Exception as e: sickrage.app.log.debug('Unable to find subtitles') sickrage.app.log.debug(str(e)) return newSubtitles = frozenset(epObj.subtitles).difference(existing_subtitles) if newSubtitles: sickrage.app.log.info('Downloaded subtitles for S%02dE%02d in %s' % ( epToSub["season"], epToSub["episode"], ', '.join(newSubtitles))) self.amActive = False
def run(self, force=False): if self.amActive or (not sickrage.app.config.use_subtitles or sickrage.app.developer) and not force: return self.amActive = True # set thread name threading.currentThread().setName(self.name) if len(sickrage.subtitles.getEnabledServiceList()) < 1: sickrage.app.log.warning( 'Not enough services selected. At least 1 service is required to search subtitles in the background' ) return sickrage.app.log.info('Checking for subtitles') # get episodes on which we want subtitles # criteria is: # - show subtitles = 1 # - episode subtitles != config wanted languages or 'und' (depends on config multi) # - search count < 2 and diff(airdate, now) > 1 week : now -> 1d # - search count < 7 and diff(airdate, now) <= 1 week : now -> 4h -> 8h -> 16h -> 1d -> 1d -> 1d today = datetime.date.today().toordinal() results = [] for s in sickrage.app.showlist: for e in (e for e in sickrage.app.main_db.get_many( 'tv_episodes', s.indexerid) if s.subtitles == 1 and e['location'] != '' and e['subtitles'] not in sickrage.subtitles.wanted_languages() and ( e['subtitles_searchcount'] <= 2 or (e['subtitles_searchcount'] <= 7 and (today - e['airdate'])))): results += [{ 'show_name': s.name, 'showid': e['showid'], 'season': e['season'], 'episode': e['episode'], 'status': e['status'], 'subtitles': e['subtitles'], 'searchcount': e['subtitles_searchcount'], 'lastsearch': e['subtitles_lastsearch'], 'location': e['location'], 'airdate_daydiff': (today - e['airdate']) }] if len(results) == 0: sickrage.app.log.info('No subtitles to download') return rules = self._getRules() now = datetime.datetime.now() for epToSub in results: if not os.path.isfile(epToSub['location']): sickrage.app.log.debug( 'Episode file does not exist, cannot download subtitles for episode %dx%d of show %s' % (epToSub['season'], epToSub['episode'], epToSub['show_name'])) continue # http://bugs.python.org/issue7980#msg221094 # I dont think this needs done here, but keeping to be safe datetime.datetime.strptime('20110101', '%Y%m%d') if ((epToSub['airdate_daydiff'] > 7 and epToSub['searchcount'] < 2 and now - datetime.datetime.strptime(epToSub['lastsearch'], dateTimeFormat) > datetime.timedelta(hours=rules['old'][epToSub['searchcount']]) ) or (epToSub['airdate_daydiff'] <= 7 and epToSub['searchcount'] < 7 and now - datetime.datetime.strptime(epToSub['lastsearch'], dateTimeFormat) > datetime.timedelta(hours=rules['new'][epToSub['searchcount']]) )): sickrage.app.log.debug( 'Downloading subtitles for episode %dx%d of show %s' % (epToSub['season'], epToSub['episode'], epToSub['show_name'])) showObj = findCertainShow(int(epToSub['showid'])) if not showObj: sickrage.app.log.debug('Show not found') return epObj = showObj.get_episode(int(epToSub["season"]), int(epToSub["episode"])) if isinstance(epObj, str): sickrage.app.log.debug('Episode not found') return existing_subtitles = epObj.subtitles try: epObj.download_subtitles() except Exception as e: sickrage.app.log.debug('Unable to find subtitles') sickrage.app.log.debug(str(e)) return newSubtitles = frozenset( epObj.subtitles).difference(existing_subtitles) if newSubtitles: sickrage.app.log.info( 'Downloaded subtitles for S%02dE%02d in %s' % (epToSub["season"], epToSub["episode"], ', '.join(newSubtitles))) self.amActive = False
def search_cache(self, episode=None, manualSearch=False, downCurQuality=False): neededEps = {} if not episode: dbData = [x['doc'] for x in sickrage.srCore.cacheDB.db.get_many('providers', self.providerID, with_doc=True)] else: dbData = [x['doc'] for x in sickrage.srCore.cacheDB.db.get_many('providers', self.providerID, with_doc=True) if x['doc']['indexerid'] == episode.show.indexerid and x['doc']['season'] == episode.season and "|" + str(episode.episode) + "|" in x['doc']['episodes']] # for each cache entry for curResult in dbData: # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult["name"]): continue # get the show object, or if it's not one of our shows then ignore it showObj = findCertainShow(sickrage.srCore.SHOWLIST, int(curResult["indexerid"])) if not showObj: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not showObj.is_anime: sickrage.srCore.srLogger.debug("" + str(showObj.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult["season"]) if curSeason == -1: continue curEp = curResult["episodes"].split("|")[1] if not curEp: continue curEp = int(curEp) curQuality = int(curResult["quality"]) curReleaseGroup = curResult["release_group"] curVersion = curResult["version"] # if the show says we want that episode then add it to the list if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch, downCurQuality): sickrage.srCore.srLogger.info( "Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[curQuality]) continue epObj = showObj.getEpisode(curSeason, curEp) # build a result object title = curResult["name"] url = curResult["url"] sickrage.srCore.srLogger.info("Found result " + title + " at " + url) result = self.provider.getResult([epObj]) result.show = showObj result.url = url result.name = title result.quality = curQuality result.release_group = curReleaseGroup result.version = curVersion result.content = None result.size = self.provider._get_size(url) result.files = self.provider._get_files(url) # add it to the list if epObj not in neededEps: neededEps[epObj.episode] = [result] else: neededEps[epObj.episode].append(result) # datetime stamp this search so cache gets cleared self.last_search = datetime.datetime.today() return neededEps
def set_scene_numbering(indexer_id, indexer, season=None, episode=None, absolute_number=None, sceneSeason=None, sceneEpisode=None, sceneAbsolute=None): """ Set scene numbering for a season/episode. To clear the scene numbering, leave both sceneSeason and sceneEpisode as None. """ if indexer_id is None: return indexer_id = int(indexer_id) indexer = int(indexer) if season and episode: dbData = [ x['doc'] for x in sickrage.srCore.mainDB.db.get_many( 'scene_numbering', indexer_id, with_doc=True) if x['doc']['index'] == indexer and x['doc']['season'] == season and x['doc']['episode'] == episode ] if len(dbData): dbData[0]['scene_season'] = sceneSeason dbData[0]['scene_episode'] = sceneEpisode sickrage.srCore.mainDB.db.update(dbData[0]) else: sickrage.srCore.mainDB.db.insert({ '_t': 'scene_numbering', 'indexer': indexer, 'indexer_id': indexer_id, 'season': season, 'episode': episode, 'scene_season': sceneSeason, 'scene_episode': sceneEpisode }) elif absolute_number: dbData = [ x['doc'] for x in sickrage.srCore.mainDB.db.get_many( 'scene_numbering', indexer_id, with_doc=True) if x['doc']['index'] == indexer and x['doc']['absolute_number'] == absolute_number ] if len(dbData): dbData[0]['scene_absolute_number'] = sceneAbsolute sickrage.srCore.mainDB.db.update(dbData[0]) else: sickrage.srCore.mainDB.db.insert({ '_t': 'scene_numbering', 'indexer': indexer, 'indexer_id': indexer_id, 'absolute_number': absolute_number, 'scene_absolute_number': sceneAbsolute }) # Reload data from DB so that cache and db are in sync show = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id) show.flushEpisodes()
def search_cache(self, ep_obj, manualSearch=False, downCurQuality=False): season = ep_obj.scene_season if ep_obj.show.scene else ep_obj.season episode = ep_obj.scene_episode if ep_obj.show.scene else ep_obj.episode neededEps = {} dbData = [] # get data from external database if sickrage.app.config.enable_api_providers_cache and not self.provider.private: try: dbData += ProviderCacheAPI().get(self.providerID, ep_obj.show.indexerid, season, episode)['data'] except Exception: pass # get data from internal database dbData += [x for x in sickrage.app.cache_db.get_many('providers', self.providerID)] # for each cache entry for curResult in (x for x in dbData if x.get('indexerid') == ep_obj.show.indexerid and x.get('season') == season and "|{}|".format( episode) in x.get('episodes', [])): result = self.provider.getResult() # ignore invalid and private IP address urls if not validate_url(curResult["url"]): if not curResult["url"].startswith('magnet'): continue elif is_ip_private(curResult["url"].split(r'//')[-1].split(r'/')[0]): continue # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult["name"]): continue # get the show object, or if it's not one of our shows then ignore it result.show = findCertainShow(int(curResult["indexerid"])) if not result.show: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not result.show.is_anime: sickrage.app.log.debug("" + str(result.show.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult["season"]) if curSeason == -1: continue try: result.episodes = [result.show.get_episode(curSeason, int(curEp)) for curEp in filter(None, curResult["episodes"].split("|"))] except EpisodeNotFoundException: continue result.quality = int(curResult["quality"]) result.release_group = curResult["release_group"] result.version = curResult["version"] # make sure we want the episode wantEp = False for curEp in result.episodes: if result.show.want_episode(curEp.season, curEp.episode, result.quality, manualSearch, downCurQuality): wantEp = True if not wantEp: sickrage.app.log.info("Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[result.quality]) continue # build a result object result.name = curResult["name"] result.url = curResult["url"] sickrage.app.log.info("Found result " + result.name + " at " + result.url) result.seeders = curResult.get("seeders", -1) result.leechers = curResult.get("leechers", -1) result.size = curResult.get("size", -1) result.content = None # add it to the list if ep_obj.episode not in neededEps: neededEps[ep_obj.episode] = [result] else: neededEps[ep_obj.episode] += [result] # datetime stamp this search so cache gets cleared self.last_search = datetime.datetime.today() return neededEps
def run(self): sickrage.app.log.info("Started adding show {} from show dir: {}".format(self.show_name, self.showDir)) index_name = IndexerApi(self.indexer).name # make sure the Indexer IDs are valid try: lINDEXER_API_PARMS = IndexerApi(self.indexer).api_params.copy() lINDEXER_API_PARMS['cache'] = False lINDEXER_API_PARMS['language'] = self.lang or sickrage.app.config.indexer_default_language sickrage.app.log.info("{}: {}".format(index_name, repr(lINDEXER_API_PARMS))) t = IndexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) s = t[self.indexer_id] if not s: return self._finishEarly() # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show if not getattr(s, 'seriesname'): sickrage.app.log.error( "Show in {} has no name on {}, probably the wrong language used to search with".format(self.showDir, index_name)) sickrage.app.alerts.error(_("Unable to add show"), _( "Show in {} has no name on {}, probably the wrong language. Delete .nfo and add manually in the correct language").format( self.showDir, index_name)) return self._finishEarly() # if the show has no episodes/seasons if not len(s): sickrage.app.log.error("Show " + str(s['seriesname']) + " is on " + str( IndexerApi(self.indexer).name) + " but contains no season/episode data.") sickrage.app.alerts.error(_("Unable to add show"), _("Show ") + str(s['seriesname']) + _(" is on ") + str( IndexerApi( self.indexer).name) + _( " but contains no season/episode data.")) return self._finishEarly() except Exception as e: sickrage.app.log.error( "{}: Error while loading information from indexer {}. Error: {}".format(self.indexer_id, index_name, e.message)) sickrage.app.alerts.error( _("Unable to add show"), _("Unable to look up the show in {} on {} using ID {}, not using the NFO. Delete .nfo and try adding " "manually again.").format(self.showDir, index_name, self.indexer_id) ) if sickrage.app.config.use_trakt: title = self.showDir.split("/")[-1] data = { 'shows': [ { 'title': title, 'ids': {IndexerApi(self.indexer).trakt_id: self.indexer_id} } ] } srTraktAPI()["sync/watchlist"].remove(data) return self._finishEarly() try: self.show = TVShow(self.indexer, self.indexer_id, self.lang) self.show.loadFromIndexer() # set up initial values self.show.location = self.showDir self.show.subtitles = self.subtitles or sickrage.app.config.subtitles_default self.show.subtitles_sr_metadata = self.subtitles_sr_metadata self.show.quality = self.quality or sickrage.app.config.quality_default self.show.flatten_folders = self.flatten_folders or sickrage.app.config.flatten_folders_default self.show.anime = self.anime or sickrage.app.config.anime_default self.show.scene = self.scene or sickrage.app.config.scene_default self.show.archive_firstmatch = self.archive or sickrage.app.config.archive_default self.show.paused = self.paused or False # set up default new/missing episode status sickrage.app.log.info( "Setting all current episodes to the specified default status: " + str(self.default_status)) self.show.default_ep_status = self.default_status if self.show.anime: self.show.release_groups = BlackAndWhiteList(self.show.indexerid) if self.blacklist: self.show.release_groups.set_black_keywords(self.blacklist) if self.whitelist: self.show.release_groups.set_white_keywords(self.whitelist) # # be smartish about this # if self.show.genre and "talk show" in self.show.genre.lower(): # self.show.air_by_date = 1 # if self.show.genre and "documentary" in self.show.genre.lower(): # self.show.air_by_date = 0 # if self.show.classification and "sports" in self.show.classification.lower(): # self.show.sports = 1 except indexer_exception as e: sickrage.app.log.error( "Unable to add show due to an error with " + IndexerApi( self.indexer).name + ": {}".format(e.message)) if self.show: sickrage.app.alerts.error( _("Unable to add ") + str(self.show.name) + _(" due to an error with ") + IndexerApi( self.indexer).name + "") else: sickrage.app.alerts.error( _("Unable to add show due to an error with ") + IndexerApi(self.indexer).name + "") return self._finishEarly() except MultipleShowObjectsException: sickrage.app.log.warning("The show in " + self.showDir + " is already in your show list, skipping") sickrage.app.alerts.error(_('Show skipped'), _("The show in ") + self.showDir + _(" is already in your show list")) return self._finishEarly() except Exception as e: sickrage.app.log.error("Error trying to add show: {}".format(e.message)) sickrage.app.log.debug(traceback.format_exc()) raise self._finishEarly() try: sickrage.app.log.debug("Attempting to retrieve show info from IMDb") self.show.loadIMDbInfo() except Exception as e: sickrage.app.log.error("Error loading IMDb info: {}".format(e.message)) try: self.show.saveToDB() except Exception as e: sickrage.app.log.error("Error saving the show to the database: {}".format(e.message)) sickrage.app.log.debug(traceback.format_exc()) raise self._finishEarly() # add it to the show list if not findCertainShow(sickrage.app.showlist, self.indexer_id): sickrage.app.showlist.append(self.show) try: self.show.loadEpisodesFromIndexer() except Exception as e: sickrage.app.log.error( "Error with " + IndexerApi( self.show.indexer).name + ", not creating episode list: {}".format(e.message)) sickrage.app.log.debug(traceback.format_exc()) try: self.show.loadEpisodesFromDir() except Exception as e: sickrage.app.log.debug("Error searching dir for episodes: {}".format(e.message)) sickrage.app.log.debug(traceback.format_exc()) # if they set default ep status to WANTED then run the backlog to search for episodes if self.show.default_ep_status == WANTED: sickrage.app.log.info("Launching backlog for this show since its episodes are WANTED") sickrage.app.backlog_searcher.searchBacklog([self.show]) self.show.writeMetadata() self.show.updateMetadata() self.show.populateCache() if sickrage.app.config.use_trakt: # if there are specific episodes that need to be added by trakt sickrage.app.trakt_searcher.manageNewShow(self.show) # add show to trakt.tv library if sickrage.app.config.trakt_sync: sickrage.app.trakt_searcher.addShowToTraktLibrary(self.show) if sickrage.app.config.trakt_sync_watchlist: sickrage.app.log.info("update watchlist") sickrage.app.notifier_providers['trakt'].update_watchlist(show_obj=self.show) # Load XEM data to DB for show xem_refresh(self.show.indexerid, self.show.indexer, force=True) # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering. if not self.scene and get_xem_numbering_for_show(self.show.indexerid, self.show.indexer): self.show.scene = 1 self.show.default_ep_status = self.default_status_after self.show.saveToDB() sickrage.app.name_cache.build(self.show) self.finish() sickrage.app.log.info( "Finished adding show {} in {}s from show dir: {}".format(self.show_name, round(time.time() - self.startTime, 2), self.showDir))
def run(self, force=False): """ Runs the daily searcher, queuing selected episodes for search :param force: Force search """ if self.amActive: return self.amActive = True # set thread name threading.currentThread().setName(self.name) # trim failed download history if sickrage.srCore.srConfig.USE_FAILED_DOWNLOADS: FailedHistory.trimHistory() sickrage.srCore.srLogger.info( "Searching for new released episodes ...") curDate = (datetime.date.today() + datetime.timedelta(days=2)).toordinal() if tz_updater.load_network_dict(): curDate = (datetime.date.today() + datetime.timedelta(days=1)).toordinal() curTime = datetime.datetime.now(tz_updater.sr_timezone) show = None for dbData in [ x['doc'] for x in sickrage.srCore.mainDB.db.all('tv_episodes', with_doc=True) if x['doc']['status'] in [UNAIRED, WANTED] and x['doc']['season'] > 0 and curDate >= x['doc']['airdate'] > 1 ]: try: if not show or int(dbData['showid']) != show.indexerid: show = findCertainShow(sickrage.srCore.SHOWLIST, int(dbData['showid'])) # for when there is orphaned series in the database but not loaded into our showlist if not show or show.paused: continue except MultipleShowObjectsException: sickrage.srCore.srLogger.info( "ERROR: expected to find a single show matching " + str(dbData['showid'])) continue if show.airs and show.network: # This is how you assure it is always converted to local time air_time = tz_updater.parse_date_time( dbData['airdate'], show.airs, show.network, dateOnly=True).astimezone(tz_updater.sr_timezone) # filter out any episodes that haven't started airing yet, # but set them to the default status while they are airing # so they are snatched faster if air_time > curTime: continue ep = show.getEpisode(int(dbData['season']), int(dbData['episode'])) with ep.lock: if ep.season == 0: sickrage.srCore.srLogger.info( "New episode " + ep.prettyName() + " airs today, setting status to SKIPPED because is a special season" ) ep.status = SKIPPED else: sickrage.srCore.srLogger.info( "New episode %s airs today, setting to default episode status for this show: %s" % (ep.prettyName(), statusStrings[ep.show.default_ep_status])) ep.status = ep.show.default_ep_status ep.saveToDB() else: sickrage.srCore.srLogger.info("No new released episodes found ...") # queue episode for daily search sickrage.srCore.SEARCHQUEUE.put(DailySearchQueueItem()) self.amActive = False
def search_cache(self, ep_obj, manualSearch=False, downCurQuality=False): season = ep_obj.scene_season if ep_obj.show.scene else ep_obj.season episode = ep_obj.scene_episode if ep_obj.show.scene else ep_obj.episode neededEps = {} dbData = [] # get data from external database if sickrage.app.config.enable_api_providers_cache and not self.provider.private: try: dbData += ProviderCacheAPI().get(self.providerID, ep_obj.show.indexerid, season, episode)['data'] except Exception: pass # get data from internal database dbData += [ x for x in sickrage.app.cache_db.get_many('providers', self.providerID) ] # for each cache entry for curResult in (x for x in dbData if x['indexerid'] == ep_obj.show.indexerid and x['season'] == season and "|" + str(episode) + "|" in x['episodes']): result = self.provider.getResult() # ignore invalid and private IP address urls if not validate_url(curResult["url"]): if not curResult["url"].startswith('magnet'): continue elif is_ip_private( curResult["url"].split(r'//')[-1].split(r'/')[0]): continue # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult["name"]): continue # get the show object, or if it's not one of our shows then ignore it result.show = findCertainShow(int(curResult["indexerid"])) if not result.show: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not result.show.is_anime: sickrage.app.log.debug("" + str(result.show.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult["season"]) if curSeason == -1: continue try: result.episodes = [ result.show.get_episode(curSeason, int(curEp)) for curEp in filter(None, curResult["episodes"].split("|")) ] except EpisodeNotFoundException: continue result.quality = int(curResult["quality"]) result.release_group = curResult["release_group"] result.version = curResult["version"] # make sure we want the episode wantEp = False for curEp in result.episodes: if result.show.want_episode(curEp.season, curEp.episode, result.quality, manualSearch, downCurQuality): wantEp = True if not wantEp: sickrage.app.log.info( "Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[result.quality]) continue # build a result object result.name = curResult["name"] result.url = curResult["url"] sickrage.app.log.info("Found result " + result.name + " at " + result.url) result.seeders = curResult.get("seeders", -1) result.leechers = curResult.get("leechers", -1) result.size = curResult.get("size", -1) result.content = None # add it to the list if ep_obj.episode not in neededEps: neededEps[ep_obj.episode] = [result] else: neededEps[ep_obj.episode] += [result] # datetime stamp this search so cache gets cleared self.last_search = datetime.datetime.today() return neededEps
def findNeededEpisodes(self, episode, manualSearch=False, downCurQuality=False): neededEps = {} cl = [] myDB = self._getDB() if not episode: sqlResults = myDB.select("SELECT * FROM [" + self.providerID + "]") elif type(episode) != list: sqlResults = myDB.select( "SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?", [episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%"]) else: for epObj in episode: cl.append([ "SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ? AND quality IN (" + ",".join( [str(x) for x in epObj.wantedQuality]) + ")", [epObj.show.indexerid, epObj.season, "%|" + str(epObj.episode) + "|%"]]) sqlResults = myDB.mass_action(cl, fetchall=True) sqlResults = list(itertools.chain(*sqlResults)) # for each cache entry for curResult in sqlResults: # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult[b"name"]): continue # get the show object, or if it's not one of our shows then ignore it showObj = findCertainShow(sickrage.showList, int(curResult[b"indexerid"])) if not showObj: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not showObj.is_anime: sickrage.LOGGER.debug("" + str(showObj.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult[b"season"]) if curSeason == -1: continue curEp = curResult[b"episodes"].split("|")[1] if not curEp: continue curEp = int(curEp) curQuality = int(curResult[b"quality"]) curReleaseGroup = curResult[b"release_group"] curVersion = curResult[b"version"] # if the show says we want that episode then add it to the list if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch, downCurQuality): sickrage.LOGGER.info("Skipping " + curResult[b"name"] + " because we don't want an episode that's " + Quality.qualityStrings[curQuality]) continue epObj = showObj.getEpisode(curSeason, curEp) # build a result object title = curResult[b"name"] url = curResult[b"url"] sickrage.LOGGER.info("Found result " + title + " at " + url) result = self.provider.getResult([epObj]) result.show = showObj result.url = url result.name = title result.quality = curQuality result.release_group = curReleaseGroup result.version = curVersion result.content = None # add it to the list if epObj not in neededEps: neededEps[epObj] = [result] else: neededEps[epObj].append(result) # datetime stamp this search so cache gets cleared self.setLastSearch() return neededEps
def findNeededEpisodes(self, episode, manualSearch=False, downCurQuality=False): sqlResults = [] neededEps = {} cl = [] if not episode: sqlResults = self._getDB().select("SELECT * FROM [" + self.providerID + "]") elif type(episode) != list: sqlResults = self._getDB().select( "SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ?", [ episode.show.indexerid, episode.season, "%|" + str(episode.episode) + "|%" ]) else: for epObj in episode: cl.append([ "SELECT * FROM [" + self.providerID + "] WHERE indexerid = ? AND season = ? AND episodes LIKE ? AND quality IN (" + ",".join([str(x) for x in epObj.wantedQuality]) + ")", [ epObj.show.indexerid, epObj.season, "%|" + str(epObj.episode) + "|%" ] ]) if len(cl) > 0: sqlResults = list( itertools.chain(*self._getDB().mass_action(cl))) del cl # cleanup # for each cache entry for curResult in sqlResults: # ignored/required words, and non-tv junk if not show_names.filterBadReleases(curResult["name"]): continue # get the show object, or if it's not one of our shows then ignore it showObj = findCertainShow(sickrage.srCore.SHOWLIST, int(curResult["indexerid"])) if not showObj: continue # skip if provider is anime only and show is not anime if self.provider.anime_only and not showObj.is_anime: sickrage.srCore.srLogger.debug("" + str(showObj.name) + " is not an anime, skiping") continue # get season and ep data (ignoring multi-eps for now) curSeason = int(curResult["season"]) if curSeason == -1: continue curEp = curResult["episodes"].split("|")[1] if not curEp: continue curEp = int(curEp) curQuality = int(curResult["quality"]) curReleaseGroup = curResult["release_group"] curVersion = curResult["version"] # if the show says we want that episode then add it to the list if not showObj.wantEpisode(curSeason, curEp, curQuality, manualSearch, downCurQuality): sickrage.srCore.srLogger.info( "Skipping " + curResult["name"] + " because we don't want an episode that's " + Quality.qualityStrings[curQuality]) continue epObj = showObj.getEpisode(curSeason, curEp) # build a result object title = curResult["name"] url = curResult["url"] sickrage.srCore.srLogger.info("Found result " + title + " at " + url) result = self.provider.getResult([epObj]) result.show = showObj result.url = url result.name = title result.quality = curQuality result.release_group = curReleaseGroup result.version = curVersion result.content = None # add it to the list if epObj not in neededEps: neededEps[epObj] = [result] else: neededEps[epObj].append(result) # datetime stamp this search so cache gets cleared self.setLastSearch() return neededEps