Added filter to exclude episodes or movies based on monitored status or tags.

pull/1038/head
Louis Vézina 5 years ago
parent 254e99531e
commit 15e3fcaca9

@ -18,7 +18,7 @@ from config import settings, base_url, save_settings
from init import * from init import *
import logging import logging
from database import database from database import database, filter_exclusions
from helper import path_mappings from helper import path_mappings
from get_languages import language_from_alpha3, language_from_alpha2, alpha2_from_alpha3, alpha2_from_language, \ from get_languages import language_from_alpha3, language_from_alpha2, alpha2_from_alpha3, alpha2_from_language, \
alpha3_from_language, alpha3_from_alpha2 alpha3_from_language, alpha3_from_alpha2
@ -78,22 +78,21 @@ class Restart(Resource):
class Badges(Resource): class Badges(Resource):
@authenticate @authenticate
def get(self): def get(self):
sonarr_only_monitored_where_clause = '' missing_episodes = database.execute("SELECT table_shows.tags, table_episodes.monitored FROM table_episodes "
if settings.sonarr.getboolean('only_monitored'): "INNER JOIN table_shows on table_shows.sonarrSeriesId = "
sonarr_only_monitored_where_clause = " AND table_episodes.monitored == 'True'" "table_episodes.sonarrSeriesId WHERE missing_subtitles is not null AND "
"missing_subtitles != '[]'")
radarr_only_monitored_where_clause = '' missing_episodes = filter_exclusions(missing_episodes, 'series')
if settings.radarr.getboolean('only_monitored'): missing_episodes = len(missing_episodes)
radarr_only_monitored_where_clause = " AND table_movies.monitored == 'True'"
missing_movies = database.execute("SELECT tags, monitored FROM table_movies WHERE missing_subtitles is not "
"null AND missing_subtitles != '[]'")
missing_movies = filter_exclusions(missing_movies, 'movie')
missing_movies = len(missing_movies)
result = { result = {
"missing_episodes": database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE missing_subtitles " "missing_episodes": missing_episodes,
"is not null AND missing_subtitles != '[]'" + "missing_movies": missing_movies,
sonarr_only_monitored_where_clause, only_one=True)['count'],
"missing_movies": database.execute("SELECT COUNT(*) as count FROM table_movies WHERE missing_subtitles "
"is not null AND missing_subtitles != '[]'" +
radarr_only_monitored_where_clause, only_one=True)['count'],
"throttled_providers": len(eval(str(settings.general.throtteled_providers))) "throttled_providers": len(eval(str(settings.general.throtteled_providers)))
} }
return jsonify(result) return jsonify(result)
@ -291,6 +290,9 @@ class Series(Resource):
if item['alternateTitles']: if item['alternateTitles']:
item.update({"alternateTitles": ast.literal_eval(item['alternateTitles'])}) item.update({"alternateTitles": ast.literal_eval(item['alternateTitles'])})
# Parse tags
item.update({"tags": ast.literal_eval(item['tags'])})
# Provide mapped path # Provide mapped path
mapped_path = path_mappings.path_replace(item['path']) mapped_path = path_mappings.path_replace(item['path'])
item.update({"mapped_path": mapped_path}) item.update({"mapped_path": mapped_path})
@ -298,21 +300,24 @@ class Series(Resource):
# Confirm if path exist # Confirm if path exist
item.update({"exist": os.path.isdir(mapped_path)}) item.update({"exist": os.path.isdir(mapped_path)})
only_monitored_where_clause = ''
if settings.sonarr.getboolean('only_monitored'):
only_monitored_where_clause = " AND table_episodes.monitored == 'True'"
# Add missing subtitles episode count # Add missing subtitles episode count
item.update({"episodeMissingCount": database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE " episodeMissingCount = database.execute("SELECT table_shows.tags, table_episodes.monitored FROM "
"sonarrSeriesId=? AND missing_subtitles is not null " "table_episodes INNER JOIN table_shows on "
"AND missing_subtitles != '[]'" + "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId "
only_monitored_where_clause, (item['sonarrSeriesId'],), "WHERE table_episodes.sonarrSeriesId=? AND missing_subtitles is not "
only_one=True)['count']}) "null AND missing_subtitles != '[]'", (item['sonarrSeriesId'],))
episodeMissingCount = filter_exclusions(episodeMissingCount, 'series')
episodeMissingCount = len(episodeMissingCount)
item.update({"episodeMissingCount": episodeMissingCount})
# Add episode count # Add episode count
item.update({"episodeFileCount": database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE " episodeFileCount = database.execute("SELECT table_shows.tags, table_episodes.monitored FROM table_episodes "
"sonarrSeriesId=?" + only_monitored_where_clause, "INNER JOIN table_shows on table_shows.sonarrSeriesId = "
(item['sonarrSeriesId'],), only_one=True)['count']}) "table_episodes.sonarrSeriesId WHERE table_episodes.sonarrSeriesId=?",
(item['sonarrSeriesId'],))
episodeFileCount = filter_exclusions(episodeFileCount, 'series')
episodeFileCount = len(episodeFileCount)
item.update({"episodeFileCount": episodeFileCount})
# Add the series desired subtitles language code2 # Add the series desired subtitles language code2
try: try:
@ -776,6 +781,9 @@ class Movies(Resource):
else: else:
item.update({"missing_subtitles": []}) item.update({"missing_subtitles": []})
# Parse tags
item.update({"tags": ast.literal_eval(item['tags'])})
# Provide mapped path # Provide mapped path
mapped_path = path_mappings.path_replace_movie(item['path']) mapped_path = path_mappings.path_replace_movie(item['path'])
item.update({"mapped_path": mapped_path}) item.update({"mapped_path": mapped_path})
@ -1113,19 +1121,15 @@ class HistorySeries(Resource):
else: else:
query_actions = [1, 3] query_actions = [1, 3]
if settings.sonarr.getboolean('only_monitored'):
series_monitored_only_query_string = " AND monitored='True'"
else:
series_monitored_only_query_string = ''
upgradable_episodes = database.execute( upgradable_episodes = database.execute(
"SELECT video_path, MAX(timestamp) as timestamp, score FROM table_history " "SELECT video_path, MAX(timestamp) as timestamp, score, table_shows.tags, table_episodes.monitored FROM "
"INNER JOIN table_episodes on table_episodes.sonarrEpisodeId = " "table_history INNER JOIN table_episodes on table_episodes.sonarrEpisodeId = "
"table_history.sonarrEpisodeId WHERE action IN (" + "table_history.sonarrEpisodeId INNER JOIN table_shows on table_shows.sonarrSeriesId = "
"table_episodes.sonarrSeriesId WHERE action IN (" +
','.join(map(str, query_actions)) + ") AND timestamp > ? AND " ','.join(map(str, query_actions)) + ") AND timestamp > ? AND "
"score is not null" + series_monitored_only_query_string + " GROUP BY " "score is not null GROUP BY table_history.video_path, table_history.language",
"table_history.video_path, table_history.language",
(minimum_timestamp,)) (minimum_timestamp,))
upgradable_episodes = filter_exclusions(upgradable_episodes, 'series')
for upgradable_episode in upgradable_episodes: for upgradable_episode in upgradable_episodes:
if upgradable_episode['timestamp'] > minimum_timestamp: if upgradable_episode['timestamp'] > minimum_timestamp:
@ -1140,19 +1144,19 @@ class HistorySeries(Resource):
row_count = database.execute("SELECT COUNT(*) as count FROM table_history LEFT JOIN table_episodes " row_count = database.execute("SELECT COUNT(*) as count FROM table_history LEFT JOIN table_episodes "
"on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId WHERE " "on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId WHERE "
"table_episodes.title is not NULL", only_one=True)['count'] "table_episodes.title is not NULL", only_one=True)['count']
data = database.execute("SELECT table_history.action, table_shows.title as seriesTitle, " data = database.execute("SELECT table_history.action, table_shows.title as seriesTitle, table_episodes.monitored, "
"table_episodes.season || 'x' || table_episodes.episode as episode_number, " "table_episodes.season || 'x' || table_episodes.episode as episode_number, "
"table_episodes.title as episodeTitle, table_history.timestamp, " "table_episodes.title as episodeTitle, table_history.timestamp, "
"table_history.description, table_history.sonarrSeriesId, table_episodes.path, " "table_history.description, table_history.sonarrSeriesId, table_episodes.path, "
"table_history.language, table_history.score FROM table_history LEFT JOIN table_shows " "table_history.language, table_history.score, table_shows.tags FROM table_history "
"on table_shows.sonarrSeriesId = table_history.sonarrSeriesId LEFT JOIN table_episodes " "LEFT JOIN table_shows on table_shows.sonarrSeriesId = table_history.sonarrSeriesId "
"on table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId WHERE " "LEFT JOIN table_episodes on table_episodes.sonarrEpisodeId = "
"table_episodes.title is not NULL ORDER BY timestamp DESC LIMIT ? OFFSET ?", "table_history.sonarrEpisodeId WHERE table_episodes.title is not NULL ORDER BY "
(length, start)) "timestamp DESC LIMIT ? OFFSET ?", (length, start))
for item in data: for item in data:
# Mark episode as upgradable or not # Mark episode as upgradable or not
if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score'])} in upgradable_episodes_not_perfect: if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']), "tags": str(item['tags']), "monitored": str(item['monitored'])} in upgradable_episodes_not_perfect:
item.update({"upgradable": True}) item.update({"upgradable": True})
else: else:
item.update({"upgradable": False}) item.update({"upgradable": False})
@ -1193,21 +1197,17 @@ class HistoryMovies(Resource):
minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) - minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
datetime.datetime(1970, 1, 1)).total_seconds() datetime.datetime(1970, 1, 1)).total_seconds()
if settings.radarr.getboolean('only_monitored'):
movies_monitored_only_query_string = ' AND table_movies.monitored = "True"'
else:
movies_monitored_only_query_string = ""
if settings.general.getboolean('upgrade_manual'): if settings.general.getboolean('upgrade_manual'):
query_actions = [1, 2, 3] query_actions = [1, 2, 3]
else: else:
query_actions = [1, 3] query_actions = [1, 3]
upgradable_movies = database.execute( upgradable_movies = database.execute(
"SELECT video_path, MAX(timestamp) as timestamp, score FROM table_history_movie " "SELECT video_path, MAX(timestamp) as timestamp, score, tags, monitored FROM table_history_movie "
"INNER JOIN table_movies on table_movies.radarrId=table_history_movie.radarrId WHERE action IN (" + "INNER JOIN table_movies on table_movies.radarrId=table_history_movie.radarrId WHERE action IN (" +
','.join(map(str, query_actions)) + ") AND timestamp > ? AND score is not NULL" + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND score is not NULL GROUP BY video_path, "
movies_monitored_only_query_string + " GROUP BY video_path, language", (minimum_timestamp,)) "language", (minimum_timestamp,))
upgradable_movies = filter_exclusions(upgradable_movies, 'movie')
for upgradable_movie in upgradable_movies: for upgradable_movie in upgradable_movies:
if upgradable_movie['timestamp'] > minimum_timestamp: if upgradable_movie['timestamp'] > minimum_timestamp:
@ -1223,15 +1223,15 @@ class HistoryMovies(Resource):
"table_movies.radarrId = table_history_movie.radarrId WHERE table_movies.title " "table_movies.radarrId = table_history_movie.radarrId WHERE table_movies.title "
"is not NULL", only_one=True)['count'] "is not NULL", only_one=True)['count']
data = database.execute("SELECT table_history_movie.action, table_movies.title, table_history_movie.timestamp, " data = database.execute("SELECT table_history_movie.action, table_movies.title, table_history_movie.timestamp, "
"table_history_movie.description, table_history_movie.radarrId, " "table_history_movie.description, table_history_movie.radarrId, table_movies.monitored, "
"table_history_movie.video_path, table_history_movie.language, " "table_history_movie.video_path, table_history_movie.language, table_movies.tags, "
"table_history_movie.score FROM table_history_movie LEFT JOIN table_movies on " "table_history_movie.score FROM table_history_movie LEFT JOIN table_movies on "
"table_movies.radarrId = table_history_movie.radarrId WHERE table_movies.title " "table_movies.radarrId = table_history_movie.radarrId WHERE table_movies.title "
"is not NULL ORDER BY timestamp DESC LIMIT ? OFFSET ?", (length, start)) "is not NULL ORDER BY timestamp DESC LIMIT ? OFFSET ?", (length, start))
for item in data: for item in data:
# Mark movies as upgradable or not # Mark movies as upgradable or not
if {"video_path": str(item['video_path']), "timestamp": float(item['timestamp']), "score": str(item['score'])} in upgradable_movies_not_perfect: if {"video_path": str(item['video_path']), "timestamp": float(item['timestamp']), "score": str(item['score']), "tags": str(item['tags']), "monitored": str(item['monitored'])} in upgradable_movies_not_perfect:
item.update({"upgradable": True}) item.update({"upgradable": True})
else: else:
item.update({"upgradable": False}) item.update({"upgradable": False})
@ -1321,22 +1321,17 @@ class WantedSeries(Resource):
length = request.args.get('length') or -1 length = request.args.get('length') or -1
draw = request.args.get('draw') draw = request.args.get('draw')
if settings.sonarr.getboolean('only_monitored'): data = database.execute("SELECT table_shows.title as seriesTitle, table_episodes.monitored, "
monitored_only_query_string = " AND monitored='True'"
else:
monitored_only_query_string = ''
row_count = database.execute("SELECT COUNT(*) as count FROM table_episodes WHERE missing_subtitles != '[]'" +
monitored_only_query_string, only_one=True)['count']
data = database.execute("SELECT table_shows.title as seriesTitle, "
"table_episodes.season || 'x' || table_episodes.episode as episode_number, " "table_episodes.season || 'x' || table_episodes.episode as episode_number, "
"table_episodes.title as episodeTitle, table_episodes.missing_subtitles, " "table_episodes.title as episodeTitle, table_episodes.missing_subtitles, "
"table_episodes.sonarrSeriesId, table_episodes.path, table_shows.hearing_impaired, " "table_episodes.sonarrSeriesId, table_episodes.path, table_shows.hearing_impaired, "
"table_episodes.sonarrEpisodeId, table_episodes.scene_name, " "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, "
"table_episodes.failedAttempts FROM table_episodes INNER JOIN table_shows on " "table_episodes.failedAttempts FROM table_episodes INNER JOIN table_shows on "
"table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE " "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE "
"table_episodes.missing_subtitles != '[]'" + monitored_only_query_string + "table_episodes.missing_subtitles != '[]' ORDER BY table_episodes._rowid_ DESC LIMIT ? "
" ORDER BY table_episodes._rowid_ DESC LIMIT ? OFFSET ?", (length, start)) "OFFSET ?", (length, start))
data = filter_exclusions(data, 'series')
row_count = len(data)
for item in data: for item in data:
# Parse missing subtitles # Parse missing subtitles
@ -1368,17 +1363,11 @@ class WantedMovies(Resource):
length = request.args.get('length') or -1 length = request.args.get('length') or -1
draw = request.args.get('draw') draw = request.args.get('draw')
if settings.radarr.getboolean('only_monitored'):
monitored_only_query_string = " AND monitored='True'"
else:
monitored_only_query_string = ''
row_count = database.execute("SELECT COUNT(*) as count FROM table_movies WHERE missing_subtitles != '[]'" +
monitored_only_query_string, only_one=True)['count']
data = database.execute("SELECT title, missing_subtitles, radarrId, path, hearing_impaired, sceneName, " data = database.execute("SELECT title, missing_subtitles, radarrId, path, hearing_impaired, sceneName, "
"failedAttempts FROM table_movies WHERE missing_subtitles != '[]'" + "failedAttempts, tags, monitored FROM table_movies WHERE missing_subtitles != '[]' "
monitored_only_query_string + " ORDER BY _rowid_ DESC LIMIT ? OFFSET ?", "ORDER BY _rowid_ DESC LIMIT ? OFFSET ?", (length, start))
(length, start)) data = filter_exclusions(data, 'movie')
row_count = len(data)
for item in data: for item in data:
# Parse missing subtitles # Parse missing subtitles

@ -76,6 +76,7 @@ defaults = {
'only_monitored': 'False', 'only_monitored': 'False',
'series_sync': '1', 'series_sync': '1',
'episodes_sync': '5', 'episodes_sync': '5',
'excluded_tags': '[]'
}, },
'radarr': { 'radarr': {
'ip': '127.0.0.1', 'ip': '127.0.0.1',
@ -88,6 +89,7 @@ defaults = {
'full_update_hour': '5', 'full_update_hour': '5',
'only_monitored': 'False', 'only_monitored': 'False',
'movies_sync': '5', 'movies_sync': '5',
'excluded_tags': '[]'
}, },
'proxy': { 'proxy': {
'type': 'None', 'type': 'None',

@ -1,17 +1,16 @@
import os import os
import ast
import sqlite3
import logging
from sqlite3worker import Sqlite3Worker from sqlite3worker import Sqlite3Worker
from get_args import args from get_args import args
from helper import path_mappings from helper import path_mappings
from config import settings
def db_init(): def db_init():
import sqlite3
import os
import logging
from get_args import args
if not os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')): if not os.path.exists(os.path.join(args.config_dir, 'db', 'bazarr.db')):
# Get SQL script from file # Get SQL script from file
fd = open(os.path.join(os.path.dirname(__file__), 'create_db.sql'), 'r') fd = open(os.path.join(os.path.dirname(__file__), 'create_db.sql'), 'r')
@ -93,6 +92,7 @@ def db_upgrade():
['table_shows', 'year', 'text'], ['table_shows', 'year', 'text'],
['table_shows', 'alternateTitles', 'text'], ['table_shows', 'alternateTitles', 'text'],
['table_shows', 'forced', 'text', 'False'], ['table_shows', 'forced', 'text', 'False'],
['table_shows', 'tags', 'text', '[]'],
['table_episodes', 'format', 'text'], ['table_episodes', 'format', 'text'],
['table_episodes', 'resolution', 'text'], ['table_episodes', 'resolution', 'text'],
['table_episodes', 'video_codec', 'text'], ['table_episodes', 'video_codec', 'text'],
@ -108,6 +108,7 @@ def db_upgrade():
['table_movies', 'imdbId', 'text'], ['table_movies', 'imdbId', 'text'],
['table_movies', 'forced', 'text', 'False'], ['table_movies', 'forced', 'text', 'False'],
['table_movies', 'movie_file_id', 'integer'], ['table_movies', 'movie_file_id', 'integer'],
['table_movies', 'tags', 'text', '[]'],
['table_history', 'video_path', 'text'], ['table_history', 'video_path', 'text'],
['table_history', 'language', 'text'], ['table_history', 'language', 'text'],
['table_history', 'provider', 'text'], ['table_history', 'provider', 'text'],
@ -134,3 +135,18 @@ def db_upgrade():
database.execute("UPDATE table_movies SET languages = '[]' WHERE languages is null") database.execute("UPDATE table_movies SET languages = '[]' WHERE languages is null")
database.execute("UPDATE table_movies SET hearing_impaired = 'False' WHERE hearing_impaired is null") database.execute("UPDATE table_movies SET hearing_impaired = 'False' WHERE hearing_impaired is null")
database.execute("UPDATE table_movies SET forced = 'False' WHERE forced is null") database.execute("UPDATE table_movies SET forced = 'False' WHERE forced is null")
def filter_exclusions(dicts_list, type):
if type == 'series':
tagsList = ast.literal_eval(settings.sonarr.excluded_tags)
monitoredOnly = settings.sonarr.getboolean('only_monitored')
else:
tagsList = ast.literal_eval(settings.radarr.excluded_tags)
monitoredOnly = settings.radarr.getboolean('only_monitored')
dictsList_tags_filtered = [item for item in dicts_list if set(tagsList).isdisjoint(ast.literal_eval(item['tags']))]
if monitoredOnly:
dictsList_tags_monitored = [item for item in dictsList_tags_filtered if item['monitored'] == 'True']
else:
dictsList_tags_monitored = dictsList_tags_filtered
return dictsList_tags_monitored

@ -153,7 +153,9 @@ def sync_episodes():
'''INSERT OR IGNORE INTO table_episodes(''' + query.keys_insert + ''') VALUES(''' + query.question_marks + '''INSERT OR IGNORE INTO table_episodes(''' + query.keys_insert + ''') VALUES(''' + query.question_marks +
''')''', query.values) ''')''', query.values)
if result > 0: if result > 0:
altered_episodes.append([added_episode['sonarrEpisodeId'], added_episode['path']]) altered_episodes.append([added_episode['sonarrEpisodeId'],
added_episode['path'],
added_episode['monitored']])
event_stream(type='episode', action='insert', series=added_episode['sonarrSeriesId'], event_stream(type='episode', action='insert', series=added_episode['sonarrSeriesId'],
episode=added_episode['sonarrEpisodeId']) episode=added_episode['sonarrEpisodeId'])
else: else:
@ -169,7 +171,11 @@ def sync_episodes():
if len(altered_episodes) <= 5: if len(altered_episodes) <= 5:
logging.debug("BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles.") logging.debug("BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles.")
for altered_episode in altered_episodes: for altered_episode in altered_episodes:
episode_download_subtitles(altered_episode[0]) if settings.sonarr.getboolean('only_monitored'):
if altered_episode[2] == 'True':
episode_download_subtitles(altered_episode[0])
else:
episode_download_subtitles(altered_episode[0])
else: else:
logging.debug("BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now.") logging.debug("BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now.")

@ -38,6 +38,7 @@ def update_movies():
pass pass
else: else:
audio_profiles = get_profile_list() audio_profiles = get_profile_list()
tagsDict = get_tags()
# Get movies data from radarr # Get movies data from radarr
url_radarr_api_movies = url_radarr() + "/api/movie?apikey=" + apikey_radarr url_radarr_api_movies = url_radarr() + "/api/movie?apikey=" + apikey_radarr
@ -134,6 +135,8 @@ def update_movies():
audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles) audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles)
tags = [d['label'] for d in tagsDict if d['id'] in movie['tags']]
# Add movies in radarr to current movies list # Add movies in radarr to current movies list
current_movies_radarr.append(str(movie['tmdbId'])) current_movies_radarr.append(str(movie['tmdbId']))
@ -156,7 +159,8 @@ def update_movies():
'audio_codec': audioCodec, 'audio_codec': audioCodec,
'overview': overview, 'overview': overview,
'imdbId': imdbId, 'imdbId': imdbId,
'movie_file_id': int(movie['movieFile']['id'])}) 'movie_file_id': int(movie['movieFile']['id']),
'tags': str(tags)})
else: else:
movies_to_add.append({'radarrId': int(movie["id"]), movies_to_add.append({'radarrId': int(movie["id"]),
'title': movie["title"], 'title': movie["title"],
@ -180,7 +184,8 @@ def update_movies():
'audio_codec': audioCodec, 'audio_codec': audioCodec,
'imdbId': imdbId, 'imdbId': imdbId,
'forced': movie_default_forced, 'forced': movie_default_forced,
'movie_file_id': int(movie['movieFile']['id'])}) 'movie_file_id': int(movie['movieFile']['id']),
'tags': str(tags)})
else: else:
logging.error( logging.error(
'BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator + 'BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator +
@ -197,7 +202,7 @@ def update_movies():
movies_in_db = database.execute("SELECT radarrId, title, path, tmdbId, overview, poster, fanart, " movies_in_db = database.execute("SELECT radarrId, title, path, tmdbId, overview, poster, fanart, "
"audio_language, sceneName, monitored, sortTitle, year, " "audio_language, sceneName, monitored, sortTitle, year, "
"alternativeTitles, format, resolution, video_codec, audio_codec, imdbId," "alternativeTitles, format, resolution, video_codec, audio_codec, imdbId,"
"movie_file_id FROM table_movies") "movie_file_id, tags FROM table_movies")
for item in movies_in_db: for item in movies_in_db:
movies_in_db_list.append(item) movies_in_db_list.append(item)
@ -331,5 +336,23 @@ def RadarrFormatVideoCodec(videoFormat, videoCodecID, videoProfile, videoCodecLi
return videoFormat return videoFormat
if __name__ == '__main__': def get_tags():
update_movies() apikey_radarr = settings.radarr.apikey
tagsDict = []
# Get tags data from Sonarr
url_sonarr_api_series = url_radarr() + "/api/tag?apikey=" + apikey_radarr
try:
tagsDict = requests.get(url_sonarr_api_series, timeout=60, verify=False)
except requests.exceptions.ConnectionError:
logging.exception("BAZARR Error trying to get tags from Radarr. Connection Error.")
return []
except requests.exceptions.Timeout:
logging.exception("BAZARR Error trying to get tags from Radarr. Timeout Error.")
return []
except requests.exceptions.RequestException:
logging.exception("BAZARR Error trying to get tags from Radarr.")
return []
else:
return tagsDict.json()

@ -3,6 +3,7 @@
import os import os
import requests import requests
import logging import logging
import ast
from config import settings, url_sonarr from config import settings, url_sonarr
from list_subtitles import list_missing_subtitles from list_subtitles import list_missing_subtitles
@ -30,6 +31,7 @@ def update_series():
serie_default_forced = 'False' serie_default_forced = 'False'
audio_profiles = get_profile_list() audio_profiles = get_profile_list()
tagsDict = get_tags()
# Get shows data from Sonarr # Get shows data from Sonarr
url_sonarr_api_series = url_sonarr() + "/api/series?apikey=" + apikey_sonarr url_sonarr_api_series = url_sonarr() + "/api/series?apikey=" + apikey_sonarr
@ -79,6 +81,8 @@ def update_series():
else: else:
audio_language = profile_id_to_language(show['languageProfileId'], audio_profiles) audio_language = profile_id_to_language(show['languageProfileId'], audio_profiles)
tags = [d['label'] for d in tagsDict if d['id'] in show['tags']]
# Add shows in Sonarr to current shows list # Add shows in Sonarr to current shows list
current_shows_sonarr.append(show['id']) current_shows_sonarr.append(show['id'])
@ -93,7 +97,8 @@ def update_series():
'audio_language': audio_language, 'audio_language': audio_language,
'sortTitle': show['sortTitle'], 'sortTitle': show['sortTitle'],
'year': str(show['year']), 'year': str(show['year']),
'alternateTitles': alternate_titles}) 'alternateTitles': alternate_titles,
'tags': str(tags)})
else: else:
series_to_add.append({'title': show["title"], series_to_add.append({'title': show["title"],
'path': show["path"], 'path': show["path"],
@ -108,7 +113,8 @@ def update_series():
'sortTitle': show['sortTitle'], 'sortTitle': show['sortTitle'],
'year': str(show['year']), 'year': str(show['year']),
'alternateTitles': alternate_titles, 'alternateTitles': alternate_titles,
'forced': serie_default_forced}) 'forced': serie_default_forced,
'tags': str(tags)})
# Remove old series from DB # Remove old series from DB
removed_series = list(set(current_shows_db_list) - set(current_shows_sonarr)) removed_series = list(set(current_shows_db_list) - set(current_shows_sonarr))
@ -120,7 +126,7 @@ def update_series():
# Update existing series in DB # Update existing series in DB
series_in_db_list = [] series_in_db_list = []
series_in_db = database.execute("SELECT title, path, tvdbId, sonarrSeriesId, overview, poster, fanart, " series_in_db = database.execute("SELECT title, path, tvdbId, sonarrSeriesId, overview, poster, fanart, "
"audio_language, sortTitle, year, alternateTitles FROM table_shows") "audio_language, sortTitle, year, alternateTitles, tags FROM table_shows")
for item in series_in_db: for item in series_in_db:
series_in_db_list.append(item) series_in_db_list.append(item)
@ -188,3 +194,25 @@ def profile_id_to_language(id_, profiles):
for profile in profiles: for profile in profiles:
if id_ == profile[0]: if id_ == profile[0]:
return profile[1] return profile[1]
def get_tags():
apikey_sonarr = settings.sonarr.apikey
tagsDict = []
# Get tags data from Sonarr
url_sonarr_api_series = url_sonarr() + "/api/tag?apikey=" + apikey_sonarr
try:
tagsDict = requests.get(url_sonarr_api_series, timeout=60, verify=False)
except requests.exceptions.ConnectionError:
logging.exception("BAZARR Error trying to get tags from Sonarr. Connection Error.")
return []
except requests.exceptions.Timeout:
logging.exception("BAZARR Error trying to get tags from Sonarr. Timeout Error.")
return []
except requests.exceptions.RequestException:
logging.exception("BAZARR Error trying to get tags from Sonarr.")
return []
else:
return tagsDict.json()

@ -28,7 +28,7 @@ from notifier import send_notifications, send_notifications_movie
from get_providers import get_providers, get_providers_auth, provider_throttle, provider_pool from get_providers import get_providers, get_providers_auth, provider_throttle, provider_pool
from knowit import api from knowit import api
from subsyncer import subsync from subsyncer import subsync
from database import database, dict_mapper from database import database, dict_mapper, filter_exclusions
from analytics import track_event from analytics import track_event
from locale import getpreferredencoding from locale import getpreferredencoding
@ -630,14 +630,12 @@ def manual_upload_subtitle(path, language, forced, title, scene_name, media_type
def series_download_subtitles(no): def series_download_subtitles(no):
if settings.sonarr.getboolean('only_monitored'): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, monitored, "
episodes_details_clause = " AND monitored='True'" "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags "
else: "FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = "
episodes_details_clause = '' "table_episodes.sonarrSeriesId WHERE table_episodes.sonarrSeriesId=? and "
"missing_subtitles!='[]'", (no,))
episodes_details = database.execute("SELECT path, missing_subtitles, sonarrEpisodeId, scene_name " episodes_details = filter_exclusions(episodes_details, 'series')
"FROM table_episodes WHERE sonarrSeriesId=? and missing_subtitles!='[]'" +
episodes_details_clause, (no,))
if not episodes_details: if not episodes_details:
logging.debug("BAZARR no episode for that sonarrSeriesId can be found in database:", str(no)) logging.debug("BAZARR no episode for that sonarrSeriesId can be found in database:", str(no))
return return
@ -684,18 +682,13 @@ def series_download_subtitles(no):
def episode_download_subtitles(no): def episode_download_subtitles(no):
if settings.sonarr.getboolean('only_monitored'): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, monitored, "
episodes_details_clause = " AND monitored='True'" "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, "
else:
episodes_details_clause = ''
episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, "
"table_episodes.sonarrEpisodeId, table_episodes.scene_name, "
"table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId, " "table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId, "
"table_shows.forced, table_shows.audio_language FROM table_episodes LEFT JOIN table_shows on " "table_shows.forced, table_shows.audio_language FROM table_episodes LEFT JOIN "
"table_episodes.sonarrSeriesId = table_shows.sonarrSeriesId " "table_shows on table_episodes.sonarrSeriesId = table_shows.sonarrSeriesId "
"WHERE sonarrEpisodeId=?" + episodes_details_clause, (no,)) "WHERE sonarrEpisodeId=?", (no,))
episodes_details = filter_exclusions(episodes_details, 'series')
if not episodes_details: if not episodes_details:
logging.debug("BAZARR no episode with that sonarrEpisodeId can be found in database:", str(no)) logging.debug("BAZARR no episode with that sonarrEpisodeId can be found in database:", str(no))
return return
@ -734,18 +727,15 @@ def episode_download_subtitles(no):
def movies_download_subtitles(no): def movies_download_subtitles(no):
if settings.radarr.getboolean('only_monitored'): movies = database.execute(
movie_details_clause = " AND monitored='True'" "SELECT path, missing_subtitles, audio_language, radarrId, sceneName, hearing_impaired, title, forced, tags, "
else: "monitored FROM table_movies WHERE radarrId=?", (no,))
movie_details_clause = '' movies = filter_exclusions(movies, 'movie')
if not len(movies):
movie = database.execute(
"SELECT path, missing_subtitles, audio_language, radarrId, sceneName, hearing_impaired, title, forced "
"FROM table_movies WHERE radarrId=?" + movie_details_clause, (no,), only_one=True)
if not movie:
logging.debug("BAZARR no movie with that radarrId can be found in database:", str(no)) logging.debug("BAZARR no movie with that radarrId can be found in database:", str(no))
return return
else:
movie = movies[0]
providers_list = get_providers() providers_list = get_providers()
providers_auth = get_providers_auth() providers_auth = get_providers_auth()
@ -897,13 +887,10 @@ def wanted_download_subtitles_movie(path, l, count_movies):
def wanted_search_missing_subtitles_series(): def wanted_search_missing_subtitles_series():
if settings.sonarr.getboolean('only_monitored'): episodes = database.execute("SELECT table_episodes.path, table_shows.tags, table_episodes.monitored FROM "
monitored_only_query_string_sonarr = ' AND monitored = "True"' "table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = "
else: "table_episodes.sonarrSeriesId WHERE missing_subtitles != '[]'")
monitored_only_query_string_sonarr = "" episodes = filter_exclusions(episodes, 'series')
episodes = database.execute("SELECT path FROM table_episodes WHERE missing_subtitles != '[]'" +
monitored_only_query_string_sonarr)
# path_replace # path_replace
dict_mapper.path_replace(episodes) dict_mapper.path_replace(episodes)
@ -920,13 +907,8 @@ def wanted_search_missing_subtitles_series():
def wanted_search_missing_subtitles_movies(): def wanted_search_missing_subtitles_movies():
if settings.radarr.getboolean('only_monitored'): movies = database.execute("SELECT path, tags, monitored FROM table_movies WHERE missing_subtitles != '[]'")
monitored_only_query_string_radarr = ' AND monitored = "True"' movies = filter_exclusions(movies, 'movie')
else:
monitored_only_query_string_radarr = ""
movies = database.execute("SELECT path FROM table_movies WHERE missing_subtitles != '[]'" +
monitored_only_query_string_radarr)
# path_replace # path_replace
dict_mapper.path_replace_movie(movies) dict_mapper.path_replace_movie(movies)
@ -1059,16 +1041,6 @@ def upgrade_subtitles():
minimum_timestamp = ((datetime.now() - timedelta(days=int(days_to_upgrade_subs))) - minimum_timestamp = ((datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
datetime(1970, 1, 1)).total_seconds() datetime(1970, 1, 1)).total_seconds()
if settings.sonarr.getboolean('only_monitored'):
series_monitored_only_query_string = ' AND table_episodes.monitored = "True"'
else:
series_monitored_only_query_string = ""
if settings.radarr.getboolean('only_monitored'):
movies_monitored_only_query_string = ' AND table_movies.monitored = "True"'
else:
movies_monitored_only_query_string = ""
if settings.general.getboolean('upgrade_manual'): if settings.general.getboolean('upgrade_manual'):
query_actions = [1, 2, 3] query_actions = [1, 2, 3]
else: else:
@ -1079,17 +1051,17 @@ def upgrade_subtitles():
"table_history.score, table_shows.hearing_impaired, table_shows.audio_language, " "table_history.score, table_shows.hearing_impaired, table_shows.audio_language, "
"table_episodes.scene_name, table_episodes.title," "table_episodes.scene_name, table_episodes.title,"
"table_episodes.sonarrSeriesId, table_episodes.sonarrEpisodeId," "table_episodes.sonarrSeriesId, table_episodes.sonarrEpisodeId,"
"MAX(table_history.timestamp) as timestamp, " "MAX(table_history.timestamp) as timestamp, table_episodes.monitored, "
"table_shows.languages, table_shows.forced " "table_shows.languages, table_shows.forced, table_shows.tags "
"FROM table_history INNER JOIN table_shows on " "FROM table_history INNER JOIN table_shows on "
"table_shows.sonarrSeriesId = table_history.sonarrSeriesId INNER JOIN " "table_shows.sonarrSeriesId = table_history.sonarrSeriesId INNER JOIN "
"table_episodes on table_episodes.sonarrEpisodeId = " "table_episodes on table_episodes.sonarrEpisodeId = "
"table_history.sonarrEpisodeId WHERE action IN " "table_history.sonarrEpisodeId WHERE action IN "
"(" + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND " "(" + ','.join(map(str, query_actions)) +
"score is not null" + series_monitored_only_query_string + ") AND timestamp > ? AND score is not null GROUP BY "
" GROUP BY table_history.video_path, table_history.language", "table_history.video_path, table_history.language",
(minimum_timestamp,)) (minimum_timestamp,))
upgradable_episodes = filter_exclusions(upgradable_episodes, 'series')
upgradable_episodes_not_perfect = [] upgradable_episodes_not_perfect = []
for upgradable_episode in upgradable_episodes: for upgradable_episode in upgradable_episodes:
if upgradable_episode['timestamp'] > minimum_timestamp: if upgradable_episode['timestamp'] > minimum_timestamp:
@ -1110,17 +1082,16 @@ def upgrade_subtitles():
if settings.general.getboolean('use_radarr'): if settings.general.getboolean('use_radarr'):
upgradable_movies = database.execute("SELECT table_history_movie.video_path, table_history_movie.language, " upgradable_movies = database.execute("SELECT table_history_movie.video_path, table_history_movie.language, "
"table_history_movie.score, table_movies.hearing_impaired, table_movies.audio_language, " "table_history_movie.score, table_movies.hearing_impaired, "
"table_movies.sceneName, table_movies.title, table_movies.radarrId, " "table_movies.audio_language, table_movies.sceneName, table_movies.title, "
"MAX(table_history_movie.timestamp) as timestamp, table_movies.languages, " "table_movies.radarrId, MAX(table_history_movie.timestamp) as timestamp, "
"table_movies.forced FROM table_history_movie INNER JOIN " "table_movies.languages, table_movies.forced, table_movies.tags, "
"table_movies on table_movies.radarrId = table_history_movie.radarrId " "table_movies.monitored FROM table_history_movie INNER JOIN table_movies "
"WHERE action IN (" + ','.join(map(str, query_actions)) + "on table_movies.radarrId = table_history_movie.radarrId WHERE action IN "
") AND timestamp > ? AND score is not null" + "(" + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND score "
movies_monitored_only_query_string + "is not null GROUP BY table_history_movie.video_path, "
" GROUP BY table_history_movie.video_path, table_history_movie.language", "table_history_movie.language", (minimum_timestamp,))
(minimum_timestamp,)) upgradable_movies = filter_exclusions(upgradable_movies, 'movie')
upgradable_movies_not_perfect = [] upgradable_movies_not_perfect = []
for upgradable_movie in upgradable_movies: for upgradable_movie in upgradable_movies:
if upgradable_movie['timestamp'] > minimum_timestamp: if upgradable_movie['timestamp'] > minimum_timestamp:

@ -42,6 +42,7 @@
<link rel="stylesheet" href="{{ url_for('static',filename='css/jquery.typeahead.min.css') }}"/> <link rel="stylesheet" href="{{ url_for('static',filename='css/jquery.typeahead.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static',filename='css/Chart.min.css') }}"/> <link rel="stylesheet" href="{{ url_for('static',filename='css/Chart.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static',filename='jstree/themes/default/style.min.css') }}"/> <link rel="stylesheet" href="{{ url_for('static',filename='jstree/themes/default/style.min.css') }}"/>
<link rel="stylesheet" href="{{ url_for('static',filename='css/tagsinput.css') }}"/>
{% endblock head_css %} {% endblock head_css %}
@ -349,6 +350,7 @@
<script src="{{ url_for('static',filename='js/jquery.typeahead.min.js') }}"></script> <script src="{{ url_for('static',filename='js/jquery.typeahead.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/Chart.min.js') }}"></script> <script src="{{ url_for('static',filename='js/Chart.min.js') }}"></script>
<script src="{{ url_for('static',filename='jstree/jstree.min.js') }}"></script> <script src="{{ url_for('static',filename='jstree/jstree.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/tagsinput.js') }}"></script>
<script> <script>
{% if not request.endpoint == 'login_page' %} {% if not request.endpoint == 'login_page' %}

@ -82,6 +82,8 @@
<h5><span id="seriesAudioLanguage" class="badge badge-secondary"></span></h5> <h5><span id="seriesAudioLanguage" class="badge badge-secondary"></span></h5>
<h5><span id="seriesMappedPath" class="badge badge-secondary"></span></h5> <h5><span id="seriesMappedPath" class="badge badge-secondary"></span></h5>
<h5><span id="seriesFileCount" class="badge badge-secondary"></span></h5> <h5><span id="seriesFileCount" class="badge badge-secondary"></span></h5>
<h5><span id="seriesTags" class="badge badge-secondary" data-toggle="tooltip" data-placement="right"
title="None" data-html="true">Tags</span></h5>
</div> </div>
<div class="row"> <div class="row">
<h5><span id="seriesSubtitlesLanguages"></span></h5> <h5><span id="seriesSubtitlesLanguages"></span></h5>
@ -1006,6 +1008,12 @@
$('#seriesAlternateTitles').hide(); $('#seriesAlternateTitles').hide();
} }
if (seriesDetails['tags'].length > 0) {
$('#seriesTags').attr("data-original-title", "<b>Tags:</b><br>" + seriesDetails['tags']);
} else {
$('#seriesTags').hide();
}
$('#seriesAudioLanguage').text(seriesDetails['audio_language']['name']); $('#seriesAudioLanguage').text(seriesDetails['audio_language']['name']);
$('#seriesMappedPath').text(seriesDetails['mapped_path']); $('#seriesMappedPath').text(seriesDetails['mapped_path']);
$('#seriesMappedPath').attr("data-original-title", seriesDetails['mapped_path']); $('#seriesMappedPath').attr("data-original-title", seriesDetails['mapped_path']);

@ -96,6 +96,8 @@
<div class="row"> <div class="row">
<h5><span id="movieAudioLanguage" class="badge badge-secondary"></span></h5> <h5><span id="movieAudioLanguage" class="badge badge-secondary"></span></h5>
<h5><span id="movieMappedPath" data-toggle="tooltip" data-placement="right" title="None" class="badge badge-secondary"></span></h5> <h5><span id="movieMappedPath" data-toggle="tooltip" data-placement="right" title="None" class="badge badge-secondary"></span></h5>
<h5><span id="movieTags" class="badge badge-secondary" data-toggle="tooltip" data-placement="right"
title="None" data-html="true">Tags</span></h5>
</div> </div>
<div class="row"> <div class="row">
<h5><span id="movieSubtitlesLanguages"></span></h5> <h5><span id="movieSubtitlesLanguages"></span></h5>
@ -824,6 +826,12 @@
$('#moviealternativeTitles').hide(); $('#moviealternativeTitles').hide();
} }
if (movieDetails['tags'].length > 0) {
$('#movieTags').attr("data-original-title", "<b>Tags:</b><br>" + movieDetails['tags']);
} else {
$('#movieTags').hide();
}
$('#movieAudioLanguage').text(movieDetails['audio_language']['name']); $('#movieAudioLanguage').text(movieDetails['audio_language']['name']);
$('#movieMappedPath').text(movieDetails['mapped_path']); $('#movieMappedPath').text(movieDetails['mapped_path']);
$('#movieMappedPath').attr("data-original-title", movieDetails['mapped_path']); $('#movieMappedPath').attr("data-original-title", movieDetails['mapped_path']);

@ -138,6 +138,15 @@
<label>Automatic download of Subtitles will only happen for monitored movies in Radarr.</label> <label>Automatic download of Subtitles will only happen for monitored movies in Radarr.</label>
</div> </div>
</div> </div>
<div class="row">
<div class="col-sm-3 text-right">
<b>Excluded tags</b>
</div>
<div class="form-group col-sm-8">
<input type="text" id="settings-radarr-excluded_tags" name="settings-radarr-excluded_tags" data-role="tagsinput">
<label>Movies with those tags (case sensitive) in Radarr will be excluded from automatic download of Subtitles.</label>
</div>
</div>
<br> <br>
<h4>Path Mappings</h4> <h4>Path Mappings</h4>
<hr/> <hr/>
@ -286,6 +295,16 @@
} }
}); });
// Set tags input values
$('settings-radarr-excluded_tags').tagsinput({
confirmKeys: [9, 13, 32, 44]
});
var tags = jQuery.makeArray({{ settings.radarr.excluded_tags|safe }})
$(tags).each(function (index, value) {
$('#settings-radarr-excluded_tags').tagsinput('add', value);
});
$('#settings-radarr-excluded_tags').tagsinput('refresh');
// Set Checkbox input values // Set Checkbox input values
$('#settings-general-use_radarr').prop('checked', {{'true' if settings.general.getboolean('use_radarr') else 'false'}}).trigger('change'); $('#settings-general-use_radarr').prop('checked', {{'true' if settings.general.getboolean('use_radarr') else 'false'}}).trigger('change');
$('#settings-radarr-ssl').prop('checked', {{'true' if settings.radarr.getboolean('ssl') else 'false'}}); $('#settings-radarr-ssl').prop('checked', {{'true' if settings.radarr.getboolean('ssl') else 'false'}});
@ -300,6 +319,7 @@
}); });
formdata.append('settings-general-path_mappings_movie', JSON.stringify(table.rows().data().toArray())); formdata.append('settings-general-path_mappings_movie', JSON.stringify(table.rows().data().toArray()));
formdata.set('settings-radarr-excluded_tags', JSON.stringify($("#settings-radarr-excluded_tags").tagsinput('items')));
$.ajax({ $.ajax({
url: "{{ url_for('api.savesettings') }}", url: "{{ url_for('api.savesettings') }}",

@ -138,6 +138,15 @@
<label>Automatic download of Subtitles will only happen for monitored episodes in Sonarr.</label> <label>Automatic download of Subtitles will only happen for monitored episodes in Sonarr.</label>
</div> </div>
</div> </div>
<div class="row">
<div class="col-sm-3 text-right">
<b>Excluded tags</b>
</div>
<div class="form-group col-sm-8">
<input type="text" id="settings-sonarr-excluded_tags" name="settings-sonarr-excluded_tags" data-role="tagsinput">
<label>Episodes from series with those tags (case sensitive) in Sonarr will be excluded from automatic download of Subtitles.</label>
</div>
</div>
<br> <br>
<h4>Path Mappings</h4> <h4>Path Mappings</h4>
<hr/> <hr/>
@ -286,6 +295,16 @@
} }
}); });
// Set tags input values
$('settings-sonarr-excluded_tags').tagsinput({
confirmKeys: [9, 13, 32, 44]
});
var tags = jQuery.makeArray({{ settings.sonarr.excluded_tags|safe }})
$(tags).each(function (index, value) {
$('#settings-sonarr-excluded_tags').tagsinput('add', value);
});
$('#settings-sonarr-excluded_tags').tagsinput('refresh');
// Set Checkbox input values // Set Checkbox input values
$('#settings-general-use_sonarr').prop('checked', {{'true' if settings.general.getboolean('use_sonarr') else 'false'}}).trigger('change'); $('#settings-general-use_sonarr').prop('checked', {{'true' if settings.general.getboolean('use_sonarr') else 'false'}}).trigger('change');
$('#settings-sonarr-ssl').prop('checked', {{'true' if settings.sonarr.getboolean('ssl') else 'false'}}); $('#settings-sonarr-ssl').prop('checked', {{'true' if settings.sonarr.getboolean('ssl') else 'false'}});
@ -300,6 +319,7 @@
}); });
formdata.append('settings-general-path_mappings', JSON.stringify(table.rows().data().toArray())); formdata.append('settings-general-path_mappings', JSON.stringify(table.rows().data().toArray()));
formdata.set('settings-sonarr-excluded_tags', JSON.stringify($("#settings-sonarr-excluded_tags").tagsinput('items')));
$.ajax({ $.ajax({
url: "{{ url_for('api.savesettings') }}", url: "{{ url_for('api.savesettings') }}",

Loading…
Cancel
Save