コード例 #1
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
コード例 #2
0
    def process(self):
        """
        Do the actual work

        :return: True
        """
        self._log("Failed download detected: (" + str(self.nzb_name) + ", " +
                  str(self.dir_name) + ")")

        release_name = show_names.determine_release_name(
            self.dir_name, self.nzb_name)
        if release_name is None:
            self._log("Warning: unable to find a valid release name.",
                      sickrage.app.log.WARNING)
            raise FailedPostProcessingFailedException()

        try:
            parsed = NameParser(False).parse(release_name)
        except InvalidNameException:
            self._log("Error: release name is invalid: " + release_name,
                      sickrage.app.log.DEBUG)
            raise FailedPostProcessingFailedException()
        except InvalidShowException:
            self._log(
                "Error: unable to parse release name " + release_name +
                " into a valid show", sickrage.app.log.DEBUG)
            raise FailedPostProcessingFailedException()

        if parsed.show.paused:
            self._log(
                "Warning: skipping failed processing for {} because the show is paused"
                .format(release_name), sickrage.app.log.DEBUG)
            raise FailedPostProcessingFailedException()

        sickrage.app.log.debug("name_parser info: ")
        sickrage.app.log.debug(" - " + str(parsed.series_name))
        sickrage.app.log.debug(" - " + str(parsed.season_number))
        sickrage.app.log.debug(" - " + str(parsed.episode_numbers))
        sickrage.app.log.debug(" - " + str(parsed.extra_info))
        sickrage.app.log.debug(" - " + str(parsed.release_group))
        sickrage.app.log.debug(" - " + str(parsed.air_date))

        for episode in parsed.episode_numbers:
            try:
                episode_obj = parsed.show.get_episode(parsed.season_number,
                                                      episode)
            except EpisodeNotFoundException as e:
                continue

            cur_status, cur_quality = Quality.split_composite_status(
                episode_obj.status)
            if cur_status not in {SNATCHED, SNATCHED_BEST, SNATCHED_PROPER}:
                continue

            sickrage.app.search_queue.put(
                FailedSearchTask(parsed.show, episode_obj.season,
                                 episode_obj.episode))

        return True
コード例 #3
0
    def task(self, force=False):
        """
        Runs the failed searcher, queuing selected episodes for search that have failed to snatch
        :param force: Force search
        """
        if self.running or not sickrage.app.config.failed_snatches.enable and not force:
            return

        try:
            self.running = True

            # set thread name
            threading.currentThread().setName(self.name)

            # trim failed download history
            FailedHistory.trim_history()

            sickrage.app.log.info("Searching for failed snatches")

            failed_snatches = False

            for snatched_episode_obj in [
                    x for x in self.snatched_episodes()
                    if (x.series_id, x.season,
                        x.episode) not in self.downloaded_releases()
            ]:
                show_object = find_show(
                    snatched_episode_obj.series_id,
                    snatched_episode_obj.series_provider_id)
                episode_object = show_object.get_episode(
                    snatched_episode_obj.season, snatched_episode_obj.episode)
                if episode_object.show.paused:
                    continue

                cur_status, cur_quality = Quality.split_composite_status(
                    episode_object.status)
                if cur_status not in {
                        EpisodeStatus.SNATCHED, EpisodeStatus.SNATCHED_BEST,
                        EpisodeStatus.SNATCHED_PROPER
                }:
                    continue

                sickrage.app.search_queue.put(
                    FailedSearchTask(show_object.series_id,
                                     show_object.series_provider_id,
                                     episode_object.season,
                                     episode_object.episode, True))

                failed_snatches = True

            if not failed_snatches:
                sickrage.app.log.info("No failed snatches found")
        finally:
            self.running = False
コード例 #4
0
ファイル: daily_searcher.py プロジェクト: zuofu123/SiCKRAGE
    def _get_wanted(show, from_date):
        """
        Get a list of episodes that we want to download
        :param show: Show these episodes are from
        :param fromDate: Search from a certain date
        :return: list of wanted episodes
        """

        wanted = []

        any_qualities, best_qualities = Quality.split_quality(show.quality)
        all_qualities = list(set(any_qualities + best_qualities))

        sickrage.app.log.debug(
            "Seeing if we need anything for today from {}".format(show.name))

        # check through the list of statuses to see if we want any
        for episode_object in show.episodes:
            if not episode_object.season > 0 or not episode_object.airdate >= from_date:
                continue

            cur_status, cur_quality = Quality.split_composite_status(
                episode_object.status)

            # if we need a better one then say yes
            if cur_status not in (EpisodeStatus.WANTED,
                                  EpisodeStatus.DOWNLOADED,
                                  EpisodeStatus.SNATCHED,
                                  EpisodeStatus.SNATCHED_PROPER):
                continue

            if cur_status != EpisodeStatus.WANTED:
                if best_qualities:
                    if cur_quality in best_qualities:
                        continue
                    elif cur_quality != Qualities.UNKNOWN and cur_quality > max(
                            best_qualities):
                        continue
                else:
                    if cur_quality in any_qualities:
                        continue
                    elif cur_quality != Qualities.UNKNOWN and cur_quality > max(
                            any_qualities):
                        continue

            # skip upgrading quality of downloaded episodes if enabled
            if cur_status == EpisodeStatus.DOWNLOADED and show.skip_downloaded:
                continue

            wanted += [(episode_object.season, episode_object.episode)]

        return wanted
コード例 #5
0
    def get_overview(self, epStatus):
        epStatus = try_int(epStatus) or UNKNOWN

        if epStatus == WANTED:
            return Overview.WANTED
        elif epStatus in (UNAIRED, UNKNOWN):
            return Overview.UNAIRED
        elif epStatus in (SKIPPED, IGNORED):
            return Overview.SKIPPED
        elif epStatus in Quality.ARCHIVED:
            return Overview.GOOD
        elif epStatus in Quality.FAILED:
            return Overview.WANTED
        elif epStatus in Quality.SNATCHED:
            return Overview.SNATCHED
        elif epStatus in Quality.SNATCHED_PROPER:
            return Overview.SNATCHED_PROPER
        elif epStatus in Quality.SNATCHED_BEST:
            return Overview.SNATCHED_BEST
        elif epStatus in Quality.DOWNLOADED:
            anyQualities, bestQualities = Quality.split_quality(self.quality)
            epStatus, curQuality = Quality.split_composite_status(epStatus)

            if bestQualities:
                maxBestQuality = max(bestQualities)
                minBestQuality = min(bestQualities)
            else:
                maxBestQuality = None
                minBestQuality = None

            # elif epStatus == DOWNLOADED and curQuality == Quality.UNKNOWN:
            #    return Overview.QUAL
            # if they don't want re-downloads then we call it good if they have anything
            if maxBestQuality is None:
                return Overview.GOOD
            # if the want only first match and already have one call it good
            elif self.skip_downloaded and curQuality in bestQualities:
                return Overview.GOOD
            # if they want only first match and current quality is higher than minimal best quality call it good
            elif self.skip_downloaded and minBestQuality is not None and curQuality > minBestQuality:
                return Overview.GOOD
            # if they have one but it's not the best they want then mark it as qual
            elif curQuality < maxBestQuality:
                return Overview.QUAL
            # if it's >= maxBestQuality then it's good
            else:
                return Overview.GOOD
        else:
            sickrage.app.log.error(
                'Could not parse episode status into a valid overview status: {}'
                .format(epStatus))
コード例 #6
0
ファイル: history.py プロジェクト: yinghuodt007/SiCKRAGE
    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)
コード例 #7
0
    def run(self, force=False, session=None):
        """
        Runs the failed searcher, queuing selected episodes for search that have failed to snatch
        :param force: Force search
        """
        if self.amActive or not sickrage.app.config.use_failed_snatcher and not force:
            return

        self.amActive = True

        # set thread name
        threading.currentThread().setName(self.name)

        # trim failed download history
        FailedHistory.trim_history()

        sickrage.app.log.info("Searching for failed snatches")

        failed_snatches = False

        for snatched_episode_obj in [
                x for x in self.snatched_episodes()
                if (x.showid, x.season,
                    x.episode) not in self.downloaded_releases()
        ]:
            show_object = find_show(snatched_episode_obj.showid,
                                    session=session)
            episode_object = show_object.get_episode(
                snatched_episode_obj.season, snatched_episode_obj.episode)
            if episode_object.show.paused:
                continue

            cur_status, cur_quality = Quality.split_composite_status(
                episode_object.status)
            if cur_status not in {SNATCHED, SNATCHED_BEST, SNATCHED_PROPER}:
                continue

            sickrage.app.io_loop.add_callback(
                sickrage.app.search_queue.put,
                FailedQueueItem(episode_object.showid, episode_object.season,
                                episode_object.episode, True))

            failed_snatches = True

        if not failed_snatches:
            sickrage.app.log.info("No failed snatches found")

        self.amActive = False
コード例 #8
0
ファイル: history.py プロジェクト: yinghuodt007/SiCKRAGE
    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)
コード例 #9
0
ファイル: backlog_searcher.py プロジェクト: vdaular/SiCKRAGE
    def _get_wanted(show, from_date):
        any_qualities, best_qualities = Quality.split_quality(show.quality)

        sickrage.app.log.debug(
            "Seeing if we need anything that's older then today for {}".format(
                show.name))

        # check through the list of statuses to see if we want any
        wanted = []
        for episode_object in show.episodes:
            if not episode_object.season > 0 or not datetime.date.today(
            ) > episode_object.airdate > from_date:
                continue

            cur_status, cur_quality = Quality.split_composite_status(
                episode_object.status)

            # if we need a better one then say yes
            if cur_status not in {
                    EpisodeStatus.WANTED, EpisodeStatus.DOWNLOADED,
                    EpisodeStatus.SNATCHED, EpisodeStatus.SNATCHED_PROPER
            }:
                continue

            if cur_status != EpisodeStatus.WANTED:
                if best_qualities:
                    if cur_quality in best_qualities:
                        continue
                    elif cur_quality != Qualities.UNKNOWN and cur_quality > max(
                            best_qualities):
                        continue
                elif any_qualities:
                    if cur_quality in any_qualities:
                        continue
                    elif cur_quality != Qualities.UNKNOWN and cur_quality > max(
                            any_qualities):
                        continue

            # skip upgrading quality of downloaded episodes if enabled
            if cur_status == EpisodeStatus.DOWNLOADED and show.skip_downloaded:
                continue

            wanted += [(episode_object.season, episode_object.episode)]

        return wanted
コード例 #10
0
    def _get_proper_list(self):
        """
        Walk providers for propers
        """

        session = sickrage.app.main_db.session()

        propers = {}
        final_propers = []

        search_date = datetime.datetime.today() - datetime.timedelta(days=2)

        orig_thread_name = threading.currentThread().getName()

        for show in get_show_list():
            wanted = self._get_wanted(show, search_date)
            if not wanted:
                sickrage.app.log.debug("Nothing needs to be downloaded for {}, skipping".format(show.name))
                continue

            self._lastProperSearch = self._get_last_proper_search(show.indexer_id)

            # for each provider get a list of the
            for providerID, providerObj in sickrage.app.search_providers.sort(randomize=sickrage.app.config.randomize_providers).items():
                # check provider type and provider is enabled
                if not sickrage.app.config.use_nzbs and providerObj.type in [NZBProvider.type, NewznabProvider.type]:
                    continue
                elif not sickrage.app.config.use_torrents and providerObj.type in [TorrentProvider.type, TorrentRssProvider.type]:
                    continue
                elif not providerObj.is_enabled:
                    continue

                threading.currentThread().setName(orig_thread_name + " :: [" + providerObj.name + "]")

                sickrage.app.log.info("Searching for any new PROPER releases from " + providerObj.name)

                try:
                    for season, episode in wanted:
                        for x in providerObj.find_propers(show.indexer_id, season, episode):
                            if not re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', x.name, re.I):
                                sickrage.app.log.debug('Found a non-proper, we have caught and skipped it.')
                                continue

                            name = self._generic_name(x.name)
                            if name not in propers:
                                sickrage.app.log.debug("Found new proper: " + x.name)
                                x.provider = providerObj
                                propers[name] = x
                except AuthException as e:
                    sickrage.app.log.warning("Authentication error: {}".format(e))
                    continue
                except Exception as e:
                    sickrage.app.log.debug("Error while searching " + providerObj.name + ", skipping: {}".format(e))
                    sickrage.app.log.debug(traceback.format_exc())
                    continue

                threading.currentThread().setName(orig_thread_name)

            self._set_last_proper_search(show.indexer_id, datetime.datetime.today().toordinal())

        # take the list of unique propers and get it sorted by
        sorted_propers = sorted(propers.values(), key=operator.attrgetter('date'), reverse=True)
        for curProper in sorted_propers:
            try:
                parse_result = NameParser(False).parse(curProper.name)
            except InvalidNameException:
                sickrage.app.log.debug("Unable to parse the filename " + curProper.name + " into a valid episode")
                continue
            except InvalidShowException:
                sickrage.app.log.debug("Unable to parse the filename " + curProper.name + " into a valid show")
                continue

            if not parse_result.series_name:
                continue

            if not parse_result.episode_numbers:
                sickrage.app.log.debug("Ignoring " + curProper.name + " because it's for a full season rather than specific episode")
                continue

            show = find_show(parse_result.indexer_id)
            sickrage.app.log.debug("Successful match! Result " + parse_result.original_name + " matched to show " + show.name)

            # set the indexer_id in the db to the show's indexer_id
            curProper.indexer_id = parse_result.indexer_id

            # set the indexer in the db to the show's indexer
            curProper.indexer = show.indexer

            # populate our Proper instance
            curProper.season = parse_result.season_number if parse_result.season_number is not None else 1
            curProper.episode = parse_result.episode_numbers[0]
            curProper.release_group = parse_result.release_group
            curProper.version = parse_result.version
            curProper.quality = Quality.name_quality(curProper.name, parse_result.is_anime)
            curProper.content = None

            # filter release
            best_result = pick_best_result(curProper)
            if not best_result:
                sickrage.app.log.debug("Proper " + curProper.name + " were rejected by our release filters.")
                continue

            # only get anime proper if it has release group and version
            if show.is_anime:
                if not best_result.release_group and best_result.version == -1:
                    sickrage.app.log.debug("Proper " + best_result.name + " doesn't have a release group and version, ignoring it")
                    continue

            # check if we actually want this proper (if it's the right quality)            
            dbData = session.query(MainDB.TVEpisode).filter_by(showid=best_result.indexer_id, season=best_result.season,
                                                               episode=best_result.episode).one_or_none()
            if not dbData:
                continue

            # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones)
            old_status, old_quality = Quality.split_composite_status(int(dbData.status))
            if old_status not in (DOWNLOADED, SNATCHED) or old_quality != best_result.quality:
                continue

            # check if we actually want this proper (if it's the right release group and a higher version)
            if show.is_anime:
                old_version = int(dbData.version)
                old_release_group = dbData.release_group
                if not -1 < old_version < best_result.version:
                    continue

                sickrage.app.log.info("Found new anime v" + str(best_result.version) + " to replace existing v" + str(old_version))

                if old_release_group != best_result.release_group:
                    sickrage.app.log.info("Skipping proper from release group: {}, does not match existing release "
                                          "group: {}".format(best_result.release_group, old_release_group))
                    continue

            # if the show is in our list and there hasn't been a proper already added for that particular episode
            # then add it to our list of propers
            if best_result.indexer_id != -1 and (best_result.indexer_id, best_result.season, best_result.episode) not in map(
                    operator.attrgetter('indexer_id', 'season', 'episode'), final_propers):
                sickrage.app.log.info("Found a proper that we need: " + str(best_result.name))
                final_propers.append(best_result)

        return final_propers
コード例 #11
0
    def want_episode(self,
                     season,
                     episode,
                     quality,
                     manualSearch=False,
                     downCurQuality=False):
        try:
            episode_object = self.get_episode(season, episode)
        except EpisodeNotFoundException:
            sickrage.app.log.debug(
                "Unable to find a matching episode in database, ignoring found episode"
            )
            return False

        sickrage.app.log.debug(
            "Checking if found episode %s S%02dE%02d is wanted at quality %s" %
            (self.name, episode_object.season or 0, episode_object.episode
             or 0, Quality.qualityStrings[quality]))

        # if the quality isn't one we want under any circumstances then just say no
        any_qualities, best_qualities = Quality.split_quality(self.quality)
        sickrage.app.log.debug("Any, Best = [{}] [{}] Found = [{}]".format(
            self.qualitiesToString(any_qualities),
            self.qualitiesToString(best_qualities),
            self.qualitiesToString([quality])))

        if quality not in any_qualities + best_qualities or quality is UNKNOWN:
            sickrage.app.log.debug(
                "Don't want this quality, ignoring found episode")
            return False

        ep_status = int(episode_object.status)
        ep_status_text = statusStrings[ep_status]

        sickrage.app.log.debug("Existing episode status: " + str(ep_status) +
                               " (" + ep_status_text + ")")

        # if we know we don't want it then just say no
        if ep_status in Quality.ARCHIVED + [UNAIRED, SKIPPED, IGNORED
                                            ] and not manualSearch:
            sickrage.app.log.debug(
                "Existing episode status is unaired/skipped/ignored/archived, ignoring found episode"
            )
            return False

        cur_status, cur_quality = Quality.split_composite_status(ep_status)

        # if it's one of these then we want it as long as it's in our allowed initial qualities
        if ep_status == WANTED:
            sickrage.app.log.debug(
                "Existing episode status is WANTED, getting found episode")
            return True
        elif manualSearch:
            if (downCurQuality
                    and quality >= cur_quality) or (not downCurQuality
                                                    and quality > cur_quality):
                sickrage.app.log.debug(
                    "Usually ignoring found episode, but forced search allows the quality, getting found episode"
                )
                return True

        # if we are re-downloading then we only want it if it's in our bestQualities list and better than what we
        # have, or we only have one bestQuality and we do not have that quality yet
        if ep_status in Quality.DOWNLOADED + Quality.SNATCHED + Quality.SNATCHED_PROPER and quality in best_qualities and (
                quality > cur_quality or cur_quality not in best_qualities):
            sickrage.app.log.debug(
                "Episode already exists but the found episode quality is wanted more, getting found episode"
            )
            return True
        elif cur_quality == UNKNOWN and manualSearch:
            sickrage.app.log.debug(
                "Episode already exists but quality is Unknown, getting found episode"
            )
            return True
        else:
            sickrage.app.log.debug(
                "Episode already exists and the found episode has same/lower quality, ignoring found episode"
            )

        sickrage.app.log.debug(
            "None of the conditions were met, ignoring found episode")
        return False
コード例 #12
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()
コード例 #13
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
コード例 #14
0
ファイル: __init__.py プロジェクト: ChrisJamesHobbs/SiCKRAGE
    def _replace_map(self):
        """
        Generates a replacement map for this episode which maps all possible custom naming patterns to the correct
        value for this episode.

        Returns: A dict with patterns as the keys and their replacement values as the values.
        """

        ep_name = self._ep_name()

        def dot(name):
            return sanitize_scene_name(name)

        def us(name):
            return re.sub('[ -]', '_', name)

        def release_name(name):
            if name:
                name = remove_non_release_groups(remove_extension(name))
            return name

        def release_group(show_id, name):
            from sickrage.core.nameparser import NameParser, InvalidNameException, InvalidShowException

            if name:
                name = remove_non_release_groups(remove_extension(name))

                try:
                    parse_result = NameParser(name, show_id=show_id, naming_pattern=True).parse(name)
                    if parse_result.release_group:
                        return parse_result.release_group
                except (InvalidNameException, InvalidShowException) as e:
                    sickrage.app.log.debug("Unable to get parse release_group: {}".format(e))

            return ''

        __, epQual = Quality.split_composite_status(self.status)

        if sickrage.app.config.naming_strip_year:
            show_name = re.sub(r"\(\d+\)$", "", self.show.name).rstrip()
        else:
            show_name = self.show.name

        # try to get the release group
        rel_grp = {"SiCKRAGE": 'SiCKRAGE'}
        if hasattr(self, 'location'):  # from the location name
            rel_grp['location'] = release_group(self.show.indexer_id, self.location)
            if not rel_grp['location']:
                del rel_grp['location']
        if hasattr(self, '_release_group'):  # from the release group field in db
            rel_grp['database'] = self.release_group
            if not rel_grp['database']:
                del rel_grp['database']
        if hasattr(self, 'release_name'):  # from the release name field in db
            rel_grp['release_name'] = release_group(self.show.indexer_id, self.release_name)
            if not rel_grp['release_name']:
                del rel_grp['release_name']

        # use release_group, release_name, location in that order
        if 'database' in rel_grp:
            relgrp = 'database'
        elif 'release_name' in rel_grp:
            relgrp = 'release_name'
        elif 'location' in rel_grp:
            relgrp = 'location'
        else:
            relgrp = 'SiCKRAGE'

        # try to get the release encoder to comply with scene naming standards
        encoder = Quality.scene_quality_from_name(self.release_name.replace(rel_grp[relgrp], ""), epQual)
        if encoder:
            sickrage.app.log.debug("Found codec for '" + show_name + ": " + ep_name + "'.")

        return {
            '%SN': show_name,
            '%S.N': dot(show_name),
            '%S_N': us(show_name),
            '%EN': ep_name,
            '%E.N': dot(ep_name),
            '%E_N': us(ep_name),
            '%QN': Quality.qualityStrings[epQual],
            '%Q.N': dot(Quality.qualityStrings[epQual]),
            '%Q_N': us(Quality.qualityStrings[epQual]),
            '%SQN': Quality.sceneQualityStrings[epQual] + encoder,
            '%SQ.N': dot(Quality.sceneQualityStrings[epQual] + encoder),
            '%SQ_N': us(Quality.sceneQualityStrings[epQual] + encoder),
            '%SY': str(self.show.startyear),
            '%S': str(self.season),
            '%0S': '%02d' % self.season,
            '%E': str(self.episode),
            '%0E': '%02d' % self.episode,
            '%XS': str(self.scene_season),
            '%0XS': '%02d' % self.scene_season,
            '%XE': str(self.scene_episode),
            '%0XE': '%02d' % self.scene_episode,
            '%AB': '%(#)03d' % {'#': self.absolute_number},
            '%XAB': '%(#)03d' % {'#': self.scene_absolute_number},
            '%RN': release_name(self.release_name),
            '%RG': rel_grp[relgrp],
            '%CRG': rel_grp[relgrp].upper(),
            '%AD': str(self.airdate).replace('-', ' '),
            '%A.D': str(self.airdate).replace('-', '.'),
            '%A_D': us(str(self.airdate)),
            '%A-D': str(self.airdate),
            '%Y': str(self.airdate.year),
            '%M': str(self.airdate.month),
            '%D': str(self.airdate.day),
            '%0M': '%02d' % self.airdate.month,
            '%0D': '%02d' % self.airdate.day,
            '%RT': "PROPER" if self.is_proper else "",
        }