mirror of https://github.com/morpheus65535/bazarr
Splitting path substitution for Radarr to address the case where Sonarr and Radarr access files trough the same path.
This commit is contained in:
parent
a40e203188
commit
6e4bc14144
18
bazarr.py
18
bazarr.py
|
@ -337,7 +337,7 @@ def movies():
|
|||
single_language = get_general_settings()[7]
|
||||
|
||||
db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
db.create_function("path_substitution", 1, path_replace)
|
||||
db.create_function("path_substitution", 1, path_replace_movie)
|
||||
c = db.cursor()
|
||||
|
||||
c.execute("SELECT COUNT(*) FROM table_movies")
|
||||
|
@ -362,7 +362,7 @@ def movieseditor():
|
|||
single_language = get_general_settings()[7]
|
||||
|
||||
db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
db.create_function("path_substitution", 1, path_replace)
|
||||
db.create_function("path_substitution", 1, path_replace_movie)
|
||||
c = db.cursor()
|
||||
|
||||
c.execute("SELECT COUNT(*) FROM table_movies")
|
||||
|
@ -444,7 +444,7 @@ def movie(no):
|
|||
url_radarr_short = get_radarr_settings()[1]
|
||||
|
||||
conn = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
conn.create_function("path_substitution", 1, path_replace)
|
||||
conn.create_function("path_substitution", 1, path_replace_movie)
|
||||
c = conn.cursor()
|
||||
|
||||
movies_details = []
|
||||
|
@ -589,7 +589,7 @@ def wantedseries():
|
|||
@route(base_url + 'wantedmovies')
|
||||
def wantedmovies():
|
||||
db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
db.create_function("path_substitution", 1, path_replace)
|
||||
db.create_function("path_substitution", 1, path_replace_movie)
|
||||
c = db.cursor()
|
||||
|
||||
c.execute("SELECT COUNT(*) FROM table_movies WHERE missing_subtitles != '[]'")
|
||||
|
@ -648,6 +648,10 @@ def save_settings():
|
|||
settings_general_destpath = request.forms.getall('settings_general_destpath')
|
||||
settings_general_pathmapping = []
|
||||
settings_general_pathmapping.extend([list(a) for a in zip(settings_general_sourcepath, settings_general_destpath)])
|
||||
settings_general_sourcepath_movie = request.forms.getall('settings_general_sourcepath_movie')
|
||||
settings_general_destpath_movie = request.forms.getall('settings_general_destpath_movie')
|
||||
settings_general_pathmapping_movie = []
|
||||
settings_general_pathmapping_movie.extend([list(a) for a in zip(settings_general_sourcepath_movie, settings_general_destpath_movie)])
|
||||
settings_general_branch = request.forms.get('settings_general_branch')
|
||||
settings_general_automatic = request.forms.get('settings_general_automatic')
|
||||
if settings_general_automatic is None:
|
||||
|
@ -682,9 +686,9 @@ def save_settings():
|
|||
else:
|
||||
settings_general_use_radarr = 'True'
|
||||
|
||||
before = c.execute("SELECT ip, port, base_url, log_level, path_mapping, use_sonarr, use_radarr FROM table_settings_general").fetchone()
|
||||
after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_loglevel), unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr))
|
||||
c.execute("UPDATE table_settings_general SET ip = ?, port = ?, base_url = ?, path_mapping = ?, log_level = ?, branch=?, auto_update=?, single_language=?, minimum_score=?, use_scenename=?, use_postprocessing=?, postprocessing_cmd=?, use_sonarr=?, use_radarr=?", (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_loglevel), unicode(settings_general_branch), unicode(settings_general_automatic), unicode(settings_general_single_language), unicode(settings_general_minimum_score), unicode(settings_general_scenename), unicode(settings_general_use_postprocessing), unicode(settings_general_postprocessing_cmd), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr)))
|
||||
before = c.execute("SELECT ip, port, base_url, log_level, path_mapping, use_sonarr, use_radarr, path_mapping_movie FROM table_settings_general").fetchone()
|
||||
after = (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_loglevel), unicode(settings_general_pathmapping), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie))
|
||||
c.execute("UPDATE table_settings_general SET ip = ?, port = ?, base_url = ?, path_mapping = ?, log_level = ?, branch=?, auto_update=?, single_language=?, minimum_score=?, use_scenename=?, use_postprocessing=?, postprocessing_cmd=?, use_sonarr=?, use_radarr=?, path_mapping_movie=?", (unicode(settings_general_ip), int(settings_general_port), unicode(settings_general_baseurl), unicode(settings_general_pathmapping), unicode(settings_general_loglevel), unicode(settings_general_branch), unicode(settings_general_automatic), unicode(settings_general_single_language), unicode(settings_general_minimum_score), unicode(settings_general_scenename), unicode(settings_general_use_postprocessing), unicode(settings_general_postprocessing_cmd), unicode(settings_general_use_sonarr), unicode(settings_general_use_radarr), unicode(settings_general_pathmapping_movie)))
|
||||
conn.commit()
|
||||
if after != before:
|
||||
configured()
|
||||
|
|
|
@ -34,8 +34,12 @@ def get_general_settings():
|
|||
postprocessing_cmd = general_settings[13]
|
||||
use_sonarr = general_settings[14]
|
||||
use_radarr = general_settings[15]
|
||||
if general_settings[16] is None:
|
||||
path_mappings_movie = []
|
||||
else:
|
||||
path_mappings_movie = ast.literal_eval(general_settings[16])
|
||||
|
||||
return [ip, port, base_url, path_mappings, log_level, branch, automatic, single_language, minimum_score, use_scenename, use_postprocessing, postprocessing_cmd, use_sonarr, use_radarr]
|
||||
return [ip, port, base_url, path_mappings, log_level, branch, automatic, single_language, minimum_score, use_scenename, use_postprocessing, postprocessing_cmd, use_sonarr, use_radarr, path_mappings_movie]
|
||||
|
||||
def path_replace(path):
|
||||
for path_mapping in path_mappings:
|
||||
|
@ -59,6 +63,28 @@ def path_replace_reverse(path):
|
|||
break
|
||||
return path
|
||||
|
||||
def path_replace_movie(path):
|
||||
for path_mapping in path_mappings_movie:
|
||||
if path_mapping[0] in path:
|
||||
path = path.replace(path_mapping[0], path_mapping[1])
|
||||
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
|
||||
path = path.replace('/', '\\')
|
||||
elif path.startswith('/'):
|
||||
path = path.replace('\\', '/')
|
||||
break
|
||||
return path
|
||||
|
||||
def path_replace_reverse_movie(path):
|
||||
for path_mapping in path_mappings_movie:
|
||||
if path_mapping[1] in path:
|
||||
path = path.replace(path_mapping[1], path_mapping[0])
|
||||
if path.startswith('\\\\') or re.match(r'^[a-zA-Z]:\\', path):
|
||||
path = path.replace('/', '\\')
|
||||
elif path.startswith('/'):
|
||||
path = path.replace('\\', '/')
|
||||
break
|
||||
return path
|
||||
|
||||
def pp_replace(pp_command, episode, subtitles, language, language_code2, language_code3):
|
||||
pp_command = pp_command.replace('{{directory}}', os.path.dirname(episode))
|
||||
pp_command = pp_command.replace('{{episode}}', episode)
|
||||
|
@ -83,4 +109,5 @@ use_scenename = result[9]
|
|||
use_processing = result[10]
|
||||
postprocessing_cmd = result[11]
|
||||
use_sonarr = result[12]
|
||||
use_radarr = result[13]
|
||||
use_radarr = result[13]
|
||||
path_mappings_movie = result[14]
|
|
@ -81,7 +81,7 @@ def update_movies():
|
|||
|
||||
for added_movie in added_movies:
|
||||
added_path = c.execute('SELECT path FROM table_movies WHERE tmdbId = ?', (added_movie,)).fetchone()
|
||||
store_subtitles_movie(path_replace(added_path[0]))
|
||||
store_subtitles_movie(path_replace_movie(added_path[0]))
|
||||
|
||||
# Close database connection
|
||||
db.close()
|
||||
|
|
|
@ -159,9 +159,9 @@ def movies_download_subtitles(no):
|
|||
providers_auth = None
|
||||
|
||||
for language in ast.literal_eval(movie[1]):
|
||||
message = download_subtitle(path_replace(movie[0]), str(pycountry.languages.lookup(language).alpha_3), movie[4], providers_list, providers_auth, movie[3], 'movies')
|
||||
message = download_subtitle(path_replace_movie(movie[0]), str(pycountry.languages.lookup(language).alpha_3), movie[4], providers_list, providers_auth, movie[3], 'movies')
|
||||
if message is not None:
|
||||
store_subtitles_movie(path_replace(movie[0]))
|
||||
store_subtitles_movie(path_replace_movie(movie[0]))
|
||||
history_log_movie(1, no, message)
|
||||
send_notifications_movie(no, message)
|
||||
list_missing_subtitles_movies(no)
|
||||
|
@ -200,20 +200,63 @@ def wanted_download_subtitles(path):
|
|||
history_log(1, episode[3], episode[2], message)
|
||||
send_notifications(episode[3], episode[2], message)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def wanted_search_missing_subtitles():
|
||||
db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
db.create_function("path_substitution", 1, path_replace)
|
||||
db.create_function("path_substitution_movie", 1, path_replace_movie)
|
||||
c = db.cursor()
|
||||
|
||||
c.execute("SELECT path_substitution(path) FROM table_episodes WHERE missing_subtitles != '[]'")
|
||||
episodes = c.fetchall()
|
||||
|
||||
c.execute("SELECT path_substitution(path) FROM table_movies WHERE missing_subtitles != '[]'")
|
||||
c.execute("SELECT path_substitution_movie(path) FROM table_movies WHERE missing_subtitles != '[]'")
|
||||
movies = c.fetchall()
|
||||
|
||||
c.close()
|
||||
|
||||
for episode in episodes:
|
||||
wanted_download_subtitles(episode[0])
|
||||
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])
|
||||
|
||||
logging.info('Finished searching for missing subtitles. Check histories for more information.')
|
||||
|
|
|
@ -83,25 +83,25 @@ def store_subtitles_movie(file):
|
|||
|
||||
for subtitle, language in subtitles.iteritems():
|
||||
if str(language) != 'und':
|
||||
actual_subtitles.append([str(language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))])
|
||||
actual_subtitles.append([str(language), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))])
|
||||
else:
|
||||
with open(path_replace(os.path.join(os.path.dirname(file), subtitle)), 'r') as f:
|
||||
with open(path_replace_movie(os.path.join(os.path.dirname(file), subtitle)), 'r') as f:
|
||||
text = list(islice(f, 100))
|
||||
text = ' '.join(text)
|
||||
encoding = UnicodeDammit(text)
|
||||
try:
|
||||
text = text.decode(encoding.original_encoding)
|
||||
except Exception as e:
|
||||
logging.exception('Error trying to detect character encoding 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.')
|
||||
logging.exception('Error trying to detect character encoding for this subtitles file: ' + path_replace_movie(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:
|
||||
detected_language = langdetect.detect(text)
|
||||
if len(detected_language) > 0:
|
||||
actual_subtitles.append([str(detected_language), path_replace_reverse(os.path.join(os.path.dirname(file), subtitle))])
|
||||
actual_subtitles.append([str(detected_language), path_replace_reverse_movie(os.path.join(os.path.dirname(file), subtitle))])
|
||||
|
||||
conn_db = sqlite3.connect(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'), timeout=30)
|
||||
c_db = conn_db.cursor()
|
||||
|
||||
c_db.execute("UPDATE table_movies SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse(file)))
|
||||
c_db.execute("UPDATE table_movies SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse_movie(file)))
|
||||
conn_db.commit()
|
||||
|
||||
c_db.close()
|
||||
|
@ -200,7 +200,7 @@ def movies_full_scan_subtitles():
|
|||
c_db.close()
|
||||
|
||||
for movie in movies:
|
||||
store_subtitles_movie(path_replace(movie[0]))
|
||||
store_subtitles_movie(path_replace_movie(movie[0]))
|
||||
|
||||
gc.collect()
|
||||
|
||||
|
@ -223,6 +223,6 @@ def movies_scan_subtitles(no):
|
|||
c_db.close()
|
||||
|
||||
for movie in movies:
|
||||
store_subtitles_movie(path_replace(movie[0]))
|
||||
store_subtitles_movie(path_replace_movie(movie[0]))
|
||||
|
||||
list_missing_subtitles_movies(no)
|
|
@ -118,6 +118,11 @@ if os.path.exists(os.path.join(os.path.dirname(__file__), 'data/db/bazarr.db'))
|
|||
else:
|
||||
c.execute('UPDATE table_settings_general SET use_radarr="False"')
|
||||
|
||||
try:
|
||||
c.execute('alter table table_settings_general add column "path_mapping_movie" "text"')
|
||||
except:
|
||||
pass
|
||||
|
||||
# Commit change to db
|
||||
db.commit()
|
||||
|
||||
|
|
|
@ -120,11 +120,11 @@
|
|||
for subtitles_file in subtitles_files:
|
||||
%>
|
||||
<tr>
|
||||
<td>{{path_replace(subtitles_file[1]) if subtitles_file[1] is not None else 'Video file subtitles track'}}</td>
|
||||
<td>{{path_replace_movie(subtitles_file[1]) if subtitles_file[1] is not None else 'Video file subtitles track'}}</td>
|
||||
<td><div class="ui tiny inverted label" style='background-color: #777777;'>{{pycountry.languages.lookup(str(subtitles_file[0])).name}}</div></td>
|
||||
<td>
|
||||
%if subtitles_file[1] is not None:
|
||||
<a class="remove_subtitles ui inverted basic compact icon" data-tooltip="Delete subtitles file from disk" data-inverted="" data-moviePath="{{details[8]}}" data-subtitlesPath="{{path_replace(subtitles_file[1])}}" data-language="{{pycountry.languages.lookup(str(subtitles_file[0])).alpha_3}}" data-radarrId={{details[10]}}>
|
||||
<a class="remove_subtitles ui inverted basic compact icon" data-tooltip="Delete subtitles file from disk" data-inverted="" data-moviePath="{{details[8]}}" data-subtitlesPath="{{path_replace_movie(subtitles_file[1])}}" data-language="{{pycountry.languages.lookup(str(subtitles_file[0])).alpha_3}}" data-radarrId={{details[10]}}>
|
||||
<i class="ui black delete icon"></i>
|
||||
</a>
|
||||
%end
|
||||
|
|
|
@ -205,7 +205,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui dividing header">Path Mappings</div>
|
||||
<div class="ui dividing header">Path Mappings for shows</div>
|
||||
<div class="twelve wide column">
|
||||
<div class="ui grid">
|
||||
%import ast
|
||||
|
@ -221,13 +221,13 @@
|
|||
<div class="two wide column">
|
||||
<div class="ui fluid input">
|
||||
<h4 class="ui header">
|
||||
Path for Sonarr / Radarr:
|
||||
Path for Sonarr:
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapsed column">
|
||||
<div class="collapsed center aligned column">
|
||||
<div class="ui basic icon" data-tooltip="Root path to the directory Sonarr or Radarr accesses." data-inverted="">
|
||||
<div class="ui basic icon" data-tooltip="Root path to the directory Sonarr accesses." data-inverted="">
|
||||
<i class="help circle large icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -279,6 +279,80 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui dividing header">Path Mappings for movies</div>
|
||||
<div class="twelve wide column">
|
||||
<div class="ui grid">
|
||||
%import ast
|
||||
%if settings_general[16] is not None:
|
||||
% path_substitutions_movie = ast.literal_eval(settings_general[16])
|
||||
%else:
|
||||
% path_substitutions_movie = []
|
||||
%end
|
||||
<div class="middle aligned row">
|
||||
<div class="right aligned four wide column">
|
||||
|
||||
</div>
|
||||
<div class="two wide column">
|
||||
<div class="ui fluid input">
|
||||
<h4 class="ui header">
|
||||
Path for Radarr:
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapsed column">
|
||||
<div class="collapsed center aligned column">
|
||||
<div class="ui basic icon" data-tooltip="Root path to the directory Radarr accesses." data-inverted="">
|
||||
<i class="help circle large icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two wide center aligned column">
|
||||
|
||||
</div>
|
||||
<div class="two wide column">
|
||||
<div class="ui fluid input">
|
||||
<h4 class="ui header">
|
||||
Path for Bazarr:
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapsed column">
|
||||
<div class="collapsed center aligned column">
|
||||
<div class="ui basic icon" data-tooltip="Path that Bazarr should use to access the same directory remotely." data-inverted="">
|
||||
<i class="help circle large icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
%for x in range(0, 5):
|
||||
% path_movie = []
|
||||
% try:
|
||||
% path_movie = path_substitutions_movie[x]
|
||||
% except IndexError:
|
||||
% path_movie = ["", ""]
|
||||
% end
|
||||
<div class="middle aligned row">
|
||||
<div class="right aligned four wide column">
|
||||
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<div class="ui fluid input">
|
||||
<input name="settings_general_sourcepath_movie" type="text" value="{{path_movie[0]}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="center aligned column">
|
||||
<i class="arrow circle right icon"></i>
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<div class="ui fluid input">
|
||||
<input name="settings_general_destpath_movie" type="text" value="{{path_movie[1]}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
%end
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui dividing header">Post-processing</div>
|
||||
<div class="twelve wide column">
|
||||
<div class="ui orange message">
|
||||
|
|
Loading…
Reference in New Issue