Пример #1
0
    def sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None,
             radarr_id=None):
        self.reference = video_path
        self.srtin = srt_path
        self.srtout = '{}.synced.srt'.format(os.path.splitext(self.srtin)[0])
        self.args = None

        ffprobe_exe = get_binary('ffprobe')
        if not ffprobe_exe:
            logging.debug('BAZARR FFprobe not found!')
            return
        else:
            logging.debug('BAZARR FFprobe used is %s', ffprobe_exe)

        ffmpeg_exe = get_binary('ffmpeg')
        if not ffmpeg_exe:
            logging.debug('BAZARR FFmpeg not found!')
            return
        else:
            logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe)

        self.ffmpeg_path = os.path.dirname(ffmpeg_exe)
        try:
            unparsed_args = [self.reference, '-i', self.srtin, '-o', self.srtout, '--ffmpegpath', self.ffmpeg_path,
                             '--vad', self.vad, '--log-dir-path', self.log_dir_path]
            if settings.subsync.getboolean('debug'):
                unparsed_args.append('--make-test-case')
            parser = make_parser()
            self.args = parser.parse_args(args=unparsed_args)
            result = run(self.args)
        except Exception as e:
            logging.exception('BAZARR an exception occurs during the synchronization process for this subtitles: '
                              '{0}'.format(self.srtin))
        else:
            if os.path.isfile(self.srtout):
                if not settings.subsync.getboolean('debug'):
                    os.remove(self.srtin)
                    os.rename(self.srtout, self.srtin)

                    offset_seconds = result['offset_seconds'] or 0
                    framerate_scale_factor = result['framerate_scale_factor'] or 0
                    message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate " \
                              "scale factor of {2}.".format(language_from_alpha3(srt_lang), offset_seconds,
                                                            "{:.2f}".format(framerate_scale_factor))

                    if media_type == 'series':
                        history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id,
                                    description=message, video_path=path_mappings.path_replace_reverse(self.reference),
                                    language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path)
                    else:
                        history_log_movie(action=5, radarr_id=radarr_id, description=message,
                                          video_path=path_mappings.path_replace_reverse_movie(self.reference),
                                          language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path)
            else:
                logging.error('BAZARR unable to sync subtitles: {0}'.format(self.srtin))

            return result
Пример #2
0
def delete_subtitles(media_type, language, forced, hi, media_path, subtitles_path, sonarr_series_id=None,
                     sonarr_episode_id=None, radarr_id=None):
    if not subtitles_path.endswith('.srt'):
        logging.error('BAZARR can only delete .srt files.')
        return False
    if hi in [True, 'true', 'True']:
        language_log = alpha2_from_alpha3(language) + ':hi'
        language_string = language_from_alpha3(language) + ' HI'
    elif forced in [True, 'true', 'True']:
        language_log = alpha2_from_alpha3(language) + ':forced'
        language_string = language_from_alpha3(language) + ' forced'
    else:
        language_log = alpha2_from_alpha3(language)
        language_string = language_from_alpha3(language)
    result = language_string + " subtitles deleted from disk."

    if media_type == 'series':
        try:
            os.remove(path_mappings.path_replace(subtitles_path))
        except OSError:
            logging.exception('BAZARR cannot delete subtitles file: ' + subtitles_path)
            store_subtitles(path_mappings.path_replace_reverse(media_path), media_path)
            return False
        else:
            history_log(0, sonarr_series_id, sonarr_episode_id, result, language=language_log,
                        video_path=path_mappings.path_replace_reverse(media_path),
                        subtitles_path=path_mappings.path_replace_reverse(subtitles_path))
            store_subtitles(path_mappings.path_replace_reverse(media_path), media_path)
            notify_sonarr(sonarr_series_id)
    else:
        try:
            os.remove(path_mappings.path_replace_movie(subtitles_path))
        except OSError:
            logging.exception('BAZARR cannot delete subtitles file: ' + subtitles_path)
            store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path)
            return False
        else:
            history_log_movie(0, radarr_id, result, language=language_log,
                              video_path=path_mappings.path_replace_reverse_movie(media_path),
                              subtitles_path=path_mappings.path_replace_reverse_movie(subtitles_path))
            store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path)
            notify_radarr(radarr_id)
            return True
Пример #3
0
    def get(self):
        history = request.args.get('history')
        if history and history not in False_Keys:
            languages = list(
                TableHistory.select(TableHistory.language).where(
                    TableHistory.language != None).dicts())
            languages += list(
                TableHistoryMovie.select(TableHistoryMovie.language).where(
                    TableHistoryMovie.language != None).dicts())
            languages_list = list(
                set([l['language'].split(':')[0] for l in languages]))
            languages_dicts = []
            for language in languages_list:
                code2 = None
                if len(language) == 2:
                    code2 = language
                elif len(language) == 3:
                    code2 = alpha2_from_alpha3(language)
                else:
                    continue

                if not any(x['code2'] == code2 for x in languages_dicts):
                    try:
                        languages_dicts.append({
                            'code2':
                            code2,
                            'name':
                            language_from_alpha2(code2),
                            # Compatibility: Use false temporarily
                            'enabled':
                            False
                        })
                    except:
                        continue
            return jsonify(sorted(languages_dicts, key=itemgetter('name')))

        result = TableSettingsLanguages.select(TableSettingsLanguages.name,
                                               TableSettingsLanguages.code2,
                                               TableSettingsLanguages.enabled)\
            .order_by(TableSettingsLanguages.name).dicts()
        result = list(result)
        for item in result:
            item['enabled'] = item['enabled'] == 1
        return jsonify(result)
Пример #4
0
def manual_search(path, language, hi, providers, providers_auth, sceneName,
                  title, media_type):
    logging.debug('BAZARR Manually searching subtitles for this file: ' + path)

    final_subtitles = []

    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()
    for lang in ast.literal_eval(language):
        lang = alpha3_from_alpha2(lang)
        if lang == 'pob':
            language_set.add(Language('por', 'BR'))
        else:
            language_set.add(Language(lang))

    use_scenename = settings.general.getboolean('use_scenename')
    minimum_score = settings.general.minimum_score
    minimum_score_movie = settings.general.minimum_score_movie
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    video = get_video(path,
                      title,
                      sceneName,
                      use_scenename,
                      providers=providers,
                      media_type=media_type)
    if video:
        min_score, max_score, scores = get_scores(
            video,
            media_type,
            min_score_movie_perc=int(minimum_score_movie),
            min_score_series_perc=int(minimum_score))

        try:
            if providers:
                subtitles = list_subtitles([video],
                                           language_set,
                                           providers=providers,
                                           provider_configs=providers_auth,
                                           pool_class=provider_pool(),
                                           throttle_callback=provider_throttle,
                                           language_hook=None)  # fixme
            else:
                subtitles = []
                logging.info("BAZARR All providers are throttled")
        except Exception as e:
            logging.exception(
                "BAZARR Error trying to get subtitle list from provider for this file: "
                + path)
        else:
            subtitles_list = []

            for s in subtitles[video]:
                try:
                    matches = s.get_matches(video)
                except AttributeError:
                    continue

                # skip wrong season/episodes
                if media_type == "series":
                    can_verify_series = True
                    if not s.hash_verifiable and "hash" in matches:
                        can_verify_series = False

                    if can_verify_series and not {
                            "series", "season", "episode"
                    }.issubset(matches):
                        logging.debug(
                            u"BAZARR Skipping %s, because it doesn't match our series/episode",
                            s)
                        continue

                score = compute_score(matches, s, video, hearing_impaired=hi)
                not_matched = scores - matches
                s.score = score
                # if score < min_score:
                #     continue

                subtitles_list.append(
                    dict(score=round((score / max_score * 100), 2),
                         language=alpha2_from_alpha3(s.language.alpha3),
                         hearing_impaired=str(s.hearing_impaired),
                         provider=s.provider_name,
                         subtitle=codecs.encode(
                             pickle.dumps(s.make_picklable()),
                             "base64").decode(),
                         url=s.page_link,
                         matches=list(matches),
                         dont_matches=list(not_matched)))

            final_subtitles = sorted(subtitles_list,
                                     key=lambda x: x['score'],
                                     reverse=True)
            logging.debug('BAZARR ' + str(len(final_subtitles)) +
                          " subtitles have been found for this file: " + path)
            logging.debug('BAZARR Ended searching subtitles for this file: ' +
                          path)
    return final_subtitles
Пример #5
0
def manual_download_subtitle(path, language, hi, subtitle, provider,
                             providers_auth, sceneName, title, media_type):
    logging.debug('BAZARR Manually downloading subtitles for this file: ' +
                  path)

    subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64"))
    use_scenename = settings.general.getboolean('use_scenename')
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd
    single = settings.general.getboolean('single_language')
    video = get_video(path,
                      title,
                      sceneName,
                      use_scenename,
                      providers={provider},
                      media_type=media_type)
    if video:
        min_score, max_score, scores = get_scores(video, media_type)
        try:
            if provider:
                download_subtitles([subtitle],
                                   providers={provider},
                                   provider_configs=providers_auth,
                                   pool_class=provider_pool(),
                                   throttle_callback=provider_throttle)
                logging.debug(
                    'BAZARR Subtitles file downloaded for this file:' + path)
            else:
                logging.info("BAZARR All providers are throttled")
                return None
        except Exception as e:
            logging.exception(
                'BAZARR Error downloading subtitles for this file ' + path)
            return None
        else:
            if not subtitle.is_valid():
                notifications.write(
                    msg='No valid subtitles file found for this file: ' + path,
                    queue='get_subtitle')
                logging.exception(
                    'BAZARR No valid subtitles file found for this file: ' +
                    path)
                return
            logging.debug('BAZARR Subtitles file downloaded for this file:' +
                          path)
            try:
                score = round(subtitle.score / max_score * 100, 2)
                fld = get_target_folder(path)
                chmod = int(settings.general.chmod,
                            8) if not sys.platform.startswith(
                                'win') and settings.general.getboolean(
                                    'chmod_enabled') else None
                saved_subtitles = save_subtitles(
                    video.original_path,
                    [subtitle],
                    single=single,
                    tags=None,  # fixme
                    directory=fld,
                    chmod=chmod,
                    # formats=("srt", "vtt")
                    path_decoder=force_unicode)

            except Exception as e:
                logging.exception(
                    'BAZARR Error saving subtitles file to disk for this file:'
                    + path)
                return
            else:
                if saved_subtitles:
                    for saved_subtitle in saved_subtitles:
                        downloaded_provider = saved_subtitle.provider_name
                        if saved_subtitle.language == 'pt-BR':
                            downloaded_language_code3 = 'pob'
                        else:
                            downloaded_language_code3 = subtitle.language.alpha3
                        downloaded_language = language_from_alpha3(
                            downloaded_language_code3)
                        downloaded_language_code2 = alpha2_from_alpha3(
                            downloaded_language_code3)
                        downloaded_path = saved_subtitle.storage_path
                        logging.debug('BAZARR Subtitles file saved to disk: ' +
                                      downloaded_path)
                        message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(
                            score) + "% using manual search."

                        if use_postprocessing is True:
                            command = pp_replace(postprocessing_cmd, path,
                                                 downloaded_path,
                                                 downloaded_language,
                                                 downloaded_language_code2,
                                                 downloaded_language_code3)
                            try:
                                if os.name == 'nt':
                                    codepage = subprocess.Popen(
                                        "chcp",
                                        shell=True,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                                    # wait for the process to terminate
                                    out_codepage, err_codepage = codepage.communicate(
                                    )
                                    encoding = out_codepage.split(
                                        ':')[-1].strip()

                                process = subprocess.Popen(
                                    command,
                                    shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
                                # wait for the process to terminate
                                out, err = process.communicate()

                                if os.name == 'nt':
                                    out = out.decode(encoding)

                            except:
                                if out == "":
                                    logging.error(
                                        'BAZARR Post-processing result for file '
                                        + path +
                                        ' : Nothing returned from command execution'
                                    )
                                else:
                                    logging.error(
                                        'BAZARR Post-processing result for file '
                                        + path + ' : ' + out)
                            else:
                                if out == "":
                                    logging.info(
                                        'BAZARR Post-processing result for file '
                                        + path +
                                        ' : Nothing returned from command execution'
                                    )
                                else:
                                    logging.info(
                                        'BAZARR Post-processing result for file '
                                        + path + ' : ' + out)

                        if media_type == 'series':
                            reversed_path = path_replace_reverse(path)
                        else:
                            reversed_path = path_replace_reverse_movie(path)

                        return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score
                else:
                    logging.error(
                        "BAZARR Tried to manually download a subtitles for file: "
                        + path +
                        " but we weren't able to do (probably throttled by " +
                        str(subtitle.provider_name) +
                        ". Please retry later or select a subtitles from another provider."
                    )
                    return None
    logging.debug('BAZARR Ended manually downloading subtitles for file: ' +
                  path)
Пример #6
0
def store_subtitles(file):
    logging.debug('BAZARR started subtitles indexing for this file: ' + file)
    actual_subtitles = []
    if os.path.exists(file):
        # notifications.write(msg='Analyzing this file for subtitles: ' + file, queue='list_subtitles')
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                subtitle_languages = embedded_subs_reader.list_languages(file)
                for subtitle_language in subtitle_languages:
                    try:
                        if alpha2_from_alpha3(subtitle_language) is not None:
                            lang = str(alpha2_from_alpha3(subtitle_language))
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this %s file: %s" %
                    (os.path.splitext(file)[1], file))
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        try:
            dest_folder = get_subtitle_destination_folder()
            subliminal_patch.core.CUSTOM_PATHS = [dest_folder
                                                  ] if dest_folder else []
            subtitles = search_external_subtitles(
                file,
                languages=get_language_set(),
                only_one=settings.general.getboolean('single_language'))
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in subtitles.iteritems():
                subtitle_path = get_external_subtitles_path(file, subtitle)
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append(
                        [str("pb"),
                         path_replace_reverse(subtitle_path)])
                elif str(language) != 'und':
                    logging.debug("BAZARR external subtitles detected: " +
                                  str(language))
                    actual_subtitles.append(
                        [str(language),
                         path_replace_reverse(subtitle_path)])
                else:
                    if os.path.splitext(subtitle)[1] != ".sub":
                        logging.debug(
                            "BAZARR falling back to file content analysis to detect language."
                        )
                        with open(
                                path_replace(
                                    os.path.join(os.path.dirname(file),
                                                 subtitle)), 'r') as f:
                            text = list(islice(f, 100))
                            text = ' '.join(text)
                            encoding = UnicodeDammit(text)
                            try:
                                text = text.decode(encoding.original_encoding)
                                detected_language = langdetect.detect(text)
                            except Exception as e:
                                logging.exception(
                                    'BAZARR Error trying to detect language for this subtitles file: '
                                    + path_replace(
                                        os.path.join(os.path.dirname(file),
                                                     subtitle)) +
                                    ' You should try to delete this subtitles file manually and ask Bazarr to download it again.'
                                )
                            else:
                                if len(detected_language) > 0:
                                    logging.debug(
                                        "BAZARR external subtitles detected and analysis guessed this language: "
                                        + str(detected_language))
                                    actual_subtitles.append([
                                        str(detected_language),
                                        path_replace_reverse(
                                            os.path.join(
                                                os.path.dirname(file),
                                                subtitle))
                                    ])

        conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                               'bazarr.db'),
                                  timeout=30)
        c_db = conn_db.cursor()
        logging.debug("BAZARR storing those languages to DB: " +
                      str(actual_subtitles))
        c_db.execute("UPDATE table_episodes SET subtitles = ? WHERE path = ?",
                     (str(actual_subtitles), path_replace_reverse(file)))
        conn_db.commit()

        c_db.close()
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' + file)

    return actual_subtitles
Пример #7
0
def download_subtitle(path,
                      language,
                      hi,
                      providers,
                      providers_auth,
                      sceneName,
                      title,
                      media_type,
                      forced_minimum_score=None,
                      is_upgrade=False):
    # fixme: supply all missing languages, not only one, to hit providers only once who support multiple languages in
    #  one query

    logging.debug('BAZARR Searching subtitles for this file: ' + path)
    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()

    if not isinstance(language, types.ListType):
        language = [language]

    for l in language:
        if l == 'pob':
            language_set.add(Language('por', 'BR'))
        else:
            language_set.add(Language(l))

    use_scenename = settings.general.getboolean('use_scenename')
    minimum_score = settings.general.minimum_score
    minimum_score_movie = settings.general.minimum_score_movie
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd
    single = settings.general.getboolean('single_language')

    # todo:
    """
    AsyncProviderPool:
    implement:
        blacklist=None,
        pre_download_hook=None,
        post_download_hook=None,
        language_hook=None
    """

    video = get_video(path,
                      title,
                      sceneName,
                      use_scenename,
                      providers=providers,
                      media_type=media_type)
    if video:
        min_score, max_score, scores = get_scores(
            video,
            media_type,
            min_score_movie_perc=int(minimum_score_movie),
            min_score_series_perc=int(minimum_score))

        if providers:
            if forced_minimum_score:
                min_score = int(forced_minimum_score) + 1
            downloaded_subtitles = download_best_subtitles(
                {video},
                language_set,
                int(min_score),
                hi,
                providers=providers,
                provider_configs=providers_auth,
                pool_class=provider_pool(),
                compute_score=compute_score,
                throttle_time=None,  # fixme
                blacklist=None,  # fixme
                throttle_callback=provider_throttle,
                pre_download_hook=None,  # fixme
                post_download_hook=None,  # fixme
                language_hook=None)  # fixme
        else:
            downloaded_subtitles = None
            logging.info("BAZARR All providers are throttled")

        saved_any = False
        if downloaded_subtitles:
            for video, subtitles in downloaded_subtitles.iteritems():
                if not subtitles:
                    continue

                try:
                    fld = get_target_folder(path)
                    chmod = int(settings.general.chmod,
                                8) if not sys.platform.startswith(
                                    'win') and settings.general.getboolean(
                                        'chmod_enabled') else None
                    saved_subtitles = save_subtitles(
                        video.original_path,
                        subtitles,
                        single=single,
                        tags=None,  # fixme
                        directory=fld,
                        chmod=chmod,
                        # formats=("srt", "vtt")
                        path_decoder=force_unicode)
                except Exception as e:
                    logging.exception(
                        'BAZARR Error saving subtitles file to disk for this file:'
                        + path)
                    pass
                else:
                    saved_any = True
                    for subtitle in saved_subtitles:
                        downloaded_provider = subtitle.provider_name
                        if subtitle.language == 'pt-BR':
                            downloaded_language_code3 = 'pob'
                        else:
                            downloaded_language_code3 = subtitle.language.alpha3
                        downloaded_language = language_from_alpha3(
                            downloaded_language_code3)
                        downloaded_language_code2 = alpha2_from_alpha3(
                            downloaded_language_code3)
                        downloaded_path = subtitle.storage_path
                        logging.debug('BAZARR Subtitles file saved to disk: ' +
                                      downloaded_path)
                        if is_upgrade:
                            action = "upgraded"
                        else:
                            action = "downloaded"
                        if video.used_scene_name:
                            message = downloaded_language + " subtitles " + action + " from " + downloaded_provider + " with a score of " + unicode(
                                round(subtitle.score * 100 / max_score, 2)
                            ) + "% using this scene name: " + sceneName
                        else:
                            message = downloaded_language + " subtitles " + action + " from " + downloaded_provider + " with a score of " + unicode(
                                round(subtitle.score * 100 / max_score,
                                      2)) + "% using filename guessing."

                        if use_postprocessing is True:
                            command = pp_replace(postprocessing_cmd, path,
                                                 downloaded_path,
                                                 downloaded_language,
                                                 downloaded_language_code2,
                                                 downloaded_language_code3)
                            try:
                                if os.name == 'nt':
                                    codepage = subprocess.Popen(
                                        "chcp",
                                        shell=True,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                                    # wait for the process to terminate
                                    out_codepage, err_codepage = codepage.communicate(
                                    )
                                    encoding = out_codepage.split(
                                        ':')[-1].strip()

                                process = subprocess.Popen(
                                    command,
                                    shell=True,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
                                # wait for the process to terminate
                                out, err = process.communicate()

                                if os.name == 'nt':
                                    out = out.decode(encoding)

                            except:
                                if out == "":
                                    logging.error(
                                        'BAZARR Post-processing result for file '
                                        + path +
                                        ' : Nothing returned from command execution'
                                    )
                                else:
                                    logging.error(
                                        'BAZARR Post-processing result for file '
                                        + path + ' : ' + out)
                            else:
                                if out == "":
                                    logging.info(
                                        'BAZARR Post-processing result for file '
                                        + path +
                                        ' : Nothing returned from command execution'
                                    )
                                else:
                                    logging.info(
                                        'BAZARR Post-processing result for file '
                                        + path + ' : ' + out)

                        # fixme: support multiple languages at once
                        if media_type == 'series':
                            reversed_path = path_replace_reverse(path)
                        else:
                            reversed_path = path_replace_reverse_movie(path)

                        return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score

        if not saved_any:
            logging.debug('BAZARR No subtitles were found for this file: ' +
                          path)
            return None
    logging.debug('BAZARR Ended searching subtitles for file: ' + path)
Пример #8
0
def store_subtitles(file):
    # languages = []
    actual_subtitles = []
    if os.path.exists(file):
        if os.path.splitext(file)[1] == '.mkv':
            try:
                with open(file, 'rb') as f:
                    mkv = enzyme.MKV(f)

                for subtitle_track in mkv.subtitle_tracks:
                    try:
                        if alpha2_from_alpha3(subtitle_track.language) != None:
                            actual_subtitles.append([
                                str(alpha2_from_alpha3(
                                    subtitle_track.language)), None
                            ])
                    except:
                        pass
            except:
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        try:
            subtitles = core.search_external_subtitles(file)
        except:
            pass
        else:
            for subtitle, language in subtitles.iteritems():
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)) is True:
                    actual_subtitles.append([
                        str("pb"),
                        path_replace_reverse(
                            os.path.join(os.path.dirname(file), subtitle))
                    ])
                elif str(language) != 'und':
                    actual_subtitles.append([
                        str(language),
                        path_replace_reverse(
                            os.path.join(os.path.dirname(file), subtitle))
                    ])
                else:
                    with open(
                            path_replace(
                                os.path.join(os.path.dirname(file), subtitle)),
                            'r') as f:
                        text = list(islice(f, 100))
                        text = ' '.join(text)
                        encoding = UnicodeDammit(text)
                        try:
                            text = text.decode(encoding.original_encoding)
                        except Exception as e:
                            logging.exception(
                                'Error trying to detect character encoding for this subtitles file: '
                                + path_replace(
                                    os.path.join(os.path.dirname(file),
                                                 subtitle)) +
                                ' You should try to delete this subtitles file manually and ask Bazarr to download it again.'
                            )
                        else:
                            detected_language = langdetect.detect(text)
                            if len(detected_language) > 0:
                                actual_subtitles.append([
                                    str(detected_language),
                                    path_replace_reverse(
                                        os.path.join(os.path.dirname(file),
                                                     subtitle))
                                ])

            conn_db = sqlite3.connect(os.path.join(config_dir, 'db/bazarr.db'),
                                      timeout=30)
            c_db = conn_db.cursor()

            c_db.execute(
                "UPDATE table_episodes SET subtitles = ? WHERE path = ?",
                (str(actual_subtitles), path_replace_reverse(file)))
            conn_db.commit()

            c_db.close()

    return actual_subtitles
Пример #9
0
def store_subtitles(file):
    logging.debug('BAZARR started subtitles indexing for this file: ' + file)
    actual_subtitles = []
    if os.path.exists(file):
        if os.path.splitext(file)[1] == '.mkv':
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                with open(file, 'rb') as f:
                    mkv = enzyme.MKV(f)

                for subtitle_track in mkv.subtitle_tracks:
                    try:
                        if alpha2_from_alpha3(subtitle_track.language) != None:
                            lang = str(
                                alpha2_from_alpha3(subtitle_track.language))
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_track.language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this mkv file: " +
                    file)
                pass
        else:
            logging.debug("BAZARR This file isn't an .mkv file.")

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        try:
            subtitles = core.search_external_subtitles(file)
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in subtitles.iteritems():
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)) is True:
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append([
                        str("pb"),
                        path_replace_reverse(
                            os.path.join(os.path.dirname(file), subtitle))
                    ])
                elif str(language) != 'und':
                    logging.debug("BAZARR external subtitles detected: " +
                                  str(language))
                    actual_subtitles.append([
                        str(language),
                        path_replace_reverse(
                            os.path.join(os.path.dirname(file), subtitle))
                    ])
                else:
                    if os.path.splitext(subtitle)[1] != ".sub":
                        logging.debug(
                            "BAZARR falling back to file content analysis to detect language."
                        )
                        with open(
                                path_replace(
                                    os.path.join(os.path.dirname(file),
                                                 subtitle)), 'r') as f:
                            text = list(islice(f, 100))
                            text = ' '.join(text)
                            encoding = UnicodeDammit(text)
                            try:
                                text = text.decode(encoding.original_encoding)
                                detected_language = langdetect.detect(text)
                            except Exception as e:
                                logging.exception(
                                    'BAZARR Error trying to detect language for this subtitles file: '
                                    + path_replace(
                                        os.path.join(os.path.dirname(file),
                                                     subtitle)) +
                                    ' You should try to delete this subtitles file manually and ask Bazarr to download it again.'
                                )
                            else:
                                if len(detected_language) > 0:
                                    logging.debug(
                                        "BAZARR external subtitles detected and analysis guessed this language: "
                                        + str(detected_language))
                                    actual_subtitles.append([
                                        str(detected_language),
                                        path_replace_reverse(
                                            os.path.join(
                                                os.path.dirname(file),
                                                subtitle))
                                    ])

        conn_db = sqlite3.connect(os.path.join(config_dir, 'db/bazarr.db'),
                                  timeout=30)
        c_db = conn_db.cursor()
        logging.debug("BAZARR storing those languages to DB: " +
                      str(actual_subtitles))
        c_db.execute("UPDATE table_episodes SET subtitles = ? WHERE path = ?",
                     (str(actual_subtitles), path_replace_reverse(file)))
        conn_db.commit()

        c_db.close()
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' + file)

    return actual_subtitles
Пример #10
0
def store_subtitles(original_path, reversed_path):
    logging.debug('BAZARR started subtitles indexing for this file: ' +
                  reversed_path)
    actual_subtitles = []
    if os.path.exists(reversed_path):
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                subtitle_languages = embedded_subs_reader.list_languages(
                    reversed_path)
                for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages:
                    try:
                        if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \
                                (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() ==
                                 "vobsub"):
                            logging.debug(
                                "BAZARR skipping %s sub for language: %s" %
                                (subtitle_codec,
                                 alpha2_from_alpha3(subtitle_language)))
                            continue

                        if alpha2_from_alpha3(subtitle_language) is not None:
                            lang = str(alpha2_from_alpha3(subtitle_language))
                            if subtitle_forced:
                                lang = lang + ":forced"
                            if subtitle_hi:
                                lang = lang + ":hi"
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this %s file: %s" %
                    (os.path.splitext(reversed_path)[1], reversed_path))
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        brazilian_portuguese_forced = [
            ".pt-br.forced", ".pob.forced", "pb.forced"
        ]
        try:
            dest_folder = get_subtitle_destination_folder()
            core.CUSTOM_PATHS = [dest_folder] if dest_folder else []
            subtitles = search_external_subtitles(
                reversed_path,
                languages=get_language_set(),
                only_one=settings.general.getboolean('single_language'))
            full_dest_folder_path = os.path.dirname(reversed_path)
            if dest_folder:
                if settings.general.subfolder == "absolute":
                    full_dest_folder_path = dest_folder
                elif settings.general.subfolder == "relative":
                    full_dest_folder_path = os.path.join(
                        os.path.dirname(reversed_path), dest_folder)
            subtitles = guess_external_subtitles(full_dest_folder_path,
                                                 subtitles)
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in subtitles.items():
                subtitle_path = get_external_subtitles_path(
                    reversed_path, subtitle)
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append([
                        str("pb"),
                        path_mappings.path_replace_reverse(subtitle_path)
                    ])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese_forced)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb:forced")
                    actual_subtitles.append([
                        str("pb:forced"),
                        path_mappings.path_replace_reverse(subtitle_path)
                    ])
                elif not language:
                    continue
                elif str(language.basename) != 'und':
                    logging.debug("BAZARR external subtitles detected: " +
                                  str(language.basename))
                    actual_subtitles.append([
                        str(language.basename +
                            (':hi' if language.hi else '')),
                        path_mappings.path_replace_reverse(subtitle_path)
                    ])

        database.execute("UPDATE table_episodes SET subtitles=? WHERE path=?",
                         (str(actual_subtitles), original_path))
        matching_episodes = database.execute(
            "SELECT sonarrEpisodeId, sonarrSeriesId FROM table_episodes WHERE path=?",
            (original_path, ))

        for episode in matching_episodes:
            if episode:
                logging.debug("BAZARR storing those languages to DB: " +
                              str(actual_subtitles))
                list_missing_subtitles(epno=episode['sonarrEpisodeId'])
            else:
                logging.debug(
                    "BAZARR haven't been able to update existing subtitles to DB : "
                    + str(actual_subtitles))
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' +
                  reversed_path)

    return actual_subtitles
Пример #11
0
def manual_download_subtitle(path, language, hi, subtitle, provider, providers_auth, sceneName, media_type):
    logging.debug('BAZARR Manually downloading subtitles for this file: ' + path)
    if hi == "True":
        hi = True
    else:
        hi = False
    subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64"))
    if media_type == 'series':
        type_of_score = 360
    elif media_type == 'movie':
        type_of_score = 120
    use_scenename = settings.general.getboolean('use_scenename')
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    language = alpha3_from_alpha2(language)
    if language == 'pob':
        lang_obj = Language('por', 'BR')
    else:
        lang_obj = Language(language)

    try:
        if sceneName is None or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except Exception as e:
        logging.exception("BAZARR Error trying to get video information for this file: " + path)
        pass
    else:
        try:
            download_subtitles([subtitle], providers=provider, provider_configs=providers_auth)
            logging.debug('BAZARR Subtitles file downloaded for this file:' + path)
        except Exception as e:
            logging.exception('BAZARR Error downloading subtitles for this file ' + path)
            return None
        else:
            single = settings.general.getboolean('single_language')
            try:
                score = round(float(compute_score(subtitle, video, hearing_impaired=hi)) / type_of_score * 100, 2)
                if used_sceneName == True:
                    video = scan_video(path)
                if single is True:
                    result = save_subtitles(video, [subtitle], single=True, encoding='utf-8')
                else:
                    result = save_subtitles(video, [subtitle], encoding='utf-8')
            except Exception as e:
                logging.exception('BAZARR Error saving subtitles file to disk for this file:' + path)
                return None
            else:
                if len(result) > 0:
                    downloaded_provider = result[0].provider_name
                    downloaded_language = language_from_alpha3(result[0].language.alpha3)
                    downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3)
                    downloaded_language_code3 = result[0].language.alpha3
                    downloaded_path = get_subtitle_path(path, downloaded_language_code2)
                    logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path)
                    message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using manual search."

                    if use_postprocessing is True:
                        command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3)
                        try:
                            if os.name == 'nt':
                                codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                # wait for the process to terminate
                                out_codepage, err_codepage = codepage.communicate()
                                encoding = out_codepage.split(':')[-1].strip()

                            process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                            # wait for the process to terminate
                            out, err = process.communicate()

                            if os.name == 'nt':
                                out = out.decode(encoding)

                        except:
                            if out == "":
                                logging.error('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution')
                            else:
                                logging.error('BAZARR Post-processing result for file ' + path + ' : ' + out)
                        else:
                            if out == "":
                                logging.info('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution')
                            else:
                                logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out)

                    return message
                else:
                    logging.error("BAZARR Tried to manually download a subtitles for file: " + path + " but we weren't able to do (probably throttled by " + str(subtitle.provider_name) + ". Please retry later or select a subtitles from another provider.")
                    return None
    logging.debug('BAZARR Ended manually downloading subtitles for file: ' + path)
Пример #12
0
def manual_download_subtitle(path, language, hi, subtitle, provider, providers_auth, sceneName, media_type):
    if hi == "True":
        hi = True
    else:
        hi = False
    subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64"))
    if media_type == 'series':
        type_of_score = 360
    elif media_type == 'movie':
        type_of_score = 120
    use_scenename = get_general_settings()[9]
    use_postprocessing = get_general_settings()[10]
    postprocessing_cmd = get_general_settings()[11]

    language = alpha3_from_alpha2(language)
    if language == 'pob':
        lang_obj = Language('por', 'BR')
    else:
        lang_obj = Language(language)

    try:
        if sceneName is None or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except Exception as e:
        logging.exception('Error trying to extract information from this filename: ' + path)
        return None
    else:
        try:
            best_subtitle = subtitle
            download_subtitles([best_subtitle], providers=provider, provider_configs=providers_auth)
        except Exception as e:
            logging.exception('Error downloading subtitles for ' + path)
            return None
        else:
            single = get_general_settings()[7]
            try:
                score = round(float(compute_score(best_subtitle, video, hearing_impaired=hi)) / type_of_score * 100, 2)
                if used_sceneName == True:
                    video = scan_video(path)
                if single is True:
                    result = save_subtitles(video, [best_subtitle], single=True, encoding='utf-8')
                else:
                    result = save_subtitles(video, [best_subtitle], encoding='utf-8')
            except Exception as e:
                logging.exception('Error saving subtitles file to disk.')
                return None
            else:
                if len(result) > 0:
                    downloaded_provider = result[0].provider_name
                    downloaded_language = language_from_alpha3(result[0].language.alpha3)
                    downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3)
                    downloaded_language_code3 = result[0].language.alpha3
                    downloaded_path = get_subtitle_path(path, language=lang_obj)
                    message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using manual search."

                    if use_postprocessing is True:
                        command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3)
                        try:
                            if os.name == 'nt':
                                codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                # wait for the process to terminate
                                out_codepage, err_codepage = codepage.communicate()
                                encoding = out_codepage.split(':')[-1].strip()

                            process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                            # wait for the process to terminate
                            out, err = process.communicate()

                            if os.name == 'nt':
                                out = out.decode(encoding)

                        except:
                            if out == "":
                                logging.error('Post-processing result for file ' + path + ' : Nothing returned from command execution')
                            else:
                                logging.error('Post-processing result for file ' + path + ' : ' + out)
                        else:
                            if out == "":
                                logging.info('Post-processing result for file ' + path + ' : Nothing returned from command execution')
                            else:
                                logging.info('Post-processing result for file ' + path + ' : ' + out)

                    return message
                else:
                    return None
Пример #13
0
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, media_type):
    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()
    if language == 'pob':
        language_set.add(Language('por', 'BR'))
    else:
        language_set.add(Language(language))

    use_scenename = get_general_settings()[9]
    minimum_score = get_general_settings()[8]
    minimum_score_movie = get_general_settings()[22]
    use_postprocessing = get_general_settings()[10]
    postprocessing_cmd = get_general_settings()[11]

    try:
        if sceneName == "None" or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except Exception as e:
        logging.exception("Error trying to get video information for this file: " + path)
    else:
        if media_type == "movie":
            max_score = 120.0
        elif media_type == "series":
            max_score = 360.0

        try:
            with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p:
                subtitles = p.list_subtitles(video, language_set)
        except Exception as e:
            logging.exception("Error trying to get subtitle list from provider")
        else:
            subtitles_list = []
            sorted_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hi)) for s in subtitles], key=operator.itemgetter(1), reverse=True)
            for s, preliminary_score in sorted_subtitles:
                if media_type == "movie":
                    if (preliminary_score / max_score * 100) < int(minimum_score_movie):
                        continue
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.movie_scores.keys()) - matched
                    required = set(['title'])
                    if any(elem in required for elem in not_matched):
                        continue
                elif media_type == "series":
                    if (preliminary_score / max_score * 100) < int(minimum_score):
                        continue
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.episode_scores.keys()) - matched
                    required = set(['series', 'season', 'episode'])
                    if any(elem in required for elem in not_matched):
                        continue
                subtitles_list.append(s)
            if len(subtitles_list) > 0:
                best_subtitle = subtitles_list[0]
                download_subtitles([best_subtitle], providers=providers, provider_configs=providers_auth)
                try:
                    calculated_score = round(float(compute_score(best_subtitle, video, hearing_impaired=hi)) / max_score * 100, 2)
                    if used_sceneName == True:
                        video = scan_video(path)
                    single = get_general_settings()[7]
                    if single is True:
                        result = save_subtitles(video, [best_subtitle], single=True, encoding='utf-8')
                    else:
                        result = save_subtitles(video, [best_subtitle], encoding='utf-8')
                except Exception as e:
                    logging.exception('Error saving subtitles file to disk.')
                    return None
                else:
                    if len(result) > 0:
                        downloaded_provider = result[0].provider_name
                        downloaded_language = language_from_alpha3(result[0].language.alpha3)
                        downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3)
                        downloaded_language_code3 = result[0].language.alpha3
                        downloaded_path = get_subtitle_path(path, language=language_set)
                        if used_sceneName == True:
                            message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using this scene name: " + sceneName
                        else:
                            message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using filename guessing."

                        if use_postprocessing is True:
                            command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3)
                            try:
                                if os.name == 'nt':
                                    codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                    # wait for the process to terminate
                                    out_codepage, err_codepage = codepage.communicate()
                                    encoding = out_codepage.split(':')[-1].strip()

                                process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                # wait for the process to terminate
                                out, err = process.communicate()

                                if os.name == 'nt':
                                    out = out.decode(encoding)

                            except:
                                if out == "":
                                    logging.error('Post-processing result for file ' + path + ' : Nothing returned from command execution')
                                else:
                                    logging.error('Post-processing result for file ' + path + ' : ' + out)
                            else:
                                if out == "":
                                    logging.info('Post-processing result for file ' + path + ' : Nothing returned from command execution')
                                else:
                                    logging.info('Post-processing result for file ' + path + ' : ' + out)

                        return message
                    else:
                        return None
            else:
                return None
Пример #14
0
def manual_search(path, language, hi, providers, providers_auth, sceneName, media_type):
    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()
    for lang in ast.literal_eval(language):
        lang = alpha3_from_alpha2(lang)
        if lang == 'pob':
            language_set.add(Language('por', 'BR'))
        else:
            language_set.add(Language(lang))

    use_scenename = get_general_settings()[9]
    use_postprocessing = get_general_settings()[10]
    postprocessing_cmd = get_general_settings()[11]

    try:
        if sceneName == "None" or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except:
        logging.error("Error trying to get video information.")
    else:
        if media_type == "movie":
            max_score = 120.0
        elif media_type == "series":
            max_score = 360.0

        try:
            with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p:
                subtitles = p.list_subtitles(video, language_set)
        except Exception as e:
            logging.exception("Error trying to get subtitle list from provider")
        else:
            subtitles_list = []
            for s in subtitles:
                {s: compute_score(s, video, hearing_impaired=hi)}
                if media_type == "movie":
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.movie_scores.keys()) - matched
                    required = set(['title'])
                    if any(elem in required for elem in not_matched):
                        continue
                    if used_sceneName:
                        not_matched.remove('hash')
                elif media_type == "series":
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.episode_scores.keys()) - matched
                    required = set(['series', 'season', 'episode'])
                    if any(elem in required for elem in not_matched):
                        continue
                    if used_sceneName:
                        not_matched.remove('hash')
                subtitles_list.append(dict(score=round((compute_score(s, video, hearing_impaired=hi) / max_score * 100), 2), language=alpha2_from_alpha3(s.language.alpha3), hearing_impaired=str(s.hearing_impaired), provider=s.provider_name, subtitle=codecs.encode(pickle.dumps(s), "base64").decode(), url=s.page_link, matches=list(matched), dont_matches=list(not_matched)))
            subtitles_dict = {}
            subtitles_dict = sorted(subtitles_list, key=lambda x: x['score'], reverse=True)
            return(subtitles_dict)
Пример #15
0
    def sync(self,
             video_path,
             srt_path,
             srt_lang,
             media_type,
             sonarr_series_id=None,
             sonarr_episode_id=None,
             radarr_id=None):
        self.reference = video_path
        self.srtin = srt_path
        self.srtout = None
        self.args = None

        ffprobe_exe = get_binary('ffprobe')
        if not ffprobe_exe:
            logging.debug('BAZARR FFprobe not found!')
            return
        else:
            logging.debug('BAZARR FFprobe used is %s', ffprobe_exe)

        ffmpeg_exe = get_binary('ffmpeg')
        if not ffmpeg_exe:
            logging.debug('BAZARR FFmpeg not found!')
            return
        else:
            logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe)

        self.ffmpeg_path = os.path.dirname(ffmpeg_exe)
        try:
            unparsed_args = [
                self.reference, '-i', self.srtin, '--overwrite-input',
                '--ffmpegpath', self.ffmpeg_path, '--vad', self.vad
            ]
            parser = make_parser()
            self.args = parser.parse_args(args=unparsed_args)
            result = run(self.args)
        except Exception as e:
            logging.exception(
                'BAZARR an exception occurs during the synchronization process for this subtitles: '
                '{0}'.format(self.srtin))
        else:
            if result['sync_was_successful']:
                message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \
                          "factor of {2}.".format(language_from_alpha3(srt_lang), result['offset_seconds'],
                                                  "{:.2f}".format(result['framerate_scale_factor']))

                if media_type == 'series':
                    history_log(action=5,
                                sonarr_series_id=sonarr_series_id,
                                sonarr_episode_id=sonarr_episode_id,
                                description=message,
                                video_path=path_mappings.path_replace_reverse(
                                    self.reference),
                                language=alpha2_from_alpha3(srt_lang),
                                subtitles_path=srt_path)
                else:
                    history_log_movie(
                        action=5,
                        radarr_id=radarr_id,
                        description=message,
                        video_path=path_mappings.path_replace_reverse_movie(
                            self.reference),
                        language=alpha2_from_alpha3(srt_lang),
                        subtitles_path=srt_path)
            else:
                logging.error('BAZARR unable to sync subtitles: {0}'.format(
                    self.srtin))

            return result
Пример #16
0
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, media_type):
    logging.debug('BAZARR Searching subtitles for this file: ' + path)
    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()
    if language == 'pob':
        language_set.add(Language('por', 'BR'))
    else:
        language_set.add(Language(language))

    use_scenename = settings.general.getboolean('use_scenename')
    minimum_score = settings.general.minimum_score
    minimum_score_movie = settings.general.minimum_score_movie
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    try:
        if sceneName == "None" or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except Exception as e:
        logging.exception("BAZARR Error trying to get video information for this file: " + path)
        pass
    else:
        if media_type == "movie":
            max_score = 120.0
        elif media_type == "series":
            max_score = 360.0

        try:
            with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p:
                subtitles = p.list_subtitles(video, language_set)
        except Exception as e:
            logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path)
        else:
            subtitles_list = []
            try:
                sorted_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hi)) for s in subtitles], key=operator.itemgetter(1), reverse=True)
            except Exception as e:
                logging.exception('BAZARR Exception raised while trying to compute score for this file: ' + path)
                return None
            else:
                for s, preliminary_score in sorted_subtitles:
                    if media_type == "movie":
                        if (preliminary_score / max_score * 100) < int(minimum_score_movie):
                            continue
                        matched = set(s.get_matches(video))
                        if hi == s.hearing_impaired:
                            matched.add('hearing_impaired')
                        not_matched = set(score.movie_scores.keys()) - matched
                        required = set(['title'])
                        if any(elem in required for elem in not_matched):
                            continue
                    elif media_type == "series":
                        if (preliminary_score / max_score * 100) < int(minimum_score):
                            continue
                        matched = set(s.get_matches(video))
                        if hi == s.hearing_impaired:
                            matched.add('hearing_impaired')
                        not_matched = set(score.episode_scores.keys()) - matched
                        required = set(['series', 'season', 'episode'])
                        if any(elem in required for elem in not_matched):
                            continue
                    subtitles_list.append(s)
                logging.debug('BAZARR ' + str(len(subtitles_list)) + " subtitles have been found for this file: " + path)
                if len(subtitles_list) > 0:
                    try:
                        download_result = False
                        for subtitle in subtitles_list:
                            download_result = p.download_subtitle(subtitle)
                            if download_result:
                                logging.debug('BAZARR Subtitles file downloaded from ' + str(subtitle.provider_name) + ' for this file: ' + path)
                                break
                            else:
                                logging.warning('BAZARR Subtitles file skipped from ' + str(subtitle.provider_name) + ' for this file: ' + path + ' because no content was returned by the provider (probably throttled).')
                                continue
                        if not download_result:
                            logging.error('BAZARR Tried to download a subtitles for file: ' + path + " but we weren't able to do it this time (probably being throttled). Going to retry on next search.")
                            return None
                    except Exception as e:
                        logging.exception('BAZARR Error downloading subtitles for this file ' + path)
                        return None
                    else:
                        try:
                            calculated_score = round(float(compute_score(subtitle, video, hearing_impaired=hi)) / max_score * 100, 2)
                            if used_sceneName:
                                video = scan_video(path)
                            single = settings.general.getboolean('single_language')
                            if single is True:
                                result = save_subtitles(video, [subtitle], single=True, encoding='utf-8')
                            else:
                                result = save_subtitles(video, [subtitle], encoding='utf-8')
                        except Exception as e:
                            logging.exception('BAZARR Error saving subtitles file to disk for this file:' + path)
                            pass
                        else:
                            downloaded_provider = result[0].provider_name
                            downloaded_language = language_from_alpha3(result[0].language.alpha3)
                            downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3)
                            downloaded_language_code3 = result[0].language.alpha3
                            downloaded_path = get_subtitle_path(path, downloaded_language_code2)
                            logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path)
                            if used_sceneName:
                                message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using this scene name: " + sceneName
                            else:
                                message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using filename guessing."

                            if use_postprocessing is True:
                                command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3)
                                try:
                                    if os.name == 'nt':
                                        codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                        # wait for the process to terminate
                                        out_codepage, err_codepage = codepage.communicate()
                                        encoding = out_codepage.split(':')[-1].strip()

                                    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                                    # wait for the process to terminate
                                    out, err = process.communicate()

                                    if os.name == 'nt':
                                        out = out.decode(encoding)

                                except:
                                    if out == "":
                                        logging.error('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution')
                                    else:
                                        logging.error('BAZARR Post-processing result for file ' + path + ' : ' + out)
                                else:
                                    if out == "":
                                        logging.info('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution')
                                    else:
                                        logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out)

                            return message
                else:
                    logging.debug('BAZARR No subtitles were found for this file: ' + path)
                    return None
    logging.debug('BAZARR Ended searching subtitles for file: ' + path)
Пример #17
0
def store_subtitles_movie(original_path, reversed_path):
    logging.debug('BAZARR started subtitles indexing for this file: ' +
                  reversed_path)
    actual_subtitles = []
    if os.path.exists(reversed_path):
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                subtitle_languages = embedded_subs_reader.list_languages(
                    reversed_path)
                for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages:
                    try:
                        if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \
                                (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() ==
                                 "vobsub"):
                            logging.debug(
                                "BAZARR skipping %s sub for language: %s" %
                                (subtitle_codec,
                                 alpha2_from_alpha3(subtitle_language)))
                            continue

                        if alpha2_from_alpha3(subtitle_language) is not None:
                            lang = str(alpha2_from_alpha3(subtitle_language))
                            if subtitle_forced:
                                lang = lang + ':forced'
                            if subtitle_hi:
                                lang = lang + ':hi'
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this %s file: %s" %
                    (os.path.splitext(reversed_path)[1], reversed_path))
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        brazilian_portuguese_forced = [
            ".pt-br.forced", ".pob.forced", "pb.forced"
        ]
        simplified_chinese_fuzzy = [u"简", u"双语"]
        simplified_chinese = [
            ".chs", ".sc", ".zhs", ".zh-hans", ".hans", ".zh_hans", ".zhhans",
            ".gb", ".simplified"
        ]
        simplified_chinese_forced = [
            ".chs.forced", ".sc.forced", ".zhs.forced", "hans.forced",
            ".gb.forced", u"简体中文.forced", u"双语.forced"
        ]
        traditional_chinese_fuzzy = [u"繁", u"雙語"]
        traditional_chinese = [
            ".cht", ".tc", ".zh-tw", ".zht", ".zh-hant", ".zhhant", ".zh_hant",
            ".hant", ".big5", ".traditional"
        ]
        traditional_chinese_forced = [
            ".cht.forced", ".tc.forced", ".zht.forced", "hant.forced",
            ".big5.forced", u"繁體中文.forced", u"雙語.forced", "zh-tw.forced"
        ]
        try:
            dest_folder = get_subtitle_destination_folder() or ''
            core.CUSTOM_PATHS = [dest_folder] if dest_folder else []
            subtitles = search_external_subtitles(reversed_path,
                                                  languages=get_language_set())
            full_dest_folder_path = os.path.dirname(reversed_path)
            if dest_folder:
                if settings.general.subfolder == "absolute":
                    full_dest_folder_path = dest_folder
                elif settings.general.subfolder == "relative":
                    full_dest_folder_path = os.path.join(
                        os.path.dirname(reversed_path), dest_folder)
            subtitles = guess_external_subtitles(full_dest_folder_path,
                                                 subtitles)
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in subtitles.items():
                subtitle_path = get_external_subtitles_path(
                    reversed_path, subtitle)
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append([
                        str("pb"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese_forced)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb:forced")
                    actual_subtitles.append([
                        str("pb:forced"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(simplified_chinese)) or (
                            str(subtitle_path).lower()
                        )[:-5] in simplified_chinese_fuzzy:
                    logging.debug("BAZARR external subtitles detected: " +
                                  "zh")
                    actual_subtitles.append([
                        str("zh"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif any(ext in (
                        str(os.path.splitext(subtitle)[0]).lower())[-12:]
                         for ext in simplified_chinese_forced):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "zh:forced")
                    actual_subtitles.append([
                        str("zh:forced"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(traditional_chinese)) or (
                            str(subtitle_path).lower()
                        )[:-5] in traditional_chinese_fuzzy:
                    logging.debug("BAZARR external subtitles detected: " +
                                  "zt")
                    actual_subtitles.append([
                        str("zt"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif any(ext in (
                        str(os.path.splitext(subtitle)[0]).lower())[-12:]
                         for ext in traditional_chinese_forced):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "zt:forced")
                    actual_subtitles.append([
                        str("zt:forced"),
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])
                elif not language:
                    continue
                elif str(language.basename) != 'und':
                    if language.forced:
                        language_str = str(language)
                    elif language.hi:
                        language_str = str(language) + ':hi'
                    else:
                        language_str = str(language)
                    logging.debug("BAZARR external subtitles detected: " +
                                  language_str)
                    actual_subtitles.append([
                        language_str,
                        path_mappings.path_replace_reverse_movie(subtitle_path)
                    ])

        database.execute("UPDATE table_movies SET subtitles=? WHERE path=?",
                         (str(actual_subtitles), original_path))
        matching_movies = database.execute(
            "SELECT radarrId FROM table_movies WHERE path=?",
            (original_path, ))

        for movie in matching_movies:
            if movie:
                logging.debug("BAZARR storing those languages to DB: " +
                              str(actual_subtitles))
                list_missing_subtitles_movies(no=movie['radarrId'])
            else:
                logging.debug(
                    "BAZARR haven't been able to update existing subtitles to DB : "
                    + str(actual_subtitles))
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' +
                  reversed_path)

    return actual_subtitles
Пример #18
0
def manual_upload_subtitle(path, language, forced, hi, title, scene_name, media_type, subtitle, audio_language):
    logging.debug('BAZARR Manually uploading subtitles for this file: ' + path)

    single = settings.general.getboolean('single_language')

    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(
        'win') and settings.general.getboolean('chmod_enabled') else None

    language = alpha3_from_alpha2(language)

    custom = CustomLanguage.from_value(language, "alpha3")
    if custom is None:
        lang_obj = Language(language)
    else:
        lang_obj = custom.subzero_language()

    if forced:
        lang_obj = Language.rebuild(lang_obj, forced=True)

    sub = Subtitle(
        lang_obj,
        mods=get_array_from(settings.general.subzero_mods)
    )

    sub.content = subtitle.read()
    if not sub.is_valid():
        logging.exception('BAZARR Invalid subtitle file: ' + subtitle.filename)
        sub.mods = None

    if settings.general.getboolean('utf8_encode'):
        sub.set_encoding("utf-8")

    saved_subtitles = []
    try:
        saved_subtitles = save_subtitles(path,
                                         [sub],
                                         single=single,
                                         tags=None,  # fixme
                                         directory=get_target_folder(path),
                                         chmod=chmod,
                                         # formats=("srt", "vtt")
                                         path_decoder=force_unicode)
    except Exception:
        logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path)
        return

    if len(saved_subtitles) < 1:
        logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path)
        return

    subtitle_path = saved_subtitles[0].storage_path

    if hi:
        modifier_string = " HI"
    elif forced:
        modifier_string = " forced"
    else:
        modifier_string = ""
    message = language_from_alpha3(language) + modifier_string + " Subtitles manually uploaded."

    if hi:
        modifier_code = ":hi"
    elif forced:
        modifier_code = ":forced"
    else:
        modifier_code = ""
    uploaded_language_code3 = language + modifier_code
    uploaded_language = language_from_alpha3(language) + modifier_string
    uploaded_language_code2 = alpha2_from_alpha3(language) + modifier_code
    audio_language_code2 = alpha2_from_language(audio_language)
    audio_language_code3 = alpha3_from_language(audio_language)

    if media_type == 'series':
        episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId) \
            .where(TableEpisodes.path == path_mappings.path_replace_reverse(path)) \
            .dicts() \
            .get_or_none()
        if not episode_metadata:
            return
        series_id = episode_metadata['sonarrSeriesId']
        episode_id = episode_metadata['sonarrEpisodeId']
        sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type,
                       percent_score=100, sonarr_series_id=episode_metadata['sonarrSeriesId'], forced=forced,
                       sonarr_episode_id=episode_metadata['sonarrEpisodeId'])
    else:
        movie_metadata = TableMovies.select(TableMovies.radarrId) \
            .where(TableMovies.path == path_mappings.path_replace_reverse_movie(path)) \
            .dicts() \
            .get_or_none()
        if not movie_metadata:
            return
        series_id = ""
        episode_id = movie_metadata['radarrId']
        sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type,
                       percent_score=100, radarr_id=movie_metadata['radarrId'], forced=forced)

    if use_postprocessing:
        command = pp_replace(postprocessing_cmd, path, subtitle_path, uploaded_language,
                             uploaded_language_code2, uploaded_language_code3, audio_language,
                             audio_language_code2, audio_language_code3, forced, 100, "1", "manual", series_id,
                             episode_id, hi=hi)
        postprocessing(command, path)

    if media_type == 'series':
        reversed_path = path_mappings.path_replace_reverse(path)
        reversed_subtitles_path = path_mappings.path_replace_reverse(subtitle_path)
        notify_sonarr(episode_metadata['sonarrSeriesId'])
        event_stream(type='series', action='update', payload=episode_metadata['sonarrSeriesId'])
        event_stream(type='episode-wanted', action='delete', payload=episode_metadata['sonarrEpisodeId'])
    else:
        reversed_path = path_mappings.path_replace_reverse_movie(path)
        reversed_subtitles_path = path_mappings.path_replace_reverse_movie(subtitle_path)
        notify_radarr(movie_metadata['radarrId'])
        event_stream(type='movie', action='update', payload=movie_metadata['radarrId'])
        event_stream(type='movie-wanted', action='delete', payload=movie_metadata['radarrId'])

    return message, reversed_path, reversed_subtitles_path
Пример #19
0
def store_subtitles_movie(original_path, reversed_path):
    logging.debug('BAZARR started subtitles indexing for this file: ' +
                  reversed_path)
    actual_subtitles = []
    if os.path.exists(reversed_path):
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                subtitle_languages = embedded_subs_reader.list_languages(
                    reversed_path)
                for subtitle_language, subtitle_forced, subtitle_codec in subtitle_languages:
                    try:
                        if settings.general.getboolean(
                                "ignore_pgs_subs"
                        ) and subtitle_codec == "hdmv_pgs_subtitle":
                            logging.debug(
                                "BAZARR skipping pgs sub for language: " +
                                str(alpha2_from_alpha3(subtitle_language)))
                            continue

                        if alpha2_from_alpha3(subtitle_language) is not None:
                            lang = str(alpha2_from_alpha3(subtitle_language))
                            if subtitle_forced:
                                lang = lang + ':forced'
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this %s file: %s" %
                    (os.path.splitext(reversed_path)[1], reversed_path))
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        brazilian_portuguese_forced = [
            ".pt-br.forced", ".pob.forced", "pb.forced"
        ]
        try:
            dest_folder = get_subtitle_destination_folder() or ''
            subliminal_patch.core.CUSTOM_PATHS = [dest_folder
                                                  ] if dest_folder else []
            subtitles = search_external_subtitles(reversed_path,
                                                  languages=get_language_set())
            subtitles = guess_external_subtitles(
                get_subtitle_destination_folder()
                or os.path.dirname(reversed_path), subtitles)
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in six.iteritems(subtitles):
                subtitle_path = get_external_subtitles_path(
                    reversed_path, subtitle)
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append(
                        [str("pb"),
                         path_replace_reverse_movie(subtitle_path)])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese_forced)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb:forced")
                    actual_subtitles.append([
                        str("pb:forced"),
                        path_replace_reverse_movie(subtitle_path)
                    ])
                elif not language:
                    continue
                elif str(language) != 'und':
                    logging.debug("BAZARR external subtitles detected: " +
                                  str(language))
                    actual_subtitles.append([
                        str(language),
                        path_replace_reverse_movie(subtitle_path)
                    ])

        database.execute("UPDATE table_movies SET subtitles=? WHERE path=?",
                         (str(actual_subtitles), original_path))
        matching_movies = database.execute(
            "SELECT radarrId FROM table_movies WHERE path=?",
            (original_path, ))

        for movie in matching_movies:
            if movie:
                logging.debug("BAZARR storing those languages to DB: " +
                              str(actual_subtitles))
                list_missing_subtitles_movies(no=movie['radarrId'])
            else:
                logging.debug(
                    "BAZARR haven't been able to update existing subtitles to DB : "
                    + str(actual_subtitles))
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' +
                  reversed_path)

    return actual_subtitles
Пример #20
0
def manual_search(path, language, hi, providers, providers_auth, sceneName, media_type):
    logging.debug('BAZARR Manually searching subtitles for this file: ' + path)

    subtitles_dict = {}

    if hi == "True":
        hi = True
    else:
        hi = False
    language_set = set()
    for lang in ast.literal_eval(language):
        lang = alpha3_from_alpha2(lang)
        if lang == 'pob':
            language_set.add(Language('por', 'BR'))
        else:
            language_set.add(Language(lang))

    use_scenename = settings.general.getboolean('use_scenename')
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    try:
        if sceneName == "None" or use_scenename is False:
            used_sceneName = False
            video = scan_video(path)
        else:
            used_sceneName = True
            video = Video.fromname(sceneName)
    except:
        logging.exception("BAZARR Error trying to get video information for this file: " + path)
    else:
        if media_type == "movie":
            max_score = 120.0
        elif media_type == "series":
            max_score = 360.0

        try:
            with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p:
                subtitles = p.list_subtitles(video, language_set)
        except Exception as e:
            logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path)
        else:
            subtitles_list = []
            for s in subtitles:
                {s: compute_score(s, video, hearing_impaired=hi)}
                if media_type == "movie":
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.movie_scores.keys()) - matched
                    required = set(['title'])
                    if any(elem in required for elem in not_matched):
                        continue
                    if used_sceneName:
                        not_matched.remove('hash')
                    if type(s) is LegendasTVSubtitle:
                        # The pickle doesn't work very well with RAR (rarfile.RarFile) or ZIP (zipfile.ZipFile)
                        s.archive.content = None
                elif media_type == "series":
                    matched = set(s.get_matches(video))
                    if hi == s.hearing_impaired:
                        matched.add('hearing_impaired')
                    not_matched = set(score.episode_scores.keys()) - matched
                    required = set(['series', 'season', 'episode'])
                    if any(elem in required for elem in not_matched):
                        continue
                    if used_sceneName:
                        not_matched.remove('hash')
                    if type(s) is LegendasTVSubtitle:
                        # The pickle doesn't work very well with RAR (rarfile.RarFile) or ZIP (zipfile.ZipFile)
                        s.archive.content = None
                subtitles_list.append(dict(score=round((compute_score(s, video, hearing_impaired=hi) / max_score * 100), 2), language=alpha2_from_alpha3(s.language.alpha3), hearing_impaired=str(s.hearing_impaired), provider=s.provider_name, subtitle=codecs.encode(pickle.dumps(s), "base64").decode(), url=s.page_link, matches=list(matched), dont_matches=list(not_matched)))
            subtitles_dict = sorted(subtitles_list, key=lambda x: x['score'], reverse=True)
            logging.debug('BAZARR ' + str(len(subtitles_dict)) + " subtitles have been found for this file: " + path)
            logging.debug('BAZARR Ended searching subtitles for this file: ' + path)
        return(subtitles_dict)
Пример #21
0
    def sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None,
             radarr_id=None):
        self.reference = video_path
        self.srtin = srt_path
        self.srtout = None

        ffprobe_exe = get_binary('ffprobe')
        if not ffprobe_exe:
            logging.debug('BAZARR FFprobe not found!')
            return
        else:
            logging.debug('BAZARR FFprobe used is %s', ffprobe_exe)

        api.initialize({'provider': 'ffmpeg', 'ffmpeg': ffprobe_exe})
        data = api.know(self.reference)

        using_what = None

        if 'subtitle' in data:
            for i, embedded_subs in enumerate(data['subtitle']):
                if 'language' in embedded_subs:
                    language = embedded_subs['language'].alpha3
                    if language == "eng":
                        using_what = "English embedded subtitle track"
                        self.reference_stream = "s:{}".format(i)
                        break
            if not self.reference_stream:
                using_what = "{0} embedded subtitle track".format(
                    language_from_alpha3(embedded_subs['language'].alpha3) or 'unknown language embedded subtitles '
                                                                              'track')
                self.reference_stream = "s:0"
        elif 'audio' in data:
            audio_tracks = data['audio']
            for i, audio_track in enumerate(audio_tracks):
                if 'language' in audio_track:
                    language = audio_track['language'].alpha3
                    if language == srt_lang:
                        using_what = "{0} audio track".format(language_from_alpha3(audio_track['language'].alpha3) or
                                                              'unknown language audio track')
                        self.reference_stream = "a:{}".format(i)
                        break
            if not self.reference_stream:
                audio_tracks = data['audio']
                for i, audio_track in enumerate(audio_tracks):
                    if 'language' in audio_track:
                        language = audio_track['language'].alpha3
                        if language == "eng":
                            using_what = "English audio track"
                            self.reference_stream = "a:{}".format(i)
                            break
                if not self.reference_stream:
                    using_what = "first audio track"
                    self.reference_stream = "a:0"
        else:
            raise NoAudioTrack

        ffmpeg_exe = get_binary('ffmpeg')
        if not ffmpeg_exe:
            logging.debug('BAZARR FFmpeg not found!')
            return
        else:
            logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe)

        self.ffmpeg_path = os.path.dirname(ffmpeg_exe)
        try:
            result = run(self)
        except Exception as e:
            logging.error('BAZARR an exception occurs during the synchronization process for this subtitles: ' +
                          self.srtin)
        else:
            if result['sync_was_successful']:
                message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \
                          "factor of {2} using {3} (0:{4}).".format(language_from_alpha3(srt_lang),
                                                                    result['offset_seconds'],
                                                                    result['framerate_scale_factor'],
                                                                    using_what,
                                                                    self.reference_stream)

                if media_type == 'series':
                    history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id,
                                description=message, video_path=path_mappings.path_replace_reverse(self.reference),
                                language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path)
                else:
                    history_log_movie(action=5, radarr_id=radarr_id, description=message,
                                      video_path=path_mappings.path_replace_reverse_movie(self.reference),
                                      language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path)
            else:
                logging.error('BAZARR unable to sync subtitles using {0}({1}): {2}'.format(using_what,
                                                                                           self.reference_stream,
                                                                                           self.srtin))

            return result
Пример #22
0
def store_subtitles(file):
    logging.debug('BAZARR started subtitles indexing for this file: ' + file)
    actual_subtitles = []
    if os.path.exists(file):
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            try:
                subtitle_languages = embedded_subs_reader.list_languages(file)
                for subtitle_language, subtitle_forced, subtitle_codec in subtitle_languages:
                    try:
                        if settings.general.getboolean(
                                "ignore_pgs_subs"
                        ) and subtitle_codec == "hdmv_pgs_subtitle":
                            logging.debug(
                                "BAZARR skipping pgs sub for language: " +
                                str(alpha2_from_alpha3(subtitle_language)))
                            continue

                        if alpha2_from_alpha3(subtitle_language) is not None:
                            lang = str(alpha2_from_alpha3(subtitle_language))
                            if subtitle_forced:
                                lang = lang + ":forced"
                            logging.debug(
                                "BAZARR embedded subtitles detected: " + lang)
                            actual_subtitles.append([lang, None])
                    except:
                        logging.debug(
                            "BAZARR unable to index this unrecognized language: "
                            + subtitle_language)
                        pass
            except Exception as e:
                logging.exception(
                    "BAZARR error when trying to analyze this %s file: %s" %
                    (os.path.splitext(file)[1], file))
                pass

        brazilian_portuguese = [".pt-br", ".pob", "pb"]
        brazilian_portuguese_forced = [
            ".pt-br.forced", ".pob.forced", "pb.forced"
        ]
        try:
            dest_folder = get_subtitle_destination_folder()
            subliminal_patch.core.CUSTOM_PATHS = [dest_folder
                                                  ] if dest_folder else []
            subtitles = search_external_subtitles(
                file,
                languages=get_language_set(),
                only_one=settings.general.getboolean('single_language'))
        except Exception as e:
            logging.exception("BAZARR unable to index external subtitles.")
            pass
        else:
            for subtitle, language in subtitles.iteritems():
                subtitle_path = get_external_subtitles_path(file, subtitle)
                if str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb")
                    actual_subtitles.append(
                        [str("pb"),
                         path_replace_reverse(subtitle_path)])
                elif str(os.path.splitext(subtitle)[0]).lower().endswith(
                        tuple(brazilian_portuguese_forced)):
                    logging.debug("BAZARR external subtitles detected: " +
                                  "pb:forced")
                    actual_subtitles.append([
                        str("pb:forced"),
                        path_replace_reverse(subtitle_path)
                    ])

                elif str(language) != 'und':
                    logging.debug("BAZARR external subtitles detected: " +
                                  str(language))
                    actual_subtitles.append(
                        [str(language),
                         path_replace_reverse(subtitle_path)])
                else:
                    if os.path.splitext(subtitle)[1] != ".sub":
                        logging.debug(
                            "BAZARR falling back to file content analysis to detect language."
                        )
                        with open(
                                os.path.join(os.path.dirname(file), subtitle),
                                'r') as f:
                            text = list(islice(f, 100))
                            text = ' '.join(text)
                            encoding = UnicodeDammit(text)
                            try:
                                text = text.decode(encoding.original_encoding)
                                detected_language = langdetect.detect(text)
                            except Exception as e:
                                logging.exception(
                                    'BAZARR Error trying to detect language for this subtitles file: '
                                    + os.path.join(os.path.dirname(file),
                                                   subtitle) +
                                    ' You should try to delete this subtitles file manually and ask Bazarr to download it again.'
                                )
                            else:
                                if len(detected_language) > 0:
                                    logging.debug(
                                        "BAZARR external subtitles detected and analysis guessed this language: "
                                        + str(detected_language))
                                    actual_subtitles.append([
                                        str(detected_language),
                                        path_replace_reverse(
                                            os.path.join(
                                                os.path.dirname(file),
                                                subtitle))
                                    ])

        update_count = TableEpisodes.update({
            TableEpisodes.subtitles:
            str(actual_subtitles)
        }).where(TableEpisodes.path == path_replace_reverse(file)).execute()
        if update_count > 0:
            logging.debug("BAZARR storing those languages to DB: " +
                          str(actual_subtitles))
        else:
            logging.debug(
                "BAZARR haven't been able to update existing subtitles to DB : "
                + str(actual_subtitles))
    else:
        logging.debug(
            "BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' + file)

    return actual_subtitles
Пример #23
0
def process_subtitle(subtitle,
                     media_type,
                     audio_language,
                     path,
                     max_score,
                     is_upgrade=False,
                     is_manual=False):
    use_postprocessing = settings.general.getboolean('use_postprocessing')
    postprocessing_cmd = settings.general.postprocessing_cmd

    downloaded_provider = subtitle.provider_name
    downloaded_language_code3 = _get_download_code3(subtitle)

    downloaded_language = language_from_alpha3(downloaded_language_code3)
    downloaded_language_code2 = alpha2_from_alpha3(downloaded_language_code3)
    audio_language_code2 = alpha2_from_language(audio_language)
    audio_language_code3 = alpha3_from_language(audio_language)
    downloaded_path = subtitle.storage_path
    subtitle_id = subtitle.id
    if subtitle.language.hi:
        modifier_string = " HI"
    elif subtitle.language.forced:
        modifier_string = " forced"
    else:
        modifier_string = ""
    logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path)
    if is_upgrade:
        action = "upgraded"
    elif is_manual:
        action = "manually downloaded"
    else:
        action = "downloaded"

    percent_score = round(subtitle.score * 100 / max_score, 2)
    message = downloaded_language + modifier_string + " subtitles " + action + " from " + \
        downloaded_provider + " with a score of " + str(percent_score) + "%."

    if media_type == 'series':
        episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId,
                                                TableEpisodes.sonarrEpisodeId) \
            .where(TableEpisodes.path == path_mappings.path_replace_reverse(path)) \
            .dicts() \
            .get_or_none()
        if not episode_metadata:
            return
        series_id = episode_metadata['sonarrSeriesId']
        episode_id = episode_metadata['sonarrEpisodeId']
        sync_subtitles(video_path=path,
                       srt_path=downloaded_path,
                       forced=subtitle.language.forced,
                       srt_lang=downloaded_language_code2,
                       media_type=media_type,
                       percent_score=percent_score,
                       sonarr_series_id=episode_metadata['sonarrSeriesId'],
                       sonarr_episode_id=episode_metadata['sonarrEpisodeId'])
    else:
        movie_metadata = TableMovies.select(TableMovies.radarrId) \
            .where(TableMovies.path == path_mappings.path_replace_reverse_movie(path)) \
            .dicts() \
            .get_or_none()
        if not movie_metadata:
            return
        series_id = ""
        episode_id = movie_metadata['radarrId']
        sync_subtitles(video_path=path,
                       srt_path=downloaded_path,
                       forced=subtitle.language.forced,
                       srt_lang=downloaded_language_code2,
                       media_type=media_type,
                       percent_score=percent_score,
                       radarr_id=movie_metadata['radarrId'])

    if use_postprocessing is True:
        command = pp_replace(postprocessing_cmd, path, downloaded_path,
                             downloaded_language, downloaded_language_code2,
                             downloaded_language_code3, audio_language,
                             audio_language_code2, audio_language_code3,
                             subtitle.language.forced, percent_score,
                             subtitle_id, downloaded_provider, series_id,
                             episode_id, subtitle.language.hi)

        if media_type == 'series':
            use_pp_threshold = settings.general.getboolean(
                'use_postprocessing_threshold')
            pp_threshold = int(settings.general.postprocessing_threshold)
        else:
            use_pp_threshold = settings.general.getboolean(
                'use_postprocessing_threshold_movie')
            pp_threshold = int(settings.general.postprocessing_threshold_movie)

        if not use_pp_threshold or (use_pp_threshold
                                    and percent_score < pp_threshold):
            logging.debug(
                "BAZARR Using post-processing command: {}".format(command))
            postprocessing(command, path)
        else:
            logging.debug(
                "BAZARR post-processing skipped because subtitles score isn't below this "
                "threshold value: " + str(pp_threshold) + "%")

    if media_type == 'series':
        reversed_path = path_mappings.path_replace_reverse(path)
        reversed_subtitles_path = path_mappings.path_replace_reverse(
            downloaded_path)
        notify_sonarr(episode_metadata['sonarrSeriesId'])
        event_stream(type='series',
                     action='update',
                     payload=episode_metadata['sonarrSeriesId'])
        event_stream(type='episode-wanted',
                     action='delete',
                     payload=episode_metadata['sonarrEpisodeId'])

    else:
        reversed_path = path_mappings.path_replace_reverse_movie(path)
        reversed_subtitles_path = path_mappings.path_replace_reverse_movie(
            downloaded_path)
        notify_radarr(movie_metadata['radarrId'])
        event_stream(type='movie-wanted',
                     action='delete',
                     payload=movie_metadata['radarrId'])

    track_event(category=downloaded_provider,
                action=action,
                label=downloaded_language)

    return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score, \
        subtitle.language.forced, subtitle.id, reversed_subtitles_path, subtitle.language.hi
Пример #24
0
def store_subtitles(original_path, reversed_path, use_cache=True):
    logging.debug('BAZARR started subtitles indexing for this file: ' + reversed_path)
    actual_subtitles = []
    if os.path.exists(reversed_path):
        if settings.general.getboolean('use_embedded_subs'):
            logging.debug("BAZARR is trying to index embedded subtitles.")
            item = TableEpisodes.select(TableEpisodes.episode_file_id, TableEpisodes.file_size)\
                .where(TableEpisodes.path == original_path)\
                .dicts()\
                .get_or_none()
            if not item:
                logging.exception(f"BAZARR error when trying to select this episode from database: {reversed_path}")
            else:
                try:
                    subtitle_languages = embedded_subs_reader(reversed_path,
                                                              file_size=item['file_size'],
                                                              episode_file_id=item['episode_file_id'],
                                                              use_cache=use_cache)
                    for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages:
                        try:
                            if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \
                                    (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() ==
                                     "vobsub") or \
                                    (settings.general.getboolean("ignore_ass_subs") and subtitle_codec.lower() ==
                                     "ass"):
                                logging.debug("BAZARR skipping %s sub for language: %s" % (subtitle_codec, alpha2_from_alpha3(subtitle_language)))
                                continue

                            if alpha2_from_alpha3(subtitle_language) is not None:
                                lang = str(alpha2_from_alpha3(subtitle_language))
                                if subtitle_forced:
                                    lang = lang + ":forced"
                                if subtitle_hi:
                                    lang = lang + ":hi"
                                logging.debug("BAZARR embedded subtitles detected: " + lang)
                                actual_subtitles.append([lang, None])
                        except Exception as error:
                            logging.debug("BAZARR unable to index this unrecognized language: %s (%s)", subtitle_language, error)
                except Exception:
                    logging.exception(
                        "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(reversed_path)[1],
                                                                                  reversed_path))
                    pass
        try:
            dest_folder = get_subtitle_destination_folder()
            core.CUSTOM_PATHS = [dest_folder] if dest_folder else []
            subtitles = search_external_subtitles(reversed_path, languages=get_language_set(),
                                                  only_one=settings.general.getboolean('single_language'))
            full_dest_folder_path = os.path.dirname(reversed_path)
            if dest_folder:
                if settings.general.subfolder == "absolute":
                    full_dest_folder_path = dest_folder
                elif settings.general.subfolder == "relative":
                    full_dest_folder_path = os.path.join(os.path.dirname(reversed_path), dest_folder)
            subtitles = guess_external_subtitles(full_dest_folder_path, subtitles)
        except Exception:
            logging.exception("BAZARR unable to index external subtitles.")
        else:
            for subtitle, language in subtitles.items():
                valid_language = False
                if language:
                    if hasattr(language, 'alpha3'):
                        valid_language = alpha2_from_alpha3(language.alpha3)
                else:
                    logging.debug(f"Skipping subtitles because we are unable to define language: {subtitle}")
                    continue

                if not valid_language:
                    logging.debug(f'{language.alpha3} is an unsupported language code.')
                    continue

                subtitle_path = get_external_subtitles_path(reversed_path, subtitle)

                custom = CustomLanguage.found_external(subtitle, subtitle_path)
                if custom is not None:
                    actual_subtitles.append([custom, path_mappings.path_replace_reverse(subtitle_path)])

                elif str(language) != 'und':
                    if language.forced:
                        language_str = str(language)
                    elif language.hi:
                        language_str = str(language) + ':hi'
                    else:
                        language_str = str(language)
                    logging.debug("BAZARR external subtitles detected: " + language_str)
                    actual_subtitles.append([language_str, path_mappings.path_replace_reverse(subtitle_path)])

        TableEpisodes.update({TableEpisodes.subtitles: str(actual_subtitles)})\
            .where(TableEpisodes.path == original_path)\
            .execute()
        matching_episodes = TableEpisodes.select(TableEpisodes.sonarrEpisodeId, TableEpisodes.sonarrSeriesId)\
            .where(TableEpisodes.path == original_path)\
            .dicts()

        for episode in matching_episodes:
            if episode:
                logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles))
                list_missing_subtitles(epno=episode['sonarrEpisodeId'])
            else:
                logging.debug("BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles))
    else:
        logging.debug("BAZARR this file doesn't seems to exist or isn't accessible.")

    logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path)

    return actual_subtitles