Пример #1
0
    def lookup(self, entry, search_allowed=True, key=None):
        """
        Perform Rotten Tomatoes lookup for entry.

        :param entry: Entry instance
        :param search_allowed: Allow fallback to search
        :param key: optionally specify an API key to use
        :raises PluginError: Failure reason
        """
        if not key:
            key = self.key or plugin_api_rottentomatoes.API_KEY
        movie = plugin_api_rottentomatoes.lookup_movie(
            smart_match=entry['title'],
            rottentomatoes_id=entry.get('rt_id', eval_lazy=False),
            only_cached=(not search_allowed),
            api_key=key,
        )
        logger.debug('Got movie: {}', movie)
        entry.update_using_map(self.field_map, movie)

        if not entry.get('imdb_id', eval_lazy=False):
            for alt_id in movie.alternate_ids:
                if alt_id.name == 'imdb':
                    entry['imdb_id'] = 'tt' + alt_id.id
                    break
Пример #2
0
 def series_lookup(self, entry, language, field_map, session=None):
     try:
         series = plugin_api_tvdb.lookup_series(
             entry.get('series_name', eval_lazy=False),
             tvdb_id=entry.get('tvdb_id', eval_lazy=False),
             language=entry.get('language', language),
             session=session,
         )
         entry.update_using_map(field_map, series)
     except LookupError as e:
         logger.debug('Error looking up tvdb series information for {}: {}',
                      entry['title'], e.args[0])
     return entry
Пример #3
0
 def on_task_metainfo(self, task, config):
     # check if disabled (value set to false)
     if config is False:
         return
     for entry in task.entries:
         if isinstance(entry.get('quality', eval_lazy=False), str):
             logger.debug(
                 'Quality is already set to {} for {}, but has not been instantiated properly.',
                 entry['quality'],
                 entry['title'],
             )
             entry['quality'] = qualities.Quality(
                 entry.get('quality', eval_lazy=False))
         else:
             entry.add_lazy_fields(self.get_quality, ['quality'])
Пример #4
0
    def get_subtitles(self, entry):
        if (entry.get('subtitles', eval_lazy=False)
                or not ('location' in entry)
                or ('$RECYCLE.BIN' in entry['location'])
                or not os.path.exists(entry['location'])):
            return
        from subliminal import scan_video
        from subliminal.core import refine, search_external_subtitles

        try:
            video = scan_video(entry['location'])
            # grab external and internal subtitles
            subtitles = video.subtitle_languages
            refiner = ('metadata', )
            refine(video, episode_refiners=refiner, movie_refiners=refiner)
            subtitles |= set(
                search_external_subtitles(entry['location']).values())
            if subtitles:
                # convert to human-readable strings
                subtitles = [str(l) for l in subtitles]
                entry['subtitles'] = subtitles
                logger.debug('Found subtitles {} for {}', '/'.join(subtitles),
                             entry['title'])
        except Exception as e:
            logger.error('Error checking local subtitles for {}: {}',
                         entry['title'], e)
Пример #5
0
    def get_media_id(self, entry):
        # Try to generate a media id based on available parser fields
        media_id = None
        if entry.get('movie_name'):
            media_id = entry['movie_name']
            if entry.get('movie_year'):
                media_id = f'{media_id} {entry["movie_year"]}'
        elif entry.get('series_name'):
            media_id = entry['series_name']
            if entry.get('series_year'):
                media_id = f'{media_id} {entry["series_year"]}'

            if entry.get('series_episode'):
                media_id = f'{media_id} S{(entry.get("series_season") or 0):02}E{entry["series_episode"]:02}'
            elif entry.get('series_season'):
                media_id = f'{media_id} S{entry["series_season"]:02}E00'
            elif entry.get('series_date'):
                media_id = f'{media_id} {entry["series_date"]}'
            else:
                # We do not want a media id for series
                media_id = None

        if media_id:
            media_id = media_id.strip().lower()

        entry['media_id'] = media_id
Пример #6
0
    def on_task_metainfo(self, task, config):
        if not config:
            return

        for entry in task.entries:
            if (entry.get('series_name')
                    or entry.get('tvdb_id', eval_lazy=False)
                    or entry.get('tvmaze_id', eval_lazy=False)
                    or entry.get('tvrage_id', eval_lazy=False)):
                entry.add_lazy_fields(self.lazy_series_lookup, self.series_map)
                if entry.get('season_pack', eval_lazy=False):
                    entry.add_lazy_fields(self.lazy_season_lookup,
                                          self.season_map)
                if ('series_season' in entry
                        and 'series_episode' in entry) or ('series_date'
                                                           in entry):
                    entry.add_lazy_fields(self.lazy_episode_lookup,
                                          self.episode_map)
Пример #7
0
    def lazy_loader(self, entry, language):
        """Does the lookup for this entry and populates the entry fields."""
        lookup = plugin.get('api_tmdb', self).lookup

        imdb_id = entry.get('imdb_id', eval_lazy=False) or extract_id(
            entry.get('imdb_url', eval_lazy=False))
        try:
            with Session() as session:
                movie = lookup(
                    smart_match=entry['title'],
                    tmdb_id=entry.get('tmdb_id', eval_lazy=False),
                    imdb_id=imdb_id,
                    language=language,
                    session=session,
                )
                entry.update_using_map(self.field_map, movie)
        except LookupError:
            log_once('TMDB lookup failed for %s' % entry['title'], logger,
                     'WARNING')
Пример #8
0
 def lazy_series_lookup(self, entry):
     """Does the lookup for this entry and populates the entry fields."""
     series_lookup = plugin.get('api_tvmaze', self).series_lookup
     with Session() as session:
         lookupargs = {
             'title': entry.get('series_name', eval_lazy=False),
             'year': entry.get('year', eval_lazy=False),
             'tvmaze_id': entry.get('tvmaze_id', eval_lazy=False),
             'tvdb_id': entry.get('tvdb_id', eval_lazy=False),
             'tvrage_id': entry.get('tvrage_idk', eval_lazy=False),
             'session': session,
         }
         try:
             series = series_lookup(**lookupargs)
         except LookupError as e:
             logger.debug(e)
         else:
             entry.update_using_map(self.series_map, series)
     return entry
Пример #9
0
 def get_quality(self, entry):
     if entry.get('quality', eval_lazy=False):
         logger.debug(
             'Quality is already set to {} for {}, skipping quality detection.',
             entry['quality'],
             entry['title'],
         )
         return
     entry['quality'] = qualities.Quality(entry['title'])
     if entry['quality']:
         logger.trace('Found quality {} for {}', entry['quality'],
                      entry['title'])
Пример #10
0
    def lazy_episode_lookup(self, entry, language):
        try:
            season_offset = entry.get('thetvdb_lookup_season_offset', 0)
            episode_offset = entry.get('thetvdb_lookup_episode_offset', 0)
            if not isinstance(season_offset, int):
                logger.error('thetvdb_lookup_season_offset must be an integer')
                season_offset = 0
            if not isinstance(episode_offset, int):
                logger.error(
                    'thetvdb_lookup_episode_offset must be an integer')
                episode_offset = 0
            if season_offset != 0 or episode_offset != 0:
                logger.debug(
                    f'Using offset for tvdb lookup: season: {season_offset}, '
                    f'episode: {episode_offset}')

            lookupargs = {
                'name': entry.get('series_name', eval_lazy=False),
                'tvdb_id': entry.get('tvdb_id', eval_lazy=False),
                'language': entry.get('language', language),
            }
            if entry['series_id_type'] == 'ep':
                lookupargs[
                    'season_number'] = entry['series_season'] + season_offset
                lookupargs['episode_number'] = entry[
                    'series_episode'] + episode_offset
            elif entry['series_id_type'] == 'sequence':
                lookupargs[
                    'absolute_number'] = entry['series_id'] + episode_offset
            elif entry['series_id_type'] == 'date':
                # TODO: Should thetvdb_lookup_episode_offset be used for date lookups as well?
                lookupargs['first_aired'] = entry['series_date']

            episode = plugin_api_tvdb.lookup_episode(**lookupargs)
            entry.update_using_map(self.episode_map, episode)
        except LookupError as e:
            logger.debug(
                'Error looking up tvdb episode information for {}: {}',
                entry['title'], e.args[0])
Пример #11
0
    def on_task_metainfo(self, task, config):
        if not config:
            return

        language = config['language'] if not isinstance(config, bool) else 'en'

        for entry in task.entries:
            # If there is information for a series lookup, register our series lazy fields
            if entry.get('series_name') or entry.get('tvdb_id',
                                                     eval_lazy=False):
                entry.add_lazy_fields(self.lazy_series_lookup,
                                      self.series_map,
                                      kwargs={'language': language})
                entry.add_lazy_fields(
                    self.lazy_series_actor_lookup,
                    self.series_actor_map,
                    kwargs={'language': language},
                )
                entry.add_lazy_fields(
                    self.lazy_series_poster_lookup,
                    self.series_poster_map,
                    kwargs={'language': language},
                )

                # If there is season and ep info as well, register episode lazy fields
                if entry.get('series_id_type') in ('ep', 'sequence', 'date'):
                    if entry.get('season_pack'):
                        logger.verbose(
                            'TheTVDB API does not support season lookup at this time, skipping {}',
                            entry,
                        )
                    else:
                        entry.add_lazy_fields(
                            self.lazy_episode_lookup,
                            self.episode_map,
                            kwargs={'language': language},
                        )
Пример #12
0
 def lazy_episode_lookup(self, entry):
     episode_lookup = plugin.get('api_tvmaze', self).episode_lookup
     with Session(expire_on_commit=False) as session:
         lookupargs = {
             'title': entry.get('series_name', eval_lazy=False),
             'year': entry.get('year', eval_lazy=False),
             'tvmaze_id': entry.get('tvmaze_id', eval_lazy=False),
             'tvdb_id': entry.get('tvdb_id', eval_lazy=False),
             'tvrage_id': entry.get('tvrage_id', eval_lazy=False),
             'series_season': entry.get('series_season', eval_lazy=False),
             'series_episode': entry.get('series_episode', eval_lazy=False),
             'series_date': entry.get('series_date', eval_lazy=False),
             'series_id_type': entry.get('series_id_type', eval_lazy=False),
             'session': session,
         }
         try:
             episode = episode_lookup(**lookupargs)
         except LookupError as e:
             logger.debug(e)
         else:
             entry.update_using_map(self.episode_map, episode)
     return entry
Пример #13
0
 def modify(self, entry, config, errors=True):
     """This can be called from a plugin to add set values to an entry"""
     for field in config:
         # If this doesn't appear to be a jinja template, just set it right away.
         if not isinstance(config[field], str) or '{' not in config[field]:
             entry[field] = config[field]
         # Store original values before overwriting with a lazy field, so that set directives can reference
         # themselves.
         else:
             orig_value = entry.get(field, UNSET, eval_lazy=False)
             try:
                 del entry[field]
             except KeyError:
                 pass
             entry.add_lazy_fields(
                 self.lazy_set,
                 [field],
                 kwargs={
                     'config': config,
                     'field': field,
                     'orig_field_value': orig_value,
                     'errors': errors,
                 },
             )
Пример #14
0
def is_season(entry: entry.Entry) -> bool:
    return entry.get('series_season') and not is_episode(entry)
Пример #15
0
    def lookup(self, entry, search_allowed=True, session=None):
        """
        Perform imdb lookup for entry.

        :param entry: Entry instance
        :param search_allowed: Allow fallback to search
        :raises PluginError: Failure reason
        """

        from flexget.manager import manager

        if entry.get('imdb_id', eval_lazy=False):
            logger.debug('No title passed. Lookup for {}', entry['imdb_id'])
        elif entry.get('imdb_url', eval_lazy=False):
            logger.debug('No title passed. Lookup for {}', entry['imdb_url'])
        elif entry.get('title', eval_lazy=False):
            logger.debug('lookup for {}', entry['title'])
        else:
            raise plugin.PluginError(
                'looking up IMDB for entry failed, no title, imdb_url or imdb_id passed.'
            )

        # if imdb_id is included, build the url.
        if entry.get('imdb_id', eval_lazy=False) and not entry.get(
                'imdb_url', eval_lazy=False):
            entry['imdb_url'] = make_url(entry['imdb_id'])

        # make sure imdb url is valid
        if entry.get('imdb_url', eval_lazy=False):
            imdb_id = extract_id(entry['imdb_url'])
            if imdb_id:
                entry['imdb_url'] = make_url(imdb_id)
            else:
                logger.debug('imdb url {} is invalid, removing it',
                             entry['imdb_url'])
                entry['imdb_url'] = ''

        # no imdb_url, check if there is cached result for it or if the
        # search is known to fail
        if not entry.get('imdb_url', eval_lazy=False):
            result = (session.query(db.SearchResult).filter(
                db.SearchResult.title == entry['title']).first())
            if result:
                # TODO: 1.2 this should really be checking task.options.retry
                if result.fails and not manager.options.execute.retry:
                    # this movie cannot be found, not worth trying again ...
                    logger.debug('{} will fail lookup', entry['title'])
                    raise plugin.PluginError('IMDB lookup failed for %s' %
                                             entry['title'])
                else:
                    if result.url:
                        logger.trace('Setting imdb url for {} from db',
                                     entry['title'])
                        entry['imdb_id'] = result.imdb_id
                        entry['imdb_url'] = result.url

        # no imdb url, but information required, try searching
        if not entry.get('imdb_url', eval_lazy=False) and search_allowed:
            logger.verbose('Searching from imdb `{}`', entry['title'])
            search = ImdbSearch()
            search_name = entry.get('movie_name',
                                    entry['title'],
                                    eval_lazy=False)
            search_result = search.smart_match(search_name)
            if search_result:
                entry['imdb_url'] = search_result['url']
                # store url for this movie, so we don't have to search on every run
                result = db.SearchResult(entry['title'], entry['imdb_url'])
                session.add(result)
                session.commit()
                logger.verbose('Found {}', entry['imdb_url'])
            else:
                log_once(
                    'IMDB lookup failed for %s' % entry['title'],
                    logger,
                    'WARNING',
                    session=session,
                )
                # store FAIL for this title
                result = db.SearchResult(entry['title'])
                result.fails = True
                session.add(result)
                session.commit()
                raise plugin.PluginError('Title `%s` lookup failed' %
                                         entry['title'])

        # check if this imdb page has been parsed & cached
        movie = session.query(
            db.Movie).filter(db.Movie.url == entry['imdb_url']).first()

        # If we have a movie from cache, we are done
        if movie and not movie.expired:
            entry.update_using_map(self.field_map, movie)
            return

        # Movie was not found in cache, or was expired
        if movie is not None:
            if movie.expired:
                logger.verbose('Movie `{}` details expired, refreshing ...',
                               movie.title)
            # Remove the old movie, we'll store another one later.
            session.query(db.MovieLanguage).filter(
                db.MovieLanguage.movie_id == movie.id).delete()
            session.query(
                db.Movie).filter(db.Movie.url == entry['imdb_url']).delete()
            session.commit()

        # search and store to cache
        if 'title' in entry:
            logger.verbose('Parsing imdb for `{}`', entry['title'])
        else:
            logger.verbose('Parsing imdb for `{}`', entry['imdb_id'])
        try:
            movie = self._parse_new_movie(entry['imdb_url'], session)
        except UnicodeDecodeError:
            logger.error(
                'Unable to determine encoding for {}. Installing chardet library may help.',
                entry['imdb_url'],
            )
            # store cache so this will not be tried again
            movie = db.Movie()
            movie.url = entry['imdb_url']
            session.add(movie)
            session.commit()
            raise plugin.PluginError('UnicodeDecodeError')
        except ValueError as e:
            # TODO: might be a little too broad catch, what was this for anyway? ;P
            if manager.options.debug:
                logger.exception(e)
            raise plugin.PluginError(
                'Invalid parameter: %s' % entry['imdb_url'], logger)

        for att in [
                'title',
                'score',
                'votes',
                'meta_score',
                'year',
                'genres',
                'languages',
                'actors',
                'directors',
                'writers',
                'mpaa_rating',
        ]:
            logger.trace('movie.{}: {}', att, getattr(movie, att))

        # Update the entry fields
        entry.update_using_map(self.field_map, movie)
Пример #16
0
def is_show(entry):
    return entry.get('series_name') or entry.get('tvdb_id', eval_lazy=False)
Пример #17
0
def is_season(entry):
    return entry.get('series_season') and not is_episode(entry)
Пример #18
0
def is_movie(entry: entry.Entry) -> bool:
    return bool(entry.get('movie_name'))
Пример #19
0
def is_movie(entry):
    return bool(entry.get('movie_name'))
Пример #20
0
    def _get_lookup_args(self, entry):
        args = {
            'title':
            entry.get('series_name', eval_lazy=False)
            or entry.get('title', eval_lazy=False),
            'year':
            entry.get('year', eval_lazy=False),
            'trakt_slug': (entry.get('trakt_show_slug', eval_lazy=False)
                           or entry.get('trakt_movie_slug', eval_lazy=False)),
            'tmdb_id':
            entry.get('tmdb_id', eval_lazy=False),
            'tvdb_id':
            entry.get('tvdb_id', eval_lazy=False),
            'imdb_id':
            entry.get('imdb_id', eval_lazy=False),
            'tvrage_id':
            entry.get('tvrage_id', eval_lazy=False),
        }

        if entry.get('trakt_movie_id', eval_lazy=False):
            args['trakt_id'] = entry['trakt_movie_id']
        elif entry.get('trakt_show_id', eval_lazy=False):
            args['trakt_id'] = entry['trakt_show_id']
        elif is_movie(entry) and entry.get('trakt_movie_id', eval_lazy=True):
            args['trakt_id'] = entry['trakt_movie_id']
        elif entry.get('trakt_show_id', eval_lazy=True):
            args['trakt_id'] = entry['trakt_show_id']

        return args