From 65927c742b2e824f3538d2121a39823e184049b4 Mon Sep 17 00:00:00 2001 From: Halali Date: Tue, 15 Jan 2019 17:25:13 +0100 Subject: [PATCH] Clen up --- bazarr/check_update.py | 4 +- bazarr/config.py | 12 +- bazarr/get_episodes.py | 27 +-- bazarr/get_languages.py | 12 +- bazarr/get_movies.py | 67 +++++--- bazarr/get_providers.py | 23 +-- bazarr/get_series.py | 38 ++--- bazarr/get_subtitle.py | 118 ++++++------- bazarr/init.py | 20 +-- bazarr/list_subtitles.py | 78 +++++---- bazarr/logger.py | 37 ++-- bazarr/main.py | 353 ++++++++++++++++++++------------------- bazarr/queueconfig.py | 2 +- bazarr/scheduler.py | 7 +- bazarr/update_db.py | 26 +-- 15 files changed, 435 insertions(+), 389 deletions(-) diff --git a/bazarr/check_update.py b/bazarr/check_update.py index f85016a35..c42200936 100644 --- a/bazarr/check_update.py +++ b/bazarr/check_update.py @@ -18,13 +18,13 @@ def gitconfig(): g = git.Repo.init(current_working_directory) config_read = g.config_reader() config_write = g.config_writer() - + try: username = config_read.get_value("user", "name") except: logging.debug('BAZARR Settings git username') config_write.set_value("user", "name", "Bazarr") - + try: email = config_read.get_value("user", "email") except: diff --git a/bazarr/config.py b/bazarr/config.py index 14791a3f2..895488068 100644 --- a/bazarr/config.py +++ b/bazarr/config.py @@ -33,12 +33,12 @@ defaults = { 'use_embedded_subs': 'True', 'adaptive_searching': 'False', 'enabled_providers': '' -}, + }, 'auth': { 'type': 'None', 'username': '', 'password': '' -}, + }, 'sonarr': { 'ip': '127.0.0.1', 'port': '8989', @@ -64,7 +64,7 @@ defaults = { 'username': '', 'password': '', 'exclude': 'localhost,127.0.0.1' -}, + }, 'opensubtitles': { 'username': '', 'password': '', @@ -73,7 +73,7 @@ defaults = { 'ssl': 'False', 'timeout': '15', 'skip_wrong_fps': 'False' -}, + }, 'addic7ed': { 'username': '', 'password': '', @@ -82,10 +82,10 @@ defaults = { 'legendastv': { 'username': '', 'password': '' -}, + }, 'assrt': { 'token': '' -}} + }} settings = simpleconfigparser(defaults=defaults) settings.read(os.path.join(args.config_dir, 'config', 'config.ini')) diff --git a/bazarr/get_episodes.py b/bazarr/get_episodes.py index f1ca5e960..e7f35a6ab 100644 --- a/bazarr/get_episodes.py +++ b/bazarr/get_episodes.py @@ -11,6 +11,7 @@ from helper import path_replace from list_subtitles import list_missing_subtitles, store_subtitles, series_full_scan_subtitles, \ movies_full_scan_subtitles + def update_all_episodes(): series_full_scan_subtitles() logging.info('BAZARR All existing episode subtitles indexed from disk.') @@ -33,7 +34,7 @@ def sync_episodes(): # 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 FROM table_episodes').fetchall() @@ -41,13 +42,13 @@ def sync_episodes(): 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() - + for seriesId in seriesIdList: q4ws.append('Getting episodes data for this show: ' + seriesId[1]) # Get episodes data for a series from Sonarr @@ -74,10 +75,10 @@ def sync_episodes(): sceneName = episode['episodeFile']['sceneName'] else: sceneName = 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'], @@ -88,23 +89,23 @@ def sync_episodes(): episode['episodeFile']['path'], episode['seasonNumber'], episode['episodeNumber'], sceneName, str(bool(episode['monitored'])))) - + 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 = ? 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) VALUES (?, ?, ?, ?, ?, ?, ?, ?)''', episodes_to_add) db.commit() - + for removed_episode in removed_episodes: c.execute('DELETE FROM table_episodes WHERE sonarrEpisodeId = ?', (removed_episode,)) db.commit() @@ -121,8 +122,8 @@ def sync_episodes(): store_subtitles(path_replace(altered_episode[1])) logging.debug('BAZARR All episodes synced from Sonarr into database.') - + list_missing_subtitles() logging.debug('BAZARR All missing subtitles updated in database.') - + q4ws.append('Episodes sync from Sonarr ended.') diff --git a/bazarr/get_languages.py b/bazarr/get_languages.py index 4baea5fb1..c76ddefc7 100644 --- a/bazarr/get_languages.py +++ b/bazarr/get_languages.py @@ -12,26 +12,26 @@ def load_language_in_db(): langs = [[lang.alpha_3, lang.alpha_2, lang.name] for lang in pycountry.languages if hasattr(lang, 'alpha_2')] - + # Open database connection db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + # Insert languages in database table c.executemany('''INSERT OR IGNORE INTO table_settings_languages(code3, code2, name) VALUES(?, ?, ?)''', langs) c.execute('''INSERT OR IGNORE INTO table_settings_languages(code3, code2, name) VALUES(?, ?, ?)''', ('pob', 'pb', 'Brazilian Portuguese')) - + langs = [[lang.bibliographic, lang.alpha_3] for lang in pycountry.languages if hasattr(lang, 'alpha_2') and hasattr(lang, 'bibliographic')] - + # Update languages in database table c.executemany('''UPDATE table_settings_languages SET code3b = ? WHERE code3 = ?''', langs) - + # Commit changes to database table db.commit() - + # Close database connection db.close() diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index d3df675a5..f6890cceb 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -19,12 +19,12 @@ def update_movies(): 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 - + 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: @@ -44,12 +44,12 @@ def update_movies(): c = db.cursor() current_movies_db = c.execute('SELECT tmdbId, path 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 = [] - + for movie in r.json(): q4ws.append("Getting data for this movie: " + movie['title']) if movie['hasFile'] is True: @@ -68,43 +68,66 @@ def update_movies(): fanart = movie['images'][1]['url'] except: fanart = "" - + if 'sceneName' in movie['movieFile']: sceneName = movie['movieFile']['sceneName'] else: sceneName = 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["tmdbId"])) + 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["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'])) + 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'])) 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'])) + 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'])) else: - logging.error('BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator + movie['movieFile']['relativePath']) - + 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= ? WHERE tmdbid = ?''', movies_to_update) + + updated_result = c.executemany( + '''UPDATE table_movies SET title = ?, path = ?, tmdbId = ?, radarrId = ?, overview = ?, poster = ?, fanart = ?, `audio_language` = ?, sceneName = ?, monitored = ?, sortTitle= ? 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) VALUES (?,?,?,?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', movies_to_add) + 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) 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) VALUES (?,?,?,(SELECT languages FROM table_movies WHERE tmdbId = ?), '[]',(SELECT `hearing_impaired` FROM table_movies WHERE tmdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?)''', movies_to_add) + 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) VALUES (?,?,?,(SELECT languages FROM table_movies WHERE tmdbId = ?), '[]',(SELECT `hearing_impaired` FROM table_movies WHERE tmdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?)''', + movies_to_add) db.commit() removed_movies = list(set(current_movies_db_list) - set(current_movies_radarr)) @@ -125,20 +148,20 @@ def update_movies(): store_subtitles_movie(path_replace_movie(altered_movie[1])) logging.debug('BAZARR All movies synced from Radarr into database.') - + list_missing_subtitles_movies() logging.debug('BAZARR All movie missing subtitles updated in database.') - + q4ws.append("Update movies list from Radarr is ended.") def get_profile_list(): apikey_radarr = settings.radarr.apikey - + # Get profiles data from radarr global profiles_list profiles_list = [] - + url_radarr_api_movies = url_radarr + "/api/profile?apikey=" + apikey_radarr try: profiles_json = requests.get(url_radarr_api_movies, timeout=15, verify=False) diff --git a/bazarr/get_providers.py b/bazarr/get_providers.py index 0159f476e..aa8a5f8b0 100644 --- a/bazarr/get_providers.py +++ b/bazarr/get_providers.py @@ -1,5 +1,9 @@ # coding=utf-8 +import datetime + from config import settings +from subliminal_patch.exceptions import TooManyRequests, APIThrottled +from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable def get_providers(): @@ -9,7 +13,7 @@ def get_providers(): providers_list.append(provider) else: providers_list = None - + return providers_list @@ -18,29 +22,28 @@ def get_providers_auth(): 'addic7ed': {'username': settings.addic7ed.username, 'password': settings.addic7ed.password, 'use_random_agents': settings.addic7ed.getboolean('random_agents'), - }, + }, 'opensubtitles': {'username': settings.opensubtitles.username, 'password': settings.opensubtitles.password, 'use_tag_search': settings.opensubtitles.getboolean('use_tag_search'), - 'only_foreign': False, # fixme - 'also_foreign': False, # fixme + 'only_foreign': False, # fixme + 'also_foreign': False, # fixme 'is_vip': settings.opensubtitles.getboolean('vip'), 'use_ssl': settings.opensubtitles.getboolean('ssl'), 'timeout': int(settings.opensubtitles.timeout) or 15, 'skip_wrong_fps': settings.opensubtitles.getboolean('skip_wrong_fps'), - }, + }, 'podnapisi': { - 'only_foreign': False, # fixme - 'also_foreign': False, # fixme + 'only_foreign': False, # fixme + 'also_foreign': False, # fixme }, 'subscene': { - 'only_foreign': False, # fixme + 'only_foreign': False, # fixme }, 'legendastv': {'username': settings.legendastv.username, 'password': settings.legendastv.password, - }, + }, 'assrt': {'token': settings.assrt.token, } } - return providers_auth diff --git a/bazarr/get_series.py b/bazarr/get_series.py index b198a5cee..f00f87294 100644 --- a/bazarr/get_series.py +++ b/bazarr/get_series.py @@ -18,12 +18,12 @@ def update_series(): 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 - + 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: @@ -41,18 +41,18 @@ def update_series(): # 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 = [] - + for show in r.json(): q4ws.append("Getting series data for this show: " + show['title']) try: @@ -68,10 +68,10 @@ def update_series(): fanart = show['images'][0]['url'].split('?')[0] except: fanart = "" - + # 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( @@ -86,16 +86,16 @@ def update_series(): 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'])) - + # 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 = ? 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) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', @@ -107,10 +107,10 @@ def update_series(): 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: @@ -121,16 +121,16 @@ def update_series(): c.executemany('DELETE FROM table_shows WHERE tvdbId = ?', deleted_items) db.commit() db.close() - + q4ws.append("Update series list from Sonarr is ended.") def get_profile_list(): apikey_sonarr = settings.sonarr.apikey - + # Get profiles data from Sonarr error = False - + url_sonarr_api_series = url_sonarr + "/api/profile?apikey=" + apikey_sonarr try: profiles_json = requests.get(url_sonarr_api_series, timeout=15, verify=False) @@ -143,7 +143,7 @@ def get_profile_list(): except requests.exceptions.RequestException as err: error = True logging.exception("BAZARR Error trying to get profiles from Sonarr.") - + url_sonarr_api_series_v3 = url_sonarr + "/api/v3/languageprofile?apikey=" + apikey_sonarr try: profiles_json_v3 = requests.get(url_sonarr_api_series_v3, timeout=15, verify=False) @@ -156,10 +156,10 @@ def get_profile_list(): except requests.exceptions.RequestException as err: error = True logging.exception("BAZARR Error trying to get profiles from Sonarr.") - + global profiles_list profiles_list = [] - + if not error: # Parsing data returned from Sonarr global sonarr_version diff --git a/bazarr/get_subtitle.py b/bazarr/get_subtitle.py index 6255b0ccc..bf78a655e 100644 --- a/bazarr/get_subtitle.py +++ b/bazarr/get_subtitle.py @@ -56,13 +56,13 @@ def get_video(path, title, sceneName, use_scenename, providers=None, media_type= # use the sceneName but keep the folder structure for better guessing path = os.path.join(os.path.dirname(path), sceneName + os.path.splitext(path)[1]) dont_use_actual_file = True - + try: video = parse_video(path, hints=hints, providers=providers, dry_run=dont_use_actual_file) video.used_scene_name = dont_use_actual_file video.original_name = original_name return video - + except: logging.exception("BAZARR Error trying to get video information for this file: " + path) @@ -87,7 +87,7 @@ def get_scores(video, media_type, min_score_movie_perc=60 * 100 / 120.0, min_sco scores = subliminal_scores.episode_scores.keys() if video.is_special: min_score = max_score * min_score_special_ep / 100.0 - + return min_score, max_score, set(scores) @@ -113,30 +113,30 @@ def force_unicode(s): def download_subtitle(path, language, hi, providers, providers_auth, sceneName, title, media_type): # fixme: supply all missing languages, not only one, to hit providers only once who support multiple languages in # one query - + logging.debug('BAZARR Searching subtitles for this file: ' + path) if hi == "True": hi = True else: hi = False language_set = set() - + if not isinstance(language, types.ListType): language = [language] - + for l in language: if l == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(l)) - + use_scenename = settings.general.getboolean('use_scenename') minimum_score = settings.general.minimum_score minimum_score_movie = settings.general.minimum_score_movie use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd single = settings.general.getboolean('single_language') - + # todo: """ AsyncProviderPool: @@ -147,7 +147,7 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, post_download_hook=None, language_hook=None """ - + """ throttle_callback: @@ -221,12 +221,12 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, } """ - + video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type) if video: min_score, max_score, scores = get_scores(video, media_type, min_score_movie_perc=int(minimum_score_movie), min_score_series_perc=int(minimum_score)) - + downloaded_subtitles = download_best_subtitles({video}, language_set, int(min_score), hi, providers=providers, provider_configs=providers_auth, @@ -238,13 +238,13 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, pre_download_hook=None, # fixme post_download_hook=None, # fixme language_hook=None) # fixme - + saved_any = False if downloaded_subtitles: for video, subtitles in downloaded_subtitles.iteritems(): if not subtitles: continue - + try: saved_subtitles = save_subtitles(video.original_name, subtitles, single=single, tags=None, # fixme @@ -271,7 +271,7 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, else: message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode( round(subtitle.score * 100 / max_score, 2)) + "% using filename guessing." - + if use_postprocessing is True: command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3) @@ -282,15 +282,15 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, # 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( @@ -303,10 +303,10 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, 'BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out) - + # fixme: support multiple languages at once return message - + if not saved_any: logging.debug('BAZARR No subtitles were found for this file: ' + path) return None @@ -315,9 +315,9 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName, def manual_search(path, language, hi, providers, providers_auth, sceneName, title, media_type): logging.debug('BAZARR Manually searching subtitles for this file: ' + path) - + final_subtitles = [] - + if hi == "True": hi = True else: @@ -329,18 +329,18 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl language_set.add(Language('por', 'BR')) else: language_set.add(Language(lang)) - + use_scenename = settings.general.getboolean('use_scenename') minimum_score = settings.general.minimum_score minimum_score_movie = settings.general.minimum_score_movie use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd - + video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type) if video: min_score, max_score, scores = get_scores(video, media_type, min_score_movie_perc=int(minimum_score_movie), min_score_series_perc=int(minimum_score)) - + try: subtitles = list_subtitles([video], language_set, providers=providers, @@ -352,19 +352,19 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path) else: subtitles_list = [] - + for s in subtitles[video]: try: matches = s.get_matches(video) except AttributeError: continue - + # skip wrong season/episodes if media_type == "series": can_verify_series = True if not s.hash_verifiable and "hash" in matches: can_verify_series = False - + if can_verify_series and not {"series", "season", "episode"}.issubset(matches): logging.debug(u"BAZARR Skipping %s, because it doesn't match our series/episode", s) continue @@ -374,14 +374,14 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl s.score = score if score < min_score: continue - + subtitles_list.append( dict(score=round((score / max_score * 100), 2), language=alpha2_from_alpha3(s.language.alpha3), hearing_impaired=str(s.hearing_impaired), provider=s.provider_name, subtitle=codecs.encode(pickle.dumps(s.make_picklable()), "base64").decode(), url=s.page_link, matches=list(matches), dont_matches=list(not_matched))) - + final_subtitles = sorted(subtitles_list, key=lambda x: x['score'], reverse=True) logging.debug('BAZARR ' + str(len(final_subtitles)) + " subtitles have been found for this file: " + path) logging.debug('BAZARR Ended searching subtitles for this file: ' + path) @@ -390,13 +390,12 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl 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) @@ -416,7 +415,7 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a score = round(subtitle.score / max_score * 100, 2) saved_subtitles = save_subtitles(video.original_name, [subtitle], single=single, path_decoder=force_unicode) - + except Exception as e: logging.exception('BAZARR Error saving subtitles file to disk for this file:' + path) return @@ -431,7 +430,7 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a 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) @@ -442,15 +441,15 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a # 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( @@ -463,7 +462,7 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a 'BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out) - + return message else: logging.error( @@ -477,18 +476,19 @@ def series_download_subtitles(no): 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() + 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() - + for episode in episodes_details: for language in ast.literal_eval(episode[1]): if language is not None: @@ -509,10 +509,10 @@ def movies_download_subtitles(no): "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() - + for language in ast.literal_eval(movie[1]): if language is not None: message = download_subtitle(path_replace_movie(movie[0]), str(alpha3_from_alpha2(language)), movie[4], @@ -531,10 +531,10 @@ def wanted_download_subtitles(path): "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: @@ -547,18 +547,19 @@ def wanted_download_subtitles(path): 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]) is True: - q4ws.append('Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) + q4ws.append( + 'Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) message = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)), episode[4], providers_list, providers_auth, str(episode[5]), episode[7], 'series') @@ -579,10 +580,10 @@ def wanted_download_subtitles_movie(path): "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: @@ -595,17 +596,18 @@ def wanted_download_subtitles_movie(path): 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: - q4ws.append('Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) + q4ws.append( + 'Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) message = download_subtitle(path_replace_movie(movie[0]), str(alpha3_from_alpha2(language)), movie[4], providers_list, providers_auth, str(movie[5]), movie[7], 'movie') @@ -638,21 +640,21 @@ def wanted_search_missing_subtitles(): 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() - + if settings.general.getboolean('use_sonarr'): for episode in episodes: wanted_download_subtitles(episode[0]) - + if settings.general.getboolean('use_radarr'): for movie in movies: wanted_download_subtitles_movie(movie[0]) - + logging.info('BAZARR Finished searching for missing subtitles. Check histories for more information.') diff --git a/bazarr/init.py b/bazarr/init.py index 80ab440c5..e399dd89c 100644 --- a/bazarr/init.py +++ b/bazarr/init.py @@ -34,7 +34,7 @@ if not os.path.exists(os.path.join(args.config_dir, 'db')): if not os.path.exists(os.path.join(args.config_dir, 'log')): os.mkdir(os.path.join(args.config_dir, 'log')) logging.debug("BAZARR Created log folder") - + if not os.path.exists(os.path.join(args.config_dir, 'config', 'releases.txt')): check_releases() logging.debug("BAZARR Created releases file") @@ -46,20 +46,20 @@ try: # Get SQL script from file fd = open(os.path.join(os.path.dirname(__file__), 'create_db.sql'), 'r') script = fd.read() - + # Close SQL script file fd.close() - + # Open database connection db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + # Execute script and commit change to database c.executescript(script) - + # Close database connection db.close() - + logging.info('BAZARR Database created successfully') except: pass @@ -80,7 +80,7 @@ if cfg.has_section('auth'): cfg.remove_option('auth', 'enabled') with open(config_file, 'w+') as configfile: cfg.write(configfile) - + if cfg.has_section('general'): if cfg.has_option('general', 'log_level'): cfg.remove_option('general', 'log_level') @@ -127,16 +127,16 @@ try: settings.general.enabled_providers = u'' if not providers_list else ','.join(providers_list) with open(os.path.join(config_dir, 'config', 'config.ini'), 'w+') as handle: settings.write(handle) - + except: pass if not os.path.exists(os.path.normpath(os.path.join(args.config_dir, 'config', 'users.json'))): cork = Cork(os.path.normpath(os.path.join(args.config_dir, 'config')), initialize=True) - + cork._store.roles[''] = 100 cork._store.save_roles() - + tstamp = str(time.time()) username = password = '' cork._store.users[username] = { diff --git a/bazarr/list_subtitles.py b/bazarr/list_subtitles.py index f4cd66299..504daf57e 100644 --- a/bazarr/list_subtitles.py +++ b/bazarr/list_subtitles.py @@ -36,7 +36,7 @@ def store_subtitles(file): 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: @@ -51,7 +51,7 @@ def store_subtitles(file): pass else: logging.debug("BAZARR This file isn't an .mkv file.") - + brazilian_portuguese = [".pt-br", ".pob", "pb"] try: # fixme: set subliminal_patch.core.CUSTOM_PATHS to a list of absolute folders or subfolders to support @@ -82,28 +82,30 @@ def store_subtitles(file): 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.') + '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)) + 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))]) - + 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))) + (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 @@ -117,7 +119,7 @@ def store_subtitles_movie(file): 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: @@ -132,7 +134,7 @@ def store_subtitles_movie(file): pass else: logging.debug("BAZARR This file isn't an .mkv file.") - + # fixme: set subliminal_patch.core.CUSTOM_PATHS to a list of absolute folders or subfolders to support # subtitles outside the media file folder subtitles = search_external_subtitles(file) @@ -147,11 +149,11 @@ def store_subtitles_movie(file): if str(os.path.splitext(subtitle)[0]).lower().endswith(tuple(brazilian_portuguese)) is True: logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append( - [str("pb"), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))]) + [str("pb"), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))]) elif str(language) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language)) actual_subtitles.append( - [str(language), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))]) + [str(language), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))]) else: if os.path.splitext(subtitle)[1] != ".sub": logging.debug("BAZARR falling back to file content analysis to detect language.") @@ -164,28 +166,30 @@ def store_subtitles_movie(file): 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.') + '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)) + logging.debug( + "BAZARR external subtitles detected and analysis guessed this language: " + str( + detected_language)) actual_subtitles.append([str(detected_language), path_replace_reverse_movie( - os.path.join(os.path.dirname(file), subtitle))]) - + 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_movies SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse_movie(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 @@ -200,7 +204,7 @@ def list_missing_subtitles(*no): episodes_subtitles = c_db.execute( "SELECT table_episodes.sonarrEpisodeId, table_episodes.subtitles, table_shows.languages FROM table_episodes INNER JOIN table_shows on table_episodes.sonarrSeriesId = table_shows.sonarrSeriesId" + query_string).fetchall() c_db.close() - + missing_subtitles_global = [] use_embedded_subs = settings.general.getboolean('use_embedded_subs') for episode_subtitles in episodes_subtitles: @@ -229,7 +233,7 @@ def list_missing_subtitles(*no): actual_subtitles_list.append(item[0]) missing_subtitles = list(set(desired_subtitles) - set(actual_subtitles_list)) missing_subtitles_global.append(tuple([str(missing_subtitles), episode_subtitles[0]])) - + conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() c_db.executemany("UPDATE table_episodes SET missing_subtitles = ? WHERE sonarrEpisodeId = ?", @@ -248,7 +252,7 @@ def list_missing_subtitles_movies(*no): c_db = conn_db.cursor() movies_subtitles = c_db.execute("SELECT radarrId, subtitles, languages FROM table_movies" + query_string).fetchall() c_db.close() - + missing_subtitles_global = [] use_embedded_subs = settings.general.getboolean('use_embedded_subs') for movie_subtitles in movies_subtitles: @@ -277,7 +281,7 @@ def list_missing_subtitles_movies(*no): actual_subtitles_list.append(item[0]) missing_subtitles = list(set(desired_subtitles) - set(actual_subtitles_list)) missing_subtitles_global.append(tuple([str(missing_subtitles), movie_subtitles[0]])) - + conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() c_db.executemany("UPDATE table_movies SET missing_subtitles = ? WHERE radarrId = ?", (missing_subtitles_global)) @@ -290,10 +294,10 @@ def series_full_scan_subtitles(): c_db = conn_db.cursor() episodes = c_db.execute("SELECT path FROM table_episodes").fetchall() c_db.close() - + for episode in episodes: store_subtitles(path_replace(episode[0])) - + gc.collect() @@ -302,10 +306,10 @@ def movies_full_scan_subtitles(): c_db = conn_db.cursor() movies = c_db.execute("SELECT path FROM table_movies").fetchall() c_db.close() - + for movie in movies: store_subtitles_movie(path_replace_movie(movie[0])) - + gc.collect() @@ -314,10 +318,10 @@ def series_scan_subtitles(no): c_db = conn_db.cursor() episodes = c_db.execute("SELECT path FROM table_episodes WHERE sonarrSeriesId = ?", (no,)).fetchall() c_db.close() - + for episode in episodes: store_subtitles(path_replace(episode[0])) - + list_missing_subtitles(no) @@ -326,8 +330,8 @@ def movies_scan_subtitles(no): c_db = conn_db.cursor() movies = c_db.execute("SELECT path FROM table_movies WHERE radarrId = ?", (no,)).fetchall() c_db.close() - + for movie in movies: store_subtitles_movie(path_replace_movie(movie[0])) - + list_missing_subtitles_movies(no) diff --git a/bazarr/logger.py b/bazarr/logger.py index 213e0a079..c83247313 100644 --- a/bazarr/logger.py +++ b/bazarr/logger.py @@ -18,7 +18,7 @@ class OneLineExceptionFormatter(logging.Formatter): """ result = super(OneLineExceptionFormatter, self).formatException(exc_info) return repr(result) # or format into one line however you want to - + def format(self, record): s = super(OneLineExceptionFormatter, self).format(record) if record.exc_text: @@ -30,7 +30,7 @@ class NoExceptionFormatter(logging.Formatter): def format(self, record): record.exc_text = '' # ensure formatException gets called return super(NoExceptionFormatter, self).format(record) - + def formatException(self, record): return '' @@ -40,21 +40,21 @@ def configure_logging(debug=False): log_level = "INFO" else: log_level = "DEBUG" - + logger.handlers = [] - + logger.setLevel(log_level) - + # Console logging ch = logging.StreamHandler() cf = (debug and logging.Formatter or NoExceptionFormatter)( '%(asctime)-15s - %(name)-32s (%(thread)x) : %(levelname)s (%(module)s:%(lineno)d) - %(message)s') ch.setFormatter(cf) - + ch.setLevel(log_level) # ch.addFilter(MyFilter()) logger.addHandler(ch) - + # File Logging global fh fh = TimedRotatingFileHandler(os.path.join(args.config_dir, 'log/bazarr.log'), when="midnight", interval=1, @@ -64,7 +64,7 @@ def configure_logging(debug=False): fh.setFormatter(f) fh.addFilter(BlacklistFilter()) fh.addFilter(PublicIPFilter()) - + if debug: logging.getLogger("apscheduler").setLevel(logging.DEBUG) logging.getLogger("subliminal").setLevel(logging.DEBUG) @@ -90,7 +90,7 @@ def configure_logging(debug=False): class MyFilter(logging.Filter): def __init__(self): super(MyFilter, self).__init__() - + def filter(self, record): if record.name != 'root': return 0 @@ -105,14 +105,14 @@ class ArgsFilteringFilter(logging.Filter): if not isinstance(arg, basestring): final_args.append(arg) continue - + final_args.append(func(arg)) record.args = type(record.args)(final_args) elif isinstance(record.args, dict): for key, arg in record.args.items(): if not isinstance(arg, basestring): continue - + record.args[key] = func(arg) @@ -121,17 +121,17 @@ class BlacklistFilter(ArgsFilteringFilter): Log filter for blacklisted tokens and passwords """ APIKEY_RE = re.compile(r'apikey(?:=|%3D)([a-zA-Z0-9]+)') - + def __init__(self): super(BlacklistFilter, self).__init__() - + def filter(self, record): def mask_apikeys(s): apikeys = self.APIKEY_RE.findall(s) for apikey in apikeys: s = s.replace(apikey, 8 * '*' + apikey[-2:]) return s - + try: record.msg = mask_apikeys(record.msg) self.filter_args(record, mask_apikeys) @@ -145,27 +145,26 @@ class PublicIPFilter(ArgsFilteringFilter): Log filter for public IP addresses """ IPV4_RE = re.compile(r'[0-9]+(?:\.[0-9]+){3}(?!\d*-[a-z0-9]{6})') - + def __init__(self): super(PublicIPFilter, self).__init__() - + def filter(self, record): def mask_ipv4(s): ipv4 = self.IPV4_RE.findall(s) for ip in ipv4: s = s.replace(ip, ip.partition('.')[0] + '.***.***.***') return s - + try: # Currently only checking for ipv4 addresses record.msg = mask_ipv4(record.msg) self.filter_args(record, mask_ipv4) except: pass - + return 1 def empty_log(): fh.doRollover() - \ No newline at end of file diff --git a/bazarr/main.py b/bazarr/main.py index 8bea99b81..5e6bd1c84 100644 --- a/bazarr/main.py +++ b/bazarr/main.py @@ -24,7 +24,7 @@ from logger import configure_logging, empty_log from gevent.pywsgi import WSGIServer from geventwebsocket import WebSocketError from geventwebsocket.handler import WebSocketHandler -#from cherrypy.wsgiserver import CherryPyWSGIServer +# from cherrypy.wsgiserver import CherryPyWSGIServer from io import BytesIO from six import text_type from beaker.middleware import SessionMiddleware @@ -131,14 +131,13 @@ def custom_auth_basic(check): return func(*a, **ka) else: return func(*a, **ka) - + return wrapper - + return decorator def check_credentials(user, pw): - username = settings.auth.username password = settings.auth.password if hashlib.md5(pw).hexdigest() == password and user == username: @@ -236,10 +235,10 @@ def wizard(): @custom_auth_basic(check_credentials) def save_wizard(): authorize() - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() - + settings_general_ip = request.forms.get('settings_general_ip') settings_general_port = request.forms.get('settings_general_port') settings_general_baseurl = request.forms.get('settings_general_baseurl') @@ -324,13 +323,14 @@ def save_wizard(): settings.radarr.only_monitored = text_type(settings_radarr_only_monitored) settings_subliminal_providers = request.forms.getall('settings_subliminal_providers') - settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join(settings_subliminal_providers) + settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join( + settings_subliminal_providers) settings_subliminal_languages = request.forms.getall('settings_subliminal_languages') c.execute("UPDATE table_settings_languages SET enabled = 0") for item in settings_subliminal_languages: c.execute("UPDATE table_settings_languages SET enabled = '1' WHERE code2 = ?", (item,)) - + settings_serie_default_enabled = request.forms.get('settings_serie_default_enabled') if settings_serie_default_enabled is None: settings_serie_default_enabled = 'False' @@ -367,16 +367,16 @@ def save_wizard(): settings_movie_default_hi = 'False' else: settings_movie_default_hi = 'True' - settings.general.movie_default_hi = text_type(settings_movie_default_hi) + settings.general.movie_default_hi = text_type(settings_movie_default_hi) with open(os.path.join(args.config_dir, 'config', 'config.ini'), 'w+') as handle: settings.write(handle) logging.info('Config file created successfully') - + conn.commit() c.close() - + configured() redirect(base_url) @@ -392,10 +392,10 @@ def static(path): def emptylog(): authorize() ref = request.environ['HTTP_REFERER'] - + empty_log() logging.info('BAZARR Log file emptied') - + redirect(ref) @@ -464,11 +464,11 @@ def redirect_root(): def series(): authorize() single_language = settings.general.getboolean('single_language') - + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_shows") missing_count = c.fetchone() missing_count = missing_count[0] @@ -478,12 +478,12 @@ def series(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(missing_count / (page_size + 0.0))) - + if settings.sonarr.getboolean('only_monitored'): monitored_only_query_string = ' AND monitored = "True"' else: monitored_only_query_string = "" - + c.execute( "SELECT tvdbId, title, path_substitution(path), languages, hearing_impaired, sonarrSeriesId, poster, audio_language FROM table_shows ORDER BY sortTitle ASC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -509,15 +509,15 @@ def series(): def serieseditor(): authorize() single_language = settings.general.getboolean('single_language') - + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_shows") missing_count = c.fetchone() missing_count = missing_count[0] - + c.execute( "SELECT tvdbId, title, path_substitution(path), languages, hearing_impaired, sonarrSeriesId, poster, audio_language FROM table_shows ORDER BY title ASC") data = c.fetchall() @@ -536,7 +536,7 @@ def search_json(query): authorize() db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + search_list = [] if settings.general.getboolean('use_sonarr'): c.execute("SELECT title, sonarrSeriesId FROM table_shows WHERE title LIKE ? ORDER BY title", @@ -544,14 +544,14 @@ def search_json(query): series = c.fetchall() for serie in series: search_list.append(dict([('name', serie[0]), ('url', base_url + 'episodes/' + str(serie[1]))])) - + if settings.general.getboolean('use_radarr'): c.execute("SELECT title, radarrId FROM table_movies WHERE title LIKE ? ORDER BY title", ('%' + query + '%',)) movies = c.fetchall() for movie in movies: search_list.append(dict([('name', movie[0]), ('url', base_url + 'movie/' + str(movie[1]))])) c.close() - + response.content_type = 'application/json' return dict(items=search_list) @@ -561,13 +561,13 @@ def search_json(query): def edit_series(no): authorize() ref = request.environ['HTTP_REFERER'] - + lang = request.forms.getall('languages') if len(lang) > 0: pass else: lang = 'None' - + single_language = settings.general.getboolean('single_language') if single_language is True: if str(lang) == "['None']": @@ -577,23 +577,23 @@ def edit_series(no): else: if str(lang) == "['']": lang = '[]' - + hi = request.forms.get('hearing_impaired') - + if hi == "on": hi = "True" else: hi = "False" - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() c.execute("UPDATE table_shows SET languages = ?, hearing_impaired = ? WHERE sonarrSeriesId LIKE ?", (str(lang), hi, no)) conn.commit() c.close() - + list_missing_subtitles(no) - + redirect(ref) @@ -602,15 +602,15 @@ def edit_series(no): def edit_serieseditor(): authorize() ref = request.environ['HTTP_REFERER'] - + series = request.forms.get('series') series = ast.literal_eval(str('[' + series + ']')) lang = request.forms.getall('languages') hi = request.forms.get('hearing_impaired') - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() - + for serie in series: if str(lang) != "[]" and str(lang) != "['']": if str(lang) == "['None']": @@ -620,13 +620,13 @@ def edit_serieseditor(): c.execute("UPDATE table_shows SET languages = ? WHERE sonarrSeriesId LIKE ?", (lang, serie)) if hi != '': c.execute("UPDATE table_shows SET hearing_impaired = ? WHERE sonarrSeriesId LIKE ?", (hi, serie)) - + conn.commit() c.close() - + for serie in series: list_missing_subtitles(serie) - + redirect(ref) @@ -635,17 +635,17 @@ def edit_serieseditor(): def episodes(no): authorize() # single_language = settings.general.getboolean('single_language') - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) conn.create_function("path_substitution", 1, path_replace) c = conn.cursor() - + series_details = [] series_details = c.execute( "SELECT title, overview, poster, fanart, hearing_impaired, tvdbid, audio_language, languages, path_substitution(path) FROM table_shows WHERE sonarrSeriesId LIKE ?", (str(no),)).fetchone() tvdbid = series_details[5] - + episodes = c.execute( "SELECT title, path_substitution(path), season, episode, subtitles, sonarrSeriesId, missing_subtitles, sonarrEpisodeId, scene_name, monitored, failedAttempts FROM table_episodes WHERE sonarrSeriesId LIKE ? ORDER BY episode ASC", (str(no),)).fetchall() @@ -656,21 +656,22 @@ def episodes(no): seasons_list = [] for key, season in itertools.groupby(episodes, operator.itemgetter(2)): seasons_list.append(list(season)) - + return template('episodes', bazarr_version=bazarr_version, no=no, details=series_details, languages=languages, seasons=seasons_list, url_sonarr_short=url_sonarr_short, base_url=base_url, tvdbid=tvdbid, number=number, current_port=settings.general.port) + @route(base_url + 'movies') @custom_auth_basic(check_credentials) def movies(): authorize() single_language = settings.general.getboolean('single_language') - + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace_movie) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_movies") missing_count = c.fetchone() missing_count = missing_count[0] @@ -680,7 +681,7 @@ def movies(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(missing_count / (page_size + 0.0))) - + c.execute( "SELECT tmdbId, title, path_substitution(path), languages, hearing_impaired, radarrId, poster, audio_language, monitored, sceneName FROM table_movies ORDER BY sortTitle ASC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -699,15 +700,15 @@ def movies(): def movieseditor(): authorize() single_language = settings.general.getboolean('single_language') - + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace_movie) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_movies") missing_count = c.fetchone() missing_count = missing_count[0] - + c.execute( "SELECT tmdbId, title, path_substitution(path), languages, hearing_impaired, radarrId, poster, audio_language FROM table_movies ORDER BY title ASC") data = c.fetchall() @@ -725,15 +726,15 @@ def movieseditor(): def edit_movieseditor(): authorize() ref = request.environ['HTTP_REFERER'] - + movies = request.forms.get('movies') movies = ast.literal_eval(str('[' + movies + ']')) lang = request.forms.getall('languages') hi = request.forms.get('hearing_impaired') - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() - + for movie in movies: if str(lang) != "[]" and str(lang) != "['']": if str(lang) == "['None']": @@ -743,13 +744,13 @@ def edit_movieseditor(): c.execute("UPDATE table_movies SET languages = ? WHERE radarrId LIKE ?", (lang, movie)) if hi != '': c.execute("UPDATE table_movies SET hearing_impaired = ? WHERE radarrId LIKE ?", (hi, movie)) - + conn.commit() c.close() - + for movie in movies: list_missing_subtitles_movies(movie) - + redirect(ref) @@ -758,31 +759,31 @@ def edit_movieseditor(): def edit_movie(no): authorize() ref = request.environ['HTTP_REFERER'] - + lang = request.forms.getall('languages') if len(lang) > 0: pass else: lang = 'None' - + if str(lang) == "['']": lang = '[]' - + hi = request.forms.get('hearing_impaired') - + if hi == "on": hi = "True" else: hi = "False" - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() c.execute("UPDATE table_movies SET languages = ?, hearing_impaired = ? WHERE radarrId LIKE ?", (str(lang), hi, no)) conn.commit() c.close() - + list_missing_subtitles_movies(no) - + redirect(ref) @@ -791,32 +792,33 @@ def edit_movie(no): def movie(no): authorize() # single_language = settings.general.getboolean('single_language') - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) conn.create_function("path_substitution", 1, path_replace_movie) c = conn.cursor() - + movies_details = [] movies_details = c.execute( "SELECT title, overview, poster, fanart, hearing_impaired, tmdbid, audio_language, languages, path_substitution(path), subtitles, radarrId, missing_subtitles, sceneName, monitored, failedAttempts FROM table_movies WHERE radarrId LIKE ?", (str(no),)).fetchone() tmdbid = movies_details[5] - + languages = c.execute("SELECT code2, name FROM table_settings_languages WHERE enabled = 1").fetchall() c.close() - + return template('movie', bazarr_version=bazarr_version, no=no, details=movies_details, languages=languages, url_radarr_short=url_radarr_short, base_url=base_url, tmdbid=tmdbid, current_port=settings.general.port) + @route(base_url + 'scan_disk/', method='GET') @custom_auth_basic(check_credentials) def scan_disk(no): authorize() ref = request.environ['HTTP_REFERER'] - + series_scan_subtitles(no) - + redirect(ref) @@ -825,9 +827,9 @@ def scan_disk(no): def scan_disk_movie(no): authorize() ref = request.environ['HTTP_REFERER'] - + movies_scan_subtitles(no) - + redirect(ref) @@ -836,9 +838,9 @@ def scan_disk_movie(no): def search_missing_subtitles(no): authorize() ref = request.environ['HTTP_REFERER'] - + series_download_subtitles(no) - + redirect(ref) @@ -847,9 +849,9 @@ def search_missing_subtitles(no): def search_missing_subtitles_movie(no): authorize() ref = request.environ['HTTP_REFERER'] - + movies_download_subtitles(no) - + redirect(ref) @@ -866,7 +868,7 @@ def historyseries(): authorize() db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_history") row_count = c.fetchone() row_count = row_count[0] @@ -876,7 +878,7 @@ def historyseries(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(row_count / (page_size + 0.0))) - + now = datetime.now() today = [] thisweek = [] @@ -891,7 +893,7 @@ def historyseries(): if now - timedelta(weeks=52) <= datetime.fromtimestamp(stat[0]) <= now: thisyear.append(datetime.fromtimestamp(stat[0]).date()) stats = [len(today), len(thisweek), len(thisyear), total] - + c.execute( "SELECT table_history.action, table_shows.title, table_episodes.season || 'x' || table_episodes.episode, table_episodes.title, table_history.timestamp, table_history.description, table_history.sonarrSeriesId FROM table_history LEFT JOIN table_shows on table_shows.sonarrSeriesId = table_history.sonarrSeriesId LEFT JOIN table_episodes on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId ORDER BY id DESC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -902,13 +904,14 @@ def historyseries(): page=page, max_page=max_page, stats=stats, base_url=base_url, page_size=page_size, current_port=settings.general.port) + @route(base_url + 'historymovies') @custom_auth_basic(check_credentials) def historymovies(): authorize() db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + c.execute("SELECT COUNT(*) FROM table_history_movie") row_count = c.fetchone() row_count = row_count[0] @@ -918,7 +921,7 @@ def historymovies(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(row_count / (page_size + 0.0))) - + now = datetime.now() today = [] thisweek = [] @@ -933,7 +936,7 @@ def historymovies(): if now - timedelta(weeks=52) <= datetime.fromtimestamp(stat[0]) <= now: thisyear.append(datetime.fromtimestamp(stat[0]).date()) stats = [len(today), len(thisweek), len(thisyear), total] - + c.execute( "SELECT table_history_movie.action, table_movies.title, table_history_movie.timestamp, table_history_movie.description, table_history_movie.radarrId FROM table_history_movie LEFT JOIN table_movies on table_movies.radarrId = table_history_movie.radarrId ORDER BY id DESC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -944,6 +947,7 @@ def historymovies(): page=page, max_page=max_page, stats=stats, base_url=base_url, page_size=page_size, current_port=settings.general.port) + @route(base_url + 'wanted') @custom_auth_basic(check_credentials) def wanted(): @@ -958,12 +962,12 @@ def wantedseries(): db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace) c = db.cursor() - + if settings.sonarr.getboolean('only_monitored'): monitored_only_query_string = ' AND monitored = "True"' else: monitored_only_query_string = "" - + c.execute("SELECT COUNT(*) FROM table_episodes WHERE missing_subtitles != '[]'" + monitored_only_query_string) missing_count = c.fetchone() missing_count = missing_count[0] @@ -973,7 +977,7 @@ def wantedseries(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(missing_count / (page_size + 0.0))) - + c.execute( "SELECT table_shows.title, table_episodes.season || 'x' || table_episodes.episode, table_episodes.title, table_episodes.missing_subtitles, table_episodes.sonarrSeriesId, path_substitution(table_episodes.path), table_shows.hearing_impaired, table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_episodes.failedAttempts FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.missing_subtitles != '[]'" + monitored_only_query_string + " ORDER BY table_episodes._rowid_ DESC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -983,6 +987,7 @@ def wantedseries(): missing_count=missing_count, page=page, max_page=max_page, base_url=base_url, page_size=page_size, current_port=settings.general.port) + @route(base_url + 'wantedmovies') @custom_auth_basic(check_credentials) def wantedmovies(): @@ -990,12 +995,12 @@ def wantedmovies(): db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) db.create_function("path_substitution", 1, path_replace_movie) c = db.cursor() - + if settings.radarr.getboolean('only_monitored'): monitored_only_query_string = ' AND monitored = "True"' else: monitored_only_query_string = "" - + c.execute("SELECT COUNT(*) FROM table_movies WHERE missing_subtitles != '[]'" + monitored_only_query_string) missing_count = c.fetchone() missing_count = missing_count[0] @@ -1005,7 +1010,7 @@ def wantedmovies(): page_size = int(settings.general.page_size) offset = (int(page) - 1) * page_size max_page = int(math.ceil(missing_count / (page_size + 0.0))) - + c.execute( "SELECT title, missing_subtitles, radarrId, path_substitution(path), hearing_impaired, sceneName, failedAttempts FROM table_movies WHERE missing_subtitles != '[]'" + monitored_only_query_string + " ORDER BY _rowid_ DESC LIMIT ? OFFSET ?", (page_size, offset,)) @@ -1015,14 +1020,15 @@ def wantedmovies(): missing_count=missing_count, page=page, max_page=max_page, base_url=base_url, page_size=page_size, current_port=settings.general.port) + @route(base_url + 'wanted_search_missing_subtitles') @custom_auth_basic(check_credentials) def wanted_search_missing_subtitles_list(): authorize() ref = request.environ['HTTP_REFERER'] - + wanted_search_missing_subtitles() - + redirect(ref) @@ -1038,8 +1044,10 @@ def _settings(): c.execute("SELECT * FROM table_settings_notifier ORDER BY name") settings_notifier = c.fetchall() c.close() - - return template('settings', bazarr_version=bazarr_version, settings=settings, settings_languages=settings_languages, settings_providers=settings_providers, settings_notifier=settings_notifier, base_url=base_url, current_port=settings.general.port) + + return template('settings', bazarr_version=bazarr_version, settings=settings, settings_languages=settings_languages, + settings_providers=settings_providers, settings_notifier=settings_notifier, base_url=base_url, + current_port=settings.general.port) @route(base_url + 'save_settings', method='POST') @@ -1047,10 +1055,10 @@ def _settings(): def save_settings(): authorize() ref = request.environ['HTTP_REFERER'] - + conn = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = conn.cursor() - + settings_general_ip = request.forms.get('settings_general_ip') settings_general_port = request.forms.get('settings_general_port') settings_general_baseurl = request.forms.get('settings_general_baseurl') @@ -1115,10 +1123,14 @@ def save_settings(): else: settings_general_use_radarr = 'True' settings_page_size = request.forms.get('settings_page_size') - - before = (unicode(settings.general.ip), int(settings.general.port), unicode(settings.general.base_url), unicode(settings.general.path_mappings), unicode(settings.general.getboolean('use_sonarr')), unicode(settings.general.getboolean('use_radarr')), unicode(settings.general.path_mappings_movie)) - after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie)) - + + before = (unicode(settings.general.ip), int(settings.general.port), unicode(settings.general.base_url), + unicode(settings.general.path_mappings), unicode(settings.general.getboolean('use_sonarr')), + unicode(settings.general.getboolean('use_radarr')), unicode(settings.general.path_mappings_movie)) + after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), + unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr), + unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie)) + settings.general.ip = text_type(settings_general_ip) settings.general.port = text_type(settings_general_port) settings.general.base_url = text_type(settings_general_baseurl) @@ -1138,17 +1150,17 @@ def save_settings(): settings.general.minimum_score_movie = text_type(settings_general_minimum_score_movies) settings.general.use_embedded_subs = text_type(settings_general_embedded) settings.general.adaptive_searching = text_type(settings_general_adaptive_searching) - + if after != before: configured() - + settings_proxy_type = request.forms.get('settings_proxy_type') settings_proxy_url = request.forms.get('settings_proxy_url') settings_proxy_port = request.forms.get('settings_proxy_port') settings_proxy_username = request.forms.get('settings_proxy_username') settings_proxy_password = request.forms.get('settings_proxy_password') settings_proxy_exclude = request.forms.get('settings_proxy_exclude') - + before_proxy_password = (unicode(settings.proxy.type), unicode(settings.proxy.exclude)) if before_proxy_password[0] != settings_proxy_type: configured() @@ -1165,11 +1177,11 @@ def save_settings(): settings.proxy.username = text_type(settings_proxy_username) settings.proxy.password = text_type(settings_proxy_password) settings.proxy.exclude = text_type(settings_proxy_exclude) - + settings_auth_type = request.forms.get('settings_auth_type') settings_auth_username = request.forms.get('settings_auth_username') settings_auth_password = request.forms.get('settings_auth_password') - + if settings.auth.type != settings_auth_type: configured() if settings.auth.password == settings_auth_password: @@ -1196,13 +1208,13 @@ def save_settings(): else: aaa._beaker_session.delete() else: - if settings.auth.password != settings_auth_password: + if settings.auth.password != settings_auth_password: aaa.user(settings_auth_username).update(role='', pwd=settings_auth_password) if settings_auth_type == 'basic' or settings_auth_type == 'None': pass else: aaa._beaker_session.delete() - + settings_sonarr_ip = request.forms.get('settings_sonarr_ip') settings_sonarr_port = request.forms.get('settings_sonarr_port') settings_sonarr_baseurl = request.forms.get('settings_sonarr_baseurl') @@ -1218,7 +1230,7 @@ def save_settings(): else: settings_sonarr_only_monitored = 'True' settings_sonarr_sync = request.forms.get('settings_sonarr_sync') - + settings.sonarr.ip = text_type(settings_sonarr_ip) settings.sonarr.port = text_type(settings_sonarr_port) settings.sonarr.base_url = text_type(settings_sonarr_baseurl) @@ -1226,7 +1238,7 @@ def save_settings(): settings.sonarr.apikey = text_type(settings_sonarr_apikey) settings.sonarr.only_monitored = text_type(settings_sonarr_only_monitored) settings.sonarr.full_update = text_type(settings_sonarr_sync) - + settings_radarr_ip = request.forms.get('settings_radarr_ip') settings_radarr_port = request.forms.get('settings_radarr_port') settings_radarr_baseurl = request.forms.get('settings_radarr_baseurl') @@ -1242,7 +1254,7 @@ def save_settings(): else: settings_radarr_only_monitored = 'True' settings_radarr_sync = request.forms.get('settings_radarr_sync') - + settings.radarr.ip = text_type(settings_radarr_ip) settings.radarr.port = text_type(settings_radarr_port) settings.radarr.base_url = text_type(settings_radarr_baseurl) @@ -1250,65 +1262,66 @@ def save_settings(): settings.radarr.apikey = text_type(settings_radarr_apikey) settings.radarr.only_monitored = text_type(settings_radarr_only_monitored) settings.radarr.full_update = text_type(settings_radarr_sync) - + settings_subliminal_providers = request.forms.getall('settings_subliminal_providers') - settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join(settings_subliminal_providers) - + settings.general.enabled_providers = u'' if not settings_subliminal_providers else ','.join( + settings_subliminal_providers) + settings.addic7ed.username = request.forms.get('settings_addic7ed_username') settings.addic7ed.password = request.forms.get('settings_addic7ed_password') settings.legendastv.username = request.forms.get('settings_legendastv_username') settings.legendastv.password = request.forms.get('settings_legendastv_password') settings.opensubtitles.username = request.forms.get('settings_opensubtitles_username') settings.opensubtitles.password = request.forms.get('settings_opensubtitles_password') - + settings_subliminal_languages = request.forms.getall('settings_subliminal_languages') c.execute("UPDATE table_settings_languages SET enabled = 0") for item in settings_subliminal_languages: c.execute("UPDATE table_settings_languages SET enabled = '1' WHERE code2 = ?", (item,)) - + settings_serie_default_enabled = request.forms.get('settings_serie_default_enabled') if settings_serie_default_enabled is None: settings_serie_default_enabled = 'False' else: settings_serie_default_enabled = 'True' settings.general.serie_default_enabled = text_type(settings_serie_default_enabled) - + settings_serie_default_languages = str(request.forms.getall('settings_serie_default_languages')) if settings_serie_default_languages == "['None']": settings_serie_default_languages = 'None' settings.general.serie_default_language = text_type(settings_serie_default_languages) - + settings_serie_default_hi = request.forms.get('settings_serie_default_hi') if settings_serie_default_hi is None: settings_serie_default_hi = 'False' else: settings_serie_default_hi = 'True' settings.general.serie_default_hi = text_type(settings_serie_default_hi) - + settings_movie_default_enabled = request.forms.get('settings_movie_default_enabled') if settings_movie_default_enabled is None: settings_movie_default_enabled = 'False' else: settings_movie_default_enabled = 'True' settings.general.movie_default_enabled = text_type(settings_movie_default_enabled) - + settings_movie_default_languages = str(request.forms.getall('settings_movie_default_languages')) if settings_movie_default_languages == "['None']": settings_movie_default_languages = 'None' settings.general.movie_default_language = text_type(settings_movie_default_languages) - + settings_movie_default_hi = request.forms.get('settings_movie_default_hi') if settings_movie_default_hi is None: settings_movie_default_hi = 'False' else: settings_movie_default_hi = 'True' - settings.general.movie_default_hi = text_type(settings_movie_default_hi) - + settings.general.movie_default_hi = text_type(settings_movie_default_hi) + with open(os.path.join(args.config_dir, 'config', 'config.ini'), 'w+') as handle: settings.write(handle) - + configure_logging(settings.general.getboolean('debug')) - + notifiers = c.execute("SELECT * FROM table_settings_notifier ORDER BY name").fetchall() for notifier in notifiers: enabled = request.forms.get('settings_notifier_' + notifier[0] + '_enabled') @@ -1319,15 +1332,15 @@ def save_settings(): notifier_url = request.forms.get('settings_notifier_' + notifier[0] + '_url') c.execute("UPDATE table_settings_notifier SET enabled = ?, url = ? WHERE name = ?", (enabled, notifier_url, notifier[0])) - + conn.commit() c.close() - + sonarr_full_update() radarr_full_update() - + logging.info('BAZARR Settings saved succesfully.') - + # reschedule full update task according to settings sonarr_full_update() @@ -1342,10 +1355,10 @@ def save_settings(): def check_update(): authorize() ref = request.environ['HTTP_REFERER'] - + if not args.no_update: check_and_apply_update() - + redirect(ref) @@ -1353,16 +1366,16 @@ def check_update(): @custom_auth_basic(check_credentials) def system(): authorize() - + def get_time_from_interval(interval): interval_clean = interval.split('[') interval_clean = interval_clean[1][:-1] interval_split = interval_clean.split(':') - + hour = interval_split[0] minute = interval_split[1].lstrip("0") second = interval_split[2].lstrip("0") - + text = "every " if hour != "0": text = text + hour @@ -1370,7 +1383,7 @@ def system(): text = text + " hour" else: text = text + " hours" - + if minute != "" and second != "": text = text + ", " elif minute == "" and second != "": @@ -1383,7 +1396,7 @@ def system(): text = text + " minute" else: text = text + " minutes" - + if second != "": text = text + " and " if second != "": @@ -1392,23 +1405,22 @@ def system(): text = text + " second" else: text = text + " seconds" - + return text - - + def get_time_from_cron(cron): text = "at " hour = str(cron[5]) minute = str(cron[6]) second = str(cron[7]) - + if hour != "0" and hour != "*": text = text + hour if hour == "0" or hour == "1": text = text + " hour" else: text = text + " hours" - + if minute != "*" and second != "0": text = text + ", " elif minute == "*" and second != "0": @@ -1421,7 +1433,7 @@ def system(): text = text + " minute" else: text = text + " minutes" - + if second != "0" and second != "*": text = text + " and " if second != "0" and second != "*": @@ -1430,21 +1442,21 @@ def system(): text = text + " second" else: text = text + " seconds" - + return text - + task_list = [] for job in scheduler.get_jobs(): if job.next_run_time is not None: next_run = pretty.date(job.next_run_time.replace(tzinfo=None)) else: next_run = "Never" - + if job.trigger.__str__().startswith('interval'): task_list.append([job.name, get_time_from_interval(str(job.trigger)), next_run, job.id]) elif job.trigger.__str__().startswith('cron'): task_list.append([job.name, get_time_from_cron(job.trigger.fields), next_run, job.id]) - + i = 0 with open(os.path.join(args.config_dir, 'log', 'bazarr.log')) as f: for i, l in enumerate(f, 1): @@ -1452,10 +1464,10 @@ def system(): row_count = i page_size = int(settings.general.page_size) max_page = int(math.ceil(row_count / (page_size + 0.0))) - + with open(os.path.join(args.config_dir, 'config', 'releases.txt'), 'r') as f: releases = ast.literal_eval(f.read()) - + use_sonarr = settings.general.getboolean('use_sonarr') apikey_sonarr = settings.sonarr.apikey sv = url_sonarr + "/api/system/status?apikey=" + apikey_sonarr @@ -1465,7 +1477,7 @@ def system(): sonarr_version = requests.get(sv, timeout=15, verify=False).json()['version'] except: pass - + use_radarr = settings.general.getboolean('use_radarr') apikey_radarr = settings.radarr.apikey rv = url_radarr + "/api/system/status?apikey=" + apikey_radarr @@ -1475,8 +1487,7 @@ def system(): radarr_version = requests.get(rv, timeout=15, verify=False).json()['version'] except: pass - - + return template('system', bazarr_version=bazarr_version, sonarr_version=sonarr_version, radarr_version=radarr_version, operating_system=platform.platform(), python_version=platform.python_version(), @@ -1496,19 +1507,18 @@ def get_logs(page): for line in reversed(open(os.path.join(args.config_dir, 'log', 'bazarr.log')).readlines()): logs_complete.append(line.rstrip()) logs = logs_complete[begin:end] - + return template('logs', logs=logs, base_url=base_url, current_port=settings.general.port) - @route(base_url + 'execute/') @custom_auth_basic(check_credentials) def execute_task(taskid): authorize() ref = request.environ['HTTP_REFERER'] - + execute_now(taskid) - + redirect(ref) @@ -1521,7 +1531,7 @@ def remove_subtitles(): subtitlesPath = request.forms.get('subtitlesPath') sonarrSeriesId = request.forms.get('sonarrSeriesId') sonarrEpisodeId = request.forms.get('sonarrEpisodeId') - + try: os.remove(subtitlesPath) result = language_from_alpha3(language) + " subtitles deleted from disk." @@ -1540,7 +1550,7 @@ def remove_subtitles_movie(): language = request.forms.get('language') subtitlesPath = request.forms.get('subtitlesPath') radarrId = request.forms.get('radarrId') - + try: os.remove(subtitlesPath) result = language_from_alpha3(language) + " subtitles deleted from disk." @@ -1556,7 +1566,7 @@ def remove_subtitles_movie(): def get_subtitle(): authorize() ref = request.environ['HTTP_REFERER'] - + episodePath = request.forms.get('episodePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') @@ -1565,10 +1575,10 @@ def get_subtitle(): sonarrEpisodeId = request.forms.get('sonarrEpisodeId') title = request.forms.get('title') # tvdbid = request.forms.get('tvdbid') - + providers_list = get_providers() providers_auth = get_providers_auth() - + try: result = download_subtitle(episodePath, language, hi, providers_list, providers_auth, sceneName, title, 'series') @@ -1587,16 +1597,16 @@ def get_subtitle(): def manual_search_json(): authorize() ref = request.environ['HTTP_REFERER'] - + episodePath = request.forms.get('episodePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') hi = request.forms.get('hi') title = request.forms.get('title') - + providers_list = get_providers() providers_auth = get_providers_auth() - + data = manual_search(episodePath, language, hi, providers_list, providers_auth, sceneName, title, 'series') return dict(data=data) @@ -1606,7 +1616,7 @@ def manual_search_json(): def manual_get_subtitle(): authorize() ref = request.environ['HTTP_REFERER'] - + episodePath = request.forms.get('episodePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') @@ -1616,10 +1626,10 @@ def manual_get_subtitle(): sonarrSeriesId = request.forms.get('sonarrSeriesId') sonarrEpisodeId = request.forms.get('sonarrEpisodeId') title = request.forms.get('title') - + providers_list = get_providers() providers_auth = get_providers_auth() - + try: result = manual_download_subtitle(episodePath, language, hi, subtitle, selected_provider, providers_auth, sceneName, title, 'series') @@ -1638,7 +1648,7 @@ def manual_get_subtitle(): def get_subtitle_movie(): authorize() ref = request.environ['HTTP_REFERER'] - + moviePath = request.forms.get('moviePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') @@ -1646,10 +1656,10 @@ def get_subtitle_movie(): radarrId = request.forms.get('radarrId') # tmdbid = request.forms.get('tmdbid') title = request.forms.get('title') - + providers_list = get_providers() providers_auth = get_providers_auth() - + try: result = download_subtitle(moviePath, language, hi, providers_list, providers_auth, sceneName, title, 'movie') if result is not None: @@ -1667,16 +1677,16 @@ def get_subtitle_movie(): def manual_search_movie_json(): authorize() ref = request.environ['HTTP_REFERER'] - + moviePath = request.forms.get('moviePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') hi = request.forms.get('hi') title = request.forms.get('title') - + providers_list = get_providers() providers_auth = get_providers_auth() - + data = manual_search(moviePath, language, hi, providers_list, providers_auth, sceneName, title, 'movie') return dict(data=data) @@ -1686,7 +1696,7 @@ def manual_search_movie_json(): def manual_get_subtitle_movie(): authorize() ref = request.environ['HTTP_REFERER'] - + moviePath = request.forms.get('moviePath') sceneName = request.forms.get('sceneName') language = request.forms.get('language') @@ -1695,10 +1705,10 @@ def manual_get_subtitle_movie(): subtitle = request.forms.get('subtitle') radarrId = request.forms.get('radarrId') title = request.forms.get('title') - + providers_list = get_providers() providers_auth = get_providers_auth() - + try: result = manual_download_subtitle(moviePath, language, hi, subtitle, selected_provider, providers_auth, sceneName, title, 'movie') @@ -1778,7 +1788,7 @@ def test_notification(protocol, provider): provider = urllib.unquote(provider) apobj = apprise.Apprise() apobj.add(protocol + "://" + provider) - + apobj.notify( title='Bazarr test notification', body=('Test notification') @@ -1791,9 +1801,9 @@ def handle_websocket(): wsock = request.environ.get('wsgi.websocket') if not wsock: abort(400, 'Expected WebSocket request.') - + queueconfig.q4ws.clear() - + while True: try: if len(queueconfig.q4ws) > 0: @@ -1808,7 +1818,8 @@ warnings.simplefilter("ignore", DeprecationWarning) server = WSGIServer((str(settings.general.ip), int(settings.general.port)), app, handler_class=WebSocketHandler) try: - logging.info('BAZARR is started and waiting for request on http://' + str(settings.general.ip) + ':' + str(settings.general.port) + str(base_url)) + logging.info('BAZARR is started and waiting for request on http://' + str(settings.general.ip) + ':' + str( + settings.general.port) + str(base_url)) # print 'Bazarr is started and waiting for request on http://' + str(ip) + ':' + str(port) + str(base_url) server.serve_forever() except KeyboardInterrupt: diff --git a/bazarr/queueconfig.py b/bazarr/queueconfig.py index 7c0fb1efa..6795fc125 100644 --- a/bazarr/queueconfig.py +++ b/bazarr/queueconfig.py @@ -1,4 +1,4 @@ from collections import deque global q4ws -q4ws = deque(maxlen=10) \ No newline at end of file +q4ws = deque(maxlen=10) diff --git a/bazarr/scheduler.py b/bazarr/scheduler.py index 0e297e370..a27012d01 100644 --- a/bazarr/scheduler.py +++ b/bazarr/scheduler.py @@ -6,6 +6,7 @@ from get_series import update_series from config import settings from get_subtitle import wanted_search_missing_subtitles from get_args import args + if not args.no_update: from check_update import check_and_apply_update, check_releases else: @@ -70,8 +71,10 @@ if not args.no_update: scheduler.add_job(check_and_apply_update, IntervalTrigger(hours=6), max_instances=1, coalesce=True, misfire_grace_time=15, id='update_bazarr', name='Update bazarr from source on Github') else: - scheduler.add_job(check_and_apply_update, CronTrigger(year='2100'), hour=4, id='update_bazarr', name='Update bazarr from source on Github') - scheduler.add_job(check_releases, IntervalTrigger(hours=6), max_instances=1, coalesce=True, misfire_grace_time=15, id='update_release', name='Update release info') + scheduler.add_job(check_and_apply_update, CronTrigger(year='2100'), hour=4, id='update_bazarr', + name='Update bazarr from source on Github') + scheduler.add_job(check_releases, IntervalTrigger(hours=6), max_instances=1, coalesce=True, + misfire_grace_time=15, id='update_release', name='Update release info') else: scheduler.add_job(check_releases, IntervalTrigger(hours=6), max_instances=1, coalesce=True, misfire_grace_time=15, id='update_release', name='Update release info') diff --git a/bazarr/update_db.py b/bazarr/update_db.py index 882811042..fab931320 100644 --- a/bazarr/update_db.py +++ b/bazarr/update_db.py @@ -12,7 +12,7 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): # Open database connection db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c = db.cursor() - + # Execute tables modifications try: c.execute('alter table table_settings_providers add column "username" "text"') @@ -20,29 +20,29 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): pass else: c.execute('UPDATE table_settings_providers SET username=""') - + try: c.execute('alter table table_settings_providers add column "password" "text"') except: pass else: c.execute('UPDATE table_settings_providers SET password=""') - + try: c.execute('alter table table_shows add column "audio_language" "text"') except: pass - + try: c.execute('alter table table_shows add column "sortTitle" "text"') except: pass - + try: c.execute('alter table table_movies add column "sortTitle" "text"') except: pass - + try: rows = c.execute('SELECT name FROM table_settings_notifier WHERE name = "Kodi/XBMC"').fetchall() if len(rows) == 0: @@ -52,21 +52,21 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): c.execute('UPDATE table_settings_notifier SET name=? WHERE name=?', (provider_new, provider_old)) except: pass - + try: c.execute('alter table table_movies add column "failedAttempts" "text"') c.execute('alter table table_episodes add column "failedAttempts" "text"') except: pass - + try: c.execute('alter table table_settings_languages add column "code3b" "text"') except: pass - + # Commit change to db db.commit() - + try: c.execute('alter table table_episodes add column "scene_name" TEXT') db.commit() @@ -77,7 +77,7 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): execute_now('sync_episodes') if settings.general.getboolean('use_radarr'): execute_now('update_movies') - + try: c.execute('alter table table_episodes add column "monitored" TEXT') db.commit() @@ -86,7 +86,7 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): else: if settings.general.getboolean('use_sonarr'): execute_now('sync_episodes') - + try: c.execute('alter table table_movies add column "monitored" TEXT') db.commit() @@ -95,5 +95,5 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): else: if settings.general.getboolean('use_radarr'): execute_now('update_movies') - + db.close()