Example #1
0
class OpenSubtitlesProvider(Provider):
    """OpenSubtitles Provider.

    :param str username: username.
    :param str password: password.

    """
    languages = {
        Language.fromopensubtitles(l)
        for l in language_converters['opensubtitles'].codes
    }
    subtitle_class = OpenSubtitlesSubtitle

    def __init__(self, username=None, password=None):
        self.server = ServerProxy('https://api.opensubtitles.org/xml-rpc',
                                  TimeoutSafeTransport(10))
        if username and not password or not username and password:
            raise ConfigurationError('Username and password must be specified')
        # None values not allowed for logging in, so replace it by ''
        self.username = username or ''
        self.password = password or ''
        self.token = None

    def initialize(self):
        logger.info('Logging in')
        response = checked(
            self.server.LogIn(self.username, self.password, 'eng',
                              'subliminal v%s' % __short_version__))
        self.token = response['token']
        logger.debug('Logged in with token %r', self.token)

    def terminate(self):
        logger.info('Logging out')
        checked(self.server.LogOut(self.token))
        self.server.close()
        self.token = None
        logger.debug('Logged out')

    def no_operation(self):
        logger.debug('No operation')
        checked(self.server.NoOperation(self.token))

    def query(self,
              languages,
              hash=None,
              size=None,
              imdb_id=None,
              query=None,
              season=None,
              episode=None,
              tag=None):
        # fill the search criteria
        criteria = []
        if hash and size:
            criteria.append({'moviehash': hash, 'moviebytesize': str(size)})
        if imdb_id:
            criteria.append({'imdbid': imdb_id[2:]})
        if tag:
            criteria.append({'tag': tag})
        if query and season and episode:
            criteria.append({
                'query': query.replace('\'', ''),
                'season': season,
                'episode': episode
            })
        elif query:
            criteria.append({'query': query.replace('\'', '')})
        if not criteria:
            raise ValueError('Not enough information')

        # add the language
        for criterion in criteria:
            criterion['sublanguageid'] = ','.join(
                sorted(l.opensubtitles for l in languages))

        # query the server
        logger.info('Searching subtitles %r', criteria)
        response = checked(self.server.SearchSubtitles(self.token, criteria))
        subtitles = []

        # exit if no data
        if not response['data']:
            logger.debug('No subtitles found')
            return subtitles

        # loop over subtitle items
        for subtitle_item in response['data']:
            # read the item
            language = Language.fromopensubtitles(
                subtitle_item['SubLanguageID'])
            hearing_impaired = bool(int(subtitle_item['SubHearingImpaired']))
            page_link = subtitle_item['SubtitlesLink']
            subtitle_id = int(subtitle_item['IDSubtitleFile'])
            matched_by = subtitle_item['MatchedBy']
            movie_kind = subtitle_item['MovieKind']
            hash = subtitle_item['MovieHash']
            movie_name = subtitle_item['MovieName']
            movie_release_name = subtitle_item['MovieReleaseName']
            movie_year = int(subtitle_item['MovieYear']
                             ) if subtitle_item['MovieYear'] else None
            movie_imdb_id = 'tt' + subtitle_item['IDMovieImdb']
            series_season = int(subtitle_item['SeriesSeason']
                                ) if subtitle_item['SeriesSeason'] else None
            series_episode = int(subtitle_item['SeriesEpisode']
                                 ) if subtitle_item['SeriesEpisode'] else None
            filename = subtitle_item['SubFileName']
            encoding = subtitle_item.get('SubEncoding') or None

            subtitle = self.subtitle_class(language, hearing_impaired,
                                           page_link, subtitle_id, matched_by,
                                           movie_kind, hash, movie_name,
                                           movie_release_name, movie_year,
                                           movie_imdb_id, series_season,
                                           series_episode, filename, encoding)
            logger.debug('Found subtitle %r by %s', subtitle, matched_by)
            subtitles.append(subtitle)

        return subtitles

    def list_subtitles(self, video, languages):
        season = episode = None
        if isinstance(video, Episode):
            query = video.series
            season = video.season
            episode = video.episode
        else:
            query = video.title

        return self.query(languages,
                          hash=video.hashes.get('opensubtitles'),
                          size=video.size,
                          imdb_id=video.imdb_id,
                          query=query,
                          season=season,
                          episode=episode,
                          tag=os.path.basename(video.name))

    def download_subtitle(self, subtitle):
        logger.info('Downloading subtitle %r', subtitle)
        response = checked(
            self.server.DownloadSubtitles(self.token,
                                          [str(subtitle.subtitle_id)]))
        subtitle.content = fix_line_ending(
            zlib.decompress(base64.b64decode(response['data'][0]['data']), 47))
Example #2
0
class OpenSubtitlesProvider(Provider):
    languages = {
        Language.fromopensubtitles(l)
        for l in language_converters['opensubtitles'].codes
    }

    def __init__(self):
        self.server = ServerProxy('https://api.opensubtitles.org/xml-rpc',
                                  TimeoutSafeTransport(10))
        self.token = None

    def initialize(self):
        logger.info('Logging in')
        response = checked(
            self.server.LogIn('', '', 'eng',
                              'subliminal v%s' % get_version(__version__)))
        self.token = response['token']
        logger.debug('Logged in with token %r', self.token)

    def terminate(self):
        logger.info('Logging out')
        checked(self.server.LogOut(self.token))
        self.server.close()
        logger.debug('Logged out')

    def no_operation(self):
        logger.debug('No operation')
        checked(self.server.NoOperation(self.token))

    def query(self,
              languages,
              hash=None,
              size=None,
              imdb_id=None,
              query=None,
              season=None,
              episode=None):
        # fill the search criteria
        criteria = []
        if hash and size:
            criteria.append({'moviehash': hash, 'moviebytesize': str(size)})
        if imdb_id:
            criteria.append({'imdbid': imdb_id})
        if query and season and episode:
            criteria.append({
                'query': query,
                'season': season,
                'episode': episode
            })
        elif query:
            criteria.append({'query': query})
        if not criteria:
            raise ValueError('Not enough information')

        # add the language
        for criterion in criteria:
            criterion['sublanguageid'] = ','.join(
                sorted(l.opensubtitles for l in languages))

        # query the server
        logger.info('Searching subtitles %r', criteria)
        response = checked(self.server.SearchSubtitles(self.token, criteria))
        subtitles = []

        # exit if no data
        if not response['data']:
            logger.info('No subtitles found')
            return subtitles

        # loop over subtitle items
        for subtitle_item in response['data']:
            # read the item
            language = Language.fromopensubtitles(
                subtitle_item['SubLanguageID'])
            hearing_impaired = bool(int(subtitle_item['SubHearingImpaired']))
            page_link = subtitle_item['SubtitlesLink']
            subtitle_id = int(subtitle_item['IDSubtitleFile'])
            matched_by = subtitle_item['MatchedBy']
            movie_kind = subtitle_item['MovieKind']
            hash = subtitle_item['MovieHash']
            movie_name = subtitle_item['MovieName']
            movie_release_name = subtitle_item['MovieReleaseName']
            movie_year = int(subtitle_item['MovieYear']
                             ) if subtitle_item['MovieYear'] else None
            movie_imdb_id = int(subtitle_item['IDMovieImdb'])
            series_season = int(subtitle_item['SeriesSeason']
                                ) if subtitle_item['SeriesSeason'] else None
            series_episode = int(subtitle_item['SeriesEpisode']
                                 ) if subtitle_item['SeriesEpisode'] else None

            subtitle = OpenSubtitlesSubtitle(language, hearing_impaired,
                                             page_link, subtitle_id,
                                             matched_by, movie_kind, hash,
                                             movie_name, movie_release_name,
                                             movie_year, movie_imdb_id,
                                             series_season, series_episode)
            logger.debug('Found subtitle %r', subtitle)
            subtitles.append(subtitle)

        return subtitles

    def list_subtitles(self, video, languages):
        query = season = episode = None
        if isinstance(video, Episode):
            query = video.series
            season = video.season
            episode = video.episode
        elif ('opensubtitles' not in video.hashes
              or not video.size) and not video.imdb_id:
            query = video.name.split(os.sep)[-1]

        return self.query(languages,
                          hash=video.hashes.get('opensubtitles'),
                          size=video.size,
                          imdb_id=video.imdb_id,
                          query=query,
                          season=season,
                          episode=episode)

    def download_subtitle(self, subtitle):
        logger.info('Downloading subtitle %r', subtitle)
        response = checked(
            self.server.DownloadSubtitles(self.token,
                                          [str(subtitle.subtitle_id)]))
        subtitle.content = fix_line_ending(
            zlib.decompress(base64.b64decode(response['data'][0]['data']), 47))