Esempio n. 1
0
def pickBestResult(results, show, quality_list=None):
    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    # build the black And white list
    bwl = None
    if show:
        if show.is_anime:
            bwl = BlackAndWhiteList(show.indexerid)
    else:
        logger.log("Could not create black and white list no show was given", logger.DEBUG)

    # find the best result for the current episode
    bestResult = None
    for cur_result in results:
            
        logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality])

        if bwl:
            if not bwl.is_valid(cur_result):
                logger.log(cur_result.name+" does not match the blacklist or the whitelist, rejecting it. Result: " + bwl.get_last_result_msg(), logger.MESSAGE)
                continue

        if quality_list and cur_result.quality not in quality_list:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if show.rls_ignore_words and filter_release_name(cur_result.name, show.rls_ignore_words):
            logger.log(u"Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words,
                       logger.MESSAGE)
            continue

        if show.rls_require_words and not filter_release_name(cur_result.name, show.rls_require_words):
            logger.log(u"Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words,
                       logger.MESSAGE)
            continue

        if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                       cur_result.provider.name):
            logger.log(cur_result.name + u" has previously failed, rejecting it")
            continue

        if not bestResult or bestResult.quality < cur_result.quality and cur_result.quality != Quality.UNKNOWN:
            bestResult = cur_result

        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
Esempio n. 2
0
def pickBestResult(results, show, quality_list=None):
    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    # build the black And white list
    bwl = None
    if show:
        if show.is_anime:
            bwl = BlackAndWhiteList(show.indexerid)
    else:
        logger.log("Could not create black and white list no show was given", logger.DEBUG)

    # find the best result for the current episode
    bestResult = None
    for cur_result in results:
            
        logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality])

        if bwl:
            if not bwl.is_valid(cur_result):
                logger.log(cur_result.name+" does not match the blacklist or the whitelist, rejecting it. Result: " + bwl.get_last_result_msg(), logger.MESSAGE)
                continue

        if quality_list and cur_result.quality not in quality_list:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if show.rls_ignore_words and filter_release_name(cur_result.name, show.rls_ignore_words):
            logger.log(u"Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words,
                       logger.MESSAGE)
            continue

        if show.rls_require_words and not filter_release_name(cur_result.name, show.rls_require_words):
            logger.log(u"Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words,
                       logger.MESSAGE)
            continue

        if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                       cur_result.provider.name):
            logger.log(cur_result.name + u" has previously failed, rejecting it")
            continue

        if not bestResult or bestResult.quality < cur_result.quality and cur_result.quality != Quality.UNKNOWN:
            bestResult = cur_result

        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
Esempio n. 3
0
def makeSceneSearchString(show, ep_obj):
    myDB = db.DBConnection()
    numseasonsSQlResult = myDB.select(
        "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0",
        [show.indexerid])
    numseasons = int(numseasonsSQlResult[0][0])

    # see if we should use dates instead of episodes
    if (show.air_by_date or show.sports) and ep_obj.airdate != datetime.date.fromordinal(1):
        epStrings = [str(ep_obj.airdate)]
    elif show.is_anime:
        epStrings = ["%02i" % int(ep_obj.scene_absolute_number if ep_obj.scene_absolute_number > 0 else ep_obj.scene_episode)]
    else:
        epStrings = ["S%02iE%02i" % (int(ep_obj.scene_season), int(ep_obj.scene_episode)),
                     "%ix%02i" % (int(ep_obj.scene_season), int(ep_obj.scene_episode))]

    # for single-season shows just search for the show name -- if total ep count (exclude s0) is less than 11
    # due to the amount of qualities and releases, it is easy to go over the 50 result limit on rss feeds otherwise
    if numseasons == 1 and not ep_obj.show.is_anime:
        epStrings = ['']

    bwl = BlackAndWhiteList(ep_obj.show.indexerid)
    showNames = set(makeSceneShowSearchStrings(show, ep_obj.scene_season))

    toReturn = []

    for curShow in showNames:
        for curEpString in epStrings:
            if len(bwl.whiteList) > 0:
                for keyword in bwl.whiteList:
                    toReturn.append(keyword + '.' + curShow + '.' + curEpString)
            else:
                toReturn.append(curShow + '.' + curEpString)

    return toReturn
Esempio n. 4
0
def isFinalResult(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

    """

    logger.log(
        u"Checking if we should keep searching after we've found " +
        result.name, logger.DEBUG)

    show_obj = result.episodes[0].show

    bwl = None
    if show_obj.is_anime:
        bwl = BlackAndWhiteList(show_obj.indexerid)

    any_qualities, best_qualities = Quality.splitQuality(show_obj.quality)

    # if there is a redownload 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 bwl and not bwl.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):

        # if this is the best redownload but we have a higher initial download then keep looking
        if any_qualities and result.quality < max(any_qualities):
            return False

        # if this is the best redownload and we don't have a higher initial download then we're done
        else:
            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
Esempio n. 5
0
def isFinalResult(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

    """

    logger.log(u"Checking if we should keep searching after we've found " + result.name, logger.DEBUG)

    show_obj = result.episodes[0].show

    bwl = None
    if show_obj.is_anime:
        bwl = BlackAndWhiteList(show_obj.indexerid)

    any_qualities, best_qualities = Quality.splitQuality(show_obj.quality)

    # if there is a redownload 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 bwl and not bwl.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):

        # if this is the best redownload but we have a higher initial download then keep looking
        if any_qualities and result.quality < max(any_qualities):
            return False

        # if this is the best redownload and we don't have a higher initial download then we're done
        else:
            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
Esempio n. 6
0
def pickBestResult(results, show, quality_list=None):
    results = results if isinstance(results, list) else [results]

    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    bwl = None
    bestResult = None

    # find the best result for the current episode
    for cur_result in results:
        if show and cur_result.show is not show:
            continue

        # filter out possible bad torrents from providers such as ezrss
        if isinstance(cur_result, sickbeard.classes.SearchResult):
            if cur_result.resultType == "torrent" and sickbeard.TORRENT_METHOD != "blackhole":
                if not cur_result.url.startswith('magnet'):
                    cur_result.content = cur_result.provider.getURL(cur_result.url)
                    if not cur_result.content:
                        continue
        else:
            if not cur_result.url.startswith('magnet'):
                cur_result.content = cur_result.provider.getURL(cur_result.url)
                if not cur_result.content:
                    continue

        # build the black And white list
        if cur_result.show.is_anime:
            if not bwl:
                bwl = BlackAndWhiteList(cur_result.show.indexerid)
            if not bwl.is_valid(cur_result):
                logger.log(cur_result.name+" does not match the blacklist or the whitelist, rejecting it. Result: " + bwl.get_last_result_msg(), logger.INFO)
                continue

        logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality])

        if quality_list and cur_result.quality not in quality_list:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if show.rls_ignore_words and show_name_helpers.containsAtLeastOneWord(cur_result.name, cur_result.show.rls_ignore_words):
            logger.log(u"Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words,
                       logger.INFO)
            continue

        if show.rls_require_words and not show_name_helpers.containsAtLeastOneWord(cur_result.name, cur_result.show.rls_require_words):
            logger.log(u"Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words,
                       logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name, parse=False):
            logger.log(u"Ignoring " + cur_result.name + " because its not a valid scene release that we want, ignoring it",
                       logger.INFO)
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                           cur_result.provider.name):
                logger.log(cur_result.name + u" has previously failed, rejecting it")
                continue

        if not bestResult or bestResult.quality < cur_result.quality and cur_result.quality != Quality.UNKNOWN:
            bestResult = cur_result

        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
Esempio n. 7
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show {0}".format("by ShowDir: {0}".format(self.showDir) if self.showDir else "by Indexer Id: {0}".format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) + ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if not self.showDir and self.root_dir:
                show_name = get_showname_from_indexer(self.indexer, self.indexer_id, self.lang)
                if show_name:
                    self.showDir = ek(os.path.join, self.root_dir, sanitize_filename(show_name))
                    dir_exists = makeDir(self.showDir)
                    if not dir_exists:
                        logger.log(u"Unable to create the folder {0}, can't add the show".format(self.showDir))
                        return

                    chmodAsParent(self.showDir)
                else:
                    logger.log(u"Unable to get a show {0}, can't add the show".format(self.showDir))
                    return

            # 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 getattr(s, 'seriesname', None) is None:
                logger.log(u"Show in {} has no name on {}, probably searched with the wrong language.".format
                           (self.showDir, sickbeard.indexerApi(self.indexer).name), logger.ERROR)

                ui.notifications.error("Unable to add show",
                                       "Show in " + self.showDir + " has no name on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + ", probably the wrong language. Delete .nfo and add manually in the correct language.")
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + " is on " + str(
                    sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.")
                ui.notifications.error("Unable to add show",
                                       "Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception as e:
            logger.log(u"%s Error while loading information from indexer %s. Error: %r" % (self.indexer_id, sickbeard.indexerApi(self.indexer).name, ex(e)), logger.ERROR)
            # logger.log(u"Show name with ID %s doesn't exist on %s anymore. If you are using trakt, it will be removed from your TRAKT watchlist. If you are adding manually, try removing the nfo and adding again" %
            #            (self.indexer_id, sickbeard.indexerApi(self.indexer).name), logger.WARNING)

            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in %s on %s using ID %s, not using the NFO. Delete .nfo and try adding manually again." %
                (self.showDir, sickbeard.indexerApi(self.indexer).name, self.indexer_id)
            )

            if sickbeard.USE_TRAKT:

                trakt_id = sickbeard.indexerApi(self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.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')

            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders is not None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(u"Setting all episodes to the specified default status: " + str(self.show.default_ep_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 sickbeard.indexer_exception as e:
            logger.log(
                u"Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) + " due to an error with " + sickbeard.indexerApi(
                        self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return

        except MultipleShowObjectsException:
            logger.log(u"The show in " + self.showDir + " is already in your show list, skipping", logger.WARNING)
            ui.notifications.error('Show skipped', "The show in " + self.showDir + " is already in your show list")
            self._finishEarly()
            return

        except Exception as e:
            logger.log(u"Error trying to add show: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        logger.log(u"Retrieving show info from IMDb", logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as e:
            logger.log(u" Something wrong on IMDb api: " + ex(e), logger.WARNING)
        except Exception as e:
            logger.log(u"Error loading IMDb info: " + ex(e), logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log(u"Error saving the show to the database: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            logger.log(
                u"Error with " + sickbeard.indexerApi(self.show.indexer).name + ", not creating episode list: " + ex(e),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            logger.log(u"Error searching dir for episodes: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(u"Launching backlog for this show since its episodes are WANTED")
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)

            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log(u"update watchlist")
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.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 sickbeard.scene_numbering.get_xem_numbering_for_show(self.show.indexerid,
                                                                                   self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        self.finish()
Esempio n. 8
0
class QueueItemAdd(ShowQueueItem):
    def __init__(self, indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang, subtitles, anime,
                 scene, paused, blacklist, whitelist, default_status_after, archive):

        self.indexer = indexer
        self.indexer_id = indexer_id
        self.showDir = showDir
        self.default_status = default_status
        self.quality = quality
        self.flatten_folders = flatten_folders
        self.lang = lang
        self.subtitles = subtitles
        self.anime = anime
        self.scene = scene
        self.paused = paused
        self.blacklist = blacklist
        self.whitelist = whitelist
        self.default_status_after = default_status_after
        self.archive = archive

        self.show = None

        # this will initialize self.show to None
        ShowQueueItem.__init__(self, ShowQueueActions.ADD, self.show)

        # Process add show in priority
        self.priority = generic_queue.QueuePriorities.HIGH

    def _getName(self):
        """
        Returns the show name if there is a show object created, if not returns
        the dir that the show is being added to.
        """
        if self.show == None:
            return self.showDir
        return self.show.name

    show_name = property(_getName)

    def _isLoading(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 self.show == None:
            return True
        return False

    isLoading = property(_isLoading)

    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show " + self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) + ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # 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 getattr(s, 'seriesname', None) is None:
                logger.log(u"Show in " + self.showDir + " has no name on " + str(
                    sickbeard.indexerApi(self.indexer).name) + ", probably the wrong language used to search with.",
                           logger.ERROR)
                ui.notifications.error("Unable to add show",
                                       "Show in " + self.showDir + " has no name on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + ", probably the wrong language. Delete .nfo and add manually in the correct language.")
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + " is on " + str(
                    sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.", logger.ERROR)
                ui.notifications.error("Unable to add show",
                                       "Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception, e:
            logger.log(u"Error while loading information from indexer %s. Error: %r" % (self.indexer_id,sickbeard.indexerApi(self.indexer).name, ex(e)),logger.ERROR)
            #logger.log(u"Show name with ID %s doesn't exist on %s anymore. If you are using trakt, it will be removed from your TRAKT watchlist. If you are adding manually, try removing the nfo and adding again" %
            #    (self.indexer_id,sickbeard.indexerApi(self.indexer).name) , logger.WARNING)

            ui.notifications.error("Unable to add show",
                                   "Unable to look up the show in " + self.showDir + " on " + str(sickbeard.indexerApi(
                                       self.indexer).name) + " using ID " + str(
                                       self.indexer_id) + ", not using the NFO. Delete .nfo and try adding manually again.")

            if sickbeard.USE_TRAKT:

                trakt_id = sickbeard.indexerApi(self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.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')

            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles != None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders != None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime != None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene != None else sickbeard.SCENE_DEFAULT
            self.show.archive_firstmatch = self.archive if self.archive != None else sickbeard.ARCHIVE_DEFAULT
            self.show.paused = self.paused if self.paused != None else False

            # set up default new/missing episode status
            logger.log(u"Setting all episodes to the specified default status: " + str(self.show.default_ep_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 sickbeard.indexer_exception, e:
            logger.log(
                u"Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) + " due to an error with " + sickbeard.indexerApi(
                        self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return
Esempio n. 9
0
    def run(self):  # pylint: disable=too-many-branches, too-many-statements, too-many-return-statements

        super(QueueItemAdd, self).run()

        if self.showDir:
            try:
                assert isinstance(self.showDir, six.text_type)
            except AssertionError:
                logger.log(traceback.format_exc(), logger.WARNING)
                self._finish_early()
                return

        logger.log('Starting to add show {0}'.format(
            'by ShowDir: {0}'.format(self.showDir) if self.
            showDir else 'by Indexer Id: {0}'.format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            lINDEXER_API_PARMS[
                'language'] = self.lang or sickbeard.INDEXER_DEFAULT_LANGUAGE

            logger.log('{0}: {1!r}'.format(
                sickbeard.indexerApi(self.indexer).name, lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if self.root_dir and not self.showDir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if not show_name:
                    logger.log(
                        'Unable to get a show {0}, can\'t add the show'.format(
                            self.showDir))
                    self._finish_early()
                    return

                self.showDir = ek(os.path.join, self.root_dir,
                                  sanitize_filename(show_name))

                dir_exists = makeDir(self.showDir)
                if not dir_exists:
                    logger.log(
                        'Unable to create the folder {0}, can\'t add the show'.
                        format(self.showDir))
                    self._finish_early()
                    return

                chmodAsParent(self.showDir)

            # 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 getattr(s, 'seriesname', None) is None:
                error_string = 'Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language.'.format(
                    self.showDir,
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string, logger.WARNING)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return

            # if the show has no episodes/seasons
            if not s:
                error_string = 'Show {0} is on {1} but contains no season/episode data.'.format(
                    s[b'seriesname'],
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return
        except Exception as error:
            error_string = 'Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.'.format(
                self.showDir,
                sickbeard.indexerApi(self.indexer).name, self.indexer_id)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            if sickbeard.USE_TRAKT:
                trakt_id = sickbeard.indexerApi(
                    self.indexer).config[b'trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY,
                                     sickbeard.TRAKT_TIMEOUT)

                title = self.showDir.split('/')[-1]
                data = {'shows': [{'title': title, 'ids': {}}]}
                if trakt_id == 'tvdb_id':
                    data[b'shows'][0][b'ids'][b'tvdb'] = self.indexer_id
                else:
                    data[b'shows'][0][b'ids'][b'tvrage'] = self.indexer_id

                trakt_api.traktRequest('sync/watchlist/remove',
                                       data,
                                       method='POST')

            self._finish_early()
            return

        try:
            try:
                newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            except MultipleShowObjectsException as error:
                # If we have the show in our list, but the location is wrong, lets fix it and refresh!
                existing_show = Show.find(sickbeard.showList, self.indexer_id)
                if existing_show and not ek(os.path.isdir,
                                            existing_show._location):  # pylint: disable=protected-access
                    newShow = existing_show
                else:
                    raise error

            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.subtitles_sr_metadata = self.subtitles_sr_metadata
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.season_folders = self.season_folders if self.season_folders is not None else sickbeard.SEASON_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(
                'Setting all episodes to the specified default status: {0}'.
                format(self.show.default_ep_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 sickbeard.indexer_exception as error:
            error_string = 'Unable to add {0} due to an error with {1}'.format(
                self.show.name if self.show else 'show',
                sickbeard.indexerApi(self.indexer).name)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            self._finish_early()
            return

        except MultipleShowObjectsException:
            error_string = 'The show in {0} is already in your show list, skipping'.format(
                self.showDir)
            logger.log(error_string, logger.WARNING)
            ui.notifications.error('Show skipped', error_string)

            self._finish_early()
            return

        except Exception as error:
            logger.log('Error trying to add show: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        logger.log('Retrieving show info from IMDb', logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as error:
            logger.log(' Something wrong on IMDb api: {0}'.format(error),
                       logger.WARNING)
        except Exception as error:
            logger.log('Error loading IMDb info: {0}'.format(error),
                       logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as error:
            logger.log(
                'Error saving the show to the database: {0}'.format(error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        # add it to the show list
        if not Show.find(sickbeard.showList, self.indexer_id):
            sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as error:
            logger.log(
                'Error with {0}, not creating episode list: {1}'.format(
                    sickbeard.indexerApi(self.show.indexer).name, error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as error:
            logger.log('Error searching dir for episodes: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(
                'Launching backlog for this show since its episodes are WANTED'
            )
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)
            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(
                    self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log('update watchlist')
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.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 sickbeard.scene_numbering.get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        super(QueueItemAdd, self).finish()
        self.finish()
Esempio n. 10
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log('Starting to add show %s' % self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u'' + str(sickbeard.indexerApi(self.indexer).name) +
                       ': ' + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id, False]

            # 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 getattr(s, 'seriesname', None) is None:
                logger.log(
                    'Show in %s has no name on %s, probably the wrong language used to search with.'
                    % (self.showDir, sickbeard.indexerApi(self.indexer).name),
                    logger.ERROR)
                ui.notifications.error(
                    'Unable to add show',
                    'Show in %s has no name on %s, probably the wrong language. Delete .nfo and add manually in the correct language.'
                    % (self.showDir, sickbeard.indexerApi(self.indexer).name))
                self._finishEarly()
                return
        except Exception as e:
            logger.log(
                'Unable to find show ID:%s on Indexer: %s' %
                (self.indexer_id, sickbeard.indexerApi(self.indexer).name),
                logger.ERROR)
            ui.notifications.error(
                'Unable to add show',
                'Unable to look up the show in %s on %s using ID %s, not using the NFO. Delete .nfo and try adding manually again.'
                % (self.showDir, sickbeard.indexerApi(
                    self.indexer).name, self.indexer_id))
            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if None is not self.subtitles else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if None is not self.flatten_folders else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if None is not self.anime else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if None is not self.scene else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if None is not self.paused else False
            self.show.tag = self.tag if None is not self.tag else 'Show List'

            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 sickbeard.indexer_exception as e:
            logger.log(
                'Unable to add show due to an error with %s: %s' %
                (sickbeard.indexerApi(self.indexer).name, ex(e)), logger.ERROR)
            if self.show:
                ui.notifications.error(
                    'Unable to add %s due to an error with %s' %
                    (self.show.name, sickbeard.indexerApi(self.indexer).name))
            else:
                ui.notifications.error(
                    'Unable to add show due to an error with %s' %
                    sickbeard.indexerApi(self.indexer).name)
            self._finishEarly()
            return

        except exceptions.MultipleShowObjectsException:
            logger.log(
                'The show in %s is already in your show list, skipping' %
                self.showDir, logger.ERROR)
            ui.notifications.error(
                'Show skipped',
                'The show in %s is already in your show list' % self.showDir)
            self._finishEarly()
            return

        except Exception as e:
            logger.log('Error trying to add show: %s' % ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        self.show.load_imdb_info()

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log('Error saving the show to the database: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            logger.log(
                'Error with %s, not creating episode list: %s' %
                (sickbeard.indexerApi(self.show.indexer).name, ex(e)),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            logger.log('Error searching directory for episodes: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they gave a custom status then change all the eps to it
        my_db = db.DBConnection()
        if self.default_status != SKIPPED:
            logger.log(
                'Setting all episodes to the specified default status: %s' %
                sickbeard.common.statusStrings[self.default_status])
            my_db.action(
                'UPDATE tv_episodes SET status = ? WHERE status = ? AND showid = ? AND season != 0',
                [self.default_status, SKIPPED, self.show.indexerid])

        # if they gave a number to start or number to end as wanted, then change those eps to it
        def get_wanted(db_obj, wanted_max, latest):
            actual = 0
            if wanted_max:
                select_id = 'FROM [tv_episodes] t5 JOIN (SELECT t3.indexerid, t3.status, t3.season*1000000+t3.episode AS t3_se, t2.start_season FROM [tv_episodes] t3'\
                            + ' JOIN (SELECT t1.showid, M%s(t1.season) AS start_season' % ('IN', 'AX')[latest]\
                            + ', MAX(t1.airdate) AS airdate, t1.episode, t1.season*1000000+t1.episode AS se FROM [tv_episodes] t1'\
                            + ' WHERE %s=t1.showid' % self.show.indexerid\
                            + ' AND 0<t1.season AND t1.status NOT IN (%s)) AS t2' % UNAIRED\
                            + ' ON t2.showid=t3.showid AND 0<t3.season AND t2.se>=t3_se ORDER BY t3_se %sSC' % ('A', 'DE')[latest]\
                            + ' %s) as t4' % (' LIMIT %s' % wanted_max, '')[-1 == wanted_max]\
                            + ' ON t4.indexerid=t5.indexerid'\
                            + '%s' % ('', ' AND t4.start_season=t5.season')[-1 == wanted_max]\
                            + ' AND t4.status NOT IN (%s)' % ','.join([str(x) for x in sickbeard.common.Quality.DOWNLOADED + [WANTED]])
                select = 'SELECT t5.indexerid as indexerid, t5.season as season, t5.episode as episode, t5.status as status ' + select_id
                update = 'UPDATE [tv_episodes] SET status=%s WHERE indexerid IN (SELECT t5.indexerid %s)' % (
                    WANTED, select_id)

                wanted_updates = db_obj.select(select)
                db_obj.action(update)
                result = db_obj.select(
                    'SELECT changes() as last FROM [tv_episodes]')
                for cur_result in result:
                    actual = cur_result['last']
                    break

                action_log = 'didn\'t find any episodes that need to be set wanted'
                if actual:
                    action_log = ('updated %s %s episodes > %s' % (
                        (((('%s of %s' % (actual, wanted_max)),
                           ('%s of max %s limited' %
                            (actual, wanted_max)))[10 == wanted_max]),
                         ('max %s available' % actual))[-1 == wanted_max],
                        ('first season', 'latest')[latest], ','.join(
                            [('S%02dE%02d=%d' %
                              (a['season'], a['episode'], a['status']))
                             for a in wanted_updates])))
                logger.log('Get wanted ' + action_log)
            return actual

        items_wanted = get_wanted(my_db,
                                  self.default_wanted_begin,
                                  latest=False)
        items_wanted += get_wanted(my_db,
                                   self.default_wanted_latest,
                                   latest=True)

        msg = ' the specified show into ' + self.showDir
        # if started with WANTED eps then run the backlog
        if WANTED == self.default_status or items_wanted:
            logger.log(
                'Launching backlog for this show since episodes are WANTED')
            sickbeard.backlogSearchScheduler.action.search_backlog(
                [self.show])  #@UndefinedVariable
            ui.notifications.message(
                'Show added/search',
                'Adding and searching for episodes of' + msg)
        else:
            ui.notifications.message('Show added', 'Adding' + msg)

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        # load ids
        self.show.ids

        # if sickbeard.USE_TRAKT:
        #     # if there are specific episodes that need to be added by trakt
        #     sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)
        #
        #     # add show to trakt.tv library
        #     if sickbeard.TRAKT_SYNC:
        #         sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.xem_refresh(self.show.indexerid,
                                              self.show.indexer,
                                              force=True)
        # check if show has XEM mapping and if user disabled scene numbering during add show, output availability to log
        if not self.scene and self.show.indexerid in sickbeard.scene_exceptions.xem_ids_list[
                self.show.indexer]:
            logger.log(
                'Alternative scene episode numbers were disabled during add show. Edit show to enable them for searching.'
            )

        # update internal name cache
        name_cache.buildNameCache(self.show)

        self.finish()
Esempio n. 11
0
def makeSceneSeasonSearchString(show, ep_obj, extraSearchType=None):
    myDB = db.DBConnection()

    if show.air_by_date or show.sports:
        numseasons = 0

        # the search string for air by date shows is just
        seasonStrings = [str(ep_obj.airdate).split('-')[0]]
    elif show.is_anime:
        numseasons = 0
        seasonEps = show.getAllEpisodes(ep_obj.season)

        # get show qualities
        anyQualities, bestQualities = common.Quality.splitQuality(show.quality)

        # compile a list of all the episode numbers we need in this 'season'
        seasonStrings = []
        for episode in seasonEps:

            # get quality of the episode
            curCompositeStatus = episode.status
            curStatus, curQuality = common.Quality.splitCompositeStatus(
                curCompositeStatus)

            if bestQualities:
                highestBestQuality = max(bestQualities)
            else:
                highestBestQuality = 0

            # if we need a better one then add it to the list of episodes to fetch
            if (curStatus in (common.DOWNLOADED, common.SNATCHED)
                    and curQuality < highestBestQuality
                ) or curStatus == common.WANTED:
                ab_number = episode.scene_absolute_number
                if ab_number > 0:
                    seasonStrings.append("%d" % ab_number)

    else:
        numseasonsSQlResult = myDB.select(
            "SELECT COUNT(DISTINCT season) as numseasons FROM tv_episodes WHERE showid = ? and season != 0",
            [show.indexerid])

        numseasons = int(numseasonsSQlResult[0][0])
        seasonStrings = ["S%02d" % int(ep_obj.scene_season)]

    bwl = BlackAndWhiteList(show.indexerid)
    showNames = set(makeSceneShowSearchStrings(show, ep_obj.scene_season))

    toReturn = []

    # search each show name
    for curShow in showNames:
        # most providers all work the same way
        if not extraSearchType:
            # if there's only one season then we can just use the show name straight up
            if numseasons == 1:
                toReturn.append(curShow)
            # for providers that don't allow multiple searches in one request we only search for Sxx style stuff
            else:
                for cur_season in seasonStrings:
                    if len(bwl.whiteList) > 0:
                        for keyword in bwl.whiteList:
                            toReturn.append(keyword + '.' + curShow + "." +
                                            cur_season)
                    else:
                        toReturn.append(curShow + "." + cur_season)

    return toReturn
Esempio n. 12
0
def pickBestResult(results, show=None, quality_list=None):
    results = results if isinstance(results, list) else [results]

    logger.log(u"Picking the best result out of " + str([x.name for x in results]), logger.DEBUG)

    bwl = None
    bestResult = None

    # find the best result for the current episode
    for cur_result in results:
        if show and cur_result.show is not show:
            continue

        # build the black And white list
        if not bwl and cur_result.show.is_anime:
            bwl = BlackAndWhiteList(cur_result.show.indexerid)
            if not bwl.is_valid(cur_result):
                logger.log(cur_result.name+" does not match the blacklist or the whitelist, rejecting it. Result: " + bwl.get_last_result_msg(), logger.INFO)
                continue

        logger.log("Quality of " + cur_result.name + " is " + Quality.qualityStrings[cur_result.quality])

        if quality_list and cur_result.quality not in quality_list:
            logger.log(cur_result.name + " is a quality we know we don't want, rejecting it", logger.DEBUG)
            continue

        if show.rls_ignore_words and filter_release_name(cur_result.name, cur_result.show.rls_ignore_words):
            logger.log(u"Ignoring " + cur_result.name + " based on ignored words filter: " + show.rls_ignore_words,
                       logger.INFO)
            continue

        if show.rls_require_words and not filter_release_name(cur_result.name, cur_result.show.rls_require_words):
            logger.log(u"Ignoring " + cur_result.name + " based on required words filter: " + show.rls_require_words,
                       logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name, parse=False):
            logger.log(u"Ignoring " + cur_result.name + " because its not a valid scene release that we want, ignoring it",
                       logger.INFO)
            continue

        if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(cur_result.name, cur_result.size,
                                                                       cur_result.provider.name):
            logger.log(cur_result.name + u" has previously failed, rejecting it")
            continue

        if not bestResult or bestResult.quality < cur_result.quality and cur_result.quality != Quality.UNKNOWN:
            bestResult = cur_result

        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower() or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower() and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower() and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name + " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
Esempio n. 13
0
def pickBestResult(results, show, quality_list=None):
    results = results if isinstance(results, list) else [results]

    logger.log(
        u"Picking the best result out of " + str([x.name for x in results]),
        logger.DEBUG)

    bwl = None
    bestResult = None

    # find the best result for the current episode
    for cur_result in results:
        if show and cur_result.show is not show:
            continue

        # filter out possible bad torrents from providers such as ezrss
        if isinstance(cur_result, sickbeard.classes.SearchResult):
            if cur_result.resultType == "torrent" and sickbeard.TORRENT_METHOD != "blackhole":
                if not cur_result.url.startswith('magnet'):
                    cur_result.content = cur_result.provider.getURL(
                        cur_result.url)
                    if not cur_result.content:
                        continue
        else:
            if not cur_result.url.startswith('magnet'):
                cur_result.content = cur_result.provider.getURL(cur_result.url)
                if not cur_result.content:
                    continue

        # build the black And white list
        if cur_result.show.is_anime:
            if not bwl:
                bwl = BlackAndWhiteList(cur_result.show.indexerid)
            if not bwl.is_valid(cur_result):
                logger.log(
                    cur_result.name +
                    " does not match the blacklist or the whitelist, rejecting it. Result: "
                    + bwl.get_last_result_msg(), logger.INFO)
                continue

        logger.log("Quality of " + cur_result.name + " is " +
                   Quality.qualityStrings[cur_result.quality])

        if quality_list and cur_result.quality not in quality_list:
            logger.log(
                cur_result.name +
                " is a quality we know we don't want, rejecting it",
                logger.DEBUG)
            continue

        if show.lang == "de" and not filter_release_name(
                cur_result.name, "german|videoman"):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on ignored words filter: show language 'de'",
                logger.INFO)
            continue

        if show.lang != "de" and filter_release_name(cur_result.name,
                                                     "german|videoman"):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on ignored words filter: show language '%s'" %
                show.lang, logger.INFO)
            continue

        if show.rls_ignore_words and filter_release_name(
                cur_result.name, cur_result.show.rls_ignore_words):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on ignored words filter: " + show.rls_ignore_words,
                logger.INFO)
            continue

        if show.rls_require_words and not filter_release_name(
                cur_result.name, cur_result.show.rls_require_words):
            logger.log(
                u"Ignoring " + cur_result.name +
                " based on required words filter: " + show.rls_require_words,
                logger.INFO)
            continue

        if not show_name_helpers.filterBadReleases(cur_result.name,
                                                   parse=False):
            logger.log(
                u"Ignoring " + cur_result.name +
                " because its not a valid scene release that we want, ignoring it",
                logger.INFO)
            continue

        if hasattr(cur_result, 'size'):
            if sickbeard.USE_FAILED_DOWNLOADS and failed_history.hasFailed(
                    cur_result.name, cur_result.size,
                    cur_result.provider.name):
                logger.log(cur_result.name +
                           u" has previously failed, rejecting it")
                continue

        if not bestResult or bestResult.quality < cur_result.quality and cur_result.quality != Quality.UNKNOWN:
            bestResult = cur_result

        elif bestResult.quality == cur_result.quality:
            if "proper" in cur_result.name.lower(
            ) or "repack" in cur_result.name.lower():
                bestResult = cur_result
            elif "internal" in bestResult.name.lower(
            ) and "internal" not in cur_result.name.lower():
                bestResult = cur_result
            elif "xvid" in bestResult.name.lower(
            ) and "x264" in cur_result.name.lower():
                logger.log(u"Preferring " + cur_result.name +
                           " (x264 over xvid)")
                bestResult = cur_result

    if bestResult:
        logger.log(u"Picked " + bestResult.name + " as the best", logger.DEBUG)
    else:
        logger.log(u"No result picked.", logger.DEBUG)

    return bestResult
Esempio n. 14
0
class QueueItemAdd(ShowQueueItem):
    def __init__(self, indexer, indexer_id, showDir, default_status, quality,
                 flatten_folders, lang, subtitles, anime, scene, paused,
                 blacklist, whitelist):

        self.indexer = indexer
        self.indexer_id = indexer_id
        self.showDir = showDir
        self.default_status = default_status
        self.quality = quality
        self.flatten_folders = flatten_folders
        self.lang = lang
        self.subtitles = subtitles
        self.anime = anime
        self.scene = scene
        self.paused = paused
        self.blacklist = blacklist
        self.whitelist = whitelist

        if sickbeard.TRAKT_USE_ROLLING_DOWNLOAD and sickbeard.USE_TRAKT:
            self.paused = sickbeard.TRAKT_ROLLING_ADD_PAUSED

        # Process add show in priority
        self.priority = generic_queue.QueuePriorities.HIGH

        self.show = None

        # this will initialize self.show to None
        ShowQueueItem.__init__(self, ShowQueueActions.ADD, self.show)

    def _getName(self):
        """
        Returns the show name if there is a show object created, if not returns
        the dir that the show is being added to.
        """
        if self.show == None:
            return self.showDir
        return self.show.name

    show_name = property(_getName)

    def _isLoading(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 self.show == None:
            return True
        return False

    isLoading = property(_isLoading)

    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show " + self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) +
                       ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # 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 getattr(s, 'seriesname', None) is None:
                logger.log(
                    u"Show in " + self.showDir + " has no name on " +
                    str(sickbeard.indexerApi(self.indexer).name) +
                    ", probably the wrong language used to search with.",
                    logger.ERROR)
                ui.notifications.error(
                    "Unable to add show",
                    "Show in " + self.showDir + " has no name on " +
                    str(sickbeard.indexerApi(self.indexer).name) +
                    ", probably the wrong language. Delete .nfo and add manually in the correct language."
                )
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(
                    u"Show " + str(s['seriesname']) + " is on " +
                    str(sickbeard.indexerApi(self.indexer).name) +
                    " but contains no season/episode data.", logger.ERROR)
                ui.notifications.error(
                    "Unable to add show", "Show " + str(s['seriesname']) +
                    " is on " + str(sickbeard.indexerApi(self.indexer).name) +
                    " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception, e:
            logger.log(
                u"Unable to find show ID:" + str(self.indexer_id) +
                " on Indexer: " + str(sickbeard.indexerApi(self.indexer).name),
                logger.ERROR)
            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in " + self.showDir + " on " +
                str(sickbeard.indexerApi(self.indexer).name) + " using ID " +
                str(self.indexer_id) +
                ", not using the NFO. Delete .nfo and try adding manually again."
            )
            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles != None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders != None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime != None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene != None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused != None else False

            # set up default new/missing episode status
            logger.log(
                u"Setting all episodes to the specified default status: " +
                str(self.show.default_ep_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 sickbeard.indexer_exception, e:
            logger.log(
                u"Unable to add show due to an error with " +
                sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) +
                    " due to an error with " +
                    sickbeard.indexerApi(self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " +
                    sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return