def _get_season_search_strings(self, show_id, season, episode): """ Get season search strings. """ search_strings = {'Season': []} season_strings = [ '%s/capitulo-%s%s/', '%s/capitulo-%s%s/hdtv/', '%s/capitulo-%s%s/hdtv-720p-ac3-5-1/', '%s/capitulo-%s%s/hdtv-1080p-ac3-5-1/', '%s/capitulo-%s%s/bluray-1080p/' ] show_object = find_show(show_id) episode_object = show_object.get_episode(season, episode) for show_name in all_possible_show_names(show_id, episode_object.scene_season): for season_string in season_strings: season_string = season_string % (show_name.replace( ' ', '-'), episode_object.scene_season, episode_object.scene_episode) search_strings['Season'].append(season_string.strip()) return [search_strings]
def _get_episode_search_strings(self, show_id, season, episode, add_string='', session=None): post_data = { 'username': self.username, 'passkey': self.passkey, 'category': [2], # TV Category } show_object = find_show(show_id, session=session) episode_object = show_object.get_episode(season, episode) if show_object.air_by_date: post_data['tvdb'] = { 'id': show_id, 'episode': str(episode_object.airdate).replace('-', '|') } elif show_object.sports: post_data['tvdb'] = { 'id': show_id, 'episode': episode_object.airdate.strftime('%b') } elif show_object.anime: post_data['tvdb'] = { 'id': show_id, 'episode': "%i" % int(episode_object.scene_absolute_number) } else: post_data['tvdb'] = { 'id': show_id, 'season': episode_object.scene_season, 'episode': episode_object.scene_episode } return [post_data]
def log_snatch(search_result): """ Logs a successful snatch :param search_result: Search result that was successful """ logDate = datetime.today() release = FailedHistory.prepare_failed_name(search_result.name) provider = search_result.provider.name if search_result.provider else "unknown" session = sickrage.app.main_db.session() show_object = find_show(search_result.series_id, search_result.series_provider_id) for episode in search_result.episodes: episode_object = show_object.get_episode(search_result.season, episode) session.add( MainDB.FailedSnatchHistory( **{ 'date': logDate, 'size': search_result.size, 'release': release, 'provider': provider, 'series_id': search_result.series_id, 'series_provider_id': search_result.series_provider_id, 'season': search_result.season, 'episode': episode, 'old_status': episode_object.status })) session.commit()
def _add_torrent_uri(self, result): if not self.auth: return False if not result: return False try: # Send magnet to rTorrent torrent = self.auth.load_magnet(result.url, result.hash) if not torrent: return False # Set label label = sickrage.app.config.torrent_label show_object = find_show(result.show_id) if show_object.is_anime: label = sickrage.app.config.torrent_label_anime if label: torrent.set_custom(1, label) if sickrage.app.config.torrent_path: torrent.set_directory(sickrage.app.config.torrent_path) # Start torrent torrent.start() return True except Exception: sickrage.app.log.debug(traceback.format_exc()) return False
def _get_season_search_strings(self, show_id, season, episode, session=None): post_data = { 'username': self.username, 'passkey': self.passkey, 'category': [2], # TV Category } show_object = find_show(show_id, session=session) episode_object = show_object.get_episode(season, episode) if show_object.air_by_date or show_object.sports: post_data['tvdb'] = { 'id': show_id, 'season': str(episode_object.airdate)[:7], } elif show_object.anime: post_data['tvdb'] = { 'id': show_id, 'season': "%d" % episode_object.scene_absolute_number, } else: post_data['tvdb'] = { 'id': show_id, 'season': episode_object.scene_season, } return [post_data]
def run(self): self.started = True show_object = find_show(self.series_id, self.series_provider_id) if not show_object: return episode_object = show_object.get_episode(self.season, self.episode) try: sickrage.app.log.info( "Starting backlog search for: [{}] S{:02d}E{:02d}".format( show_object.name, self.season, self.episode)) WebSocketMessage( 'SEARCH_QUEUE_STATUS_UPDATED', { 'seriesSlug': show_object.slug, 'episodeId': episode_object.episode_id, 'searchQueueStatus': episode_object.search_queue_status }).push() search_result = search_providers(self.series_id, self.series_provider_id, self.season, self.episode, manualSearch=False) if search_result: snatch = all([(search_result.series_id, search_result.season, episode) not in sickrage.app.search_queue.SNATCH_HISTORY for episode in search_result.episodes]) if snatch: [ sickrage.app.search_queue.SNATCH_HISTORY.append( (search_result.series_id, search_result.season, episode)) for episode in search_result.episodes ] sickrage.app.log.info("Downloading {} from {}".format( search_result.name, search_result.provider.name)) snatch_episode(search_result) else: sickrage.app.log.info( "Unable to find search results for: [{}] S{:02d}E{:02d}". format(show_object.name, self.season, self.episode)) except Exception: sickrage.app.log.debug(traceback.format_exc()) finally: WebSocketMessage( 'SEARCH_QUEUE_STATUS_UPDATED', { 'seriesSlug': show_object.slug, 'episodeId': episode_object.episode_id, 'searchQueueStatus': episode_object.search_queue_status }).push() sickrage.app.log.info( "Finished backlog search for: [{}] S{:02d}E{:02d}".format( show_object.name, self.season, self.episode))
def is_final_result(result): """ Checks if the given result is good enough quality that we can stop searching for other ones. If the result is the highest quality in both the any/best quality lists then this function returns True, if not then it's False """ sickrage.app.log.debug( "Checking if we should keep searching after we've found " + result.name) show_obj = find_show(result.show_id) any_qualities, best_qualities = Quality.split_quality(show_obj.quality) # if there is a download that's higher than this then we definitely need to keep looking if best_qualities and result.quality < max(best_qualities): return False # if it does not match the shows black and white list its no good elif show_obj.is_anime and show_obj.release_groups.is_valid(result): return False # if there's no redownload that's higher (above) and this is the highest initial download then we're good elif any_qualities and result.quality in any_qualities: return True elif best_qualities and result.quality == max(best_qualities): return True # if we got here than it's either not on the lists, they're empty, or it's lower than the highest required else: return False
def is_loading(self): """ Returns True if we've gotten far enough to have a show object, or False if we still only know the folder name. """ if find_show(self.indexer_id): return True
def get(self, *args, **kwargs): """ Display the new show page which collects a tvdb id, folder, and extra options and posts them to addNewShow """ show_list = self.get_argument('list', 'trending') limit = self.get_argument('limit', None) or 10 trakt_shows = [] shows, black_list = getattr(TraktAPI()['shows'], show_list)( extended="full", limit=int(limit) + get_show_list().count()), False while len(trakt_shows) < int(limit): trakt_shows += [ x for x in shows if 'tvdb' in x.ids and not find_show(int(x.ids['tvdb']), session=self.db_session) ] return self.render( "/home/trakt_shows.mako", title="Trakt {} Shows".format(show_list.capitalize()), header="Trakt {} Shows".format(show_list.capitalize()), enable_anime_options=False, black_list=black_list, trakt_shows=trakt_shows[:int(limit)], trakt_list=show_list, limit=limit, controller='home', action="trakt_shows")
def _get_season_search_strings(self, series_id, series_provider_id, season, episode): search_string = {'Season': []} show_object = find_show(series_id, series_provider_id) if not show_object: return [search_string] episode_object = show_object.get_episode(season, episode) for show_name in set( show_names.all_possible_show_names(series_id, series_provider_id)): for sep in ' ', ' - ': season_string = show_name + sep + 'Series ' if show_object.search_format in [ SearchFormat.AIR_BY_DATE, SearchFormat.SPORTS ]: season_string += str(episode_object.airdate).split('-')[0] elif show_object.search_format == SearchFormat.ANIME: season_string += '%d' % episode_object.get_absolute_numbering( ) else: season_string += '%d' % episode_object.get_season_episode_numbering( )[0] search_string['Season'].append( re.sub(r'\s+', ' ', season_string.replace('.', ' ').strip())) return [search_string]
def _get_episode_search_strings(self, series_id, series_provider_id, season, episode, add_string=''): """ Get episode search strings. """ search_strings = { 'Episode': [] } episode_strings = ['%s/capitulo-%s%s/', '%s/capitulo-%s%s/hdtv/', '%s/capitulo-%s%s/hdtv-720p-ac3-5-1/', '%s/capitulo-%s%s/hdtv-1080p-ac3-5-1/', '%s/capitulo-%s%s/bluray-1080p/'] show_object = find_show(series_id, series_provider_id) if not show_object: return [search_strings] episode_object = show_object.get_episode(season, episode) for show_name in all_possible_show_names(series_id, series_provider_id, episode_object.season): for episode_string in episode_strings: episode_string = episode_string % ( show_name.replace(' ', '-'), episode_object.get_season_episode_numbering()[0], episode_object.get_season_episode_numbering()[1] ) search_strings['Episode'].append(episode_string.strip()) return [search_strings]
def handle_post(self): term = self.get_argument('term') shows = [] episodes = [] session = sickrage.app.main_db.session() for result in session.query(MainDB.TVShow).filter( MainDB.TVShow.name.like('%{}%'.format(term))).all(): shows.append({ 'category': 'shows', 'showid': result.indexer_id, 'seasons': len(set([s.season for s in result.episodes])), 'name': result.name, 'img': sickrage.app.config.web_root + showImage(result.indexer_id, 'poster_thumb').url }) for result in session.query(MainDB.TVEpisode).filter( MainDB.TVEpisode.name.like('%{}%'.format(term))).all(): show_object = find_show(result.showid) if not show_object: continue episodes.append({ 'category': 'episodes', 'showid': result.showid, 'episodeid': result.indexer_id, 'season': result.season, 'episode': result.episode, 'name': result.name, 'showname': show_object.name, 'img': sickrage.app.config.web_root + showImage(result.showid, 'poster_thumb').url }) if not len(shows): shows = [{ 'category': 'shows', 'showid': '', 'name': term, 'img': '/images/poster-thumb.png', 'seasons': 0, }] return self.write(json.dumps(shows + episodes))
def _get_season_search_strings(self, show_id, season, episode, session=None): """ Get season search strings. """ search_string = { 'Season': [] } show_object = find_show(show_id, session=session) episode_object = show_object.get_episode(season, episode) for show_name in all_possible_show_names(show_id, episode_object.scene_season): episode_string = "{}{}".format(show_name, self.search_separator) if show_object.air_by_date or show_object.sports: episode_string += str(episode_object.airdate).split('-')[0] elif show_object.anime: episode_string += 'Season' else: episode_string += 'S{season:0>2}'.format(season=episode_object.scene_season) search_string['Season'].append(episode_string.strip()) return [search_string]
def get_scene_numbering(series_id, series_provider_id, 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 series_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) """ show_obj = find_show(series_id, series_provider_id) if not show_obj: return -1, -1 result = find_scene_numbering(series_id, series_provider_id, season, episode) if result: return result if fallback_to_xem: xem_result = find_xem_numbering(series_id, series_provider_id, season, episode) if xem_result: return xem_result return -1, -1
def get_scene_absolute_numbering(indexer_id, indexer, absolute_number, fallback_to_xem=True): """ Returns absolute number, 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 absolute number """ show_obj = find_show(indexer_id) if not show_obj: return -1 result = find_scene_absolute_numbering(indexer_id, indexer, absolute_number) if result: return result if fallback_to_xem: xem_result = find_xem_absolute_numbering(indexer_id, indexer, absolute_number) if xem_result: return xem_result return -1
def _get_season_search_strings(self, show_id, season, episode): post_data = { 'username': self.username, 'passkey': self.passkey, 'category': [2], # TV Category } show_object = find_show(show_id) if not show_object: return [post_data] episode_object = show_object.get_episode(season, episode) if show_object.search_format in [SearchFormats.AIR_BY_DATE, SearchFormats.SPORTS]: post_data['tvdb'] = { 'id': show_id, 'season': str(episode_object.airdate)[:7], } elif show_object.search_format == SearchFormats.ANIME: post_data['tvdb'] = { 'id': show_id, 'season': "%d" % episode_object.get_absolute_numbering(), } else: post_data['tvdb'] = { 'id': show_id, 'season': episode_object.get_season_episode_numbering()[0], } return [post_data]
def update_show(self, indexer_id, indexer_update_only=False, force=False): show_obj = find_show(indexer_id) if self.is_being_added(indexer_id): raise CantUpdateShowException( "{} is still being added, please wait until it is finished before trying to update." .format(show_obj.name)) if self.is_being_updated(indexer_id): raise CantUpdateShowException( "{} is already being updated, can't update again until it's done." .format(show_obj.name)) if self.is_being_updated(indexer_id): raise CantUpdateShowException( "{} is in the process of being updated, can't update again until it's done." .format(show_obj.name)) if force: sickrage.app.io_loop.add_callback( self.put, QueueItemForceUpdate(indexer_id, indexer_update_only)) else: sickrage.app.io_loop.add_callback( self.put, QueueItemUpdate(indexer_id, indexer_update_only))
def run(self): super(ShowTaskRefresh, self).run() start_time = time.time() tv_show = find_show(self.series_id, self.series_provider_id) sickrage.app.log.info("Performing refresh for show: {}".format( tv_show.name)) tv_show.refresh_dir() tv_show.write_metadata(force=self.force) tv_show.populate_cache(force=self.force) # Load XEM data to DB for show # xem_refresh(show.series_id, show.series_provider_id) tv_show.last_refresh = datetime.datetime.now() tv_show.save() WebSocketMessage( 'SHOW_REFRESHED', { 'seriesSlug': tv_show.slug, 'series': tv_show.to_json(episodes=True, details=True) }).push() sickrage.app.log.info("Finished refresh in {}s for show: {}".format( round(time.time() - start_time, 2), tv_show.name))
def _get_episode_search_strings(self, show_id, season, episode, add_string='', session=None): """ Get episode search strings. """ show_object = find_show(show_id, session=session) episode_object = show_object.get_episode(season, episode) search_strings = {'Episode': []} episode_strings = [ '%s/capitulo-%s%s/', '%s/capitulo-%s%s/hdtv/', '%s/capitulo-%s%s/hdtv-720p-ac3-5-1/', '%s/capitulo-%s%s/hdtv-1080p-ac3-5-1/', '%s/capitulo-%s%s/bluray-1080p/' ] for show_name in all_possible_show_names(show_id, episode_object.scene_season): for episode_string in episode_strings: episode_string = episode_string % ( show_name.replace(' ', '-'), episode_object.scene_season, episode_object.scene_episode) search_strings['Episode'].append(episode_string.strip()) return [search_strings]
def revert_failed_episode(series_id, series_provider_id, season, episode): """Restore the episodes of a failed download to their original state""" session = sickrage.app.main_db.session() show_object = find_show(series_id, series_provider_id) if not show_object: return episode_object = show_object.get_episode(season, episode) history_eps = dict( (x.episode, x) for x in session.query(MainDB.FailedSnatchHistory).filter_by( series_id=series_id, series_provider_id=series_provider_id, season=season, episode=episode)) try: sickrage.app.log.info("Reverting episode (%s, %s): %s" % (season, episode, episode_object.name)) if episode in history_eps: sickrage.app.log.info("Found in history") episode_object.status = history_eps[episode].old_status else: sickrage.app.log.debug( "WARNING: Episode not found in history. Setting it back to WANTED" ) episode_object.status = EpisodeStatus.WANTED episode_object.save() except EpisodeNotFoundException as e: sickrage.app.log.warning( "Unable to create episode, please set its status manually: {}". format(e))
def sendNZB(nzb, session=None): """ Sends an NZB to SABnzbd via the API. :param nzb: The NZBSearchResult object to send to SAB """ show_object = find_show(nzb.show_id, session=session) if not show_object: return False category = sickrage.app.config.sab_category if show_object.is_anime: category = sickrage.app.config.sab_category_anime # if it aired more than 7 days ago, override with the backlog category IDs for episode__number in nzb.episodes: episode_object = show_object.get_episode(nzb.season, episode__number) if datetime.date.today() - episode_object.airdate > datetime.timedelta(days=7): category = sickrage.app.config.sab_category_anime_backlog if episode_object.show.is_anime else sickrage.app.config.sab_category_backlog # set up a dict with the URL params in it params = {'output': 'json'} if sickrage.app.config.sab_username: params['ma_username'] = sickrage.app.config.sab_username if sickrage.app.config.sab_password: params['ma_password'] = sickrage.app.config.sab_password if sickrage.app.config.sab_apikey: params['apikey'] = sickrage.app.config.sab_apikey if category: params['cat'] = category if nzb.priority: params['priority'] = 2 if sickrage.app.config.sab_forced else 1 sickrage.app.log.info('Sending NZB to SABnzbd') url = urljoin(sickrage.app.config.sab_host, 'api') try: jdata = None if nzb.resultType == 'nzb': params['mode'] = 'addurl' params['name'] = nzb.url jdata = WebSession().get(url, params=params, verify=False).json() elif nzb.resultType == 'nzbdata': params['mode'] = 'addfile' multiPartParams = {'nzbfile': (nzb.name + '.nzb', nzb.extraInfo[0])} jdata = WebSession().get(url, params=params, file=multiPartParams, verify=False).json() if not jdata: raise Exception except Exception: sickrage.app.log.info('Error connecting to sab, no data returned') return False sickrage.app.log.debug('Result text from SAB: {}'.format(jdata)) result, error_ = SabNZBd._check_sab_response(jdata) return result
def mark_failed(series_id, series_provider_id, season, episode): """ Mark an episode as failed :param epObj: Episode object to mark as failed :return: empty string """ log_str = "" show_object = find_show(series_id, series_provider_id) if not show_object: return log_str try: episode_object = show_object.get_episode(season, episode) quality = Quality.split_composite_status(episode_object.status)[1] episode_object.status = Quality.composite_status( EpisodeStatus.FAILED, quality) episode_object.save() except EpisodeNotFoundException as e: sickrage.app.log.warning( "Unable to get episode, please set its status manually: {}". format(e)) return log_str
def search(self, search_strings, age=0, series_id=None, series_provider_id=None, season=None, episode=None, **kwargs): results = [] # Only search if user conditions are true lang_info = find_show(series_id, series_provider_id).lang for mode in search_strings: sickrage.app.log.debug('Search mode: {}'.format(mode)) # Only search if user conditions are true if self.custom_settings['onlyspasearch'] and lang_info != 'es' and mode != 'RSS': sickrage.app.log.debug('Show info is not spanish, skipping provider search') continue for search_string in search_strings[mode]: if mode != 'RSS': sickrage.app.log.debug('Search string: {}'.format(search_string)) for search_url in self.urls['search']: resp = self.session.get(search_url % search_string) if not resp or not resp.text: sickrage.app.log.debug("No data returned from provider") continue results += self.parse(resp.text, mode) return results
def post(self, *args, **kwargs): # make a list of all shows and their associated args to_download = {} for arg in self.get_arguments('toDownload'): indexer_id, what = arg.split('-') if indexer_id not in to_download: to_download[indexer_id] = [] to_download[indexer_id].append(what) for cur_indexer_id in to_download: # get a list of all the eps we want to download subtitles if they just said "all" if 'all' in to_download[cur_indexer_id]: to_download[cur_indexer_id] = [ '{}x{}'.format(x.season, x.episode) for x in self.db_session.query(TVEpisode).filter_by( showid=int(cur_indexer_id)). filter(TVEpisode.status.endswith(4), TVEpisode.season != 0) ] for epResult in to_download[cur_indexer_id]: season, episode = epResult.split('x') show = find_show(int(cur_indexer_id), session=self.db_session) show.get_episode(int(season), int(episode)).download_subtitles() return self.redirect('/manage/subtitleMissed/')
def search_series_provider_for_series_id(show_name, series_provider_id): """ Contacts series provider to check for information on shows by series name to retrieve series id :param show_name: Name of show :param series_provider_id: series provider id :return: """ show_name = re.sub('[. -]', ' ', show_name) series_provider = sickrage.app.series_providers[series_provider_id] # Query series provider for search term and build the list of results sickrage.app.log.debug( "Trying to find show ID for show {} on series provider {}".format( show_name, series_provider.name)) series_provider_data = series_provider.search(show_name) if not series_provider_data: return # try to pick a show that's in my show list for series in series_provider_data: series_id = series.get('id', None) if not series_id: continue if find_show(int(series_id), series_provider_id): return series_id return series_provider_data[0].get('id', None)
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 not all([indexer_id, season, episode]): return season, episode show_obj = find_show(int(indexer_id)) if show_obj and not show_obj.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 _get_episode_search_strings(self, show_id, season, episode, add_string='', session=None): search_string = {'Episode': []} show_object = find_show(show_id, session=session) episode_object = show_object.get_episode(season, episode) for show_name in set(show_names.all_possible_show_names(show_id)): for sep in ' ', ' - ': ep_string = sanitize_scene_name(show_name) + sep if show_object.air_by_date: ep_string += str(episode_object.airdate).replace('-', '|') elif show_object.sports: ep_string += str(episode_object.airdate).replace('-', '|') + '|' + episode_object.airdate.strftime('%b') elif show_object.anime: ep_string += '%i' % int(episode_object.scene_absolute_number) else: ep_string += sickrage.app.naming_ep_type[2] % {'seasonnumber': episode_object.scene_season, 'episodenumber': episode_object.scene_episode} if add_string: ep_string += ' %s' % add_string search_string['Episode'].append(re.sub(r'\s+', ' ', ep_string.replace('.', ' ').strip())) return [search_string]
def get_absolute_number_from_season_and_episode(show_id, season, episode): """ Find the absolute number for a show episode :param show_id: Show ID :param season: Season number :param episode: Episode number :return: The absolute number """ session = sickrage.app.main_db.session() absolute_number = None show = find_show(show_id) if season and episode: try: dbData = session.query(MainDB.TVEpisode).filter_by( showid=show_id, season=season, episode=episode).one() absolute_number = dbData.absolute_number sickrage.app.log.debug( "Found absolute number %s for show %s S%02dE%02d" % (absolute_number, show.name, season, episode)) except orm.exc.NoResultFound: sickrage.app.log.debug( "No entries for absolute number for show %s S%02dE%02d" % (show.name, season, episode)) return absolute_number
def get_show(self, name): show_id = None if not name: return show_id def indexer_lookup(term): for indexer in IndexerApi().indexers: result = IndexerApi(indexer).search_for_show_id(term) if result: return result def scene_exception_lookup(term): tv_show = find_show_by_scene_exception(term) if tv_show: return tv_show.indexer_id def show_cache_lookup(term): tv_show = find_show_by_name(term) if tv_show: return tv_show.indexer_id for lookup in [show_cache_lookup, scene_exception_lookup, indexer_lookup]: for show_name in list({name, strip_accents(name), strip_accents(name).replace("'", " ")}): try: show_id = lookup(show_name) if not show_id: continue if self.validate_show and not find_show(show_id): continue if show_id: return show_id except Exception as e: sickrage.app.log.debug('SiCKRAGE encountered a error when attempting to lookup a show ID by show name, Error: {!r}'.format(e))
def run(self): self.started = True show_object = find_show(self.series_id, self.series_provider_id) if not show_object: return episode_object = show_object.get_episode(self.season, self.episode) try: sickrage.app.log.info("Starting daily search for: [" + show_object.name + "]") WebSocketMessage( 'SEARCH_QUEUE_STATUS_UPDATED', { 'seriesSlug': show_object.slug, 'episodeId': episode_object.episode_id, 'searchQueueStatus': episode_object.search_queue_status }).push() search_result = search_providers( self.series_id, self.series_provider_id, self.season, self.episode, cacheOnly=sickrage.app.config.general.enable_rss_cache) if search_result: snatch = all([(search_result.series_id, search_result.season, episode) not in sickrage.app.search_queue.SNATCH_HISTORY for episode in search_result.episodes]) if snatch: [ sickrage.app.search_queue.SNATCH_HISTORY.append( (search_result.series_id, search_result.season, episode)) for episode in search_result.episodes ] sickrage.app.log.info("Downloading " + search_result.name + " from " + search_result.provider.name) snatch_episode(search_result) else: sickrage.app.log.info("Unable to find search results for: [" + show_object.name + "]") except Exception: sickrage.app.log.debug(traceback.format_exc()) finally: WebSocketMessage( 'SEARCH_QUEUE_STATUS_UPDATED', { 'seriesSlug': show_object.slug, 'episodeId': episode_object.episode_id, 'searchQueueStatus': episode_object.search_queue_status }).push() sickrage.app.log.info("Finished daily search for: [" + show_object.name + "]")