mirror of
https://github.com/morpheus65535/bazarr.git
synced 2025-04-23 22:27:17 -04:00
Added Sync Optimization for Movies, Series and Episodes to ignore unmonitored items
This commit is contained in:
parent
3922d52d5c
commit
990448b06e
9 changed files with 222 additions and 46 deletions
|
@ -161,6 +161,8 @@ validators = [
|
|||
Validator('sonarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
|
||||
Validator('sonarr.exclude_season_zero', must_exist=True, default=False, is_type_of=bool),
|
||||
Validator('sonarr.defer_search_signalr', must_exist=True, default=False, is_type_of=bool),
|
||||
Validator('sonarr.sync_only_monitored_series', must_exist=True, default=False, is_type_of=bool),
|
||||
Validator('sonarr.sync_only_monitored_episodes', must_exist=True, default=False, is_type_of=bool),
|
||||
|
||||
# radarr section
|
||||
Validator('radarr.ip', must_exist=True, default='127.0.0.1', is_type_of=str),
|
||||
|
@ -180,6 +182,7 @@ validators = [
|
|||
Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
|
||||
Validator('radarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
|
||||
Validator('radarr.defer_search_signalr', must_exist=True, default=False, is_type_of=bool),
|
||||
Validator('radarr.sync_only_monitored_movies', must_exist=True, default=False, is_type_of=bool),
|
||||
|
||||
# proxy section
|
||||
Validator('proxy.type', must_exist=True, default=None, is_type_of=(NoneType, str),
|
||||
|
|
|
@ -8,3 +8,6 @@ headers = {"User-Agent": os.environ["SZ_USER_AGENT"]}
|
|||
|
||||
# hearing-impaired detection regex
|
||||
hi_regex = re.compile(r'[*¶♫♪].{3,}[*¶♫♪]|[\[\(\{].{3,}[\]\)\}](?<!{\\an\d})')
|
||||
|
||||
# minimum file size for Bazarr to consider it a video
|
||||
MINIMUM_VIDEO_SIZE = 20480
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import os
|
||||
import logging
|
||||
from constants import MINIMUM_VIDEO_SIZE
|
||||
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
|
@ -16,6 +17,13 @@ from app.event_handler import event_stream, show_progress, hide_progress
|
|||
from .utils import get_profile_list, get_tags, get_movies_from_radarr_api
|
||||
from .parser import movieParser
|
||||
|
||||
# map between booleans and strings in DB
|
||||
bool_map = {"True": True, "False": False}
|
||||
|
||||
FEATURE_PREFIX = "SYNC_MOVIES "
|
||||
def trace(message):
|
||||
if settings.general.debug:
|
||||
logging.debug(FEATURE_PREFIX + message)
|
||||
|
||||
def update_all_movies():
|
||||
movies_full_scan_subtitles()
|
||||
|
@ -45,6 +53,16 @@ def update_movie(updated_movie, send_event):
|
|||
event_stream(type='movie', action='update', payload=updated_movie['radarrId'])
|
||||
|
||||
|
||||
def get_movie_monitored_status(movie_id):
|
||||
existing_movie_monitored = database.execute(
|
||||
select(TableMovies.monitored)
|
||||
.where(TableMovies.tmdbId == movie_id))\
|
||||
.first()
|
||||
if existing_movie_monitored is None:
|
||||
return True
|
||||
else:
|
||||
return bool_map[existing_movie_monitored[0]]
|
||||
|
||||
# Insert new movies in DB
|
||||
def add_movie(added_movie, send_event):
|
||||
try:
|
||||
|
@ -104,12 +122,12 @@ def update_movies(send_event=True):
|
|||
|
||||
current_movies_radarr = [str(movie['tmdbId']) for movie in movies if movie['hasFile'] and
|
||||
'movieFile' in movie and
|
||||
(movie['movieFile']['size'] > 20480 or
|
||||
get_movie_file_size_from_db(movie['movieFile']['path']) > 20480)]
|
||||
(movie['movieFile']['size'] > MINIMUM_VIDEO_SIZE or
|
||||
get_movie_file_size_from_db(movie['movieFile']['path']) > MINIMUM_VIDEO_SIZE)]
|
||||
|
||||
# Remove old movies from DB
|
||||
# Remove movies from DB that either no longer exist in Radarr or exist and Radarr says do not have a movie file
|
||||
movies_to_delete = list(set(current_movies_id_db) - set(current_movies_radarr))
|
||||
|
||||
movies_deleted = []
|
||||
if len(movies_to_delete):
|
||||
try:
|
||||
database.execute(delete(TableMovies).where(TableMovies.tmdbId.in_(movies_to_delete)))
|
||||
|
@ -117,11 +135,19 @@ def update_movies(send_event=True):
|
|||
logging.error(f"BAZARR cannot delete movies because of {e}")
|
||||
else:
|
||||
for removed_movie in movies_to_delete:
|
||||
movies_deleted.append(removed_movie['title'])
|
||||
if send_event:
|
||||
event_stream(type='movie', action='delete', payload=removed_movie)
|
||||
|
||||
# Build new and updated movies
|
||||
# Add new movies and update movies that Radarr says have media files
|
||||
# Any new movies added to Radarr that don't have media files yet will not be added to DB
|
||||
movies_count = len(movies)
|
||||
sync_monitored = settings.radarr.sync_only_monitored_movies
|
||||
if sync_monitored:
|
||||
skipped_count = 0
|
||||
files_missing = 0
|
||||
movies_added = []
|
||||
movies_updated = []
|
||||
for i, movie in enumerate(movies):
|
||||
if send_event:
|
||||
show_progress(id='movies_progress',
|
||||
|
@ -129,12 +155,22 @@ def update_movies(send_event=True):
|
|||
name=movie['title'],
|
||||
value=i,
|
||||
count=movies_count)
|
||||
|
||||
# Only movies that Radarr says have files downloaded will be kept up to date in the DB
|
||||
if movie['hasFile'] is True:
|
||||
if 'movieFile' in movie:
|
||||
if (movie['movieFile']['size'] > 20480 or
|
||||
get_movie_file_size_from_db(movie['movieFile']['path']) > 20480):
|
||||
# Add movies in radarr to current movies list
|
||||
if sync_monitored:
|
||||
if get_movie_monitored_status(movie['tmdbId']) != movie['monitored']:
|
||||
# monitored status is not the same as our DB
|
||||
trace(f"{i}: (Monitor Status Mismatch) {movie['title']}")
|
||||
elif not movie['monitored']:
|
||||
trace(f"{i}: (Skipped Unmonitored) {movie['title']}")
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
if (movie['movieFile']['size'] > MINIMUM_VIDEO_SIZE or
|
||||
get_movie_file_size_from_db(movie['movieFile']['path']) > MINIMUM_VIDEO_SIZE):
|
||||
# Add/update movies from Radarr that have a movie file to current movies list
|
||||
trace(f"{i}: (Processing) {movie['title']}")
|
||||
if str(movie['tmdbId']) in current_movies_id_db:
|
||||
parsed_movie = movieParser(movie, action='update',
|
||||
tags_dict=tagsDict,
|
||||
|
@ -142,16 +178,29 @@ def update_movies(send_event=True):
|
|||
audio_profiles=audio_profiles)
|
||||
if not any([parsed_movie.items() <= x for x in current_movies_db_kv]):
|
||||
update_movie(parsed_movie, send_event)
|
||||
movies_updated.append(parsed_movie['title'])
|
||||
else:
|
||||
parsed_movie = movieParser(movie, action='insert',
|
||||
tags_dict=tagsDict,
|
||||
movie_default_profile=movie_default_profile,
|
||||
audio_profiles=audio_profiles)
|
||||
add_movie(parsed_movie, send_event)
|
||||
movies_added.append(parsed_movie['title'])
|
||||
else:
|
||||
trace(f"{i}: (Skipped File Missing) {movie['title']}")
|
||||
files_missing += 1
|
||||
|
||||
if send_event:
|
||||
hide_progress(id='movies_progress')
|
||||
|
||||
trace(f"Skipped {files_missing} file missing movies out of {i}")
|
||||
if sync_monitored:
|
||||
trace(f"Skipped {skipped_count} unmonitored movies out of {i}")
|
||||
trace(f"Processed {i - files_missing - skipped_count} movies out of {i} " +
|
||||
f"with {len(movies_added)} added, {len(movies_updated)} updated and {len(movies_deleted)} deleted")
|
||||
else:
|
||||
trace(f"Processed {i - files_missing} movies out of {i} with {len(movies_added)} added and {len(movies_updated)} updated")
|
||||
|
||||
logging.debug('BAZARR All movies synced from Radarr into database.')
|
||||
|
||||
|
||||
|
|
|
@ -13,12 +13,6 @@ from .converter import RadarrFormatAudioCodec, RadarrFormatVideoCodec
|
|||
|
||||
def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles):
|
||||
if 'movieFile' in movie:
|
||||
# Detect file separator
|
||||
if movie['path'][0] == "/":
|
||||
separator = "/"
|
||||
else:
|
||||
separator = "\\"
|
||||
|
||||
try:
|
||||
overview = str(movie['overview'])
|
||||
except Exception:
|
||||
|
@ -120,10 +114,9 @@ def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles)
|
|||
|
||||
tags = [d['label'] for d in tags_dict if d['id'] in movie['tags']]
|
||||
|
||||
if action == 'update':
|
||||
return {'radarrId': int(movie["id"]),
|
||||
parsed_movie = {'radarrId': int(movie["id"]),
|
||||
'title': movie["title"],
|
||||
'path': movie["path"] + separator + movie['movieFile']['relativePath'],
|
||||
'path': os.path.join(movie["path"], movie['movieFile']['relativePath']),
|
||||
'tmdbId': str(movie["tmdbId"]),
|
||||
'poster': poster,
|
||||
'fanart': fanart,
|
||||
|
@ -142,30 +135,12 @@ def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles)
|
|||
'movie_file_id': int(movie['movieFile']['id']),
|
||||
'tags': str(tags),
|
||||
'file_size': movie['movieFile']['size']}
|
||||
else:
|
||||
return {'radarrId': int(movie["id"]),
|
||||
'title': movie["title"],
|
||||
'path': movie["path"] + separator + movie['movieFile']['relativePath'],
|
||||
'tmdbId': str(movie["tmdbId"]),
|
||||
'subtitles': '[]',
|
||||
'overview': overview,
|
||||
'poster': poster,
|
||||
'fanart': fanart,
|
||||
'audio_language': str(audio_language),
|
||||
'sceneName': sceneName,
|
||||
'monitored': str(bool(movie['monitored'])),
|
||||
'sortTitle': movie['sortTitle'],
|
||||
'year': str(movie['year']),
|
||||
'alternativeTitles': alternativeTitles,
|
||||
'format': format,
|
||||
'resolution': resolution,
|
||||
'video_codec': videoCodec,
|
||||
'audio_codec': audioCodec,
|
||||
'imdbId': imdbId,
|
||||
'movie_file_id': int(movie['movieFile']['id']),
|
||||
'tags': str(tags),
|
||||
'profileId': movie_default_profile,
|
||||
'file_size': movie['movieFile']['size']}
|
||||
|
||||
if action == 'insert':
|
||||
parsed_movie['subtitles'] = '[]'
|
||||
parsed_movie['profileId'] = movie_default_profile
|
||||
|
||||
return parsed_movie
|
||||
|
||||
|
||||
def profile_id_to_language(id, profiles):
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
import os
|
||||
import logging
|
||||
from constants import MINIMUM_VIDEO_SIZE
|
||||
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from app.database import database, TableEpisodes, delete, update, insert, select
|
||||
from app.database import database, TableShows, TableEpisodes, delete, update, insert, select
|
||||
from app.config import settings
|
||||
from utilities.path_mappings import path_mappings
|
||||
from subtitles.indexer.series import store_subtitles, series_full_scan_subtitles
|
||||
|
@ -16,14 +17,29 @@ from sonarr.info import get_sonarr_info, url_sonarr
|
|||
from .parser import episodeParser
|
||||
from .utils import get_episodes_from_sonarr_api, get_episodesFiles_from_sonarr_api
|
||||
|
||||
# map between booleans and strings in DB
|
||||
bool_map = {"True": True, "False": False}
|
||||
|
||||
FEATURE_PREFIX = "SYNC_EPISODES "
|
||||
def trace(message):
|
||||
if settings.general.debug:
|
||||
logging.debug(FEATURE_PREFIX + message)
|
||||
|
||||
def get_episodes_monitored_table(series_id):
|
||||
episodes_monitored = database.execute(
|
||||
select(TableEpisodes.episode_file_id, TableEpisodes.monitored)
|
||||
.where(TableEpisodes.sonarrSeriesId == series_id))\
|
||||
.all()
|
||||
episode_dict = dict((x, y) for x, y in episodes_monitored)
|
||||
return episode_dict
|
||||
|
||||
def update_all_episodes():
|
||||
series_full_scan_subtitles()
|
||||
logging.info('BAZARR All existing episode subtitles indexed from disk.')
|
||||
|
||||
|
||||
def sync_episodes(series_id, send_event=True):
|
||||
logging.debug('BAZARR Starting episodes sync from Sonarr.')
|
||||
logging.debug(f'BAZARR Starting episodes sync from Sonarr for series ID {series_id}.')
|
||||
apikey_sonarr = settings.sonarr.apikey
|
||||
|
||||
# Get current episodes id in DB
|
||||
|
@ -58,16 +74,42 @@ def sync_episodes(series_id, send_event=True):
|
|||
if item:
|
||||
episode['episodeFile'] = item[0]
|
||||
|
||||
|
||||
sync_monitored = settings.sonarr.sync_only_monitored_series and settings.sonarr.sync_only_monitored_episodes
|
||||
if sync_monitored:
|
||||
episodes_monitored = get_episodes_monitored_table(series_id)
|
||||
skipped_count = 0
|
||||
|
||||
for episode in episodes:
|
||||
if 'hasFile' in episode:
|
||||
if episode['hasFile'] is True:
|
||||
if 'episodeFile' in episode:
|
||||
# monitored_status_db = get_episodes_monitored_status(episode['episodeFileId'])
|
||||
if sync_monitored:
|
||||
try:
|
||||
monitored_status_db = bool_map[episodes_monitored[episode['episodeFileId']]]
|
||||
except KeyError:
|
||||
monitored_status_db = None
|
||||
|
||||
if monitored_status_db is None:
|
||||
# not in db, might need to add, if we have a file on disk
|
||||
pass
|
||||
elif monitored_status_db != episode['monitored']:
|
||||
# monitored status changed and we don't know about it until now
|
||||
trace(f"(Monitor Status Mismatch) {episode['title']}")
|
||||
# pass
|
||||
elif not episode['monitored']:
|
||||
# Add unmonitored episode in sonarr to current episode list, otherwise it will be deleted from db
|
||||
current_episodes_sonarr.append(episode['id'])
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
bazarr_file_size = \
|
||||
os.path.getsize(path_mappings.path_replace(episode['episodeFile']['path']))
|
||||
except OSError:
|
||||
bazarr_file_size = 0
|
||||
if episode['episodeFile']['size'] > 20480 or bazarr_file_size > 20480:
|
||||
if episode['episodeFile']['size'] > MINIMUM_VIDEO_SIZE or bazarr_file_size > MINIMUM_VIDEO_SIZE:
|
||||
# Add episodes in sonarr to current episode list
|
||||
current_episodes_sonarr.append(episode['id'])
|
||||
|
||||
|
@ -80,6 +122,12 @@ def sync_episodes(series_id, send_event=True):
|
|||
episodes_to_add.append(episodeParser(episode))
|
||||
else:
|
||||
return
|
||||
|
||||
if sync_monitored:
|
||||
# try to avoid unnecessary database calls
|
||||
if settings.general.debug:
|
||||
series_title = database.execute(select(TableShows.title).where(TableShows.sonarrSeriesId == series_id)).first()[0]
|
||||
trace(f"Skipped {skipped_count} unmonitored episodes out of {len(episodes)} for {series_title}")
|
||||
|
||||
# Remove old episodes from DB
|
||||
episodes_to_delete = list(set(current_episodes_id_db_list) - set(current_episodes_sonarr))
|
||||
|
|
|
@ -4,6 +4,7 @@ import os
|
|||
|
||||
from app.config import settings
|
||||
from app.database import TableShows, database, select
|
||||
from constants import MINIMUM_VIDEO_SIZE
|
||||
from utilities.path_mappings import path_mappings
|
||||
from utilities.video_analyzer import embedded_audio_reader
|
||||
from sonarr.info import get_sonarr_info
|
||||
|
@ -92,7 +93,7 @@ def episodeParser(episode):
|
|||
bazarr_file_size = os.path.getsize(path_mappings.path_replace(episode['episodeFile']['path']))
|
||||
except OSError:
|
||||
bazarr_file_size = 0
|
||||
if episode['episodeFile']['size'] > 20480 or bazarr_file_size > 20480:
|
||||
if episode['episodeFile']['size'] > MINIMUM_VIDEO_SIZE or bazarr_file_size > MINIMUM_VIDEO_SIZE:
|
||||
if 'sceneName' in episode['episodeFile']:
|
||||
sceneName = episode['episodeFile']['sceneName']
|
||||
else:
|
||||
|
|
|
@ -16,6 +16,20 @@ from .episodes import sync_episodes
|
|||
from .parser import seriesParser
|
||||
from .utils import get_profile_list, get_tags, get_series_from_sonarr_api
|
||||
|
||||
# map between booleans and strings in DB
|
||||
bool_map = {"True": True, "False": False}
|
||||
|
||||
FEATURE_PREFIX = "SYNC_SERIES "
|
||||
def trace(message):
|
||||
if settings.general.debug:
|
||||
logging.debug(FEATURE_PREFIX + message)
|
||||
|
||||
def get_series_monitored_table():
|
||||
series_monitored = database.execute(
|
||||
select(TableShows.tvdbId, TableShows.monitored))\
|
||||
.all()
|
||||
series_dict = dict((x, y) for x, y in series_monitored)
|
||||
return series_dict
|
||||
|
||||
def update_series(send_event=True):
|
||||
check_sonarr_rootfolder()
|
||||
|
@ -55,6 +69,12 @@ def update_series(send_event=True):
|
|||
current_shows_sonarr = []
|
||||
|
||||
series_count = len(series)
|
||||
sync_monitored = settings.sonarr.sync_only_monitored_series
|
||||
if sync_monitored:
|
||||
series_monitored = get_series_monitored_table()
|
||||
skipped_count = 0
|
||||
trace(f"Starting sync for {series_count} shows")
|
||||
|
||||
for i, show in enumerate(series):
|
||||
if send_event:
|
||||
show_progress(id='series_progress',
|
||||
|
@ -63,6 +83,26 @@ def update_series(send_event=True):
|
|||
value=i,
|
||||
count=series_count)
|
||||
|
||||
if sync_monitored:
|
||||
try:
|
||||
monitored_status_db = bool_map[series_monitored[show['tvdbId']]]
|
||||
except KeyError:
|
||||
monitored_status_db = None
|
||||
if monitored_status_db is None:
|
||||
# not in db, need to add
|
||||
pass
|
||||
elif monitored_status_db != show['monitored']:
|
||||
# monitored status changed and we don't know about it until now
|
||||
trace(f"{i}: (Monitor Status Mismatch) {show['title']}")
|
||||
# pass
|
||||
elif not show['monitored']:
|
||||
# Add unmonitored series in sonarr to current series list, otherwise it will be deleted from db
|
||||
trace(f"{i}: (Skipped Unmonitored) {show['title']}")
|
||||
current_shows_sonarr.append(show['id'])
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
trace(f"{i}: (Processing) {show['title']}")
|
||||
# Add shows in Sonarr to current shows list
|
||||
current_shows_sonarr.append(show['id'])
|
||||
|
||||
|
@ -76,6 +116,7 @@ def update_series(send_event=True):
|
|||
.filter_by(**updated_series))\
|
||||
.first():
|
||||
try:
|
||||
trace(f"Updating {show['title']}")
|
||||
database.execute(
|
||||
update(TableShows)
|
||||
.values(updated_series)
|
||||
|
@ -92,6 +133,7 @@ def update_series(send_event=True):
|
|||
audio_profiles=audio_profiles)
|
||||
|
||||
try:
|
||||
trace(f"Inserting {show['title']}")
|
||||
database.execute(
|
||||
insert(TableShows)
|
||||
.values(added_series))
|
||||
|
@ -110,6 +152,10 @@ def update_series(send_event=True):
|
|||
removed_series = list(set(current_shows_db) - set(current_shows_sonarr))
|
||||
|
||||
for series in removed_series:
|
||||
# try to avoid unnecessary database calls
|
||||
if settings.general.debug:
|
||||
series_title = database.execute(select(TableShows.title).where(TableShows.sonarrSeriesId == series)).first()[0]
|
||||
trace(f"Deleting {series_title}")
|
||||
database.execute(
|
||||
delete(TableShows)
|
||||
.where(TableShows.sonarrSeriesId == series))
|
||||
|
@ -120,6 +166,8 @@ def update_series(send_event=True):
|
|||
if send_event:
|
||||
hide_progress(id='series_progress')
|
||||
|
||||
if sync_monitored:
|
||||
trace(f"skipped {skipped_count} unmonitored series out of {i}")
|
||||
logging.debug('BAZARR All series synced from Sonarr into database.')
|
||||
|
||||
|
||||
|
|
|
@ -266,6 +266,11 @@ def parse_video_metadata(file, file_size, episode_file_id=None, movie_file_id=No
|
|||
elif embedded_subs_parser == 'mediainfo':
|
||||
mediainfo_path = get_binary("mediainfo")
|
||||
|
||||
# see if file exists (perhaps offline)
|
||||
if not os.path.exists(file):
|
||||
logging.error(f'Video file "{file}" cannot be found for analysis')
|
||||
return None
|
||||
|
||||
# if we have ffprobe available
|
||||
if ffprobe_path:
|
||||
try:
|
||||
|
|
|
@ -35,11 +35,55 @@ const SettingsSchedulerView: FunctionComponent = () => {
|
|||
options={seriesSyncOptions}
|
||||
settingKey="settings-sonarr-series_sync"
|
||||
></Selector>
|
||||
<Check
|
||||
label="Sync Only Monitored Series"
|
||||
settingKey={"settings-sonarr-sync_only_monitored_series"}
|
||||
></Check>
|
||||
<CollapseBox settingKey={"settings-sonarr-sync_only_monitored_series"}>
|
||||
<Message>
|
||||
If enabled, only series with a monitored status in Sonarr will be
|
||||
synced. If you make changes to a specific unmonitored Sonarr series
|
||||
and you want Bazarr to know about those changes, simply toggle the
|
||||
monitored status back on in Sonarr and Bazarr will sync any changes.
|
||||
</Message>
|
||||
</CollapseBox>
|
||||
<CollapseBox settingKey={"settings-sonarr-sync_only_monitored_series"}>
|
||||
<Check
|
||||
label="Sync Only Monitored Episodes"
|
||||
settingKey={"settings-sonarr-sync_only_monitored_episodes"}
|
||||
></Check>
|
||||
<CollapseBox
|
||||
settingKey={"settings-sonarr-sync_only_monitored_episodes"}
|
||||
>
|
||||
<Message>
|
||||
If enabled, only episodes with a monitored status in Sonarr will
|
||||
be synced. If you make changes to a specific unmonitored Sonarr
|
||||
episode (or season) and you want Bazarr to know about those
|
||||
changes, simply toggle the monitored status back on in Sonarr and
|
||||
Bazarr will sync any changes. This setting is especially helpful
|
||||
for long running TV series with many seasons and many episodes,
|
||||
but that are still actively producing new episodes (e.g. Saturday
|
||||
Night Live).
|
||||
</Message>
|
||||
</CollapseBox>
|
||||
</CollapseBox>
|
||||
<Selector
|
||||
label="Sync with Radarr"
|
||||
options={moviesSyncOptions}
|
||||
settingKey="settings-radarr-movies_sync"
|
||||
></Selector>
|
||||
<Check
|
||||
label="Sync Only Monitored Movies"
|
||||
settingKey={"settings-radarr-sync_only_monitored_movies"}
|
||||
></Check>
|
||||
<CollapseBox settingKey={"settings-radarr-sync_only_monitored_movies"}>
|
||||
<Message>
|
||||
If enabled, only movies with a monitored status in Radarr will be
|
||||
synced. If you make changes to a specific unmonitored Radarr movie
|
||||
and you want Bazarr to know about those changes, simply toggle the
|
||||
monitored status back on in Radarr and Bazarr will sync any changes.
|
||||
</Message>
|
||||
</CollapseBox>
|
||||
</Section>
|
||||
<Section header="Disk Indexing">
|
||||
<Selector
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue