Esempio n. 1
0
    def _parse_string(self, name):
        guess = guessit.guessit(name, dict(show_type=self.show_type))
        result = self.to_parse_result(name, guess)

        search_series = helpers.get_show(result.series_name, self.try_indexers) if not self.naming_pattern else None

        # confirm passed in show object indexer id matches result show object indexer id
        series_obj = None if search_series and self.series and search_series.indexerid != self.series.indexerid else search_series
        result.series = series_obj or self.series

        # if this is a naming pattern test or result doesn't have a show object then return best result
        if not result.series or self.naming_pattern:
            return result

        new_episode_numbers = []
        new_season_numbers = []
        new_absolute_numbers = []

        # if we have an air-by-date show and the result is air-by-date,
        # then get the real season/episode numbers
        if result.series.air_by_date and result.is_air_by_date:
            new_episode_numbers, new_season_numbers = self._parse_air_by_date(result)

        elif result.series.is_anime or result.is_anime:
            new_episode_numbers, new_season_numbers, new_absolute_numbers = self._parse_anime(result)

        elif result.season_number and result.episode_numbers:
            new_episode_numbers, new_season_numbers, new_absolute_numbers = self._parse_series(result)

        # Remove None from the list of seasons, as we can't sort on that
        new_season_numbers = sorted({season for season in new_season_numbers if season is not None})

        # need to do a quick sanity check here ex. It's possible that we now have episodes
        # from more than one season (by tvdb numbering), and this is just too much
        # for the application, so we'd need to flag it.
        if len(new_season_numbers) > 1:
            raise InvalidNameException('Scene numbering results episodes from seasons {seasons}, (i.e. more than one) '
                                       'and Medusa does not support this. Sorry.'.format(seasons=new_season_numbers))

        # If guess it's possible that we'd have duplicate episodes too,
        # so lets eliminate them
        new_episode_numbers = sorted(set(new_episode_numbers))

        # maybe even duplicate absolute numbers so why not do them as well
        new_absolute_numbers = sorted(set(new_absolute_numbers))

        if new_absolute_numbers:
            result.ab_episode_numbers = new_absolute_numbers

        if new_season_numbers and new_episode_numbers:
            result.episode_numbers = new_episode_numbers
            result.season_number = new_season_numbers[0]

        # For anime that we still couldn't get a season, let's assume we should use 1.
        if result.series.is_anime and result.season_number is None and result.episode_numbers:
            result.season_number = 1
            log.warning(
                'Unable to parse season number for anime {name}, '
                'assuming absolute numbered anime with season 1',
                {'name': result.series.name}
            )

        if result.series.is_scene:
            log.debug(
                'Converted parsed result {original} into {result}',
                {'original': result.original_name, 'result': result}
            )

        return result
Esempio n. 2
0
    def _parse_string(self, name):
        guess = guessit.guessit(name, dict(show_type=self.show_type))
        result = self.to_parse_result(name, guess)

        search_series = helpers.get_show(result.series_name, self.try_indexers) if not self.naming_pattern else None

        # confirm passed in show object indexer id matches result show object indexer id
        series_obj = None if search_series and self.series and search_series.indexerid != self.series.indexerid else search_series
        result.series = series_obj or self.series

        # if this is a naming pattern test or result doesn't have a show object then return best result
        if not result.series or self.naming_pattern:
            return result

        new_episode_numbers = []
        new_season_numbers = []
        new_absolute_numbers = []

        # if we have an air-by-date show and the result is air-by-date,
        # then get the real season/episode numbers
        if result.series.air_by_date and result.is_air_by_date:
            new_episode_numbers, new_season_numbers = self._parse_air_by_date(result)

        elif result.series.is_anime or result.is_anime:
            new_episode_numbers, new_season_numbers, new_absolute_numbers = self._parse_anime(result)

        elif result.season_number and result.episode_numbers:
            new_episode_numbers, new_season_numbers, new_absolute_numbers = self._parse_series(result)

        # Remove None from the list of seasons, as we can't sort on that
        new_season_numbers = sorted({season for season in new_season_numbers if season is not None})

        # need to do a quick sanity check here ex. It's possible that we now have episodes
        # from more than one season (by tvdb numbering), and this is just too much
        # for the application, so we'd need to flag it.
        if len(new_season_numbers) > 1:
            raise InvalidNameException('Scene numbering results episodes from seasons {seasons}, (i.e. more than one) '
                                       'and Medusa does not support this. Sorry.'.format(seasons=new_season_numbers))

        # If guess it's possible that we'd have duplicate episodes too,
        # so lets eliminate them
        new_episode_numbers = sorted(set(new_episode_numbers))

        # maybe even duplicate absolute numbers so why not do them as well
        new_absolute_numbers = sorted(set(new_absolute_numbers))

        if new_absolute_numbers:
            result.ab_episode_numbers = new_absolute_numbers

        if new_episode_numbers:
            result.episode_numbers = new_episode_numbers

        if new_season_numbers:
            result.season_number = new_season_numbers[0]

        # For anime that we still couldn't get a season, let's assume we should use 1.
        if result.series.is_anime and result.season_number is None and result.episode_numbers:
            result.season_number = 1
            log.info(
                'Unable to parse season number for anime {name}, '
                'assuming absolute numbered anime with season 1',
                {'name': result.series.name}
            )

        if result.series.is_scene:
            log.debug(
                'Converted parsed result {original} into {result}',
                {'original': result.original_name, 'result': result}
            )

        return result
Esempio n. 3
0
    def _parse_string(self, name):
        guess = guessit.guessit(name, dict(show_type=self.show_type))
        result = self.to_parse_result(name, guess)

        search_series = helpers.get_show(result.series_name, self.try_indexers) if not self.naming_pattern else None

        # confirm passed in show object indexer id matches result show object indexer id
        series_obj = None if search_series and self.series and search_series.indexerid != self.series.indexerid else search_series
        result.series = series_obj or self.series

        # if this is a naming pattern test or result doesn't have a show object then return best result
        if not result.series or self.naming_pattern:
            return result

        new_episode_numbers = []
        new_season_numbers = []
        new_absolute_numbers = []

        # if we have an air-by-date show and the result is air-by-date,
        # then get the real season/episode numbers
        if result.series.air_by_date and result.is_air_by_date:
            log.debug('Series {name} is air by date', {'name': result.series.name})
            airdate = result.air_date.toordinal()
            main_db_con = db.DBConnection()
            sql_result = main_db_con.select(
                b'SELECT season, episode FROM tv_episodes WHERE indexer = ? AND showid = ? AND airdate = ?',
                [result.series.indexer, result.series.series_id, airdate])

            season_number = None
            episode_numbers = []

            if sql_result:
                season_number = int(sql_result[0][0])
                episode_numbers = [int(sql_result[0][1])]

                # Use the next query item if we have multiple results
                # and the current one is a special episode (season 0)
                if season_number == 0 and len(sql_result) > 1:
                    season_number = int(sql_result[1][0])
                    episode_numbers = [int(sql_result[1][1])]

                log.debug(
                    'Database info for series {name}: Season: {season} Episode(s): {episodes}', {
                        'name': result.series.name,
                        'season': season_number,
                        'episodes': episode_numbers
                    }
                )

            if season_number is None or not episode_numbers:
                log.debug('Series {name} has no season or episodes, using indexer',
                          {'name': result.series.name})
                try:
                    indexer_api_params = indexerApi(result.series.indexer).api_params.copy()

                    if result.series.lang:
                        indexer_api_params['language'] = result.series.lang

                    indexer_api = indexerApi(result.series.indexer).indexer(**indexer_api_params)
                    tv_episode = indexer_api[result.series.indexerid].aired_on(result.air_date)[0]

                    season_number = int(tv_episode['seasonnumber'])
                    episode_numbers = [int(tv_episode['episodenumber'])]
                    log.debug(
                        'Indexer info for series {name}: {ep}', {
                            'name': result.series.name,
                            'ep': episode_num(season_number, episode_numbers[0]),
                        }
                    )
                except IndexerEpisodeNotFound:
                    log.warning(
                        'Unable to find episode with date {date} for series {name}. Skipping',
                        {'date': result.air_date, 'name': result.series.name}
                    )
                    episode_numbers = []
                except IndexerError as error:
                    log.warning(
                        'Unable to contact {indexer_api.name}: {error}',
                        {'indexer_api': indexer_api, 'error': error.message}
                    )
                    episode_numbers = []
                except IndexerException as error:
                    log.warning(
                        'Indexer exception: {indexer_api.name}: {error}',
                        {'indexer_api': indexer_api, 'error': error.message}
                    )
                    episode_numbers = []

            for episode_number in episode_numbers:
                season = season_number
                episode = episode_number

                if result.series.is_scene:
                    (season, episode) = scene_numbering.get_indexer_numbering(
                        result.series,
                        season_number,
                        episode_number,
                    )
                    log.debug(
                        'Scene numbering enabled series {name}, using indexer numbering: {ep}',
                        {'name': result.series.name, 'ep': episode_num(season, episode)}
                    )
                new_episode_numbers.append(episode)
                new_season_numbers.append(season)

        elif result.series.is_anime and result.is_anime:
            log.debug('Scene numbering enabled series {name} is anime',
                      {'name': result.series.name})
            scene_season = scene_exceptions.get_scene_exceptions_by_name(result.series_name)[0][1]

            for absolute_episode in result.ab_episode_numbers:
                a = absolute_episode

                # Apparently we got a scene_season using the season scene exceptions. If we also do not have a season
                # parsed, guessit made a 'mistake' and it should have set the season with the value.
                # This is required for titles like: '[HorribleSubs].Kekkai.Sensen.&.Beyond.-.01.[1080p].mkv'
                if result.season_number is None and scene_season > 0:
                    season = scene_season
                    episode = [a]
                    log.debug(
                        'Detected a season scene exception [{series_name} -> {scene_season}] without a '
                        'season number in the title, '
                        'assuming the episode # [{scene_absolute}] is the scene_absolute #.',
                        {'series_name': result.series_name, 'scene_season': scene_season, 'scene_absolute': a}
                    )
                else:
                    if result.series.is_scene:
                        a = scene_numbering.get_indexer_absolute_numbering(result.series, absolute_episode,
                                                                           True, scene_season)

                    # Translate the absolute episode number, back to the indexers season and episode.
                    (season, episode) = helpers.get_all_episodes_from_absolute_number(result.series, [a])
                    log.debug(
                        'Scene numbering enabled series {name} using indexer for absolute {absolute}: {ep}',
                        {'name': result.series.name, 'absolute': a, 'ep': episode_num(season, episode, 'absolute')}
                    )

                new_absolute_numbers.append(a)
                new_episode_numbers.extend(episode)
                new_season_numbers.append(season)

        elif result.season_number and result.episode_numbers:
            for episode_number in result.episode_numbers:
                season = result.season_number
                episode = episode_number

                if result.series.is_scene:
                    (season, episode) = scene_numbering.get_indexer_numbering(
                        result.series,
                        result.season_number,
                        episode_number
                    )
                    log.debug(
                        'Scene numbering enabled series {name} using indexer numbering: {ep}',
                        {'name': result.series.name, 'ep': episode_num(season, episode)}
                    )

                if result.series.is_anime:
                    a = helpers.get_absolute_number_from_season_and_episode(result.series, season, episode)
                    if a:
                        new_absolute_numbers.append(a)
                        log.debug(
                            'Scene numbering enabled anime {name} using indexer with absolute {absolute}: {ep}',
                            {'name': result.series.name, 'absolute': a, 'ep': episode_num(season, episode, 'absolute')}
                        )

                new_episode_numbers.append(episode)
                new_season_numbers.append(season)

        # need to do a quick sanity check heregex.  It's possible that we now have episodes
        # from more than one season (by tvdb numbering), and this is just too much
        # for the application, so we'd need to flag it.
        new_season_numbers = sorted(set(new_season_numbers))  # remove duplicates
        if len(new_season_numbers) > 1:
            raise InvalidNameException('Scene numbering results episodes from seasons {seasons}, (i.e. more than one) '
                                       'and Medusa does not support this. Sorry.'.format(seasons=new_season_numbers))

        # If guess it's possible that we'd have duplicate episodes too,
        # so lets eliminate them
        new_episode_numbers = sorted(set(new_episode_numbers))

        # maybe even duplicate absolute numbers so why not do them as well
        new_absolute_numbers = sorted(set(new_absolute_numbers))

        if new_absolute_numbers:
            result.ab_episode_numbers = new_absolute_numbers

        if new_season_numbers and new_episode_numbers:
            result.episode_numbers = new_episode_numbers
            result.season_number = new_season_numbers[0]

        # For anime that we still couldn't get a season, let's assume we should use 1.
        if result.series.is_anime and result.season_number is None and result.episode_numbers:
            result.season_number = 1
            log.warning(
                'Unable to parse season number for anime {name}, '
                'assuming absolute numbered anime with season 1',
                {'name': result.series.name}
            )

        if result.series.is_scene:
            log.debug(
                'Converted parsed result {original} into {result}',
                {'original': result.original_name, 'result': result}
            )

        return result