示例#1
0
def update_from_source():
    tar_download_url = 'https://github.com/morpheus65535/bazarr/tarball/{}'.format(settings.general.branch)
    update_dir = os.path.join(os.path.dirname(__file__), '..', 'update')
    
    logging.info('BAZARR Downloading update from: ' + tar_download_url)
    notifications.write(msg='Downloading update from: ' + tar_download_url, queue='check_update')
    data = request_content(tar_download_url)
    
    if not data:
        logging.error("BAZARR Unable to retrieve new version from '%s', can't update", tar_download_url)
        notifications.write(msg=("Unable to retrieve new version from '%s', can't update", tar_download_url),
                            type='error', queue='check_update')
        return
    
    download_name = settings.general.branch + '-github'
    tar_download_path = os.path.join(os.path.dirname(__file__), '..', download_name)
    
    # Save tar to disk
    with open(tar_download_path, 'wb') as f:
        f.write(data)
    
    # Extract the tar to update folder
    logging.info('BAZARR Extracting file: ' + tar_download_path)
    notifications.write(msg='Extracting file: ' + tar_download_path, queue='check_update')
    tar = tarfile.open(tar_download_path)
    tar.extractall(update_dir)
    tar.close()
    
    # Delete the tar.gz
    logging.info('BAZARR Deleting file: ' + tar_download_path)
    notifications.write(msg='Deleting file: ' + tar_download_path, queue='check_update')
    os.remove(tar_download_path)
    
    # Find update dir name
    update_dir_contents = [x for x in os.listdir(update_dir) if os.path.isdir(os.path.join(update_dir, x))]
    if len(update_dir_contents) != 1:
        logging.error("BAZARR Invalid update data, update failed: " + str(update_dir_contents))
        notifications.write(msg="BAZARR Invalid update data, update failed: " + str(update_dir_contents),
                            type='error', queue='check_update')
        return
    
    content_dir = os.path.join(update_dir, update_dir_contents[0])
    
    # walk temp folder and move files to main folder
    for dirname, dirnames, filenames in os.walk(content_dir):
        dirname = dirname[len(content_dir) + 1:]
        for curfile in filenames:
            old_path = os.path.join(content_dir, dirname, curfile)
            new_path = os.path.join(os.path.dirname(__file__), '..', dirname, curfile)
            
            if os.path.isfile(new_path):
                os.remove(new_path)
            os.renames(old_path, new_path)
    updated()
示例#2
0
def movies_full_scan_subtitles():
    movies = database.execute("SELECT path FROM table_movies")
    count_movies = len(movies)

    for i, movie in enumerate(movies, 1):
        notifications.write(msg='Updating all movies subtitles from disk...',
                            queue='list_subtitles_movies',
                            item=i,
                            length=count_movies)
        store_subtitles_movie(movie['path'], path_replace_movie(movie['path']))

    gc.collect()
示例#3
0
def series_full_scan_subtitles():
    episodes = TableEpisodes.select(TableEpisodes.path)
    count_episodes = episodes.count()

    for i, episode in enumerate(episodes, 1):
        notifications.write(msg='Updating all episodes subtitles from disk...',
                            queue='list_subtitles_series',
                            item=i,
                            length=count_episodes)
        store_subtitles(path_replace(episode.path))

    gc.collect()
示例#4
0
def movies_full_scan_subtitles():
    movies = TableMovies.select(TableMovies.path)
    count_movies = movies.count()

    for i, movie in enumerate(movies, 1):
        notifications.write(msg='Updating all movies subtitles from disk...',
                            queue='list_subtitles_movies',
                            item=i,
                            length=count_movies)
        store_subtitles_movie(path_replace_movie(movie.path))

    gc.collect()
示例#5
0
def series_download_subtitles(no):
    if settings.sonarr.getboolean('only_monitored'):
        monitored_only_query_string = ' AND monitored = "True"'
    else:
        monitored_only_query_string = ""

    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                              timeout=30)
    c_db = conn_db.cursor()
    episodes_details = c_db.execute(
        'SELECT path, missing_subtitles, sonarrEpisodeId, scene_name FROM table_episodes WHERE sonarrSeriesId = ? AND missing_subtitles != "[]"'
        + monitored_only_query_string, (no, )).fetchall()
    series_details = c_db.execute(
        "SELECT hearing_impaired, title FROM table_shows WHERE sonarrSeriesId = ?",
        (no, )).fetchone()
    c_db.close()

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    count_episodes_details = len(episodes_details)

    for i, episode in enumerate(episodes_details, 1):
        for language in ast.literal_eval(episode[1]):
            if language is not None:
                notifications.write(msg='Searching for series subtitles...',
                                    queue='get_subtitle',
                                    item=i,
                                    length=count_episodes_details)
                result = download_subtitle(path_replace(episode[0]),
                                           str(alpha3_from_alpha2(language)),
                                           series_details[0],
                                           providers_list, providers_auth,
                                           str(episode[3]), series_details[1],
                                           'series')
                if result is not None:
                    message = result[0]
                    path = result[1]
                    language_code = result[2]
                    provider = result[3]
                    score = result[4]
                    store_subtitles(path_replace(episode[0]))
                    history_log(1, no, episode[2], message, path,
                                language_code, provider, score)
                    send_notifications(no, episode[2], message)
    list_missing_subtitles(no)

    if count_episodes_details:
        notifications.write(msg='Searching completed. Please reload the page.',
                            type='success',
                            duration='permanent',
                            button='refresh',
                            queue='get_subtitle')
示例#6
0
def series_full_scan_subtitles():
    episodes = database.execute("SELECT path FROM table_episodes")
    count_episodes = len(episodes)

    for i, episode in enumerate(episodes, 1):
        notifications.write(msg='Updating all episodes subtitles from disk...',
                            queue='list_subtitles_series',
                            item=i,
                            length=count_episodes)
        store_subtitles(path_replace(episode['path']))

    gc.collect()
示例#7
0
def movies_full_scan_subtitles():
    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
    c_db = conn_db.cursor()
    movies = c_db.execute("SELECT path FROM table_movies").fetchall()
    c_db.close()
    count_movies = len(movies)
    
    for i, movie in enumerate(movies, 1):
        notifications.write(msg='Updating all movies subtitles from disk...',
                            queue='list_subtitles_movies', item=i, length=count_movies)
        store_subtitles_movie(path_replace_movie(movie[0]))
    
    gc.collect()
示例#8
0
def episode_download_subtitles(no):
    if settings.sonarr.getboolean('only_monitored'):
        monitored_only_query_string = ' AND monitored = "True"'
    else:
        monitored_only_query_string = ""

    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                              timeout=30)
    c_db = conn_db.cursor()
    episodes_details = c_db.execute(
        'SELECT table_episodes.path, table_episodes.missing_subtitles, table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.sonarrEpisodeId = ?'
        + monitored_only_query_string, (no, )).fetchall()
    c_db.close()

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    for episode in episodes_details:
        for language in ast.literal_eval(episode[1]):
            if language is not None:
                notifications.write(msg='Searching for ' +
                                    str(language_from_alpha2(language)) +
                                    ' subtitles for this episode: ' +
                                    path_replace(episode[0]),
                                    queue='get_subtitle')
                result = download_subtitle(path_replace(episode[0]),
                                           str(alpha3_from_alpha2(language)),
                                           episode[4],
                                           providers_list, providers_auth,
                                           str(episode[3]), episode[5],
                                           'series')
                if result is not None:
                    message = result[0]
                    path = result[1]
                    language_code = result[2]
                    provider = result[3]
                    score = result[4]
                    store_subtitles(path_replace(episode[0]))
                    history_log(1, episode[6], episode[2], message, path,
                                language_code, provider, score)
                    send_notifications(episode[6], episode[2], message)

        list_missing_subtitles(episode[6])
示例#9
0
def movies_download_subtitles(no):
    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                              timeout=30)
    c_db = conn_db.cursor()
    movie = c_db.execute(
        "SELECT path, missing_subtitles, radarrId, sceneName, hearing_impaired, title FROM table_movies WHERE radarrId = ?",
        (no, )).fetchone()
    c_db.close()

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    count_movie = len(ast.literal_eval(movie[1]))

    for i, language in enumerate(ast.literal_eval(movie[1]), 1):
        if language is not None:
            notifications.write(msg='Searching for movies subtitles',
                                queue='get_subtitle',
                                item=i,
                                length=count_movie)
            result = download_subtitle(path_replace_movie(movie[0]),
                                       str(alpha3_from_alpha2(language)),
                                       movie[4],
                                       providers_list, providers_auth,
                                       str(movie[3]), movie[5], 'movie')
            if result is not None:
                message = result[0]
                path = result[1]
                language_code = result[2]
                provider = result[3]
                score = result[4]
                store_subtitles_movie(path_replace_movie(movie[0]))
                history_log_movie(1, no, message, path, language_code,
                                  provider, score)
                send_notifications_movie(no, message)
    list_missing_subtitles_movies(no)

    if count_movie:
        notifications.write(msg='Searching completed. Please reload the page.',
                            type='success',
                            duration='permanent',
                            button='refresh',
                            queue='get_subtitle')
示例#10
0
def check_and_apply_update():
    check_releases()
    if not args.release_update:
        gitconfig()
        branch = settings.general.branch
        g = git.cmd.Git(current_working_directory)
        g.fetch('origin')
        result = g.diff('--shortstat', 'origin/' + branch)
        if len(result) == 0:
            notifications.write(msg='No new version of Bazarr available.',
                                queue='check_update')
            logging.info('BAZARR No new version of Bazarr available.')
        else:
            g.reset('--hard', 'HEAD')
            g.checkout(branch)
            g.reset('--hard', 'origin/' + branch)
            g.pull()
            logging.info(
                'BAZARR Updated to latest version. Restart required. ' +
                result)
            updated()
    else:
        url = 'https://api.github.com/repos/morpheus65535/bazarr/releases'
        releases = request_json(url,
                                timeout=20,
                                whitelist_status_code=404,
                                validator=lambda x: type(x) == list)

        if releases is None:
            notifications.write(msg='Could not get releases from GitHub.',
                                queue='check_update',
                                type='warning')
            logging.warn('BAZARR Could not get releases from GitHub.')
            return
        else:
            release = releases[0]
        latest_release = release['tag_name']

        if ('v' + os.environ["BAZARR_VERSION"]
            ) != latest_release and settings.general.branch == 'master':
            update_from_source()
        elif settings.general.branch != 'master':
            notifications.write(
                msg="Can't update development branch from source",
                queue='check_update')  # fixme
            logging.info(
                "BAZARR Can't update development branch from source")  # fixme
        else:
            notifications.write(msg='Bazarr is up to date',
                                queue='check_update')
            logging.info('BAZARR is up to date')
示例#11
0
def wanted_search_missing_subtitles():
    db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                         timeout=30)
    db.create_function("path_substitution", 1, path_replace)
    db.create_function("path_substitution_movie", 1, path_replace_movie)
    c = db.cursor()

    if settings.sonarr.getboolean('only_monitored'):
        monitored_only_query_string_sonarr = ' AND monitored = "True"'
    else:
        monitored_only_query_string_sonarr = ""

    if settings.radarr.getboolean('only_monitored'):
        monitored_only_query_string_radarr = ' AND monitored = "True"'
    else:
        monitored_only_query_string_radarr = ""

    c.execute(
        "SELECT path_substitution(path) FROM table_episodes WHERE missing_subtitles != '[]'"
        + monitored_only_query_string_sonarr)
    episodes = c.fetchall()

    c.execute(
        "SELECT path_substitution_movie(path) FROM table_movies WHERE missing_subtitles != '[]'"
        + monitored_only_query_string_radarr)
    movies = c.fetchall()

    c.close()
    providers = get_providers()
    if settings.general.getboolean('use_sonarr'):
        if providers:
            count_episodes = len(episodes)
            for i, episode in enumerate(episodes, 1):
                wanted_download_subtitles(episode[0], i, count_episodes)
        else:
            notifications.write(msg='BAZARR All providers are throttled',
                                queue='get_subtitle',
                                duration='long')
            logging.info("BAZARR All providers are throttled")

    if settings.general.getboolean('use_radarr'):
        if providers:
            count_movies = len(movies)
            for i, movie in enumerate(movies, 1):
                wanted_download_subtitles_movie(movie[0], i, count_movies)
        else:
            notifications.write(msg='BAZARR All providers are throttled',
                                queue='get_subtitle',
                                duration='long')
            logging.info("BAZARR All providers are throttled")

    logging.info(
        'BAZARR Finished searching for missing subtitles. Check histories for more information.'
    )

    notifications.write(msg='Searching completed. Please reload the page.',
                        type='success',
                        duration='permanent',
                        button='refresh',
                        queue='get_subtitle')
示例#12
0
def update_series():
    notifications.write(msg="Update series list from Sonarr is running...",
                        queue='get_series')
    apikey_sonarr = settings.sonarr.apikey
    serie_default_enabled = settings.general.getboolean(
        'serie_default_enabled')
    serie_default_language = settings.general.serie_default_language
    serie_default_hi = settings.general.serie_default_hi
    serie_default_forced = settings.general.serie_default_forced

    if apikey_sonarr is None:
        pass
    else:
        get_profile_list()

        # Get shows data from Sonarr
        url_sonarr_api_series = url_sonarr + "/api/series?apikey=" + apikey_sonarr
        try:
            r = requests.get(url_sonarr_api_series, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception(
                "BAZARR Error trying to get series from Sonarr. Http error.")
        except requests.exceptions.ConnectionError as errc:
            logging.exception(
                "BAZARR Error trying to get series from Sonarr. Connection Error."
            )
        except requests.exceptions.Timeout as errt:
            logging.exception(
                "BAZARR Error trying to get series from Sonarr. Timeout Error."
            )
        except requests.exceptions.RequestException as err:
            logging.exception("BAZARR Error trying to get series from Sonarr.")
        else:
            # Open database connection
            db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                              'bazarr.db'),
                                 timeout=30)
            c = db.cursor()

            # Get current shows in DB
            current_shows_db = c.execute(
                'SELECT tvdbId FROM table_shows').fetchall()

            # Close database connection
            db.close()

            current_shows_db_list = [x[0] for x in current_shows_db]
            current_shows_sonarr = []
            series_to_update = []
            series_to_add = []

            seriesListLength = len(r.json())
            for i, show in enumerate(r.json(), 1):
                notifications.write(msg="Getting series data from Sonarr...",
                                    queue='get_series',
                                    item=i,
                                    length=seriesListLength)
                try:
                    overview = unicode(show['overview'])
                except:
                    overview = ""
                try:
                    poster_big = show['images'][2]['url'].split('?')[0]
                    poster = os.path.splitext(poster_big)[
                        0] + '-250' + os.path.splitext(poster_big)[1]
                except:
                    poster = ""
                try:
                    fanart = show['images'][0]['url'].split('?')[0]
                except:
                    fanart = ""

                if show['alternateTitles'] != None:
                    alternateTitles = str(
                        [item['title'] for item in show['alternateTitles']])

                # Add shows in Sonarr to current shows list
                current_shows_sonarr.append(show['tvdbId'])

                if show['tvdbId'] in current_shows_db_list:
                    series_to_update.append(
                        (show["title"], show["path"], show["tvdbId"],
                         show["id"], overview, poster, fanart,
                         profile_id_to_language(
                             (show['qualityProfileId'] if sonarr_version == 2
                              else show['languageProfileId'])),
                         show['sortTitle'], show['year'], alternateTitles,
                         show["tvdbId"]))
                else:
                    if serie_default_enabled is True:
                        series_to_add.append(
                            (show["title"], show["path"], show["tvdbId"],
                             serie_default_language, serie_default_hi,
                             show["id"], overview, poster, fanart,
                             profile_id_to_language(show['qualityProfileId']),
                             show['sortTitle'], show['year'], alternateTitles,
                             serie_default_forced))
                    else:
                        series_to_add.append(
                            (show["title"], show["path"], show["tvdbId"],
                             show["tvdbId"], show["tvdbId"], show["id"],
                             overview, poster, fanart,
                             profile_id_to_language(show['qualityProfileId']),
                             show['sortTitle'], show['year'], alternateTitles,
                             show["id"]))

            # Update or insert series in DB
            db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                              'bazarr.db'),
                                 timeout=30)
            c = db.cursor()

            updated_result = c.executemany(
                '''UPDATE table_shows SET title = ?, path = ?, tvdbId = ?, sonarrSeriesId = ?, overview = ?, poster = ?, fanart = ?, `audio_language` = ? , sortTitle = ?, year = ?, alternateTitles = ? WHERE tvdbid = ?''',
                series_to_update)
            db.commit()

            if serie_default_enabled is True:
                added_result = c.executemany(
                    '''INSERT OR IGNORE INTO table_shows(title, path, tvdbId, languages,`hearing_impaired`, sonarrSeriesId, overview, poster, fanart, `audio_language`, sortTitle, year, alternateTitles, forced) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                    series_to_add)
                db.commit()
            else:
                added_result = c.executemany(
                    '''INSERT OR IGNORE INTO table_shows(title, path, tvdbId, languages,`hearing_impaired`, sonarrSeriesId, overview, poster, fanart, `audio_language`, sortTitle, year, alternateTitles, forced) VALUES (?,?,?,(SELECT languages FROM table_shows WHERE tvdbId = ?),(SELECT `hearing_impaired` FROM table_shows WHERE tvdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?, (SELECT `forced` FROM table_shows WHERE tvdbId = ?))''',
                    series_to_add)
                db.commit()
            db.close()

            for show in series_to_add:
                list_missing_subtitles(show[5])

            # Delete shows not in Sonarr anymore
            deleted_items = []
            for item in current_shows_db_list:
                if item not in current_shows_sonarr:
                    deleted_items.append(tuple([item]))
            db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                              'bazarr.db'),
                                 timeout=30)
            c = db.cursor()
            c.executemany('DELETE FROM table_shows WHERE tvdbId = ?',
                          deleted_items)
            db.commit()
            db.close()
示例#13
0
def update_movies():
    logging.debug('BAZARR Starting movie sync from Radarr.')
    apikey_radarr = settings.radarr.apikey
    movie_default_enabled = settings.general.getboolean(
        'movie_default_enabled')
    movie_default_language = settings.general.movie_default_language
    movie_default_hi = settings.general.movie_default_hi
    movie_default_forced = settings.general.movie_default_forced

    if apikey_radarr is None:
        pass
    else:
        get_profile_list()

        # Get movies data from radarr
        url_radarr_api_movies = url_radarr + "/api/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.")
        except requests.exceptions.ConnectionError as errc:
            logging.exception(
                "BAZARR Error trying to get movies from Radarr. Connection Error."
            )
        except requests.exceptions.Timeout as errt:
            logging.exception(
                "BAZARR Error trying to get movies from Radarr. Timeout Error."
            )
        except requests.exceptions.RequestException as err:
            logging.exception("BAZARR Error trying to get movies from Radarr.")
        else:
            # Get current movies in DB
            db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                              'bazarr.db'),
                                 timeout=30)
            c = db.cursor()
            current_movies_db = c.execute(
                'SELECT tmdbId, path, radarrId FROM table_movies').fetchall()
            db.close()

            current_movies_db_list = [x[0] for x in current_movies_db]
            current_movies_radarr = []
            movies_to_update = []
            movies_to_add = []

            moviesIdListLength = len(r.json())
            for i, movie in enumerate(r.json(), 1):
                notifications.write(msg="Getting movies data from Radarr...",
                                    queue='get_movies',
                                    item=i,
                                    length=moviesIdListLength)
                if movie['hasFile'] is True:
                    if 'movieFile' in movie:
                        if movie["path"] != None and movie['movieFile'][
                                'relativePath'] != None:
                            try:
                                overview = unicode(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

                            if movie['alternativeTitles'] != None:
                                alternativeTitles = str([
                                    item['title']
                                    for item in movie['alternativeTitles']
                                ])

                            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 = movie['movieFile']['quality'][
                                    'quality']['resolution'].lstrip(
                                        'r').lower()
                            except:
                                resolution = None

                            if 'mediaInfo' in movie['movieFile']:
                                videoFormat = videoCodecID = videoProfile = videoCodecLibrary = None
                                if 'videoFormat' in movie['movieFile'][
                                        'mediaInfo']:
                                    videoFormat = movie['movieFile'][
                                        'mediaInfo']['videoFormat']
                                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, videoProfile,
                                    videoCodecLibrary)

                                audioFormat = audioCodecID = audioProfile = audioAdditionalFeatures = None
                                if 'audioFormat' in movie['movieFile'][
                                        'mediaInfo']:
                                    audioFormat = movie['movieFile'][
                                        'mediaInfo']['audioFormat']
                                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

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

                            # Detect file separator
                            if movie['path'][0] == "/":
                                separator = "/"
                            else:
                                separator = "\\"

                            if unicode(
                                    movie['tmdbId']) in current_movies_db_list:
                                movies_to_update.append(
                                    (movie["title"],
                                     movie["path"] + separator +
                                     movie['movieFile']['relativePath'],
                                     movie["tmdbId"], movie["id"], overview,
                                     poster, fanart,
                                     profile_id_to_language(
                                         movie['qualityProfileId']), sceneName,
                                     unicode(bool(movie['monitored'])),
                                     movie['sortTitle'], movie['year'],
                                     alternativeTitles, format, resolution,
                                     videoCodec, audioCodec, imdbId,
                                     movie["tmdbId"]))
                            else:
                                if movie_default_enabled is True:
                                    movies_to_add.append(
                                        (movie["title"],
                                         movie["path"] + separator +
                                         movie['movieFile']['relativePath'],
                                         movie["tmdbId"],
                                         movie_default_language, '[]',
                                         movie_default_hi, movie["id"],
                                         overview, poster, fanart,
                                         profile_id_to_language(
                                             movie['qualityProfileId']),
                                         sceneName,
                                         unicode(bool(movie['monitored'])),
                                         movie['sortTitle'], movie['year'],
                                         alternativeTitles, format, resolution,
                                         videoCodec, audioCodec, imdbId,
                                         movie_default_forced))
                                else:
                                    movies_to_add.append(
                                        (movie["title"],
                                         movie["path"] + separator +
                                         movie['movieFile']['relativePath'],
                                         movie["tmdbId"], movie["tmdbId"],
                                         movie["tmdbId"], movie["id"],
                                         overview, poster, fanart,
                                         profile_id_to_language(
                                             movie['qualityProfileId']),
                                         sceneName,
                                         unicode(bool(movie['monitored'])),
                                         movie['sortTitle'], movie['year'],
                                         alternativeTitles, format, resolution,
                                         videoCodec, audioCodec, imdbId,
                                         movie["tmdbId"]))
                        else:
                            logging.error(
                                'BAZARR Radarr returned a movie without a file path: '
                                + movie["path"] + separator +
                                movie['movieFile']['relativePath'])

            # Update or insert movies in DB
            db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                              'bazarr.db'),
                                 timeout=30)
            c = db.cursor()

            updated_result = c.executemany(
                '''UPDATE table_movies SET title = ?, path = ?, tmdbId = ?, radarrId = ?, overview = ?, poster = ?, fanart = ?, `audio_language` = ?, sceneName = ?, monitored = ?, sortTitle = ?, year = ?, alternativeTitles = ?, format = ?, resolution = ?, video_codec = ?, audio_codec = ?, imdbId = ? WHERE tmdbid = ?''',
                movies_to_update)
            db.commit()

            if movie_default_enabled is True:
                added_result = c.executemany(
                    '''INSERT OR IGNORE INTO table_movies(title, path, tmdbId, languages, subtitles,`hearing_impaired`, radarrId, overview, poster, fanart, `audio_language`, sceneName, monitored, sortTitle, year, alternativeTitles, format, resolution, video_codec, audio_codec, imdbId, forced) VALUES (?,?,?,?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
                    movies_to_add)
                db.commit()
            else:
                added_result = c.executemany(
                    '''INSERT OR IGNORE INTO table_movies(title, path, tmdbId, languages, subtitles,`hearing_impaired`, radarrId, overview, poster, fanart, `audio_language`, sceneName, monitored, sortTitle, year, alternativeTitles, format, resolution, video_codec, audio_codec, imdbId, forced) VALUES (?,?,?,(SELECT languages FROM table_movies WHERE tmdbId = ?), '[]',(SELECT `hearing_impaired` FROM table_movies WHERE tmdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT `forced` FROM table_movies WHERE tmdbId = ?))''',
                    movies_to_add)
                db.commit()

            removed_movies = list(
                set(current_movies_db_list) - set(current_movies_radarr))

            for removed_movie in removed_movies:
                c.execute('DELETE FROM table_movies WHERE tmdbId = ?',
                          (removed_movie, ))
                db.commit()

            # Get movies list after INSERT and UPDATE
            movies_now_in_db = c.execute(
                'SELECT tmdbId, path, radarrId FROM table_movies').fetchall()

            # Close database connection
            db.close()

            # Get only movies added or modified and store subtitles for them
            altered_movies = set(movies_now_in_db).difference(
                set(current_movies_db))
            for altered_movie in altered_movies:
                store_subtitles_movie(path_replace_movie(altered_movie[1]))
                list_missing_subtitles_movies(altered_movie[2])

            # 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:
                    movies_download_subtitles(altered_movie[2])
            else:
                logging.debug(
                    "BAZARR More than 5 movies were added during this sync then we wont search for subtitles."
                )

    logging.debug('BAZARR All movies synced from Radarr into database.')
示例#14
0
def upgrade_subtitles():
    days_to_upgrade_subs = settings.general.days_to_upgrade_subs
    minimum_timestamp = (
        (datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
        datetime(1970, 1, 1)).total_seconds()

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

    db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                         timeout=30)
    c = db.cursor()
    episodes_list = c.execute(
        """SELECT table_history.video_path, table_history.language, table_history.score,
                                        table_shows.hearing_impaired, table_episodes.scene_name, table_episodes.title,
                                        table_episodes.sonarrSeriesId, table_episodes.sonarrEpisodeId,
                                        MAX(table_history.timestamp), table_shows.languages
                                   FROM table_history
                             INNER JOIN table_shows on table_shows.sonarrSeriesId = table_history.sonarrSeriesId
                             INNER JOIN table_episodes on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId
                                  WHERE action IN (""" +
        ','.join(map(str, query_actions)) + """) AND timestamp > ? AND 
                                        score is not null
                               GROUP BY table_history.video_path, table_history.language""",
        (minimum_timestamp, )).fetchall()
    movies_list = c.execute(
        """SELECT table_history_movie.video_path, table_history_movie.language,
                                      table_history_movie.score, table_movies.hearing_impaired, table_movies.sceneName,
                                      table_movies.title, table_movies.radarrId, MAX(table_history_movie.timestamp), 
                                      table_movies.languages
                                 FROM table_history_movie
                           INNER JOIN table_movies on table_movies.radarrId = table_history_movie.radarrId
                                WHERE action  IN (""" +
        ','.join(map(str, query_actions)) + """) AND timestamp > ? AND 
                                      score is not null
                             GROUP BY table_history_movie.video_path, table_history_movie.language""",
        (minimum_timestamp, )).fetchall()
    db.close()

    episodes_to_upgrade = []
    for episode in episodes_list:
        if os.path.exists(path_replace(episode[0])) and int(episode[2]) < 360:
            episodes_to_upgrade.append(episode)

    movies_to_upgrade = []
    for movie in movies_list:
        if os.path.exists(path_replace_movie(
                movie[0])) and int(movie[2]) < 120:
            movies_to_upgrade.append(movie)

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    count_episode_to_upgrade = len(episodes_to_upgrade)
    count_movie_to_upgrade = len(movies_to_upgrade)

    for i, episode in enumerate(episodes_to_upgrade, 1):
        if episode[1] in ast.literal_eval(str(episode[9])):
            notifications.write(msg='Upgrading series subtitles : ' + str(i) +
                                '/' + str(count_episode_to_upgrade),
                                queue='get_subtitle',
                                duration='long')
            result = download_subtitle(path_replace(episode[0]),
                                       str(alpha3_from_alpha2(episode[1])),
                                       episode[3],
                                       providers_list,
                                       providers_auth,
                                       str(episode[4]),
                                       episode[5],
                                       'series',
                                       forced_minimum_score=int(episode[2]),
                                       is_upgrade=True)
            if result is not None:
                message = result[0]
                path = result[1]
                language_code = result[2]
                provider = result[3]
                score = result[4]
                store_subtitles(path_replace(episode[0]))
                history_log(3, episode[6], episode[7], message, path,
                            language_code, provider, score)
                send_notifications(episode[6], episode[7], message)

    for i, movie in enumerate(movies_to_upgrade, 1):
        if movie[1] in ast.literal_eval(str(movie[8])):
            notifications.write(msg='Upgrading movie subtitles : ' + str(i) +
                                '/' + str(count_movie_to_upgrade),
                                queue='get_subtitle',
                                duration='long')
            result = download_subtitle(path_replace_movie(movie[0]),
                                       str(alpha3_from_alpha2(movie[1])),
                                       movie[3],
                                       providers_list,
                                       providers_auth,
                                       str(movie[4]),
                                       movie[5],
                                       'movie',
                                       forced_minimum_score=int(movie[2]),
                                       is_upgrade=True)
            if result is not None:
                message = result[0]
                path = result[1]
                language_code = result[2]
                provider = result[3]
                score = result[4]
                store_subtitles_movie(path_replace_movie(movie[0]))
                history_log_movie(3, movie[6], message, path, language_code,
                                  provider, score)
                send_notifications_movie(movie[6], message)
示例#15
0
def wanted_download_subtitles_movie(path):
    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                              timeout=30)
    c_db = conn_db.cursor()
    movies_details = c_db.execute(
        "SELECT path, missing_subtitles, radarrId, radarrId, hearing_impaired, sceneName, failedAttempts, title FROM table_movies WHERE path = ? AND missing_subtitles != '[]'",
        (path_replace_reverse_movie(path), )).fetchall()
    c_db.close()

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    for movie in movies_details:
        attempt = movie[6]
        if type(attempt) == unicode:
            attempt = ast.literal_eval(attempt)
        for language in ast.literal_eval(movie[1]):
            if attempt is None:
                attempt = []
                attempt.append([language, time.time()])
            else:
                att = zip(*attempt)[0]
                if language not in att:
                    attempt.append([language, time.time()])

            conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                                   'bazarr.db'),
                                      timeout=30)
            c_db = conn_db.cursor()
            c_db.execute(
                'UPDATE table_movies SET failedAttempts = ? WHERE radarrId = ?',
                (unicode(attempt), movie[2]))
            conn_db.commit()
            c_db.close()

            for i in range(len(attempt)):
                if attempt[i][0] == language:
                    if search_active(attempt[i][1]) is True:
                        notifications.write(
                            msg='Searching ' +
                            str(language_from_alpha2(language)) +
                            ' subtitles for this movie: ' + path,
                            queue='get_subtitle')
                        result = download_subtitle(
                            path_replace_movie(movie[0]),
                            str(alpha3_from_alpha2(language)),
                            movie[4], providers_list, providers_auth,
                            str(movie[5]), movie[7], 'movie')
                        if result is not None:
                            message = result[0]
                            path = result[1]
                            language_code = result[2]
                            provider = result[3]
                            score = result[4]
                            store_subtitles_movie(path_replace_movie(movie[0]))
                            list_missing_subtitles_movies(movie[3])
                            history_log_movie(1, movie[3], message, path,
                                              language_code, provider, score)
                            send_notifications_movie(movie[3], message)
                    else:
                        logging.info('BAZARR Search is not active for movie ' +
                                     movie[0] + ' Language: ' + attempt[i][0])
示例#16
0
def wanted_download_subtitles(path):
    conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'),
                              timeout=30)
    c_db = conn_db.cursor()
    episodes_details = c_db.execute(
        "SELECT table_episodes.path, table_episodes.missing_subtitles, table_episodes.sonarrEpisodeId, table_episodes.sonarrSeriesId, table_shows.hearing_impaired, table_episodes.scene_name, table_episodes.failedAttempts, table_shows.title FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.path = ? AND missing_subtitles != '[]'",
        (path_replace_reverse(path), )).fetchall()
    c_db.close()

    providers_list = get_providers()
    providers_auth = get_providers_auth()

    for episode in episodes_details:
        attempt = episode[6]
        if type(attempt) == unicode:
            attempt = ast.literal_eval(attempt)
        for language in ast.literal_eval(episode[1]):
            if attempt is None:
                attempt = []
                attempt.append([language, time.time()])
            else:
                att = zip(*attempt)[0]
                if language not in att:
                    attempt.append([language, time.time()])

            conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db',
                                                   'bazarr.db'),
                                      timeout=30)
            c_db = conn_db.cursor()
            c_db.execute(
                'UPDATE table_episodes SET failedAttempts = ? WHERE sonarrEpisodeId = ?',
                (unicode(attempt), episode[2]))
            conn_db.commit()
            c_db.close()

            for i in range(len(attempt)):
                if attempt[i][0] == language:
                    if search_active(attempt[i][1]):
                        notifications.write(
                            msg='Searching ' +
                            str(language_from_alpha2(language)) +
                            ' subtitles for this episode: ' + path,
                            queue='get_subtitle')
                        result = download_subtitle(
                            path_replace(episode[0]),
                            str(alpha3_from_alpha2(language)),
                            episode[4], providers_list, providers_auth,
                            str(episode[5]), episode[7], 'series')
                        if result is not None:
                            message = result[0]
                            path = result[1]
                            language_code = result[2]
                            provider = result[3]
                            score = result[4]
                            store_subtitles(path_replace(episode[0]))
                            list_missing_subtitles(episode[3])
                            history_log(1, episode[3], episode[2], message,
                                        path, language_code, provider, score)
                            send_notifications(episode[3], episode[2], message)
                    else:
                        logging.debug(
                            'BAZARR Search is not active for episode ' +
                            episode[0] + ' Language: ' + attempt[i][0])
示例#17
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)
示例#18
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 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) is not 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:
            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
示例#19
0
def update_series():
    notifications.write(msg="Update series list from Sonarr is running...", queue='get_series')
    apikey_sonarr = settings.sonarr.apikey
    sonarr_version = get_sonarr_version()
    serie_default_enabled = settings.general.getboolean('serie_default_enabled')
    serie_default_language = settings.general.serie_default_language
    serie_default_hi = settings.general.serie_default_hi
    serie_default_forced = settings.general.serie_default_forced
    
    if apikey_sonarr is None:
        pass
    else:
        audio_profiles = get_profile_list()
        
        # Get shows data from Sonarr
        url_sonarr_api_series = url_sonarr + "/api/series?apikey=" + apikey_sonarr
        try:
            r = requests.get(url_sonarr_api_series, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception("BAZARR Error trying to get series from Sonarr. Http error.")
            return
        except requests.exceptions.ConnectionError as errc:
            logging.exception("BAZARR Error trying to get series from Sonarr. Connection Error.")
            return
        except requests.exceptions.Timeout as errt:
            logging.exception("BAZARR Error trying to get series from Sonarr. Timeout Error.")
            return
        except requests.exceptions.RequestException as err:
            logging.exception("BAZARR Error trying to get series from Sonarr.")
            return
        else:
            # Get current shows in DB
            current_shows_db = TableShows.select(
                TableShows.tvdb_id
            )
            
            current_shows_db_list = [x.tvdb_id for x in current_shows_db]
            current_shows_sonarr = []
            series_to_update = []
            series_to_add = []
            altered_series = []

            seriesListLength = len(r.json())
            for i, show in enumerate(r.json(), 1):
                notifications.write(msg="Getting series data from Sonarr...", queue='get_series', item=i, length=seriesListLength)
                try:
                    overview = unicode(show['overview'])
                except:
                    overview = ""
                try:
                    poster_big = show['images'][2]['url'].split('?')[0]
                    poster = os.path.splitext(poster_big)[0] + '-250' + os.path.splitext(poster_big)[1]
                except:
                    poster = ""
                try:
                    fanart = show['images'][0]['url'].split('?')[0]
                except:
                    fanart = ""

                if show['alternateTitles'] != None:
                    alternateTitles = str([item['title'] for item in show['alternateTitles']])
                else:
                    alternateTitles = None

                # Add shows in Sonarr to current shows list
                current_shows_sonarr.append(show['tvdbId'])
                
                if show['tvdbId'] in current_shows_db_list:
                    series_to_update.append({'title': unicode(show["title"]),
                                             'path': unicode(show["path"]),
                                             'tvdb_id': int(show["tvdbId"]),
                                             'sonarr_series_id': int(show["id"]),
                                             'overview': unicode(overview),
                                             'poster': unicode(poster),
                                             'fanart': unicode(fanart),
                                             'audio_language': unicode(profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles)),
                                             'sort_title': unicode(show['sortTitle']),
                                             'year': unicode(show['year']),
                                             'alternate_titles': unicode(alternateTitles)})
                else:
                    if serie_default_enabled is True:
                        series_to_add.append({'title': show["title"],
                                              'path': show["path"],
                                              'tvdb_id': show["tvdbId"],
                                              'languages': serie_default_language,
                                              'hearing_impaired': serie_default_hi,
                                              'sonarr_series_id': show["id"],
                                              'overview': overview,
                                              'poster': poster,
                                              'fanart': fanart,
                                              'audio_language': profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles),
                                              'sort_title': show['sortTitle'],
                                              'year': show['year'],
                                              'alternate_titles': alternateTitles,
                                              'forced': serie_default_forced})
                    else:
                        series_to_add.append({'title': show["title"],
                                              'path': show["path"],
                                              'tvdb_id': show["tvdbId"],
                                              'sonarr_series_id': show["id"],
                                              'overview': overview,
                                              'poster': poster,
                                              'fanart': fanart,
                                              'audio_language': profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles),
                                              'sort_title': show['sortTitle'],
                                              'year': show['year'],
                                              'alternate_titles': alternateTitles})
            
            # Update existing series in DB
            series_in_db_list = []
            series_in_db = TableShows.select(
                TableShows.title,
                TableShows.path,
                TableShows.tvdb_id,
                TableShows.sonarr_series_id,
                TableShows.overview,
                TableShows.poster,
                TableShows.fanart,
                TableShows.audio_language,
                TableShows.sort_title,
                TableShows.year,
                TableShows.alternate_titles
            ).dicts()

            for item in series_in_db:
                series_in_db_list.append(item)

            series_to_update_list = [i for i in series_to_update if i not in series_in_db_list]

            for updated_series in series_to_update_list:
                TableShows.update(
                    updated_series
                ).where(
                    TableShows.sonarr_series_id == updated_series['sonarr_series_id']
                ).execute()

            # Insert new series in DB
            for added_series in series_to_add:
                TableShows.insert(
                    added_series
                ).on_conflict_ignore().execute()
                list_missing_subtitles(added_series['sonarr_series_id'])

            # Remove old series from DB
            removed_series = list(set(current_shows_db_list) - set(current_shows_sonarr))

            for series in removed_series:
                TableShows.delete().where(
                    TableShows.tvdb_id == series
                ).execute()

            logging.debug('BAZARR All series synced from Sonarr into database.')
示例#20
0
def sync_episodes():
    notifications.write(msg='Episodes sync from Sonarr started...', queue='get_episodes')
    logging.debug('BAZARR Starting episodes sync from Sonarr.')
    apikey_sonarr = settings.sonarr.apikey
    
    # Open database connection
    db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
    c = db.cursor()
    
    # Get current episodes id in DB
    current_episodes_db = c.execute('SELECT sonarrEpisodeId, path, sonarrSeriesId FROM table_episodes').fetchall()

    current_episodes_db_list = [x[0] for x in current_episodes_db]
    current_episodes_sonarr = []
    episodes_to_update = []
    episodes_to_add = []
    
    # Get sonarrId for each series from database
    seriesIdList = c.execute("SELECT sonarrSeriesId, title FROM table_shows").fetchall()
    
    # Close database connection
    c.close()

    seriesIdListLength = len(seriesIdList)
    for i, seriesId in enumerate(seriesIdList, 1):
        notifications.write(msg='Getting episodes data from Sonarr...', queue='get_episodes', item=i, length=seriesIdListLength)
        # Get episodes data for a series from Sonarr
        url_sonarr_api_episode = url_sonarr + "/api/episode?seriesId=" + str(seriesId[0]) + "&apikey=" + apikey_sonarr
        try:
            r = requests.get(url_sonarr_api_episode, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception("BAZARR Error trying to get episodes from Sonarr. Http error.")
        except requests.exceptions.ConnectionError as errc:
            logging.exception("BAZARR Error trying to get episodes from Sonarr. Connection Error.")
        except requests.exceptions.Timeout as errt:
            logging.exception("BAZARR Error trying to get episodes from Sonarr. Timeout Error.")
        except requests.exceptions.RequestException as err:
            logging.exception("BAZARR Error trying to get episodes from Sonarr.")
        else:
            for episode in r.json():
                if 'hasFile' in episode:
                    if episode['hasFile'] is True:
                        if 'episodeFile' in episode:
                            if episode['episodeFile']['size'] > 20480:
                                # Add shows in Sonarr to current shows list
                                if 'sceneName' in episode['episodeFile']:
                                    sceneName = episode['episodeFile']['sceneName']
                                else:
                                    sceneName = None

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

                                if 'mediaInfo' in episode['episodeFile']:
                                    if 'videoCodec' in episode['episodeFile']['mediaInfo']:
                                        videoCodec = episode['episodeFile']['mediaInfo']['videoCodec']
                                        videoCodec = SonarrFormatVideoCodec(videoCodec)
                                    else: videoCodec = None

                                    if 'audioCodec' in episode['episodeFile']['mediaInfo']:
                                        audioCodec = episode['episodeFile']['mediaInfo']['audioCodec']
                                        audioCodec = SonarrFormatAudioCodec(audioCodec)
                                    else: audioCodec = None
                                else:
                                    videoCodec = None
                                    audioCodec = None

                                # Add episodes in sonarr to current episode list
                                current_episodes_sonarr.append(episode['id'])
                                
                                if episode['id'] in current_episodes_db_list:
                                    episodes_to_update.append((episode['title'], episode['episodeFile']['path'],
                                                               episode['seasonNumber'], episode['episodeNumber'],
                                                               sceneName, str(bool(episode['monitored'])),
                                                               format, resolution,
                                                               videoCodec, audioCodec, episode['id']))
                                else:
                                    episodes_to_add.append((episode['seriesId'], episode['id'], episode['title'],
                                                            episode['episodeFile']['path'], episode['seasonNumber'],
                                                            episode['episodeNumber'], sceneName,
                                                            str(bool(episode['monitored'])), format, resolution,
                                                            videoCodec, audioCodec))
    
    removed_episodes = list(set(current_episodes_db_list) - set(current_episodes_sonarr))
    
    # Update or insert movies in DB
    db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30)
    c = db.cursor()
    
    updated_result = c.executemany(
        '''UPDATE table_episodes SET title = ?, path = ?, season = ?, episode = ?, scene_name = ?, monitored = ?, format = ?, resolution = ?, video_codec = ?, audio_codec = ? WHERE sonarrEpisodeId = ?''',
        episodes_to_update)
    db.commit()
    
    added_result = c.executemany(
        '''INSERT OR IGNORE INTO table_episodes(sonarrSeriesId, sonarrEpisodeId, title, path, season, episode, scene_name, monitored, format, resolution, video_codec, audio_codec) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''',
        episodes_to_add)
    db.commit()
    
    for removed_episode in removed_episodes:
        c.execute('DELETE FROM table_episodes WHERE sonarrEpisodeId = ?', (removed_episode,))
        db.commit()

    # Get episodes list after INSERT and UPDATE
    episodes_now_in_db = c.execute('SELECT sonarrEpisodeId, path, sonarrSeriesId FROM table_episodes').fetchall()

    # Close database connection
    c.close()

    # Get only episodes added or modified and store subtitles for them
    altered_episodes = set(episodes_now_in_db).difference(set(current_episodes_db))
    for altered_episode in altered_episodes:
        store_subtitles(path_replace(altered_episode[1]))
        list_missing_subtitles(altered_episode[2])

    logging.debug('BAZARR All episodes synced from Sonarr into database.')

    # Search for desired subtitles if no more than 5 episodes have been added.
    if len(altered_episodes) <= 5:
        logging.debug("BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles.")
        for altered_episode in altered_episodes:
            episode_download_subtitles(altered_episode[0])
    else:
        logging.debug("BAZARR More than 5 episodes were added during this sync then we wont search for subtitles.")
示例#21
0
def sync_episodes():
    notifications.write(msg='Episodes sync from Sonarr started...',
                        queue='get_episodes')
    logging.debug('BAZARR Starting episodes sync from Sonarr.')
    apikey_sonarr = settings.sonarr.apikey

    # Get current episodes id in DB
    current_episodes_db = TableEpisodes.select(TableEpisodes.sonarr_episode_id,
                                               TableEpisodes.path,
                                               TableEpisodes.sonarr_series_id)

    current_episodes_db_list = [
        x.sonarr_episode_id for x in current_episodes_db
    ]

    current_episodes_sonarr = []
    episodes_to_update = []
    episodes_to_add = []
    altered_episodes = []

    # Get sonarrId for each series from database
    seriesIdList = TableShows.select(TableShows.sonarr_series_id,
                                     TableShows.title)

    seriesIdListLength = seriesIdList.count()
    for i, seriesId in enumerate(seriesIdList, 1):
        notifications.write(msg='Getting episodes data from Sonarr...',
                            queue='get_episodes',
                            item=i,
                            length=seriesIdListLength)
        # Get episodes data for a series from Sonarr
        url_sonarr_api_episode = url_sonarr + "/api/episode?seriesId=" + str(
            seriesId.sonarr_series_id) + "&apikey=" + apikey_sonarr
        try:
            r = requests.get(url_sonarr_api_episode, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Http error.")
            return
        except requests.exceptions.ConnectionError as errc:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Connection Error."
            )
            return
        except requests.exceptions.Timeout as errt:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Timeout Error."
            )
            return
        except requests.exceptions.RequestException as err:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr.")
            return
        else:
            for episode in r.json():
                if 'hasFile' in episode:
                    if episode['hasFile'] is True:
                        if 'episodeFile' in episode:
                            if episode['episodeFile']['size'] > 20480:
                                # Add shows in Sonarr to current shows list
                                if 'sceneName' in episode['episodeFile']:
                                    sceneName = episode['episodeFile'][
                                        'sceneName']
                                else:
                                    sceneName = None

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

                                if 'mediaInfo' in episode['episodeFile']:
                                    if 'videoCodec' in episode['episodeFile'][
                                            'mediaInfo']:
                                        videoCodec = episode['episodeFile'][
                                            'mediaInfo']['videoCodec']
                                        videoCodec = SonarrFormatVideoCodec(
                                            videoCodec)
                                    else:
                                        videoCodec = None

                                    if 'audioCodec' in episode['episodeFile'][
                                            'mediaInfo']:
                                        audioCodec = episode['episodeFile'][
                                            'mediaInfo']['audioCodec']
                                        audioCodec = SonarrFormatAudioCodec(
                                            audioCodec)
                                    else:
                                        audioCodec = None
                                else:
                                    videoCodec = None
                                    audioCodec = None

                                # Add episodes in sonarr to current episode list
                                current_episodes_sonarr.append(episode['id'])

                                if episode['id'] in current_episodes_db_list:
                                    episodes_to_update.append({
                                        'sonarr_series_id':
                                        episode['seriesId'],
                                        'sonarr_episode_id':
                                        episode['id'],
                                        'title':
                                        episode['title'],
                                        'path':
                                        episode['episodeFile']['path'],
                                        'season':
                                        episode['seasonNumber'],
                                        'episode':
                                        episode['episodeNumber'],
                                        'scene_name':
                                        sceneName,
                                        'monitored':
                                        str(bool(episode['monitored'])),
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'episode_file_id':
                                        episode['episodeFile']['id']
                                    })
                                else:
                                    episodes_to_add.append({
                                        'sonarr_series_id':
                                        episode['seriesId'],
                                        'sonarr_episode_id':
                                        episode['id'],
                                        'title':
                                        episode['title'],
                                        'path':
                                        episode['episodeFile']['path'],
                                        'season':
                                        episode['seasonNumber'],
                                        'episode':
                                        episode['episodeNumber'],
                                        'scene_name':
                                        sceneName,
                                        'monitored':
                                        str(bool(episode['monitored'])),
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'episode_file_id':
                                        episode['episodeFile']['id']
                                    })

    # Update existing episodes in DB
    episode_in_db_list = []
    episodes_in_db = TableEpisodes.select(
        TableEpisodes.sonarr_series_id, TableEpisodes.sonarr_episode_id,
        TableEpisodes.title, TableEpisodes.path, TableEpisodes.season,
        TableEpisodes.episode, TableEpisodes.scene_name,
        TableEpisodes.monitored, TableEpisodes.format,
        TableEpisodes.resolution, TableEpisodes.video_codec,
        TableEpisodes.audio_codec, TableEpisodes.episode_file_id).dicts()

    for item in episodes_in_db:
        episode_in_db_list.append(item)

    episodes_to_update_list = [
        i for i in episodes_to_update if i not in episode_in_db_list
    ]

    for updated_episode in episodes_to_update_list:
        TableEpisodes.update(updated_episode).where(
            TableEpisodes.sonarr_episode_id ==
            updated_episode['sonarr_episode_id']).execute()
        altered_episodes.append([
            updated_episode['sonarr_episode_id'], updated_episode['path'],
            updated_episode['sonarr_series_id']
        ])

    # Insert new episodes in DB
    for added_episode in episodes_to_add:
        TableEpisodes.insert(added_episode).on_conflict_ignore().execute()
        altered_episodes.append([
            added_episode['sonarr_episode_id'], added_episode['path'],
            added_episode['sonarr_series_id']
        ])

    # Remove old episodes from DB
    removed_episodes = list(
        set(current_episodes_db_list) - set(current_episodes_sonarr))

    for removed_episode in removed_episodes:
        TableEpisodes.delete().where(
            TableEpisodes.sonarr_episode_id == removed_episode).execute()

    # Store subtitles for added or modified episodes
    for i, altered_episode in enumerate(altered_episodes, 1):
        notifications.write(msg='Indexing episodes embedded subtitles...',
                            queue='get_episodes',
                            item=i,
                            length=len(altered_episodes))
        store_subtitles(path_replace(altered_episode[1]))
        list_missing_subtitles(altered_episode[2])

    logging.debug('BAZARR All episodes synced from Sonarr into database.')

    # Search for desired subtitles if no more than 5 episodes have been added.
    if len(altered_episodes) <= 5:
        logging.debug(
            "BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles."
        )
        for altered_episode in altered_episodes:
            episode_download_subtitles(altered_episode[0])
    else:
        logging.debug(
            "BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now."
        )
示例#22
0
def update_movies():
    logging.debug('BAZARR Starting movie sync from Radarr.')
    apikey_radarr = settings.radarr.apikey
    movie_default_enabled = settings.general.getboolean(
        'movie_default_enabled')
    movie_default_language = settings.general.movie_default_language
    movie_default_hi = settings.general.movie_default_hi
    movie_default_forced = settings.general.movie_default_forced

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

        # Get movies data from radarr
        url_radarr_api_movies = url_radarr(
        ) + "/api/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):
                notifications.write(msg="Getting movies data from Radarr...",
                                    queue='get_movies',
                                    item=i,
                                    length=moviesIdListLength)
                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 = unicode(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

                            if 'alternativeTitles' in movie:
                                alternativeTitles = str([
                                    item['title']
                                    for item in movie['alternativeTitles']
                                ])
                            else:
                                alternativeTitles = None

                            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 = movie['movieFile']['quality'][
                                    'quality']['resolution'].lstrip(
                                        'r').lower()
                            except:
                                resolution = None

                            if 'mediaInfo' in movie['movieFile']:
                                videoFormat = videoCodecID = videoProfile = videoCodecLibrary = None
                                if 'videoFormat' in movie['movieFile'][
                                        'mediaInfo']:
                                    videoFormat = movie['movieFile'][
                                        'mediaInfo']['videoFormat']
                                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, videoProfile,
                                    videoCodecLibrary)

                                audioFormat = audioCodecID = audioProfile = audioAdditionalFeatures = None
                                if 'audioFormat' in movie['movieFile'][
                                        'mediaInfo']:
                                    audioFormat = movie['movieFile'][
                                        'mediaInfo']['audioFormat']
                                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

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

                            if unicode(
                                    movie['tmdbId']) in current_movies_db_list:
                                movies_to_update.append({
                                    'radarrId':
                                    movie["id"],
                                    'title':
                                    unicode(movie["title"]),
                                    'path':
                                    unicode(
                                        movie["path"] + separator +
                                        movie['movieFile']['relativePath']),
                                    'tmdbId':
                                    unicode(movie["tmdbId"]),
                                    'poster':
                                    unicode(poster),
                                    'fanart':
                                    unicode(fanart),
                                    'audio_language':
                                    unicode(
                                        profile_id_to_language(
                                            movie['qualityProfileId'],
                                            audio_profiles)),
                                    'sceneName':
                                    sceneName,
                                    'monitored':
                                    unicode(bool(movie['monitored'])),
                                    'year':
                                    unicode(movie['year']),
                                    'sortTitle':
                                    unicode(movie['sortTitle']),
                                    'alternativeTitles':
                                    unicode(alternativeTitles),
                                    'format':
                                    unicode(format),
                                    'resolution':
                                    unicode(resolution),
                                    'video_codec':
                                    unicode(videoCodec),
                                    'audio_codec':
                                    unicode(audioCodec),
                                    'overview':
                                    unicode(overview),
                                    'imdbId':
                                    unicode(imdbId),
                                    'movie_file_id':
                                    movie['movieFile']['id']
                                })
                            else:
                                if movie_default_enabled is True:
                                    movies_to_add.append({
                                        'radarrId':
                                        movie["id"],
                                        'title':
                                        movie["title"],
                                        'path':
                                        movie["path"] + separator +
                                        movie['movieFile']['relativePath'],
                                        'tmdbId':
                                        movie["tmdbId"],
                                        'languages':
                                        movie_default_language,
                                        'subtitles':
                                        '[]',
                                        'hearing_impaired':
                                        movie_default_hi,
                                        'overview':
                                        overview,
                                        'poster':
                                        poster,
                                        'fanart':
                                        fanart,
                                        'audio_language':
                                        profile_id_to_language(
                                            movie['qualityProfileId'],
                                            audio_profiles),
                                        'sceneName':
                                        sceneName,
                                        'monitored':
                                        unicode(bool(movie['monitored'])),
                                        'sortTitle':
                                        movie['sortTitle'],
                                        'year':
                                        movie['year'],
                                        'alternativeTitles':
                                        alternativeTitles,
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'imdbId':
                                        imdbId,
                                        'forced':
                                        movie_default_forced,
                                        'movie_file_id':
                                        movie['movieFile']['id']
                                    })
                                else:
                                    movies_to_add.append({
                                        'radarrId':
                                        movie["id"],
                                        'title':
                                        movie["title"],
                                        'path':
                                        movie["path"] + separator +
                                        movie['movieFile']['relativePath'],
                                        'tmdbId':
                                        movie["tmdbId"],
                                        'languages':
                                        None,
                                        'subtitles':
                                        '[]',
                                        'hearing_impaired':
                                        None,
                                        'overview':
                                        overview,
                                        'poster':
                                        poster,
                                        'fanart':
                                        fanart,
                                        'audio_language':
                                        profile_id_to_language(
                                            movie['qualityProfileId'],
                                            audio_profiles),
                                        'sceneName':
                                        sceneName,
                                        'monitored':
                                        unicode(bool(movie['monitored'])),
                                        'sortTitle':
                                        movie['sortTitle'],
                                        'year':
                                        movie['year'],
                                        'alternativeTitles':
                                        alternativeTitles,
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'imdbId':
                                        imdbId,
                                        'forced':
                                        None,
                                        'movie_file_id':
                                        movie['movieFile']['id']
                                    })
                        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 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 radarrId = ?''',
                    query.values + (updated_movie['radarrId'], ))
                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_replace_movie(added_movie['path']))

            # Store subtitles for added or modified movies
            for i, altered_movie in enumerate(altered_movies, 1):
                notifications.write(
                    msg='Indexing movies embedded subtitles...',
                    queue='get_movies',
                    item=i,
                    length=len(altered_movies))
                store_subtitles_movie(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:
                    if settings.radarr.getboolean('only_monitored'):
                        if altered_movie[3] == 'True':
                            movies_download_subtitles(altered_movie[2])
                    else:
                        movies_download_subtitles(altered_movie[2])
            else:
                logging.debug(
                    "BAZARR More than 5 movies were added during this sync then we wont search for subtitles."
                )
示例#23
0
def sync_episodes():
    notifications.write(msg='Episodes sync from Sonarr started...',
                        queue='get_episodes')
    logging.debug('BAZARR Starting episodes sync from Sonarr.')
    apikey_sonarr = settings.sonarr.apikey

    # Get current episodes id in DB
    current_episodes_db = database.execute(
        "SELECT sonarrEpisodeId, path, sonarrSeriesId FROM table_episodes")

    current_episodes_db_list = [
        x['sonarrEpisodeId'] for x in current_episodes_db
    ]

    current_episodes_sonarr = []
    episodes_to_update = []
    episodes_to_add = []
    altered_episodes = []

    # Get sonarrId for each series from database
    seriesIdList = database.execute(
        "SELECT sonarrSeriesId, title FROM table_shows")

    seriesIdListLength = len(seriesIdList)
    for i, seriesId in enumerate(seriesIdList, 1):
        notifications.write(msg='Getting episodes data from Sonarr...',
                            queue='get_episodes',
                            item=i,
                            length=seriesIdListLength)
        # Get episodes data for a series from Sonarr
        url_sonarr_api_episode = url_sonarr() + "/api/episode?seriesId=" + str(
            seriesId['sonarrSeriesId']) + "&apikey=" + apikey_sonarr
        try:
            r = requests.get(url_sonarr_api_episode, timeout=60, verify=False)
            r.raise_for_status()
        except requests.exceptions.HTTPError as errh:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Http error.")
            return
        except requests.exceptions.ConnectionError as errc:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Connection Error."
            )
            return
        except requests.exceptions.Timeout as errt:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr. Timeout Error."
            )
            return
        except requests.exceptions.RequestException as err:
            logging.exception(
                "BAZARR Error trying to get episodes from Sonarr.")
            return
        else:
            for episode in r.json():
                if 'hasFile' in episode:
                    if episode['hasFile'] is True:
                        if 'episodeFile' in episode:
                            if episode['episodeFile']['size'] > 20480:
                                # Add shows in Sonarr to current shows list
                                if 'sceneName' in episode['episodeFile']:
                                    sceneName = episode['episodeFile'][
                                        'sceneName']
                                else:
                                    sceneName = None

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

                                if 'mediaInfo' in episode['episodeFile']:
                                    if 'videoCodec' in episode['episodeFile'][
                                            'mediaInfo']:
                                        videoCodec = episode['episodeFile'][
                                            'mediaInfo']['videoCodec']
                                        videoCodec = SonarrFormatVideoCodec(
                                            videoCodec)
                                    else:
                                        videoCodec = None

                                    if 'audioCodec' in episode['episodeFile'][
                                            'mediaInfo']:
                                        audioCodec = episode['episodeFile'][
                                            'mediaInfo']['audioCodec']
                                        audioCodec = SonarrFormatAudioCodec(
                                            audioCodec)
                                    else:
                                        audioCodec = None
                                else:
                                    videoCodec = None
                                    audioCodec = None

                                # Add episodes in sonarr to current episode list
                                current_episodes_sonarr.append(episode['id'])

                                if episode['id'] in current_episodes_db_list:
                                    episodes_to_update.append({
                                        'sonarrSeriesId':
                                        episode['seriesId'],
                                        'sonarrEpisodeId':
                                        episode['id'],
                                        'title':
                                        episode['title'],
                                        'path':
                                        episode['episodeFile']['path'],
                                        'season':
                                        episode['seasonNumber'],
                                        'episode':
                                        episode['episodeNumber'],
                                        'scene_name':
                                        sceneName,
                                        'monitored':
                                        str(bool(episode['monitored'])),
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'episode_file_id':
                                        episode['episodeFile']['id']
                                    })
                                else:
                                    episodes_to_add.append({
                                        'sonarrSeriesId':
                                        episode['seriesId'],
                                        'sonarrEpisodeId':
                                        episode['id'],
                                        'title':
                                        episode['title'],
                                        'path':
                                        episode['episodeFile']['path'],
                                        'season':
                                        episode['seasonNumber'],
                                        'episode':
                                        episode['episodeNumber'],
                                        'scene_name':
                                        sceneName,
                                        'monitored':
                                        str(bool(episode['monitored'])),
                                        'format':
                                        format,
                                        'resolution':
                                        resolution,
                                        'video_codec':
                                        videoCodec,
                                        'audio_codec':
                                        audioCodec,
                                        'episode_file_id':
                                        episode['episodeFile']['id']
                                    })

    # Remove old episodes from DB
    removed_episodes = list(
        set(current_episodes_db_list) - set(current_episodes_sonarr))

    for removed_episode in removed_episodes:
        database.execute("DELETE FROM table_episodes WHERE sonarrEpisodeId=?",
                         (removed_episode, ))

    # Update existing episodes in DB
    episode_in_db_list = []
    episodes_in_db = database.execute(
        "SELECT sonarrSeriesId, sonarrEpisodeId, title, path, season, episode, "
        "scene_name, monitored, format, resolution, video_codec, audio_codec, "
        "episode_file_id FROM table_episodes")

    for item in episodes_in_db:
        episode_in_db_list.append(item)

    episodes_to_update_list = [
        i for i in episodes_to_update if i not in episode_in_db_list
    ]

    for updated_episode in episodes_to_update_list:
        query = dict_converter.convert(updated_episode)
        database.execute(
            '''UPDATE table_episodes SET ''' + query.keys_update +
            ''' WHERE sonarrEpisodeId = ?''',
            query.values + (updated_episode['sonarrEpisodeId'], ))
        altered_episodes.append([
            updated_episode['sonarrEpisodeId'], updated_episode['path'],
            updated_episode['sonarrSeriesId']
        ])

    # Insert new episodes in DB
    for added_episode in episodes_to_add:
        query = dict_converter.convert(added_episode)
        result = database.execute(
            '''INSERT OR IGNORE INTO table_episodes(''' + query.keys_insert +
            ''') VALUES(''' + query.question_marks + ''')''', query.values)
        if result > 0:
            altered_episodes.append(
                [added_episode['sonarrEpisodeId'], added_episode['path']])
        else:
            logging.debug(
                'BAZARR unable to insert this episode into the database:',
                path_replace(added_episode['path']))

    # Store subtitles for added or modified episodes
    for i, altered_episode in enumerate(altered_episodes, 1):
        notifications.write(msg='Indexing episodes embedded subtitles...',
                            queue='get_episodes',
                            item=i,
                            length=len(altered_episodes))
        store_subtitles(altered_episode[1], path_replace(altered_episode[1]))

    logging.debug('BAZARR All episodes synced from Sonarr into database.')

    # Search for desired subtitles if no more than 5 episodes have been added.
    if len(altered_episodes) <= 5:
        logging.debug(
            "BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles."
        )
        for altered_episode in altered_episodes:
            episode_download_subtitles(altered_episode[0])
    else:
        logging.debug(
            "BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now."
        )
示例#24
0
def update_series():
    notifications.write(msg="Update series list from Sonarr is running...",
                        queue='get_series')
    apikey_sonarr = settings.sonarr.apikey
    if apikey_sonarr is None:
        return

    sonarr_version = get_sonarr_version()
    serie_default_enabled = settings.general.getboolean(
        'serie_default_enabled')
    serie_default_language = settings.general.serie_default_language
    serie_default_hi = settings.general.serie_default_hi
    serie_default_forced = settings.general.serie_default_forced
    audio_profiles = get_profile_list()

    # Get shows data from Sonarr
    url_sonarr_api_series = url_sonarr(
    ) + "/api/series?apikey=" + apikey_sonarr
    try:
        r = requests.get(url_sonarr_api_series, timeout=60, verify=False)
        r.raise_for_status()
    except requests.exceptions.HTTPError:
        logging.exception(
            "BAZARR Error trying to get series from Sonarr. Http error.")
        return
    except requests.exceptions.ConnectionError:
        logging.exception(
            "BAZARR Error trying to get series from Sonarr. Connection Error.")
        return
    except requests.exceptions.Timeout:
        logging.exception(
            "BAZARR Error trying to get series from Sonarr. Timeout Error.")
        return
    except requests.exceptions.RequestException:
        logging.exception("BAZARR Error trying to get series from Sonarr.")
        return

    # Get current shows in DB
    current_shows_db = database.execute(
        "SELECT sonarrSeriesId FROM table_shows")

    current_shows_db_list = [x['sonarrSeriesId'] for x in current_shows_db]
    current_shows_sonarr = []
    series_to_update = []
    series_to_add = []

    series_list_length = len(r.json())
    for i, show in enumerate(r.json(), 1):
        notifications.write(msg="Getting series data from Sonarr...",
                            queue='get_series',
                            item=i,
                            length=series_list_length)

        overview = show['overview'] if 'overview' in show else ''
        poster = ''
        fanart = ''
        for image in show['images']:
            if image['coverType'] == 'poster':
                poster_big = image['url'].split('?')[0]
                poster = os.path.splitext(
                    poster_big)[0] + '-250' + os.path.splitext(poster_big)[1]

            if image['coverType'] == 'fanart':
                fanart = image['url'].split('?')[0]

        alternate_titles = None
        if show['alternateTitles'] is not None:
            alternate_titles = str(
                [item['title'] for item in show['alternateTitles']])

        if sonarr_version.startswith('2'):
            audio_language = profile_id_to_language(show['qualityProfileId'],
                                                    audio_profiles)
        else:
            audio_language = profile_id_to_language(show['languageProfileId'],
                                                    audio_profiles)

        # Add shows in Sonarr to current shows list
        current_shows_sonarr.append(show['id'])

        if show['id'] in current_shows_db_list:
            series_to_update.append({
                'title': show["title"],
                'path': show["path"],
                'tvdbId': int(show["tvdbId"]),
                'sonarrSeriesId': int(show["id"]),
                'overview': overview,
                'poster': poster,
                'fanart': fanart,
                'audio_language': audio_language,
                'sortTitle': show['sortTitle'],
                'year': show['year'],
                'alternateTitles': alternate_titles
            })
        else:
            if serie_default_enabled is True:
                series_to_add.append({
                    'title': show["title"],
                    'path': show["path"],
                    'tvdbId': show["tvdbId"],
                    'languages': serie_default_language,
                    'hearing_impaired': serie_default_hi,
                    'sonarrSeriesId': show["id"],
                    'overview': overview,
                    'poster': poster,
                    'fanart': fanart,
                    'audio_language': audio_language,
                    'sortTitle': show['sortTitle'],
                    'year': show['year'],
                    'alternateTitles': alternate_titles,
                    'forced': serie_default_forced
                })
            else:
                series_to_add.append({
                    'title': show["title"],
                    'path': show["path"],
                    'tvdbId': show["tvdbId"],
                    'sonarrSeriesId': show["id"],
                    'overview': overview,
                    'poster': poster,
                    'fanart': fanart,
                    'audio_language': audio_language,
                    'sortTitle': show['sortTitle'],
                    'year': show['year'],
                    'alternateTitles': alternate_titles
                })

    # Remove old series from DB
    removed_series = list(
        set(current_shows_db_list) - set(current_shows_sonarr))

    for series in removed_series:
        database.execute("DELETE FROM table_shows WHERE sonarrSEriesId=?",
                         (series, ))

    # Update existing series in DB
    series_in_db_list = []
    series_in_db = database.execute(
        "SELECT title, path, tvdbId, sonarrSeriesId, overview, poster, fanart, "
        "audio_language, sortTitle, year, alternateTitles FROM table_shows")

    for item in series_in_db:
        series_in_db_list.append(item)

    series_to_update_list = [
        i for i in series_to_update if i not in series_in_db_list
    ]

    for updated_series in series_to_update_list:
        query = dict_converter.convert(updated_series)
        database.execute(
            '''UPDATE table_shows SET ''' + query.keys_update +
            ''' WHERE sonarrSeriesId = ?''',
            query.values + (updated_series['sonarrSeriesId'], ))

    # Insert new series in DB
    for added_series in series_to_add:
        query = dict_converter.convert(added_series)
        result = database.execute(
            '''INSERT OR IGNORE INTO table_shows(''' + query.keys_insert +
            ''') VALUES(''' + query.question_marks + ''')''', query.values)
        if result:
            list_missing_subtitles(no=added_series['sonarrSeriesId'])
        else:
            logging.debug(
                'BAZARR unable to insert this series into the database:',
                path_replace(added_series['path']))

    logging.debug('BAZARR All series synced from Sonarr into database.')