예제 #1
0
def generate_sample_ep(multi=None, abd=False, sports=False, anime_type=None):
    # make a fake episode object
    ep = FakeEpisode(2, 3, 3, "Ep Name")

    ep.status = Quality.composite_status(EpisodeStatus.DOWNLOADED,
                                         Qualities.HDTV)
    ep.airdate = date(2011, 3, 9)

    if abd:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP'
        ep.show.search_format = SearchFormat.AIR_BY_DATE
    elif sports:
        ep.release_name = 'Show.Name.2011.03.09.HDTV.XviD-RLSGROUP'
        ep.show.search_format = SearchFormat.SPORTS
    else:
        if anime_type != 3:
            ep.show.search_format = SearchFormat.ANIME
            ep.release_name = 'Show.Name.003.HDTV.XviD-RLSGROUP'
        else:
            ep.release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'

    if multi is not None:
        ep.name = "Ep Name (1)"

        if anime_type != 3:
            ep.show.search_format = SearchFormat.ANIME

            ep.release_name = 'Show.Name.003-004.HDTV.XviD-RLSGROUP'

            second_ep = FakeEpisode(2, 4, 4, "Ep Name (2)")
            second_ep.status = Quality.composite_status(
                EpisodeStatus.DOWNLOADED, Qualities.HDTV)
            second_ep.release_name = ep.release_name

            ep.related_episodes.append(second_ep)
        else:
            ep.release_name = 'Show.Name.S02E03E04E05.HDTV.XviD-RLSGROUP'

            second_ep = FakeEpisode(2, 4, 4, "Ep Name (2)")
            second_ep.status = Quality.composite_status(
                EpisodeStatus.DOWNLOADED, Qualities.HDTV)
            second_ep.release_name = ep.release_name

            third_ep = FakeEpisode(2, 5, 5, "Ep Name (3)")
            third_ep.status = Quality.composite_status(
                EpisodeStatus.DOWNLOADED, Qualities.HDTV)
            third_ep.release_name = ep.release_name

            ep.related_episodes.append(second_ep)
            ep.related_episodes.append(third_ep)

    return ep
예제 #2
0
    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
예제 #3
0
    def log_failed(show_id, season, episode, release, provider=None, session=None):
        """
        Log a failed download

        :param epObj: Episode object
        :param release: Release group
        :param provider: Provider used for snatch
        """
        show_object = find_show(show_id, session=session)
        episode_object = show_object.get_episode(season, episode)

        status, quality = Quality.split_composite_status(episode_object.status)
        action = Quality.composite_status(FAILED, quality)

        History._log_history_item(action, show_id, season, episode, quality, release, provider, session=session)
예제 #4
0
    def __init__(self, season, episode, absolute_number, name):
        self.name = name
        self.season = season
        self.episode = episode
        self.absolute_number = absolute_number
        self.airdate = datetime.date(2010, 3, 9)
        self.status = Quality.composite_status(DOWNLOADED, Quality.SDTV)
        self.release_name = 'Show.Name.S02E03.HDTV.XviD-RLSGROUP'
        self.release_group = 'RLSGROUP'
        self.is_proper = True

        self.show = FakeShow()
        self.scene_season = season
        self.scene_episode = episode
        self.scene_absolute_number = absolute_number
        self.related_episodes = []
예제 #5
0
    def log_subtitle(show_id, season, episode, status, subtitle):
        """
        Log download of subtitle

        :param showid: Showid of download
        :param season: Show season
        :param episode: Show episode
        :param status: Status of download
        :param subtitleResult: Result object
        """
        resource = subtitle.language.opensubtitles
        provider = subtitle.provider_name

        status, quality = Quality.split_composite_status(status)
        action = Quality.composite_status(SUBTITLED, quality)

        History._log_history_item(action, show_id, season, episode, quality, resource, provider)
예제 #6
0
    def log_snatch(search_result):
        """
        Log history of snatch

        :param search_result: search result object
        """
        for episode in search_result.episodes:
            quality = search_result.quality
            version = search_result.version

            provider = search_result.provider.name if search_result.provider else "unknown"

            action = Quality.composite_status(SNATCHED, search_result.quality)

            resource = search_result.name

            release_group = search_result.release_group

            History._log_history_item(action, search_result.show_id, search_result.season, episode, quality, resource, provider, version, release_group)
예제 #7
0
    def refresh_dir(self):
        # make sure the show dir is where we think it is unless dirs are created on the fly
        if not os.path.isdir(
                self.location
        ) and not sickrage.app.config.create_missing_show_dirs:
            return False

        # load from dir
        try:
            self.load_episodes_from_dir()
        except Exception as e:
            sickrage.app.log.debug(
                "Error searching dir for episodes: {}".format(e))
            sickrage.app.log.debug(traceback.format_exc())

        # run through all locations from DB, check that they exist
        sickrage.app.log.debug(
            str(self.indexer_id) +
            ": Loading all episodes with a location from the database")

        for curEp in self.episodes:
            if curEp.location == '':
                continue

            curLoc = os.path.normpath(curEp.location)
            season = int(curEp.season)
            episode = int(curEp.episode)

            # if the path doesn't exist or if it's not in our show dir
            if not os.path.isfile(curLoc) or not os.path.normpath(
                    curLoc).startswith(os.path.normpath(self.location)):
                # check if downloaded files still exist, update our data if this has changed
                if not sickrage.app.config.skip_removed_files:
                    # if it used to have a file associated with it and it doesn't anymore then set it to
                    # EP_DEFAULT_DELETED_STATUS
                    if curEp.location and curEp.status in Quality.DOWNLOADED:
                        if sickrage.app.config.ep_default_deleted_status == ARCHIVED:
                            __, oldQuality = Quality.split_composite_status(
                                curEp.status)
                            new_status = Quality.composite_status(
                                ARCHIVED, oldQuality)
                        else:
                            new_status = sickrage.app.config.ep_default_deleted_status

                        sickrage.app.log.debug(
                            "%s: Location for S%02dE%02d doesn't exist, "
                            "removing it and changing our status to %s" %
                            (self.indexer_id, season or 0, episode
                             or 0, statusStrings[new_status]))

                        curEp.status = new_status
                        curEp.subtitles = ''
                        curEp.subtitles_searchcount = 0
                        curEp.subtitles_lastsearch = 0

                    curEp.location = ''
                    curEp.hasnfo = False
                    curEp.hastbn = False
                    curEp.release_name = ''
            else:
                if curEp.status in Quality.ARCHIVED:
                    __, oldQuality = Quality.split_composite_status(
                        curEp.status)
                    curEp.status = Quality.composite_status(
                        DOWNLOADED, oldQuality)

                # the file exists, set its modify file stamp
                if sickrage.app.config.airdate_episodes:
                    curEp.airdateModifyStamp()
예제 #8
0
    def make_ep_from_file(self, filename):
        if not os.path.isfile(filename):
            sickrage.app.log.info(
                str(self.indexer_id) +
                ": That isn't even a real file dude... " + filename)
            return None

        sickrage.app.log.debug(
            str(self.indexer_id) + ": Creating episode object from " +
            filename)

        try:
            parse_result = NameParser(validate_show=False).parse(
                filename, skip_scene_detection=True)
        except InvalidNameException:
            sickrage.app.log.debug("Unable to parse the filename " + filename +
                                   " into a valid episode")
            return None
        except InvalidShowException:
            sickrage.app.log.debug("Unable to parse the filename " + filename +
                                   " into a valid show")
            return None

        if not len(parse_result.episode_numbers):
            sickrage.app.log.info("parse_result: " + str(parse_result))
            sickrage.app.log.warning("No episode number found in " + filename +
                                     ", ignoring it")
            return None

        # for now lets assume that any episode in the show dir belongs to that show
        season = parse_result.season_number if parse_result.season_number is not None else 1
        root_ep = None

        for curEpNum in parse_result.episode_numbers:
            episode = int(curEpNum)

            sickrage.app.log.debug("%s: %s parsed to %s S%02dE%02d" %
                                   (self.indexer_id, filename, self.name,
                                    season or 0, episode or 0))

            check_quality_again = False

            try:
                episode_obj = self.get_episode(season, episode)
            except EpisodeNotFoundException:
                object_session(self).add(
                    TVEpisode(
                        **{
                            'showid': self.indexer_id,
                            'indexer': self.indexer,
                            'season': season,
                            'episode': episode,
                            'location': filename
                        }))
                object_session(self).commit()
                episode_obj = self.get_episode(season, episode)

            # if there is a new file associated with this ep then re-check the quality
            if episode_obj.location and os.path.normpath(
                    episode_obj.location) != os.path.normpath(filename):
                sickrage.app.log.debug(
                    "The old episode had a different file associated with it, I will re-check "
                    "the quality based on the new filename " + filename)
                check_quality_again = True

            # if the sizes are the same then it's probably the same file
            old_size = episode_obj.file_size
            episode_obj.location = filename
            same_file = old_size and episode_obj.file_size == old_size
            episode_obj.checkForMetaFiles()

            if root_ep is None:
                root_ep = episode_obj
            else:
                if episode_obj not in root_ep.related_episodes:
                    root_ep.related_episodes.append(episode_obj)

            # if it's a new file then
            if not same_file:
                episode_obj.release_name = ''

            # if they replace a file on me I'll make some attempt at re-checking the quality unless I know it's the
            # same file
            if check_quality_again and not same_file:
                new_quality = Quality.name_quality(filename, self.is_anime)
                sickrage.app.log.debug("Since this file has been renamed")

                episode_obj.status = Quality.composite_status(
                    DOWNLOADED, new_quality)

            # check for status/quality changes as long as it's a new file
            elif not same_file and is_media_file(
                    filename
            ) and episode_obj.status not in Quality.DOWNLOADED + Quality.ARCHIVED + [
                    IGNORED
            ]:
                old_status, old_quality = Quality.split_composite_status(
                    episode_obj.status)
                new_quality = Quality.name_quality(filename, self.is_anime)

                new_status = None

                # if it was snatched and now exists then set the status correctly
                if old_status == SNATCHED and old_quality <= new_quality:
                    sickrage.app.log.debug(
                        "STATUS: this ep used to be snatched with quality " +
                        Quality.qualityStrings[old_quality] +
                        " but a file exists with quality " +
                        Quality.qualityStrings[new_quality] +
                        " so I'm setting the status to DOWNLOADED")
                    new_status = DOWNLOADED

                # if it was snatched proper and we found a higher quality one then allow the status change
                elif old_status == SNATCHED_PROPER and old_quality < new_quality:
                    sickrage.app.log.debug(
                        "STATUS: this ep used to be snatched proper with quality "
                        + Quality.qualityStrings[old_quality] +
                        " but a file exists with quality " +
                        Quality.qualityStrings[new_quality] +
                        " so I'm setting the status to DOWNLOADED")
                    new_status = DOWNLOADED

                elif old_status not in (SNATCHED, SNATCHED_PROPER):
                    new_status = DOWNLOADED

                if new_status is not None:
                    sickrage.app.log.debug(
                        "STATUS: we have an associated file, so setting the status from "
                        + str(episode_obj.status) + " to DOWNLOADED/" + str(
                            Quality.status_from_name(filename,
                                                     anime=self.is_anime)))
                    episode_obj.status = Quality.composite_status(
                        new_status, new_quality)

        # creating metafiles on the root should be good enough
        if root_ep:
            root_ep.create_meta_files()

        object_session(self).commit()

        return root_ep
예제 #9
0
def snatch_episode(result, end_status=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param end_status: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    show_object = find_show(result.show_id)

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.app.config.allow_high_priority:
        # if it aired recently make it high priority
        for episode_number in result.episodes:
            if date.today() - show_object.get_episode(
                    result.season, episode_number).airdate <= timedelta(
                        days=7):
                result.priority = 1

    if re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', result.name,
                 re.I) is not None:
        end_status = SNATCHED_PROPER

    # get result content
    result.content = result.provider.get_content(result.url)

    dlResult = False
    if result.type in ("nzb", "nzbdata"):
        if sickrage.app.config.nzb_method == "blackhole":
            dlResult = result.provider.download_result(result)
        elif sickrage.app.config.nzb_method == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.app.config.nzb_method == "nzbget":
            is_proper = True if end_status == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        elif sickrage.app.config.nzb_method == "download_station":
            client = get_client_instance(sickrage.app.config.nzb_method,
                                         client_type='nzb')()
            dlResult = client.sendNZB(result)
        else:
            sickrage.app.log.error("Unknown NZB action specified in config: " +
                                   sickrage.app.config.nzb_method)
    elif result.type in ("torrent", "torznab"):
        # add public trackers to torrent result
        if not result.provider.private:
            result = result.provider.add_trackers(result)

        if sickrage.app.config.torrent_method == "blackhole":
            dlResult = result.provider.download_result(result)
        else:
            if any([result.content, result.url.startswith('magnet:')]):
                client = get_client_instance(
                    sickrage.app.config.torrent_method,
                    client_type='torrent')()
                dlResult = client.send_torrent(result)
            else:
                sickrage.app.log.warning("Torrent file content is empty")
    else:
        sickrage.app.log.error(
            "Unknown result type, unable to download it (%r)" % result.type)

    # no download results found
    if not dlResult:
        return False

    FailedHistory.log_snatch(result)
    History.log_snatch(result)

    sickrage.app.alerts.message(_('Episode snatched'), result.name)

    trakt_data = []
    for episode_number in result.episodes:
        episode_obj = show_object.get_episode(result.season, episode_number)

        if is_first_best_match(result):
            episode_obj.status = Quality.composite_status(
                SNATCHED_BEST, result.quality)
        else:
            episode_obj.status = Quality.composite_status(
                end_status, result.quality)

        episode_obj.save()

        # don't notify when we re-download an episode
        if episode_obj.status not in Quality.DOWNLOADED:
            try:
                Notifiers.mass_notify_snatch(
                    episode_obj._format_pattern('%SN - %Sx%0E - %EN - %QN') +
                    " from " + result.provider.name)
            except Exception:
                sickrage.app.log.debug("Failed to send snatch notification")

            trakt_data.append((episode_obj.season, episode_obj.episode))

    data = sickrage.app.notifier_providers[
        'trakt'].trakt_episode_data_generate(trakt_data)

    if sickrage.app.config.use_trakt and sickrage.app.config.trakt_sync_watchlist:
        if data:
            sickrage.app.notifier_providers['trakt'].update_watchlist(
                show_object, data_episode=data, update="add")

    return True