Esempio n. 1
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))
Esempio n. 2
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))
Esempio n. 3
0
class OpensubtitlesProvider(BaseProvider):
    def __init__(self):
        self.movie_title_year_pattern = re.compile('^(.*)(\s+\((\d+)\))$')
        self.sub_extensions = ['srt', 'sub', 'ass']
        self.logger = logging.getLogger(self.__class__.__name__)

        self.server = None
        self.token = None

    def _ensure_login(self):
        """
        Ensure that the server is opened
        :return:
        :rtype:
        """
        if self.server is None:
            self.server = ServerProxy('https://api.opensubtitles.org/xml-rpc',
                                      TimeoutSafeTransport(100))

            self.logger.info('Logging in')
            response = checked(self.server.LogIn('', '', 'eng', 'subfind v1'))
            self.token = response['token']
            self.logger.debug('Logged in with token %r', self.token)

    def get_sub(self, release):
        sub_id = int(release['IDSubtitleFile'])

        self.logger.info('Downloading subtitle %r', sub_id)
        response = checked(self.server.DownloadSubtitles(self.token, [sub_id]))
        # pprint(response)
        content = fix_line_ending(
            zlib.decompress(base64.b64decode(response['data'][0]['data']), 47))
        # desc_sub_file = join(target_folder, '%s.%s.%s' % (release_name, release['lang'], release['SubFormat']))
        # write_file_content(desc_sub_file, content)

        return Subtitle(content=content, extension=release['SubFormat'])

    def get_releases(self, release_name, langs):
        self._ensure_login()

        release_matching_checker = ReleaseMatchingChecker(release_name)

        criteria = [{'query': release_name}]

        for i in range(5):
            try:
                response = self.server.SearchSubtitles(self.token, criteria)
                break
            except socket.timeout:
                print('socket timeout, try again')
                continue

        checked(response)
        # pprint(response)

        ret = {}
        if response and 'data' in response:
            for subtitle_item in response['data']:
                try:
                    opensubtitle_lang = subtitle_item['SubLanguageID']
                    release_lang = str(
                        Language.fromopensubtitles(opensubtitle_lang).alpha2)
                except:
                    # Exception when
                    continue

                # Ignore not match language
                if release_lang not in langs:
                    continue

                if release_lang not in ret:
                    ret[release_lang] = []

                item_release_name = subtitle_item['MovieReleaseName']
                try:
                    release_matching_checker.check(item_release_name)
                except (ReleaseNotMatchError, MovieNotFound):
                    continue

                release = {
                    'name': item_release_name,
                    'lang': release_lang,
                    'IDSubtitleFile': subtitle_item['IDSubtitleFile'],
                    'SubFormat': subtitle_item['SubFormat']
                }
                ret[release_lang].append(release)

        return ret