diff --git a/bazarr/get_episodes.py b/bazarr/get_episodes.py index e7f35a6ab..4f80a2953 100644 --- a/bazarr/get_episodes.py +++ b/bazarr/get_episodes.py @@ -3,6 +3,7 @@ import os import sqlite3 import requests import logging +import re from queueconfig import q4ws from get_args import args @@ -75,7 +76,19 @@ def sync_episodes(): sceneName = episode['episodeFile']['sceneName'] else: sceneName = None - + + try: + format, resolution = episode['episodeFile']['quality']['quality']['name'].split('-') + except: + format = episode['episodeFile']['quality']['quality']['name'] + resolution = str(episode['episodeFile']['quality']['quality']['resolution']) + 'p' + + videoCodec = episode['episodeFile']['mediaInfo']['videoCodec'] + videoCodec = SonarrFormatVideoCodec(videoCodec) + + audioCodec = episode['episodeFile']['mediaInfo']['audioCodec'] + audioCodec = SonarrFormatAudioCodec(audioCodec) + # Add episodes in sonarr to current episode list current_episodes_sonarr.append(episode['id']) @@ -83,12 +96,14 @@ def sync_episodes(): episodes_to_update.append((episode['title'], episode['episodeFile']['path'], episode['seasonNumber'], episode['episodeNumber'], sceneName, str(bool(episode['monitored'])), - episode['id'])) + 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'])))) + str(bool(episode['monitored'])), format, resolution, + videoCodec, audioCodec)) removed_episodes = list(set(current_episodes_db_list) - set(current_episodes_sonarr)) @@ -97,12 +112,12 @@ def sync_episodes(): c = db.cursor() updated_result = c.executemany( - '''UPDATE table_episodes SET title = ?, path = ?, season = ?, episode = ?, scene_name = ?, monitored = ? WHERE sonarrEpisodeId = ?''', + '''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) VALUES (?, ?, ?, ?, ?, ?, ?, ?)''', + '''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() @@ -127,3 +142,28 @@ def sync_episodes(): logging.debug('BAZARR All missing subtitles updated in database.') q4ws.append('Episodes sync from Sonarr ended.') + + +def SonarrFormatAudioCodec(audioCodec): + if audioCodec == 'AC-3': return 'AC3' + if audioCodec == 'E-AC-3': return 'EAC3' + if audioCodec == 'MPEG Audio': return 'MP3' + + return audioCodec + + +def SonarrFormatVideoCodec(videoCodec): + if videoCodec == 'x264' or videoCodec == 'AVC': return 'h264' + if videoCodec == 'x265' or videoCodec == 'HEVC': return 'h265' + if videoCodec.startswith('XviD'): return 'XviD' + if videoCodec.startswith('DivX'): return 'DivX' + if videoCodec == 'MPEG-1 Video': return 'Mpeg' + if videoCodec == 'MPEG-2 Video': return 'Mpeg2' + if videoCodec == 'MPEG-4 Video': return 'Mpeg4' + if videoCodec == 'VC-1': return 'VC1' + if videoCodec.endswith('VP6'): return 'VP6' + if videoCodec.endswith('VP7'): return 'VP7' + if videoCodec.endswith('VP8'): return 'VP8' + if videoCodec.endswith('VP9'): return 'VP9' + + return videoCodec diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index f6890cceb..695322758 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -73,7 +73,31 @@ def update_movies(): 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'] + resolution = movie['movieFile']['quality']['quality']['resolution'].lstrip('r').lower() + + videoFormat = movie['movieFile']['mediaInfo']['videoFormat'] + videoCodecID = movie['movieFile']['mediaInfo']['videoCodecID'] + videoProfile = movie['movieFile']['mediaInfo']['videoProfile'] + videoCodecLibrary = movie['movieFile']['mediaInfo']['videoCodecLibrary'] + videoCodec = RadarrFormatVideoCodec(videoFormat, videoCodecID, videoProfile, videoCodecLibrary) + + audioFormat = movie['movieFile']['mediaInfo']['audioFormat'] + audioCodecID = movie['movieFile']['mediaInfo']['audioCodecID'] + audioProfile = movie['movieFile']['mediaInfo']['audioProfile'] + audioAdditionalFeatures = movie['movieFile']['mediaInfo']['audioAdditionalFeatures'] + audioCodec = RadarrFormatAudioCodec(audioFormat, audioCodecID, audioProfile, audioAdditionalFeatures) + # Add movies in radarr to current movies list current_movies_radarr.append(unicode(movie['tmdbId'])) @@ -89,22 +113,27 @@ def update_movies(): movie["tmdbId"], movie["id"], overview, poster, fanart, profile_id_to_language(movie['qualityProfileId']), sceneName, unicode(bool(movie['monitored'])), movie['sortTitle'], - movie["tmdbId"])) + 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, + 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'])) + unicode(bool(movie['monitored'])), movie['sortTitle'], + movie['year'], alternativeTitles, format, resolution, + videoCodec, audioCodec, imdbId)) 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'])) + unicode(bool(movie['monitored'])), movie['sortTitle'], + movie['year'], alternativeTitles, format, resolution, + videoCodec, audioCodec, imdbId)) else: logging.error( 'BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator + @@ -115,18 +144,18 @@ def update_movies(): 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 = ?''', + '''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) VALUES (?,?,?,?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', + '''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) 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 = ?), ?, ?, ?, ?, ?, ?, ?, ?)''', + '''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) VALUES (?,?,?,(SELECT languages FROM table_movies WHERE tmdbId = ?), '[]',(SELECT `hearing_impaired` FROM table_movies WHERE tmdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', movies_to_add) db.commit() @@ -183,5 +212,51 @@ def profile_id_to_language(id): return profile[1] +def RadarrFormatAudioCodec(audioFormat, audioCodecID, audioProfile, audioAdditionalFeatures): + if audioFormat == "AC-3": return "AC3" + if audioFormat == "E-AC-3": return "EAC3" + if audioFormat == "AAC": + if audioCodecID == "A_AAC/MPEG4/LC/SBR": + return "HE-AAC" + else: + return "AAC" + if audioFormat.strip() == "mp3": return "MP3" + if audioFormat == "MPEG Audio": + if audioCodecID == "55" or audioCodecID == "A_MPEG/L3" or audioProfile == "Layer 3": return "MP3" + if audioCodecID == "A_MPEG/L2" or audioProfile == "Layer 2": return "MP2" + if audioFormat == "MLP FBA": + if audioAdditionalFeatures == "16-ch": + return "TrueHD Atmos" + else: + return "TrueHD" + + return audioFormat + + +def RadarrFormatVideoCodec(videoFormat, videoCodecID, videoProfile, videoCodecLibrary): + if videoFormat == "x264": return "h264" + if videoFormat == "AVC" or videoFormat == "V.MPEG4/ISO/AVC": return "h264" + if videoFormat == "HEVC" or videoFormat == "V_MPEGH/ISO/HEVC": + if videoCodecLibrary.startswith("x265"): return "h265" + if videoFormat == "MPEG Video": + if videoCodecID == "2" or videoCodecID == "V_MPEG2": + return "Mpeg2" + else: + return "Mpeg" + if videoFormat == "MPEG-1 Video": return "Mpeg" + if videoFormat == "MPEG-2 Video": return "Mpeg2" + if videoFormat == "MPEG-4 Visual": + if videoCodecID.endswith("XVID") or videoCodecLibrary.startswith("XviD"): return "XviD" + if videoCodecID.endswith("DIV3") or videoCodecID.endswith("DIVX") or videoCodecID.endswith( + "DX50") or videoCodecLibrary.startswith("DivX"): return "DivX" + if videoFormat == "VC-1": return "VC1" + if videoFormat == "WMV2": + return "WMV" + if videoFormat == "DivX" or videoFormat == "div3": + return "DivX" + + return videoFormat + + if __name__ == '__main__': update_movies() diff --git a/bazarr/get_series.py b/bazarr/get_series.py index f00f87294..960cb8c57 100644 --- a/bazarr/get_series.py +++ b/bazarr/get_series.py @@ -68,7 +68,10 @@ def update_series(): 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']) @@ -76,34 +79,36 @@ def update_series(): 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["tvdbId"])) + 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'])) + profile_id_to_language(show['qualityProfileId']), show['sortTitle'], + show['year'], alternateTitles)) 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'])) + profile_id_to_language(show['qualityProfileId']), show['sortTitle'], + show['year'], alternateTitles)) # 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 = ?''', + '''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) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', + '''INSERT OR IGNORE INTO table_shows(title, path, tvdbId, languages,`hearing_impaired`, sonarrSeriesId, overview, poster, fanart, `audio_language`, sortTitle, year, alternateTitles) 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) VALUES (?,?,?,(SELECT languages FROM table_shows WHERE tvdbId = ?),(SELECT `hearing_impaired` FROM table_shows WHERE tvdbId = ?), ?, ?, ?, ?, ?, ?)''', + '''INSERT OR IGNORE INTO table_shows(title, path, tvdbId, languages,`hearing_impaired`, sonarrSeriesId, overview, poster, fanart, `audio_language`, sortTitle, year, alternateTitles) VALUES (?,?,?,(SELECT languages FROM table_shows WHERE tvdbId = ?),(SELECT `hearing_impaired` FROM table_shows WHERE tvdbId = ?), ?, ?, ?, ?, ?, ?, ?, ?)''', series_to_add) db.commit() db.close() diff --git a/bazarr/get_subtitle.py b/bazarr/get_subtitle.py index a1c85eb51..f823b3704 100644 --- a/bazarr/get_subtitle.py +++ b/bazarr/get_subtitle.py @@ -12,13 +12,15 @@ import cPickle as pickle import codecs import types import chardet +import re import subliminal import subliminal_patch +from ast import literal_eval from datetime import datetime, timedelta from subzero.language import Language -from subzero.video import parse_video, refine_video +from subzero.video import parse_video from subliminal import region, score as subliminal_scores, \ - list_subtitles + list_subtitles, Episode, Movie from subliminal_patch.core import SZAsyncProviderPool, download_best_subtitles, save_subtitles, download_subtitles from subliminal_patch.score import compute_score from get_languages import language_from_alpha3, alpha2_from_alpha3, alpha3_from_alpha2, language_from_alpha2 @@ -64,12 +66,9 @@ def get_video(path, title, sceneName, use_scenename, providers=None, media_type= video.used_scene_name = dont_use_actual_file video.original_name = original_name video.original_path = original_path - try: - refine_video(video) - except Exception as e: - logging.debug('BAZARR Error trying to refine this file: ' + path) - pass + refine_from_db(original_path,video) return video + except: logging.exception("BAZARR Error trying to get video information for this file: " + path) else: @@ -104,7 +103,7 @@ def get_scores(video, media_type, min_score_movie_perc=60 * 100 / 120.0, min_sco 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 @@ -237,7 +236,7 @@ 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": @@ -616,3 +615,47 @@ def search_active(timestamp): return False else: return True + + +def refine_from_db(path, video): + if isinstance(video, Episode): + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) + c = db.cursor() + data = c.execute("SELECT table_shows.title, table_episodes.season, table_episodes.episode, table_episodes.title, table_shows.year, table_shows.tvdbId, table_shows.alternateTitles, table_episodes.format, table_episodes.resolution, table_episodes.video_codec, table_episodes.audio_codec FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.path = ?", (path_replace_reverse(path),)).fetchone() + db.close() + if data: + video.series = re.sub(r'(\(\d\d\d\d\))' , '', data[0]) + video.season = int(data[1]) + video.episode = int(data[2]) + video.title = data[3] + if int(data[4]) > 0: video.year = int(data[4]) + video.series_tvdb_id = int(data[5]) + video.alternative_series = ast.literal_eval(data[6]) + if not video.format: + video.format = str(data[7]) + if not video.resolution: + video.resolution = str(data[8]) + if not video.video_codec: + if data[9]: video.video_codec = data[9] + if not video.audio_codec: + if data[10]: video.audio_codec = data[10] + elif isinstance(video, Movie): + db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) + c = db.cursor() + data = c.execute("SELECT title, year, alternativeTitles, format, resolution, video_codec, audio_codec, imdbId FROM table_movies WHERE path = ?", (path_replace_reverse_movie(path),)).fetchone() + db.close() + if data: + video.title = re.sub(r'(\(\d\d\d\d\))' , '', data[0]) + if int(data[1]) > 0: video.year = int(data[1]) + if data[7]: video.imdb_id = data[7] + video.alternative_titles = ast.literal_eval(data[2]) + if not video.format: + if data[3]: video.format = data[3] + if not video.resolution: + if data[4]: video.resolution = data[4] + if not video.video_codec: + if data[5]: video.video_codec = data[5] + if not video.audio_codec: + if data[6]: video.audio_codec = data[6] + + return video diff --git a/bazarr/main.py b/bazarr/main.py index 77586d27b..e8e2f2460 100644 --- a/bazarr/main.py +++ b/bazarr/main.py @@ -1,6 +1,9 @@ # coding=utf-8 -bazarr_version = '0.7.1' +bazarr_version = '0.7.2' + +from gevent import monkey +monkey.patch_all() import gc import sys diff --git a/bazarr/update_db.py b/bazarr/update_db.py index fab931320..98a1b55c0 100644 --- a/bazarr/update_db.py +++ b/bazarr/update_db.py @@ -95,5 +95,31 @@ if os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): else: if settings.general.getboolean('use_radarr'): execute_now('update_movies') + + try: + c.execute('alter table table_shows add column "year" "text"') + c.execute('alter table table_shows add column "alternateTitles" "text"') + + c.execute('alter table table_episodes add column "format" "text"') + c.execute('alter table table_episodes add column "resolution" "text"') + c.execute('alter table table_episodes add column "video_codec" "text"') + c.execute('alter table table_episodes add column "audio_codec" "text"') + + c.execute('alter table table_movies add column "year" "text"') + c.execute('alter table table_movies add column "alternativeTitles" "text"') + c.execute('alter table table_movies add column "format" "text"') + c.execute('alter table table_movies add column "resolution" "text"') + c.execute('alter table table_movies add column "video_codec" "text"') + c.execute('alter table table_movies add column "audio_codec" "text"') + c.execute('alter table table_movies add column "imdbId" "text"') + db.commit() + except: + pass + else: + if settings.general.getboolean('use_sonarr'): + execute_now('update_series') + execute_now('sync_episodes') + if settings.general.getboolean('use_radarr'): + execute_now('update_movies') db.close() diff --git a/views/wantedmovies.tpl b/views/wantedmovies.tpl index 0537f7719..df87d8edd 100644 --- a/views/wantedmovies.tpl +++ b/views/wantedmovies.tpl @@ -73,12 +73,12 @@ active = search_active(lang[1]) if active: %> - + {{language}} %else: - + {{language}} diff --git a/views/wantedseries.tpl b/views/wantedseries.tpl index 4e80152f7..d1dac768c 100644 --- a/views/wantedseries.tpl +++ b/views/wantedseries.tpl @@ -80,12 +80,12 @@ active = search_active(lang[1]) if active: %> - + {{language}} %else: - + {{language}}