bazarr/get_subtitle.py

263 lines
13 KiB
Python
Raw Normal View History

2017-09-17 00:11:47 +00:00
import os
2017-10-16 23:27:19 +00:00
import sqlite3
import ast
2017-12-06 04:07:37 +00:00
import logging
2018-03-24 00:00:50 +00:00
import subprocess
2017-09-17 00:11:47 +00:00
from babelfish import *
from subliminal import *
2017-09-17 13:02:16 +00:00
from pycountry import *
2018-03-24 00:00:50 +00:00
from bs4 import UnicodeDammit
2017-10-16 23:27:19 +00:00
from get_general_settings import *
from list_subtitles import *
from utils import *
2018-04-24 14:48:52 +00:00
from notifier import send_notifications, send_notifications_movie
2017-09-17 00:11:47 +00:00
# configure the cache
2018-01-16 04:30:41 +00:00
region.configure('dogpile.cache.memory')
2017-09-17 00:11:47 +00:00
2018-05-02 10:25:42 +00:00
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, type):
if type == 'series':
type_of_score = 359
elif type == 'movies':
type_of_score = 119
minimum_score = float(get_general_settings()[8]) / 100 * type_of_score
use_scenename = get_general_settings()[9]
2018-03-24 00:00:50 +00:00
use_postprocessing = get_general_settings()[10]
postprocessing_cmd = get_general_settings()[11]
2017-11-16 18:39:47 +00:00
try:
if sceneName is None or use_scenename == "False":
used_sceneName = False
video = scan_video(path)
else:
used_sceneName = True
video = Video.fromname(sceneName)
except Exception as e:
logging.exception('Error trying to extract information from this filename: ' + path)
2017-11-16 18:39:47 +00:00
return None
else:
try:
best_subtitles = download_best_subtitles([video], {Language(language)}, providers=providers, min_score=minimum_score, hearing_impaired=hi, provider_configs=providers_auth)
except Exception as e:
logging.exception('Error trying to get the best subtitles for this file: ' + path)
return None
else:
try:
2018-01-05 15:41:08 +00:00
best_subtitle = best_subtitles[video][0]
except:
logging.debug('No subtitles found for ' + path)
2018-01-05 15:41:08 +00:00
return None
else:
2018-01-10 16:44:47 +00:00
single = get_general_settings()[7]
2018-01-05 15:41:08 +00:00
try:
2018-05-02 10:25:42 +00:00
score = round(float(compute_score(best_subtitle, video)) / type_of_score * 100, 2)
if used_sceneName == True:
video = scan_video(path)
2018-01-10 16:44:47 +00:00
if single == 'True':
result = save_subtitles(video, [best_subtitle], single=True, encoding='utf-8')
else:
result = save_subtitles(video, [best_subtitle], encoding='utf-8')
2018-01-05 15:41:08 +00:00
except:
logging.error('Error saving subtitles file to disk.')
return None
else:
2018-03-24 00:00:50 +00:00
downloaded_provider = str(result[0][0]).strip('<>').split(' ')[0][:-8]
downloaded_language = pycountry.languages.lookup(str(str(result[0][0]).strip('<>').split(' ')[2].strip('[]'))).name
downloaded_language_code2 = pycountry.languages.lookup(downloaded_language).alpha_2
downloaded_language_code3 = pycountry.languages.lookup(downloaded_language).alpha_3
downloaded_path = result[1]
if used_sceneName == True:
2018-03-15 02:59:07 +00:00
message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using this scene name obtained from Sonarr: " + sceneName
else:
2018-03-15 02:59:07 +00:00
message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using filename guessing."
2018-03-24 00:00:50 +00:00
if use_postprocessing == "True":
command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3)
try:
if os.name == 'nt':
codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for the process to terminate
out_codepage, err_codepage = codepage.communicate()
encoding = out_codepage.split(':')[-1].strip()
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for the process to terminate
out, err = process.communicate()
if os.name == 'nt':
out = out.decode(encoding)
except:
if out == "":
logging.error('Post-processing result for file ' + path + ' : Nothing returned from command execution')
else:
logging.error('Post-processing result for file ' + path + ' : ' + out)
else:
if out == "":
logging.info('Post-processing result for file ' + path + ' : Nothing returned from command execution')
else:
logging.info('Post-processing result for file ' + path + ' : ' + out)
2018-01-05 15:41:08 +00:00
return message
2017-10-16 23:27:19 +00:00
def series_download_subtitles(no):
conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
2017-10-16 23:27:19 +00:00
c_db = conn_db.cursor()
episodes_details = c_db.execute("SELECT path, missing_subtitles, sonarrEpisodeId, scene_name FROM table_episodes WHERE sonarrSeriesId = ?", (no,)).fetchall()
2017-10-16 23:27:19 +00:00
series_details = c_db.execute("SELECT hearing_impaired FROM table_shows WHERE sonarrSeriesId = ?", (no,)).fetchone()
enabled_providers = c_db.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
2017-10-16 23:27:19 +00:00
c_db.close()
providers_list = []
providers_auth = {}
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
try:
if provider[2] is not '' and provider[3] is not '':
provider_auth = providers_auth.append(provider[0])
provider_auth.update({'username':providers[2], 'password':providers[3]})
else:
providers_auth = None
except:
providers_auth = None
else:
providers_list = None
providers_auth = None
2017-10-16 23:27:19 +00:00
for episode in episodes_details:
for language in ast.literal_eval(episode[1]):
2018-05-02 10:25:42 +00:00
message = download_subtitle(path_replace(episode[0]), str(pycountry.languages.lookup(language).alpha_3), series_details[0], providers_list, providers_auth, episode[3], 'series')
2017-10-16 23:27:19 +00:00
if message is not None:
store_subtitles(path_replace(episode[0]))
history_log(1, no, episode[2], message)
send_notifications(no, episode[2], message)
2017-11-16 18:42:23 +00:00
list_missing_subtitles(no)
2017-10-16 23:27:19 +00:00
2018-04-24 14:48:52 +00:00
def movies_download_subtitles(no):
conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
c_db = conn_db.cursor()
movie = c_db.execute("SELECT path, missing_subtitles, radarrId, sceneName, hearing_impaired FROM table_movies WHERE radarrId = ?", (no,)).fetchone()
enabled_providers = c_db.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
c_db.close()
providers_list = []
providers_auth = {}
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
try:
if provider[2] is not '' and provider[3] is not '':
provider_auth = providers_auth.append(provider[0])
provider_auth.update({'username': providers[2], 'password': providers[3]})
else:
providers_auth = None
except:
providers_auth = None
else:
providers_list = None
providers_auth = None
for language in ast.literal_eval(movie[1]):
message = download_subtitle(path_replace_movie(movie[0]), str(pycountry.languages.lookup(language).alpha_3), movie[4], providers_list, providers_auth, movie[3], 'movies')
2018-04-24 14:48:52 +00:00
if message is not None:
store_subtitles_movie(path_replace_movie(movie[0]))
2018-04-24 14:48:52 +00:00
history_log_movie(1, no, message)
send_notifications_movie(no, message)
list_missing_subtitles_movies(no)
2017-10-16 23:27:19 +00:00
def wanted_download_subtitles(path):
2017-12-05 00:01:10 +00:00
conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
2017-11-16 19:09:40 +00:00
c_db = conn_db.cursor()
episodes_details = c_db.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, table_episodes.sonarrEpisodeId, table_episodes.sonarrSeriesId, table_shows.hearing_impaired, table_episodes.scene_name 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()
enabled_providers = c_db.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
2017-11-16 19:09:40 +00:00
c_db.close()
2017-10-16 23:27:19 +00:00
2017-11-16 19:09:40 +00:00
providers_list = []
providers_auth = {}
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
try:
if provider[2] is not '' and provider[3] is not '':
provider_auth = providers_auth.append(provider[0])
provider_auth.update({'username':providers[2], 'password':providers[3]})
else:
providers_auth = None
except:
providers_auth = None
else:
providers_list = None
providers_auth = None
2017-10-16 23:27:19 +00:00
2017-11-16 19:09:40 +00:00
for episode in episodes_details:
for language in ast.literal_eval(episode[1]):
2018-05-02 10:25:42 +00:00
message = download_subtitle(path_replace(episode[0]), str(pycountry.languages.lookup(language).alpha_3), episode[4], providers_list, providers_auth, episode[5], 'series')
2017-11-16 19:09:40 +00:00
if message is not None:
store_subtitles(path_replace(episode[0]))
list_missing_subtitles(episode[3])
history_log(1, episode[3], episode[2], message)
send_notifications(episode[3], episode[2], message)
2017-11-16 17:04:20 +00:00
def wanted_download_subtitles_movie(path):
conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
c_db = conn_db.cursor()
movies_details = c_db.execute("SELECT path, missing_subtitles, radarrId, radarrId, hearing_impaired, sceneName FROM table_movies WHERE path = ? AND missing_subtitles != '[]'", (path_replace_reverse_movie(path),)).fetchall()
enabled_providers = c_db.execute("SELECT * FROM table_settings_providers WHERE enabled = 1").fetchall()
c_db.close()
providers_list = []
providers_auth = {}
if len(enabled_providers) > 0:
for provider in enabled_providers:
providers_list.append(provider[0])
try:
if provider[2] is not '' and provider[3] is not '':
provider_auth = providers_auth.append(provider[0])
provider_auth.update({'username': providers[2], 'password': providers[3]})
else:
providers_auth = None
except:
providers_auth = None
else:
providers_list = None
providers_auth = None
for movie in movies_details:
for language in ast.literal_eval(movie[1]):
message = download_subtitle(path_replace_movie(movie[0]), str(pycountry.languages.lookup(language).alpha_3), movie[4], providers_list, providers_auth, movie[5], 'movies')
if message is not None:
store_subtitles_movie(path_replace_movie(movie[0]))
list_missing_subtitles_movies(movie[3])
history_log_movie(1, movie[3], message)
send_notifications_movie(movie[3], message)
2017-10-23 03:00:11 +00:00
def wanted_search_missing_subtitles():
2017-12-05 00:01:10 +00:00
db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
2017-10-23 03:00:11 +00:00
db.create_function("path_substitution", 1, path_replace)
db.create_function("path_substitution_movie", 1, path_replace_movie)
2017-10-23 03:00:11 +00:00
c = db.cursor()
2018-05-02 10:25:42 +00:00
c.execute("SELECT path_substitution(path) FROM table_episodes WHERE missing_subtitles != '[]'")
episodes = c.fetchall()
c.execute("SELECT path_substitution_movie(path) FROM table_movies WHERE missing_subtitles != '[]'")
2018-05-02 10:25:42 +00:00
movies = c.fetchall()
2017-10-23 03:00:11 +00:00
c.close()
integration = get_general_settings()
if integration[12] == "True":
for episode in episodes:
wanted_download_subtitles(episode[0])
if integration[13] == "True":
for movie in movies:
wanted_download_subtitles_movie(movie[0])
2017-12-06 04:07:37 +00:00
2018-05-02 10:25:42 +00:00
logging.info('Finished searching for missing subtitles. Check histories for more information.')