Exemple #1
0
def check_radarr_rootfolder():
    get_radarr_rootfolder()
    rootfolder = TableMoviesRootfolder.select(TableMoviesRootfolder.id, TableMoviesRootfolder.path).dicts()
    for item in rootfolder:
        root_path = item['path']
        if not root_path.endswith(('/', '\\')):
            if root_path.startswith('/'):
                root_path += '/'
            else:
                root_path += '\\'
        if not os.path.isdir(path_mappings.path_replace_movie(root_path)):
            TableMoviesRootfolder.update({TableMoviesRootfolder.accessible: 0,
                                         TableMoviesRootfolder.error: 'This Radarr root directory does not seems to '
                                                                      'be accessible by Bazarr. Please check path '
                                                                      'mapping.'}) \
                .where(TableMoviesRootfolder.id == item['id']) \
                .execute()
        elif not os.access(path_mappings.path_replace_movie(root_path), os.W_OK):
            TableMoviesRootfolder.update({TableMoviesRootfolder.accessible: 0,
                                          TableMoviesRootfolder.error: 'Bazarr cannot write to this directory'}) \
                .where(TableMoviesRootfolder.id == item['id']) \
                .execute()
        else:
            TableMoviesRootfolder.update({TableMoviesRootfolder.accessible: 1,
                                          TableMoviesRootfolder.error: ''}) \
                .where(TableMoviesRootfolder.id == item['id']) \
                .execute()
Exemple #2
0
 def path_replace_movie(self, values_dict):
     if type(values_dict) is list:
         for item in values_dict:
             item['path'] = path_mappings.path_replace_movie(item['path'])
     elif type(values_dict) is dict:
         values_dict['path'] = path_mappings.path_replace_movie(values_dict['path'])
     else:
         return path_mappings.path_replace_movie(values_dict)
Exemple #3
0
    def delete(self):
        # Delete
        radarrId = request.args.get('radarrid')
        movieInfo = TableMovies.select(TableMovies.path) \
            .where(TableMovies.radarrId == radarrId) \
            .dicts() \
            .get_or_none()

        if not movieInfo:
            return 'Movie not found', 500

        moviePath = path_mappings.path_replace_movie(movieInfo['path'])

        language = request.form.get('language')
        forced = request.form.get('forced')
        hi = request.form.get('hi')
        subtitlesPath = request.form.get('path')

        subtitlesPath = path_mappings.path_replace_reverse_movie(subtitlesPath)

        result = delete_subtitles(media_type='movie',
                                  language=language,
                                  forced=forced,
                                  hi=hi,
                                  media_path=moviePath,
                                  subtitles_path=subtitlesPath,
                                  radarr_id=radarrId)
        if result:
            return '', 202
        else:
            return '', 204
Exemple #4
0
    def post(self):
        radarr_id = int(request.args.get('radarrid'))
        provider = request.form.get('provider')
        subs_id = request.form.get('subs_id')
        language = request.form.get('language')
        # TODO
        forced = False
        hi = False

        data = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == radarr_id).dicts().get()

        media_path = data['path']
        subtitles_path = request.form.get('subtitles_path')

        blacklist_log_movie(radarr_id=radarr_id,
                            provider=provider,
                            subs_id=subs_id,
                            language=language)
        delete_subtitles(media_type='movie',
                         language=language,
                         forced=forced,
                         hi=hi,
                         media_path=path_mappings.path_replace_movie(media_path),
                         subtitles_path=subtitles_path,
                         radarr_id=radarr_id)
        movies_download_subtitles(radarr_id)
        event_stream(type='movie-history')
        return '', 200
Exemple #5
0
def get_health_issues():
    # this function must return a list of dictionaries consisting of to keys: object and issue
    health_issues = []

    # get Sonarr rootfolder issues
    if settings.general.getboolean('use_sonarr'):
        rootfolder = TableShowsRootfolder.select(TableShowsRootfolder.path,
                                                 TableShowsRootfolder.accessible,
                                                 TableShowsRootfolder.error)\
            .where(TableShowsRootfolder.accessible == 0)\
            .dicts()
        for item in rootfolder:
            health_issues.append({
                'object':
                path_mappings.path_replace(item['path']),
                'issue':
                item['error']
            })

    # get Radarr rootfolder issues
    if settings.general.getboolean('use_radarr'):
        rootfolder = TableMoviesRootfolder.select(TableMoviesRootfolder.path,
                                                  TableMoviesRootfolder.accessible,
                                                  TableMoviesRootfolder.error)\
            .where(TableMoviesRootfolder.accessible == 0)\
            .dicts()
        for item in rootfolder:
            health_issues.append({
                'object':
                path_mappings.path_replace_movie(item['path']),
                'issue':
                item['error']
            })

    return health_issues
Exemple #6
0
    def get(self):
        # Manual Search
        radarrId = request.args.get('radarrid')
        movieInfo = TableMovies.select(TableMovies.title,
                                       TableMovies.path,
                                       TableMovies.sceneName,
                                       TableMovies.profileId) \
            .where(TableMovies.radarrId == radarrId) \
            .dicts() \
            .get_or_none()

        if not movieInfo:
            return 'Movie not found', 500

        title = movieInfo['title']
        moviePath = path_mappings.path_replace_movie(movieInfo['path'])
        sceneName = movieInfo['sceneName'] or "None"
        profileId = movieInfo['profileId']

        providers_list = get_providers()

        data = manual_search(moviePath, profileId, providers_list, sceneName, title, 'movie')
        if not data:
            data = []
        return jsonify(data=data)
Exemple #7
0
def movies_full_scan_subtitles():
    movies = database.execute("SELECT path FROM table_movies")
    
    for i, movie in enumerate(movies, 1):
        store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
    
    gc.collect()
Exemple #8
0
def movies_scan_subtitles(no):
    movies = TableMovies.select(TableMovies.path)\
        .where(TableMovies.radarrId == no)\
        .order_by(TableMovies.radarrId)\
        .dicts()

    for movie in movies:
        store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']), use_cache=False)
Exemple #9
0
def movies_scan_subtitles(no):
    movies = database.execute(
        "SELECT path FROM table_movies WHERE radarrId=? ORDER BY radarrId",
        (no, ))

    for movie in movies:
        store_subtitles_movie(movie['path'],
                              path_mappings.path_replace_movie(movie['path']))
Exemple #10
0
    def post(self):
        # Manual Download
        radarrId = request.args.get('radarrid')
        movieInfo = TableMovies.select(TableMovies.title,
                                       TableMovies.path,
                                       TableMovies.sceneName,
                                       TableMovies.audio_language) \
            .where(TableMovies.radarrId == radarrId) \
            .dicts() \
            .get()

        title = movieInfo['title']
        moviePath = path_mappings.path_replace_movie(movieInfo['path'])
        sceneName = movieInfo['sceneName']
        if sceneName is None: sceneName = "None"
        audio_language = movieInfo['audio_language']

        language = request.form.get('language')
        hi = request.form.get('hi').capitalize()
        forced = request.form.get('forced').capitalize()
        selected_provider = request.form.get('provider')
        subtitle = request.form.get('subtitle')

        providers_auth = get_providers_auth()

        audio_language_list = get_audio_profile_languages(movie_id=radarrId)
        if len(audio_language_list) > 0:
            audio_language = audio_language_list[0]['name']
        else:
            audio_language = 'None'

        try:
            result = manual_download_subtitle(moviePath, language, audio_language, hi, forced, subtitle,
                                              selected_provider, providers_auth, sceneName, title, 'movie',
                                              profile_id=get_profile_id(movie_id=radarrId))
            if result is not None:
                message = result[0]
                path = result[1]
                forced = result[5]
                if result[8]:
                    language_code = result[2] + ":hi"
                elif forced:
                    language_code = result[2] + ":forced"
                else:
                    language_code = result[2]
                provider = result[3]
                score = result[4]
                subs_id = result[6]
                subs_path = result[7]
                history_log_movie(2, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
                if not settings.general.getboolean('dont_notify_manual_actions'):
                    send_notifications_movie(radarrId, message)
                store_subtitles_movie(path, moviePath)
        except OSError:
            pass

        return '', 204
Exemple #11
0
def movies_full_scan_subtitles():
    use_ffprobe_cache = settings.radarr.getboolean('use_ffprobe_cache')

    movies = TableMovies.select(TableMovies.path).dicts()

    count_movies = len(movies)
    for i, movie in enumerate(movies):
        show_progress(id='movies_disk_scan',
                      header='Full disk scan...',
                      name='Movies subtitles',
                      value=i,
                      count=count_movies)
        store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']),
                              use_cache=use_ffprobe_cache)

    hide_progress(id='movies_disk_scan')

    gc.collect()
Exemple #12
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

    language_log = language
    language_string = language_from_alpha2(language)
    if hi in [True, 'true', 'True']:
        language_log += ':hi'
        language_string += ' HI'
    elif forced in [True, 'true', 'True']:
        language_log += ':forced'
        language_string += ' forced'
        
    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
Exemple #13
0
def postprocessMovie(item):
    postprocess(item)
    # Parse audio language
    if 'audio_language' in item and item['audio_language'] is not None:
        item['audio_language'] = get_audio_profile_languages(movie_id=item['radarrId'])

    # Parse alternate titles
    if 'alternativeTitles' in item:
        if item['alternativeTitles'] is None:
            item['alternativeTitles'] = []
        else:
            item['alternativeTitles'] = ast.literal_eval(item['alternativeTitles'])

    # Parse failed attempts
    if 'failedAttempts' in item:
        if item['failedAttempts']:
            item['failedAttempts'] = ast.literal_eval(item['failedAttempts'])

    # Parse subtitles
    if 'subtitles' in item:
        if item['subtitles'] is None:
            item['subtitles'] = []
        else:
            item['subtitles'] = ast.literal_eval(item['subtitles'])
        for i, subs in enumerate(item['subtitles']):
            language = subs[0].split(':')
            item['subtitles'][i] = {"path": path_mappings.path_replace_movie(subs[1]),
                                    "name": language_from_alpha2(language[0]),
                                    "code2": language[0],
                                    "code3": alpha3_from_alpha2(language[0]),
                                    "forced": False,
                                    "hi": False}
            if len(language) > 1:
                item['subtitles'][i].update({
                    "forced": True if language[1] == 'forced' else False,
                    "hi": True if language[1] == 'hi' else False
                })

        if settings.general.getboolean('embedded_subs_show_desired'):
            desired_lang_list = get_desired_languages(item['profileId'])
            item['subtitles'] = [x for x in item['subtitles'] if x['code2'] in desired_lang_list or x['path']]

        item['subtitles'] = sorted(item['subtitles'], key=itemgetter('name', 'forced'))

    # Parse missing subtitles
    if 'missing_subtitles' in item:
        if item['missing_subtitles'] is None:
            item['missing_subtitles'] = []
        else:
            item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles'])
        for i, subs in enumerate(item['missing_subtitles']):
            language = subs.split(':')
            item['missing_subtitles'][i] = {"name": language_from_alpha2(language[0]),
                                            "code2": language[0],
                                            "code3": alpha3_from_alpha2(language[0]),
                                            "forced": False,
                                            "hi": False}
            if len(language) > 1:
                item['missing_subtitles'][i].update({
                    "forced": True if language[1] == 'forced' else False,
                    "hi": True if language[1] == 'hi' else False
                })

    # Provide mapped path
    if 'path' in item:
        if item['path']:
            item['path'] = path_mappings.path_replace_movie(item['path'])

    if 'subtitles_path' in item:
        # Provide mapped subtitles path
        item['subtitles_path'] = path_mappings.path_replace_movie(item['subtitles_path'])

    # map poster and fanart to server proxy
    if 'poster' in item:
        poster = item['poster']
        item['poster'] = f"{base_url}/images/movies{poster}" if poster else None

    if 'fanart' in item:
        fanart = item['fanart']
        item['fanart'] = f"{base_url}/images/movies{fanart}" if fanart else None
Exemple #14
0
def _wanted_movie(movie):
    audio_language_list = get_audio_profile_languages(movie_id=movie['radarrId'])
    if len(audio_language_list) > 0:
        audio_language = audio_language_list[0]['name']
    else:
        audio_language = 'None'

    languages = []

    for language in ast.literal_eval(movie['missing_subtitles']):
        # confirm if language is still missing or if cutoff have been reached
        confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles) \
            .where(TableMovies.radarrId == movie['radarrId']) \
            .dicts() \
            .get_or_none()
        if not confirmed_missing_subs:
            continue

        if language not in ast.literal_eval(confirmed_missing_subs['missing_subtitles']):
            continue

        if is_search_active(desired_language=language, attempt_string=movie['failedAttempts']):
            TableMovies.update({TableMovies.failedAttempts:
                                updateFailedAttempts(desired_language=language,
                                                     attempt_string=movie['failedAttempts'])}) \
                .where(TableMovies.radarrId == movie['radarrId']) \
                .execute()

            hi_ = "True" if language.endswith(':hi') else "False"
            forced_ = "True" if language.endswith(':forced') else "False"
            languages.append((language.split(":")[0], hi_, forced_))

        else:
            logging.info(f"BAZARR Search is throttled by adaptive search for this movie {movie['path']} and "
                         f"language: {language}")

    for result in generate_subtitles(path_mappings.path_replace_movie(movie['path']),
                                     languages,
                                     audio_language,
                                     str(movie['sceneName']),
                                     movie['title'], 'movie'):

        if result:
            message = result[0]
            path = result[1]
            forced = result[5]
            if result[8]:
                language_code = result[2] + ":hi"
            elif forced:
                language_code = result[2] + ":forced"
            else:
                language_code = result[2]
            provider = result[3]
            score = result[4]
            subs_id = result[6]
            subs_path = result[7]
            store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
            history_log_movie(1, movie['radarrId'], message, path, language_code, provider, score,
                              subs_id, subs_path)
            event_stream(type='movie-wanted', action='delete', payload=movie['radarrId'])
            send_notifications_movie(movie['radarrId'], message)
Exemple #15
0
    def patch(self):
        action = request.args.get('action')

        language = request.form.get('language')
        subtitles_path = request.form.get('path')
        media_type = request.form.get('type')
        id = request.form.get('id')

        if media_type == 'episode':
            subtitles_path = path_mappings.path_replace(subtitles_path)
            metadata = TableEpisodes.select(TableEpisodes.path, TableEpisodes.sonarrSeriesId)\
                .where(TableEpisodes.sonarrEpisodeId == id)\
                .dicts()\
                .get_or_none()

            if not metadata:
                return 'Episode not found', 500

            video_path = path_mappings.path_replace(metadata['path'])
        else:
            subtitles_path = path_mappings.path_replace_movie(subtitles_path)
            metadata = TableMovies.select(TableMovies.path).where(
                TableMovies.radarrId == id).dicts().get_or_none()

            if not metadata:
                return 'Movie not found', 500

            video_path = path_mappings.path_replace_movie(metadata['path'])

        if action == 'sync':
            subsync = SubSyncer()
            if media_type == 'episode':
                subsync.sync(video_path=video_path,
                             srt_path=subtitles_path,
                             srt_lang=language,
                             media_type='series',
                             sonarr_series_id=metadata['sonarrSeriesId'],
                             sonarr_episode_id=int(id))
            else:
                subsync.sync(video_path=video_path,
                             srt_path=subtitles_path,
                             srt_lang=language,
                             media_type='movies',
                             radarr_id=id)
            del subsync
            gc.collect()
        elif action == 'translate':
            dest_language = language
            forced = True if request.form.get('forced') == 'true' else False
            hi = True if request.form.get('hi') == 'true' else False
            result = translate_subtitles_file(video_path=video_path,
                                              source_srt_file=subtitles_path,
                                              to_lang=dest_language,
                                              forced=forced,
                                              hi=hi)
            if result:
                if media_type == 'episode':
                    store_subtitles(
                        path_mappings.path_replace_reverse(video_path),
                        video_path)
                else:
                    store_subtitles_movie(
                        path_mappings.path_replace_reverse_movie(video_path),
                        video_path)
                return '', 200
            else:
                return '', 404
        else:
            subtitles_apply_mods(language, subtitles_path, [action])

        # apply chmod if required
        chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(
            'win') and settings.general.getboolean('chmod_enabled') else None
        if chmod:
            os.chmod(subtitles_path, chmod)

        return '', 204
Exemple #16
0
def movies_download_subtitles(no):
    conditions = [(TableMovies.radarrId == no)]
    conditions += get_exclusion_clause('movie')
    movies = TableMovies.select(TableMovies.path,
                                TableMovies.missing_subtitles,
                                TableMovies.audio_language,
                                TableMovies.radarrId,
                                TableMovies.sceneName,
                                TableMovies.title,
                                TableMovies.tags,
                                TableMovies.monitored)\
        .where(reduce(operator.and_, conditions))\
        .dicts()
    if not len(movies):
        logging.debug(
            "BAZARR no movie with that radarrId can be found in database:",
            str(no))
        return
    else:
        movie = movies[0]

    if ast.literal_eval(movie['missing_subtitles']):
        count_movie = len(ast.literal_eval(movie['missing_subtitles']))
    else:
        count_movie = 0

    audio_language_list = get_audio_profile_languages(
        movie_id=movie['radarrId'])
    if len(audio_language_list) > 0:
        audio_language = audio_language_list[0]['name']
    else:
        audio_language = 'None'

    languages = []
    providers_list = None

    for i, language in enumerate(ast.literal_eval(movie['missing_subtitles'])):
        providers_list = get_providers()

        if language is not None:
            hi_ = "True" if language.endswith(':hi') else "False"
            forced_ = "True" if language.endswith(':forced') else "False"
            languages.append((language.split(":")[0], hi_, forced_))

        if providers_list:
            # confirm if language is still missing or if cutoff have been reached
            confirmed_missing_subs = TableMovies.select(TableMovies.missing_subtitles) \
                .where(TableMovies.radarrId == movie['radarrId']) \
                .dicts() \
                .get_or_none()
            if not confirmed_missing_subs:
                continue

            if language not in ast.literal_eval(
                    confirmed_missing_subs['missing_subtitles']):
                continue

            show_progress(id='movie_search_progress_{}'.format(no),
                          header='Searching missing subtitles...',
                          name=movie['title'],
                          value=i,
                          count=count_movie)

    if providers_list:
        for result in generate_subtitles(
                path_mappings.path_replace_movie(movie['path']), languages,
                audio_language, str(movie['sceneName']), movie['title'],
                'movie'):

            if result:
                message = result[0]
                path = result[1]
                forced = result[5]
                if result[8]:
                    language_code = result[2] + ":hi"
                elif forced:
                    language_code = result[2] + ":forced"
                else:
                    language_code = result[2]
                provider = result[3]
                score = result[4]
                subs_id = result[6]
                subs_path = result[7]
                store_subtitles_movie(
                    movie['path'],
                    path_mappings.path_replace_movie(movie['path']))
                history_log_movie(1, no, message, path, language_code,
                                  provider, score, subs_id, subs_path)
                send_notifications_movie(no, message)
    else:
        logging.info("BAZARR All providers are throttled")

    hide_progress(id='movie_search_progress_{}'.format(no))
Exemple #17
0
    def get(self):
        start = request.args.get('start') or 0
        length = request.args.get('length') or -1
        radarrid = request.args.get('radarrid')

        upgradable_movies = []
        upgradable_movies_not_perfect = []
        if settings.general.getboolean('upgrade_subs'):
            days_to_upgrade_subs = settings.general.days_to_upgrade_subs
            minimum_timestamp = (
                (datetime.datetime.now() -
                 timedelta(days=int(days_to_upgrade_subs))) -
                datetime.datetime(1970, 1, 1)).total_seconds()

            if settings.general.getboolean('upgrade_manual'):
                query_actions = [1, 2, 3, 6]
            else:
                query_actions = [1, 3]

            upgradable_movies_conditions = [
                (TableHistoryMovie.action.in_(query_actions)),
                (TableHistoryMovie.timestamp > minimum_timestamp),
                (TableHistoryMovie.score.is_null(False))
            ]
            upgradable_movies_conditions += get_exclusion_clause('movie')
            upgradable_movies = TableHistoryMovie.select(TableHistoryMovie.video_path,
                                                         fn.MAX(TableHistoryMovie.timestamp).alias('timestamp'),
                                                         TableHistoryMovie.score,
                                                         TableMovies.tags,
                                                         TableMovies.monitored)\
                .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
                .where(reduce(operator.and_, upgradable_movies_conditions))\
                .group_by(TableHistoryMovie.video_path)\
                .dicts()
            upgradable_movies = list(upgradable_movies)

            for upgradable_movie in upgradable_movies:
                if upgradable_movie['timestamp'] > minimum_timestamp:
                    try:
                        int(upgradable_movie['score'])
                    except ValueError:
                        pass
                    else:
                        if int(upgradable_movie['score']) < 120:
                            upgradable_movies_not_perfect.append(
                                upgradable_movie)

        query_conditions = [(TableMovies.title.is_null(False))]
        if radarrid:
            query_conditions.append((TableMovies.radarrId == radarrid))
        query_condition = reduce(operator.and_, query_conditions)

        movie_history = TableHistoryMovie.select(TableHistoryMovie.id,
                                                 TableHistoryMovie.action,
                                                 TableMovies.title,
                                                 TableHistoryMovie.timestamp,
                                                 TableHistoryMovie.description,
                                                 TableHistoryMovie.radarrId,
                                                 TableMovies.monitored,
                                                 TableHistoryMovie.video_path.alias('path'),
                                                 TableHistoryMovie.language,
                                                 TableMovies.tags,
                                                 TableHistoryMovie.score,
                                                 TableHistoryMovie.subs_id,
                                                 TableHistoryMovie.provider,
                                                 TableHistoryMovie.subtitles_path)\
            .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
            .where(query_condition)\
            .order_by(TableHistoryMovie.timestamp.desc())\
            .limit(length)\
            .offset(start)\
            .dicts()
        movie_history = list(movie_history)

        blacklist_db = TableBlacklistMovie.select(
            TableBlacklistMovie.provider, TableBlacklistMovie.subs_id).dicts()
        blacklist_db = list(blacklist_db)

        for item in movie_history:
            # Mark movies as upgradable or not
            item.update({"upgradable": False})
            if {
                    "video_path": str(item['path']),
                    "timestamp": float(item['timestamp']),
                    "score": str(item['score']),
                    "tags": str(item['tags']),
                    "monitored": str(item['monitored'])
            } in upgradable_movies_not_perfect:  # noqa: E129
                if os.path.isfile(
                        path_mappings.path_replace_movie(
                            item['subtitles_path'])):
                    item.update({"upgradable": True})

            del item['path']

            postprocessMovie(item)

            if item['score']:
                item['score'] = str(round(
                    (int(item['score']) * 100 / 120), 2)) + "%"

            # Make timestamp pretty
            if item['timestamp']:
                item["raw_timestamp"] = int(item['timestamp'])
                item["parsed_timestamp"] = datetime.datetime.fromtimestamp(
                    int(item['timestamp'])).strftime('%x %X')
                item['timestamp'] = pretty.date(item["raw_timestamp"])

            # Check if subtitles is blacklisted
            item.update({"blacklisted": False})
            if item['action'] not in [0, 4, 5]:
                for blacklisted_item in blacklist_db:
                    if blacklisted_item['provider'] == item[
                            'provider'] and blacklisted_item[
                                'subs_id'] == item['subs_id']:  # noqa: E125
                        item.update({"blacklisted": True})
                        break

        count = TableHistoryMovie.select()\
            .join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
            .where(TableMovies.title.is_null(False))\
            .count()

        return jsonify(data=movie_history, total=count)
Exemple #18
0
    def post(self):
        # Upload
        # TODO: Support Multiply Upload
        radarrId = request.args.get('radarrid')
        movieInfo = TableMovies.select(TableMovies.title,
                                       TableMovies.path,
                                       TableMovies.sceneName,
                                       TableMovies.audio_language) \
            .where(TableMovies.radarrId == radarrId) \
            .dicts() \
            .get_or_none()

        if not movieInfo:
            return 'Movie not found', 500

        moviePath = path_mappings.path_replace_movie(movieInfo['path'])
        sceneName = movieInfo['sceneName'] or 'None'

        title = movieInfo['title']
        audioLanguage = movieInfo['audio_language']

        language = request.form.get('language')
        forced = True if request.form.get('forced') == 'true' else False
        hi = True if request.form.get('hi') == 'true' else False
        subFile = request.files.get('file')

        _, ext = os.path.splitext(subFile.filename)

        if ext not in SUBTITLE_EXTENSIONS:
            raise ValueError('A subtitle of an invalid format was uploaded.')

        try:
            result = manual_upload_subtitle(path=moviePath,
                                            language=language,
                                            forced=forced,
                                            hi=hi,
                                            title=title,
                                            scene_name=sceneName,
                                            media_type='movie',
                                            subtitle=subFile,
                                            audio_language=audioLanguage)

            if not result:
                logging.debug(
                    f"BAZARR unable to process subtitles for this movie: {moviePath}"
                )
            else:
                message = result[0]
                path = result[1]
                subs_path = result[2]
                if hi:
                    language_code = language + ":hi"
                elif forced:
                    language_code = language + ":forced"
                else:
                    language_code = language
                provider = "manual"
                score = 120
                history_log_movie(4,
                                  radarrId,
                                  message,
                                  path,
                                  language_code,
                                  provider,
                                  score,
                                  subtitles_path=subs_path)
                if not settings.general.getboolean(
                        'dont_notify_manual_actions'):
                    send_notifications_movie(radarrId, message)
                store_subtitles_movie(path, moviePath)
        except OSError:
            pass

        return '', 204
Exemple #19
0
    def patch(self):
        # Download
        radarrId = request.args.get('radarrid')

        movieInfo = TableMovies.select(TableMovies.title,
                                       TableMovies.path,
                                       TableMovies.sceneName,
                                       TableMovies.audio_language)\
            .where(TableMovies.radarrId == radarrId)\
            .dicts()\
            .get_or_none()

        if not movieInfo:
            return 'Movie not found', 500

        moviePath = path_mappings.path_replace_movie(movieInfo['path'])
        sceneName = movieInfo['sceneName'] or 'None'

        title = movieInfo['title']
        audio_language = movieInfo['audio_language']

        language = request.form.get('language')
        hi = request.form.get('hi').capitalize()
        forced = request.form.get('forced').capitalize()

        audio_language_list = get_audio_profile_languages(movie_id=radarrId)
        if len(audio_language_list) > 0:
            audio_language = audio_language_list[0]['name']
        else:
            audio_language = None

        try:
            result = list(
                generate_subtitles(
                    moviePath, [(language, hi, forced)],
                    audio_language,
                    sceneName,
                    title,
                    'movie',
                    profile_id=get_profile_id(movie_id=radarrId)))
            if result:
                result = result[0]
                message = result[0]
                path = result[1]
                forced = result[5]
                if result[8]:
                    language_code = result[2] + ":hi"
                elif forced:
                    language_code = result[2] + ":forced"
                else:
                    language_code = result[2]
                provider = result[3]
                score = result[4]
                subs_id = result[6]
                subs_path = result[7]
                history_log_movie(1, radarrId, message, path, language_code,
                                  provider, score, subs_id, subs_path)
                send_notifications_movie(radarrId, message)
                store_subtitles_movie(path, moviePath)
            else:
                event_stream(type='movie', payload=radarrId)
        except OSError:
            pass

        return '', 204
Exemple #20
0
def update_one_movie(movie_id, action):
    logging.debug(
        'BAZARR syncing this specific movie from Radarr: {}'.format(movie_id))

    # Check if there's a row in database for this movie ID
    existing_movie = TableMovies.select(TableMovies.path)\
        .where(TableMovies.radarrId == movie_id)\
        .dicts()\
        .get_or_none()

    # Remove movie from DB
    if action == 'deleted':
        if existing_movie:
            try:
                TableMovies.delete().where(
                    TableMovies.radarrId == movie_id).execute()
            except Exception as e:
                logging.error(
                    f"BAZARR cannot delete movie {existing_movie['path']} because of {e}"
                )
            else:
                event_stream(type='movie',
                             action='delete',
                             payload=int(movie_id))
                logging.debug(
                    'BAZARR deleted this movie from the database:{}'.format(
                        path_mappings.path_replace_movie(
                            existing_movie['path'])))
        return

    movie_default_enabled = settings.general.getboolean(
        'movie_default_enabled')

    if movie_default_enabled is True:
        movie_default_profile = settings.general.movie_default_profile
        if movie_default_profile == '':
            movie_default_profile = None
    else:
        movie_default_profile = None

    audio_profiles = get_profile_list()
    tagsDict = get_tags()

    try:
        # Get movie data from radarr api
        movie = None
        movie_data = get_movies_from_radarr_api(
            url=url_radarr(),
            apikey_radarr=settings.radarr.apikey,
            radarr_id=movie_id)
        if not movie_data:
            return
        else:
            if action == 'updated' and existing_movie:
                movie = movieParser(
                    movie_data,
                    action='update',
                    tags_dict=tagsDict,
                    movie_default_profile=movie_default_profile,
                    audio_profiles=audio_profiles)
            elif action == 'updated' and not existing_movie:
                movie = movieParser(
                    movie_data,
                    action='insert',
                    tags_dict=tagsDict,
                    movie_default_profile=movie_default_profile,
                    audio_profiles=audio_profiles)
    except Exception:
        logging.debug(
            'BAZARR cannot get movie returned by SignalR feed from Radarr API.'
        )
        return

    # Drop useless events
    if not movie and not existing_movie:
        return

    # Remove movie from DB
    if not movie and existing_movie:
        try:
            TableMovies.delete().where(
                TableMovies.radarrId == movie_id).execute()
        except Exception as e:
            logging.error(
                f"BAZARR cannot insert episode {existing_movie['path']} because of {e}"
            )
        else:
            event_stream(type='movie', action='delete', payload=int(movie_id))
            logging.debug(
                'BAZARR deleted this movie from the database:{}'.format(
                    path_mappings.path_replace_movie(existing_movie['path'])))
            return

    # Update existing movie in DB
    elif movie and existing_movie:
        try:
            TableMovies.update(movie).where(
                TableMovies.radarrId == movie['radarrId']).execute()
        except IntegrityError as e:
            logging.error(
                f"BAZARR cannot insert episode {movie['path']} because of {e}")
        else:
            event_stream(type='movie', action='update', payload=int(movie_id))
            logging.debug(
                'BAZARR updated this movie into the database:{}'.format(
                    path_mappings.path_replace_movie(movie['path'])))

    # Insert new movie in DB
    elif movie and not existing_movie:
        try:
            TableMovies.insert(movie).on_conflict(action='IGNORE').execute()
        except IntegrityError as e:
            logging.error(
                f"BAZARR cannot insert movie {movie['path']} because of {e}")
        else:
            event_stream(type='movie', action='update', payload=int(movie_id))
            logging.debug(
                'BAZARR inserted this movie into the database:{}'.format(
                    path_mappings.path_replace_movie(movie['path'])))

    # Storing existing subtitles
    logging.debug('BAZARR storing subtitles for this movie: {}'.format(
        path_mappings.path_replace_movie(movie['path'])))
    store_subtitles_movie(movie['path'],
                          path_mappings.path_replace_movie(movie['path']))

    # Downloading missing subtitles
    logging.debug(
        'BAZARR downloading missing subtitles for this movie: {}'.format(
            path_mappings.path_replace_movie(movie['path'])))
    movies_download_subtitles(movie_id)
Exemple #21
0
def update_movies():
    logging.debug('BAZARR Starting movie sync from Radarr.')
    apikey_radarr = settings.radarr.apikey

    radarr_version = get_radarr_version()
    movie_default_enabled = settings.general.getboolean(
        'movie_default_enabled')

    if movie_default_enabled is True:
        movie_default_language = settings.general.movie_default_language
        movie_default_hi = settings.general.movie_default_hi
        movie_default_forced = settings.general.movie_default_forced
    else:
        movie_default_language = '[]'
        movie_default_hi = 'False'
        movie_default_forced = 'False'

    if apikey_radarr is None:
        pass
    else:
        audio_profiles = get_profile_list()
        tagsDict = get_tags()

        # Get movies data from radarr
        if radarr_version.startswith('0'):
            url_radarr_api_movies = url_radarr(
            ) + "/api/movie?apikey=" + apikey_radarr
        else:
            url_radarr_api_movies = url_radarr(
            ) + "/api/v3/movie?apikey=" + apikey_radarr

        try:
            r = requests.get(url_radarr_api_movies, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception(
                "BAZARR Error trying to get movies from Radarr. Http error.")
            return
        except requests.exceptions.ConnectionError as errc:
            logging.exception(
                "BAZARR Error trying to get movies from Radarr. Connection Error."
            )
            return
        except requests.exceptions.Timeout as errt:
            logging.exception(
                "BAZARR Error trying to get movies from Radarr. Timeout Error."
            )
            return
        except requests.exceptions.RequestException as err:
            logging.exception("BAZARR Error trying to get movies from Radarr.")
            return
        else:
            # Get current movies in DB
            current_movies_db = database.execute(
                "SELECT tmdbId, path, radarrId FROM table_movies")

            current_movies_db_list = [x['tmdbId'] for x in current_movies_db]

            current_movies_radarr = []
            movies_to_update = []
            movies_to_add = []
            altered_movies = []

            moviesIdListLength = len(r.json())
            for i, movie in enumerate(r.json(), 1):
                if movie['hasFile'] is True:
                    if 'movieFile' in movie:
                        # Detect file separator
                        if movie['path'][0] == "/":
                            separator = "/"
                        else:
                            separator = "\\"

                        if movie["path"] != None and movie['movieFile'][
                                'relativePath'] != None:
                            try:
                                overview = str(movie['overview'])
                            except:
                                overview = ""
                            try:
                                poster_big = movie['images'][0]['url']
                                poster = os.path.splitext(
                                    poster_big)[0] + '-500' + os.path.splitext(
                                        poster_big)[1]
                            except:
                                poster = ""
                            try:
                                fanart = movie['images'][1]['url']
                            except:
                                fanart = ""

                            if 'sceneName' in movie['movieFile']:
                                sceneName = movie['movieFile']['sceneName']
                            else:
                                sceneName = None

                            alternativeTitles = None
                            if radarr_version.startswith('0'):
                                if 'alternativeTitles' in movie:
                                    alternativeTitles = str([
                                        item['title']
                                        for item in movie['alternativeTitles']
                                    ])
                            else:
                                if 'alternateTitles' in movie:
                                    alternativeTitles = str([
                                        item['title']
                                        for item in movie['alternateTitles']
                                    ])

                            if 'imdbId' in movie: imdbId = movie['imdbId']
                            else: imdbId = None

                            try:
                                format, resolution = movie['movieFile'][
                                    'quality']['quality']['name'].split('-')
                            except:
                                format = movie['movieFile']['quality'][
                                    'quality']['name']
                                try:
                                    resolution = str(
                                        movie['movieFile']['quality']
                                        ['quality']['resolution']) + 'p'
                                except:
                                    resolution = None

                            if 'mediaInfo' in movie['movieFile']:
                                videoFormat = videoCodecID = videoProfile = videoCodecLibrary = None
                                if radarr_version.startswith('0'):
                                    if 'videoFormat' in movie['movieFile'][
                                            'mediaInfo']:
                                        videoFormat = movie['movieFile'][
                                            'mediaInfo']['videoFormat']
                                else:
                                    if 'videoCodec' in movie['movieFile'][
                                            'mediaInfo']:
                                        videoFormat = movie['movieFile'][
                                            'mediaInfo']['videoCodec']
                                if 'videoCodecID' in movie['movieFile'][
                                        'mediaInfo']:
                                    videoCodecID = movie['movieFile'][
                                        'mediaInfo']['videoCodecID']
                                if 'videoProfile' in movie['movieFile'][
                                        'mediaInfo']:
                                    videoProfile = movie['movieFile'][
                                        'mediaInfo']['videoProfile']
                                if 'videoCodecLibrary' in movie['movieFile'][
                                        'mediaInfo']:
                                    videoCodecLibrary = movie['movieFile'][
                                        'mediaInfo']['videoCodecLibrary']
                                videoCodec = RadarrFormatVideoCodec(
                                    videoFormat, videoCodecID,
                                    videoCodecLibrary)

                                audioFormat = audioCodecID = audioProfile = audioAdditionalFeatures = None
                                if radarr_version.startswith('0'):
                                    if 'audioFormat' in movie['movieFile'][
                                            'mediaInfo']:
                                        audioFormat = movie['movieFile'][
                                            'mediaInfo']['audioFormat']
                                else:
                                    if 'audioCodec' in movie['movieFile'][
                                            'mediaInfo']:
                                        audioFormat = movie['movieFile'][
                                            'mediaInfo']['audioCodec']
                                if 'audioCodecID' in movie['movieFile'][
                                        'mediaInfo']:
                                    audioCodecID = movie['movieFile'][
                                        'mediaInfo']['audioCodecID']
                                if 'audioProfile' in movie['movieFile'][
                                        'mediaInfo']:
                                    audioProfile = movie['movieFile'][
                                        'mediaInfo']['audioProfile']
                                if 'audioAdditionalFeatures' in movie[
                                        'movieFile']['mediaInfo']:
                                    audioAdditionalFeatures = movie[
                                        'movieFile']['mediaInfo'][
                                            'audioAdditionalFeatures']
                                audioCodec = RadarrFormatAudioCodec(
                                    audioFormat, audioCodecID, audioProfile,
                                    audioAdditionalFeatures)
                            else:
                                videoCodec = None
                                audioCodec = None

                            audio_language = None
                            if radarr_version.startswith('0'):
                                if 'mediaInfo' in movie['movieFile']:
                                    if 'audioLanguages' in movie['movieFile'][
                                            'mediaInfo']:
                                        audio_language_list = movie[
                                            'movieFile']['mediaInfo'][
                                                'audioLanguages'].split('/')
                                        if len(audio_language_list):
                                            audio_language = audio_language_list[
                                                0].strip()
                                if not audio_language:
                                    audio_language = profile_id_to_language(
                                        movie['qualityProfileId'],
                                        audio_profiles)
                            else:
                                if 'languages' in movie['movieFile'] and len(
                                        movie['movieFile']['languages']):
                                    for item in movie['movieFile'][
                                            'languages']:
                                        if isinstance(item, dict):
                                            if 'name' in item:
                                                audio_language = item['name']
                                                break

                            tags = [
                                d['label'] for d in tagsDict
                                if d['id'] in movie['tags']
                            ]

                            # Add movies in radarr to current movies list
                            current_movies_radarr.append(str(movie['tmdbId']))

                            if str(movie['tmdbId']) in current_movies_db_list:
                                movies_to_update.append({
                                    'radarrId':
                                    int(movie["id"]),
                                    'title':
                                    movie["title"],
                                    'path':
                                    movie["path"] + separator +
                                    movie['movieFile']['relativePath'],
                                    'tmdbId':
                                    str(movie["tmdbId"]),
                                    'poster':
                                    poster,
                                    'fanart':
                                    fanart,
                                    'audio_language':
                                    audio_language,
                                    'sceneName':
                                    sceneName,
                                    'monitored':
                                    str(bool(movie['monitored'])),
                                    'year':
                                    str(movie['year']),
                                    'sortTitle':
                                    movie['sortTitle'],
                                    'alternativeTitles':
                                    alternativeTitles,
                                    'format':
                                    format,
                                    'resolution':
                                    resolution,
                                    'video_codec':
                                    videoCodec,
                                    'audio_codec':
                                    audioCodec,
                                    'overview':
                                    overview,
                                    'imdbId':
                                    imdbId,
                                    'movie_file_id':
                                    int(movie['movieFile']['id']),
                                    'tags':
                                    str(tags)
                                })
                            else:
                                movies_to_add.append({
                                    'radarrId':
                                    int(movie["id"]),
                                    'title':
                                    movie["title"],
                                    'path':
                                    movie["path"] + separator +
                                    movie['movieFile']['relativePath'],
                                    'tmdbId':
                                    str(movie["tmdbId"]),
                                    'languages':
                                    movie_default_language,
                                    'subtitles':
                                    '[]',
                                    'hearing_impaired':
                                    movie_default_hi,
                                    'overview':
                                    overview,
                                    'poster':
                                    poster,
                                    'fanart':
                                    fanart,
                                    'audio_language':
                                    audio_language,
                                    'sceneName':
                                    sceneName,
                                    'monitored':
                                    str(bool(movie['monitored'])),
                                    'sortTitle':
                                    movie['sortTitle'],
                                    'year':
                                    str(movie['year']),
                                    'alternativeTitles':
                                    alternativeTitles,
                                    'format':
                                    format,
                                    'resolution':
                                    resolution,
                                    'video_codec':
                                    videoCodec,
                                    'audio_codec':
                                    audioCodec,
                                    'imdbId':
                                    imdbId,
                                    'forced':
                                    movie_default_forced,
                                    'movie_file_id':
                                    int(movie['movieFile']['id']),
                                    'tags':
                                    str(tags)
                                })
                        else:
                            logging.error(
                                'BAZARR Radarr returned a movie without a file path: '
                                + movie["path"] + separator +
                                movie['movieFile']['relativePath'])

            # Remove old movies from DB
            removed_movies = list(
                set(current_movies_db_list) - set(current_movies_radarr))

            for removed_movie in removed_movies:
                database.execute("DELETE FROM table_movies WHERE tmdbId=?",
                                 (removed_movie, ))

            # Update movies in DB
            movies_in_db_list = []
            movies_in_db = database.execute(
                "SELECT radarrId, title, path, tmdbId, overview, poster, fanart, "
                "audio_language, sceneName, monitored, sortTitle, year, "
                "alternativeTitles, format, resolution, video_codec, audio_codec, imdbId,"
                "movie_file_id, tags FROM table_movies")

            for item in movies_in_db:
                movies_in_db_list.append(item)

            movies_to_update_list = [
                i for i in movies_to_update if i not in movies_in_db_list
            ]

            for updated_movie in movies_to_update_list:
                query = dict_converter.convert(updated_movie)
                database.execute(
                    '''UPDATE table_movies SET ''' + query.keys_update +
                    ''' WHERE tmdbId = ?''',
                    query.values + (updated_movie['tmdbId'], ))
                altered_movies.append([
                    updated_movie['tmdbId'], updated_movie['path'],
                    updated_movie['radarrId'], updated_movie['monitored']
                ])

            # Insert new movies in DB
            for added_movie in movies_to_add:
                query = dict_converter.convert(added_movie)
                result = database.execute(
                    '''INSERT OR IGNORE INTO table_movies(''' +
                    query.keys_insert + ''') VALUES(''' +
                    query.question_marks + ''')''', query.values)
                if result > 0:
                    altered_movies.append([
                        added_movie['tmdbId'], added_movie['path'],
                        added_movie['radarrId'], added_movie['monitored']
                    ])
                else:
                    logging.debug(
                        'BAZARR unable to insert this movie into the database:',
                        path_mappings.path_replace_movie(added_movie['path']))

            # Store subtitles for added or modified movies
            for i, altered_movie in enumerate(altered_movies, 1):
                store_subtitles_movie(
                    altered_movie[1],
                    path_mappings.path_replace_movie(altered_movie[1]))

            logging.debug(
                'BAZARR All movies synced from Radarr into database.')

            # Search for desired subtitles if no more than 5 movies have been added.
            if len(altered_movies) <= 5:
                logging.debug(
                    "BAZARR No more than 5 movies were added during this sync then we'll search for subtitles."
                )
                for altered_movie in altered_movies:
                    data = database.execute(
                        "SELECT * FROM table_movies WHERE radarrId = ?" +
                        get_exclusion_clause('movie'), (altered_movie[2], ),
                        only_one=True)
                    if data:
                        movies_download_subtitles(data['radarrId'])
                    else:
                        logging.debug(
                            "BAZARR skipping download for this movie as it is excluded."
                        )
            else:
                logging.debug(
                    "BAZARR More than 5 movies were added during this sync then we wont search for subtitles."
                )
Exemple #22
0
def update_movies(send_event=True):
    check_radarr_rootfolder()
    logging.debug('BAZARR Starting movie sync from Radarr.')
    apikey_radarr = settings.radarr.apikey

    movie_default_enabled = settings.general.getboolean(
        'movie_default_enabled')

    if movie_default_enabled is True:
        movie_default_profile = settings.general.movie_default_profile
        if movie_default_profile == '':
            movie_default_profile = None
    else:
        movie_default_profile = None

    if apikey_radarr is None:
        pass
    else:
        audio_profiles = get_profile_list()
        tagsDict = get_tags()

        # Get movies data from radarr
        movies = get_movies_from_radarr_api(url=url_radarr(),
                                            apikey_radarr=apikey_radarr)
        if not movies:
            return
        else:
            # Get current movies in DB
            current_movies_db = TableMovies.select(
                TableMovies.tmdbId, TableMovies.path,
                TableMovies.radarrId).dicts()

            current_movies_db_list = [x['tmdbId'] for x in current_movies_db]

            current_movies_radarr = []
            movies_to_update = []
            movies_to_add = []
            altered_movies = []

            # Build new and updated movies
            movies_count = len(movies)
            for i, movie in enumerate(movies):
                if send_event:
                    show_progress(id='movies_progress',
                                  header='Syncing movies...',
                                  name=movie['title'],
                                  value=i,
                                  count=movies_count)

                if movie['hasFile'] is True:
                    if 'movieFile' in movie:
                        if movie['movieFile']['size'] > 20480:
                            # Add movies in radarr to current movies list
                            current_movies_radarr.append(str(movie['tmdbId']))

                            if str(movie['tmdbId']) in current_movies_db_list:
                                movies_to_update.append(
                                    movieParser(movie,
                                                action='update',
                                                tags_dict=tagsDict,
                                                movie_default_profile=
                                                movie_default_profile,
                                                audio_profiles=audio_profiles))
                            else:
                                movies_to_add.append(
                                    movieParser(movie,
                                                action='insert',
                                                tags_dict=tagsDict,
                                                movie_default_profile=
                                                movie_default_profile,
                                                audio_profiles=audio_profiles))

            if send_event:
                hide_progress(id='movies_progress')

            # Remove old movies from DB
            removed_movies = list(
                set(current_movies_db_list) - set(current_movies_radarr))

            for removed_movie in removed_movies:
                try:
                    TableMovies.delete().where(
                        TableMovies.tmdbId == removed_movie).execute()
                except Exception as e:
                    logging.error(
                        f"BAZARR cannot remove movie tmdbId {removed_movie} because of {e}"
                    )
                    continue

            # Update movies in DB
            movies_in_db_list = []
            movies_in_db = TableMovies.select(
                TableMovies.radarrId, TableMovies.title, TableMovies.path,
                TableMovies.tmdbId, TableMovies.overview, TableMovies.poster,
                TableMovies.fanart, TableMovies.audio_language,
                TableMovies.sceneName, TableMovies.monitored,
                TableMovies.sortTitle, TableMovies.year,
                TableMovies.alternativeTitles, TableMovies.format,
                TableMovies.resolution, TableMovies.video_codec,
                TableMovies.audio_codec, TableMovies.imdbId,
                TableMovies.movie_file_id, TableMovies.tags,
                TableMovies.file_size).dicts()

            for item in movies_in_db:
                movies_in_db_list.append(item)

            movies_to_update_list = [
                i for i in movies_to_update if i not in movies_in_db_list
            ]

            for updated_movie in movies_to_update_list:
                try:
                    TableMovies.update(updated_movie).where(
                        TableMovies.tmdbId ==
                        updated_movie['tmdbId']).execute()
                except IntegrityError as e:
                    logging.error(
                        f"BAZARR cannot update movie {updated_movie['path']} because of {e}"
                    )
                    continue
                else:
                    altered_movies.append([
                        updated_movie['tmdbId'], updated_movie['path'],
                        updated_movie['radarrId'], updated_movie['monitored']
                    ])

            # Insert new movies in DB
            for added_movie in movies_to_add:
                try:
                    result = TableMovies.insert(added_movie).on_conflict(
                        action='IGNORE').execute()
                except IntegrityError as e:
                    logging.error(
                        f"BAZARR cannot insert movie {added_movie['path']} because of {e}"
                    )
                    continue
                else:
                    if result > 0:
                        altered_movies.append([
                            added_movie['tmdbId'], added_movie['path'],
                            added_movie['radarrId'], added_movie['monitored']
                        ])
                        if send_event:
                            event_stream(type='movie',
                                         action='update',
                                         payload=int(added_movie['radarrId']))
                    else:
                        logging.debug(
                            'BAZARR unable to insert this movie into the database:',
                            path_mappings.path_replace_movie(
                                added_movie['path']))

            # Store subtitles for added or modified movies
            for i, altered_movie in enumerate(altered_movies, 1):
                store_subtitles_movie(
                    altered_movie[1],
                    path_mappings.path_replace_movie(altered_movie[1]))

            logging.debug(
                'BAZARR All movies synced from Radarr into database.')