Merge remote-tracking branch 'origin/development' into development

This commit is contained in:
morpheus65535 2023-12-28 14:41:24 -05:00
commit 965b0bcc79
6 changed files with 83 additions and 65 deletions

View File

@ -34,6 +34,9 @@ def validate_ip_address(ip_string):
return False return False
ONE_HUNDRED_YEARS_IN_MINUTES = 52560000
ONE_HUNDRED_YEARS_IN_HOURS = 876000
class Validator(OriginalValidator): class Validator(OriginalValidator):
# Give the ability to personalize messages sent by the original dynasync Validator class. # Give the ability to personalize messages sent by the original dynasync Validator class.
default_messages = MappingProxyType( default_messages = MappingProxyType(
@ -99,14 +102,15 @@ validators = [
Validator('general.subfolder', must_exist=True, default='current', is_type_of=str), Validator('general.subfolder', must_exist=True, default='current', is_type_of=str),
Validator('general.subfolder_custom', must_exist=True, default='', is_type_of=str), Validator('general.subfolder_custom', must_exist=True, default='', is_type_of=str),
Validator('general.upgrade_subs', must_exist=True, default=True, is_type_of=bool), Validator('general.upgrade_subs', must_exist=True, default=True, is_type_of=bool),
Validator('general.upgrade_frequency', must_exist=True, default=12, is_type_of=int, is_in=[6, 12, 24]), Validator('general.upgrade_frequency', must_exist=True, default=12, is_type_of=int,
is_in=[6, 12, 24, ONE_HUNDRED_YEARS_IN_HOURS]),
Validator('general.days_to_upgrade_subs', must_exist=True, default=7, is_type_of=int, gte=0, lte=30), Validator('general.days_to_upgrade_subs', must_exist=True, default=7, is_type_of=int, gte=0, lte=30),
Validator('general.upgrade_manual', must_exist=True, default=True, is_type_of=bool), Validator('general.upgrade_manual', must_exist=True, default=True, is_type_of=bool),
Validator('general.anti_captcha_provider', must_exist=True, default=None, is_type_of=(NoneType, str), Validator('general.anti_captcha_provider', must_exist=True, default=None, is_type_of=(NoneType, str),
is_in=[None, 'anti-captcha', 'death-by-captcha']), is_in=[None, 'anti-captcha', 'death-by-captcha']),
Validator('general.wanted_search_frequency', must_exist=True, default=6, is_type_of=int, is_in=[6, 12, 24]), Validator('general.wanted_search_frequency', must_exist=True, default=6, is_type_of=int, is_in=[6, 12, 24, ONE_HUNDRED_YEARS_IN_HOURS]),
Validator('general.wanted_search_frequency_movie', must_exist=True, default=6, is_type_of=int, Validator('general.wanted_search_frequency_movie', must_exist=True, default=6, is_type_of=int,
is_in=[6, 12, 24]), is_in=[6, 12, 24, ONE_HUNDRED_YEARS_IN_HOURS]),
Validator('general.subzero_mods', must_exist=True, default='', is_type_of=str), Validator('general.subzero_mods', must_exist=True, default='', is_type_of=str),
Validator('general.dont_notify_manual_actions', must_exist=True, default=False, is_type_of=bool), Validator('general.dont_notify_manual_actions', must_exist=True, default=False, is_type_of=bool),
Validator('general.hi_extension', must_exist=True, default='hi', is_type_of=str, is_in=['hi', 'cc', 'sdh']), Validator('general.hi_extension', must_exist=True, default='hi', is_type_of=str, is_in=['hi', 'cc', 'sdh']),
@ -151,9 +155,7 @@ validators = [
Validator('sonarr.full_update_hour', must_exist=True, default=4, is_type_of=int, gte=0, lte=23), Validator('sonarr.full_update_hour', must_exist=True, default=4, is_type_of=int, gte=0, lte=23),
Validator('sonarr.only_monitored', must_exist=True, default=False, is_type_of=bool), Validator('sonarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('sonarr.series_sync', must_exist=True, default=60, is_type_of=int, Validator('sonarr.series_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440]), is_in=[15, 60, 180, 360, 720, 1440, ONE_HUNDRED_YEARS_IN_MINUTES]),
Validator('sonarr.episodes_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440]),
Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list), Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
Validator('sonarr.excluded_series_types', must_exist=True, default=[], is_type_of=list), Validator('sonarr.excluded_series_types', must_exist=True, default=[], is_type_of=list),
Validator('sonarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool), Validator('sonarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
@ -174,7 +176,7 @@ validators = [
Validator('radarr.full_update_hour', must_exist=True, default=4, is_type_of=int, gte=0, lte=23), Validator('radarr.full_update_hour', must_exist=True, default=4, is_type_of=int, gte=0, lte=23),
Validator('radarr.only_monitored', must_exist=True, default=False, is_type_of=bool), Validator('radarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('radarr.movies_sync', must_exist=True, default=60, is_type_of=int, Validator('radarr.movies_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440]), is_in=[15, 60, 180, 360, 720, 1440, ONE_HUNDRED_YEARS_IN_MINUTES]),
Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list), 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.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.defer_search_signalr', must_exist=True, default=False, is_type_of=bool),
@ -409,8 +411,6 @@ str_keys = ['chmod']
# Increase Sonarr and Radarr sync interval since we now use SignalR feed to update in real time # Increase Sonarr and Radarr sync interval since we now use SignalR feed to update in real time
if settings.sonarr.series_sync < 15: if settings.sonarr.series_sync < 15:
settings.sonarr.series_sync = 60 settings.sonarr.series_sync = 60
if settings.sonarr.episodes_sync < 15:
settings.sonarr.episodes_sync = 60
if settings.radarr.movies_sync < 15: if settings.radarr.movies_sync < 15:
settings.radarr.movies_sync = 60 settings.radarr.movies_sync = 60
@ -534,7 +534,7 @@ def save_settings(settings_items):
if key in ['update_schedule', 'settings-general-use_sonarr', 'settings-general-use_radarr', if key in ['update_schedule', 'settings-general-use_sonarr', 'settings-general-use_radarr',
'settings-general-auto_update', 'settings-general-upgrade_subs', 'settings-general-auto_update', 'settings-general-upgrade_subs',
'settings-sonarr-series_sync', 'settings-sonarr-episodes_sync', 'settings-radarr-movies_sync', 'settings-sonarr-series_sync', 'settings-radarr-movies_sync',
'settings-sonarr-full_update', 'settings-sonarr-full_update_day', 'settings-sonarr-full_update_hour', 'settings-sonarr-full_update', 'settings-sonarr-full_update_day', 'settings-sonarr-full_update_hour',
'settings-radarr-full_update', 'settings-radarr-full_update_day', 'settings-radarr-full_update_hour', 'settings-radarr-full_update', 'settings-radarr-full_update_day', 'settings-radarr-full_update_hour',
'settings-general-wanted_search_frequency', 'settings-general-wanted_search_frequency_movie', 'settings-general-wanted_search_frequency', 'settings-general-wanted_search_frequency_movie',

View File

@ -36,6 +36,20 @@ if not args.no_update:
else: else:
from .check_update import check_releases from .check_update import check_releases
from dateutil.relativedelta import relativedelta
NO_INTERVAL = "None"
NEVER_DATE = "Never"
ONE_YEAR_IN_SECONDS = 60 * 60 * 24 * 365
def a_long_time_from_now(job):
# currently defined as more than a year from now
delta = job.next_run_time - datetime.now(job.next_run_time.tzinfo)
return delta.total_seconds() > ONE_YEAR_IN_SECONDS
def in_a_century():
century = datetime.now() + relativedelta(years=100)
return century.year
class Scheduler: class Scheduler:
@ -106,7 +120,9 @@ class Scheduler:
('minute', 60), ('minute', 60),
('second', 1) ('second', 1)
] ]
if seconds > ONE_YEAR_IN_SECONDS:
# more than a year is None
return NO_INTERVAL
strings = [] strings = []
for period_name, period_seconds in periods: for period_name, period_seconds in periods:
if seconds > period_seconds: if seconds > period_seconds:
@ -118,14 +134,11 @@ class Scheduler:
def get_time_from_cron(cron): def get_time_from_cron(cron):
year = str(cron[0]) year = str(cron[0])
if year == "2100":
return "Never"
day = str(cron[4]) day = str(cron[4])
hour = str(cron[5]) hour = str(cron[5])
if day == "*": if day == "*":
text = "everyday" text = "every day"
else: else:
text = f"every {day_name[int(day)]}" text = f"every {day_name[int(day)]}"
@ -136,12 +149,20 @@ class Scheduler:
task_list = [] task_list = []
for job in self.aps_scheduler.get_jobs(): for job in self.aps_scheduler.get_jobs():
next_run = 'Never' next_run = NEVER_DATE
if job.next_run_time: if job.next_run_time:
next_run = pretty.date(job.next_run_time.replace(tzinfo=None)) if a_long_time_from_now(job):
if isinstance(job.trigger, CronTrigger): # Never for IntervalTrigger jobs
if job.next_run_time and str(job.trigger.__getstate__()['fields'][0]) != "2100": next_run = NEVER_DATE
else:
next_run = pretty.date(job.next_run_time.replace(tzinfo=None)) next_run = pretty.date(job.next_run_time.replace(tzinfo=None))
if isinstance(job.trigger, CronTrigger):
if a_long_time_from_now(job):
# Never for CronTrigger jobs
next_run = NEVER_DATE
else:
if job.next_run_time:
next_run = pretty.date(job.next_run_time.replace(tzinfo=None))
if job.id in self.__running_tasks: if job.id in self.__running_tasks:
running = True running = True
@ -149,13 +170,21 @@ class Scheduler:
running = False running = False
if isinstance(job.trigger, IntervalTrigger): if isinstance(job.trigger, IntervalTrigger):
interval = f"every {get_time_from_interval(job.trigger.__getstate__()['interval'])}" interval = get_time_from_interval(job.trigger.__getstate__()['interval'])
if interval != NO_INTERVAL:
interval = f"every {interval}"
# else:
# interval = "100 Year Interval"
task_list.append({'name': job.name, 'interval': interval, 'next_run_in': next_run, task_list.append({'name': job.name, 'interval': interval, 'next_run_in': next_run,
'next_run_time': next_run, 'job_id': job.id, 'job_running': running}) 'next_run_time': next_run, 'job_id': job.id, 'job_running': running})
elif isinstance(job.trigger, CronTrigger): elif isinstance(job.trigger, CronTrigger):
task_list.append({'name': job.name, 'interval': get_time_from_cron(job.trigger.fields), if a_long_time_from_now(job):
'next_run_in': next_run, 'next_run_time': next_run, 'job_id': job.id, interval = NO_INTERVAL
'job_running': running}) else:
interval = get_time_from_cron(job.trigger.fields)
task_list.append({'name': job.name, 'interval': interval,
'next_run_in': next_run, 'next_run_time': next_run, 'job_id': job.id,
'job_running': running})
return task_list return task_list
@ -175,29 +204,23 @@ class Scheduler:
def __cache_cleanup_task(self): def __cache_cleanup_task(self):
self.aps_scheduler.add_job(cache_maintenance, IntervalTrigger(hours=24), max_instances=1, coalesce=True, self.aps_scheduler.add_job(cache_maintenance, IntervalTrigger(hours=24), max_instances=1, coalesce=True,
misfire_grace_time=15, id='cache_cleanup', name='Cache maintenance') misfire_grace_time=15, id='cache_cleanup', name='Cache Maintenance')
def __check_health_task(self): def __check_health_task(self):
self.aps_scheduler.add_job(check_health, IntervalTrigger(hours=6), max_instances=1, coalesce=True, self.aps_scheduler.add_job(check_health, IntervalTrigger(hours=6), max_instances=1, coalesce=True,
misfire_grace_time=15, id='check_health', name='Check health') misfire_grace_time=15, id='check_health', name='Check Health')
def __automatic_backup(self): def __automatic_backup(self):
backup = settings.backup.frequency backup = settings.backup.frequency
if backup == "Daily": if backup == "Daily":
self.aps_scheduler.add_job( trigger = CronTrigger(hour=settings.backup.hour)
backup_to_zip, CronTrigger(hour=settings.backup.hour), max_instances=1, coalesce=True,
misfire_grace_time=15, id='backup', name='Backup database and configuration file',
replace_existing=True)
elif backup == "Weekly": elif backup == "Weekly":
self.aps_scheduler.add_job( trigger = CronTrigger(day_of_week=settings.backup.day, hour=settings.backup.hour)
backup_to_zip, CronTrigger(day_of_week=settings.backup.day, hour=settings.backup.hour),
max_instances=1, coalesce=True, misfire_grace_time=15, id='backup',
name='Backup database and configuration file', replace_existing=True)
elif backup == "Manually": elif backup == "Manually":
try: trigger = CronTrigger(year=in_a_century())
self.aps_scheduler.remove_job(job_id='backup') self.aps_scheduler.add_job(backup_to_zip, trigger,
except JobLookupError: max_instances=1, coalesce=True, misfire_grace_time=15, id='backup',
pass name='Backup Database and Configuration File', replace_existing=True)
def __sonarr_full_update_task(self): def __sonarr_full_update_task(self):
if settings.general.use_sonarr: if settings.general.use_sonarr:
@ -206,18 +229,18 @@ class Scheduler:
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_episodes, CronTrigger(hour=settings.sonarr.full_update_hour), max_instances=1, update_all_episodes, CronTrigger(hour=settings.sonarr.full_update_hour), max_instances=1,
coalesce=True, misfire_grace_time=15, id='update_all_episodes', coalesce=True, misfire_grace_time=15, id='update_all_episodes',
name='Index all Episode Subtitles from disk', replace_existing=True) name='Index All Episode Subtitles from Disk', replace_existing=True)
elif full_update == "Weekly": elif full_update == "Weekly":
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_episodes, update_all_episodes,
CronTrigger(day_of_week=settings.sonarr.full_update_day, hour=settings.sonarr.full_update_hour), CronTrigger(day_of_week=settings.sonarr.full_update_day, hour=settings.sonarr.full_update_hour),
max_instances=1, coalesce=True, misfire_grace_time=15, id='update_all_episodes', max_instances=1, coalesce=True, misfire_grace_time=15, id='update_all_episodes',
name='Index all Episode Subtitles from disk', replace_existing=True) name='Index All Episode Subtitles from Disk', replace_existing=True)
elif full_update == "Manually": elif full_update == "Manually":
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_episodes, CronTrigger(year='2100'), max_instances=1, coalesce=True, update_all_episodes, CronTrigger(year=in_a_century()), max_instances=1, coalesce=True,
misfire_grace_time=15, id='update_all_episodes', misfire_grace_time=15, id='update_all_episodes',
name='Index all Episode Subtitles from disk', replace_existing=True) name='Index All Episode Subtitles from Disk', replace_existing=True)
def __radarr_full_update_task(self): def __radarr_full_update_task(self):
if settings.general.use_radarr: if settings.general.use_radarr:
@ -226,17 +249,17 @@ class Scheduler:
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_movies, CronTrigger(hour=settings.radarr.full_update_hour), max_instances=1, update_all_movies, CronTrigger(hour=settings.radarr.full_update_hour), max_instances=1,
coalesce=True, misfire_grace_time=15, coalesce=True, misfire_grace_time=15,
id='update_all_movies', name='Index all Movie Subtitles from disk', replace_existing=True) id='update_all_movies', name='Index All Movie Subtitles from Disk', replace_existing=True)
elif full_update == "Weekly": elif full_update == "Weekly":
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_movies, update_all_movies,
CronTrigger(day_of_week=settings.radarr.full_update_day, hour=settings.radarr.full_update_hour), CronTrigger(day_of_week=settings.radarr.full_update_day, hour=settings.radarr.full_update_hour),
max_instances=1, coalesce=True, misfire_grace_time=15, id='update_all_movies', max_instances=1, coalesce=True, misfire_grace_time=15, id='update_all_movies',
name='Index all Movie Subtitles from disk', replace_existing=True) name='Index All Movie Subtitles from Disk', replace_existing=True)
elif full_update == "Manually": elif full_update == "Manually":
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
update_all_movies, CronTrigger(year='2100'), max_instances=1, coalesce=True, misfire_grace_time=15, update_all_movies, CronTrigger(year=in_a_century()), max_instances=1, coalesce=True, misfire_grace_time=15,
id='update_all_movies', name='Index all Movie Subtitles from disk', replace_existing=True) id='update_all_movies', name='Index All Movie Subtitles from Disk', replace_existing=True)
def __update_bazarr_task(self): def __update_bazarr_task(self):
if not args.no_update and os.environ["BAZARR_VERSION"] != '': if not args.no_update and os.environ["BAZARR_VERSION"] != '':
@ -248,7 +271,7 @@ class Scheduler:
misfire_grace_time=15, id='update_bazarr', name=task_name, replace_existing=True) misfire_grace_time=15, id='update_bazarr', name=task_name, replace_existing=True)
else: else:
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
check_if_new_update, CronTrigger(year='2100'), hour=4, id='update_bazarr', name=task_name, check_if_new_update, CronTrigger(year=in_a_century()), hour=4, id='update_bazarr', name=task_name,
replace_existing=True) replace_existing=True)
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
check_releases, IntervalTrigger(hours=3), max_instances=1, coalesce=True, misfire_grace_time=15, check_releases, IntervalTrigger(hours=3), max_instances=1, coalesce=True, misfire_grace_time=15,
@ -269,13 +292,13 @@ class Scheduler:
wanted_search_missing_subtitles_series, wanted_search_missing_subtitles_series,
IntervalTrigger(hours=int(settings.general.wanted_search_frequency)), max_instances=1, coalesce=True, IntervalTrigger(hours=int(settings.general.wanted_search_frequency)), max_instances=1, coalesce=True,
misfire_grace_time=15, id='wanted_search_missing_subtitles_series', replace_existing=True, misfire_grace_time=15, id='wanted_search_missing_subtitles_series', replace_existing=True,
name='Search for wanted Series Subtitles') name='Search for Missing Series Subtitles')
if settings.general.use_radarr: if settings.general.use_radarr:
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
wanted_search_missing_subtitles_movies, wanted_search_missing_subtitles_movies,
IntervalTrigger(hours=int(settings.general.wanted_search_frequency_movie)), max_instances=1, IntervalTrigger(hours=int(settings.general.wanted_search_frequency_movie)), max_instances=1,
coalesce=True, misfire_grace_time=15, id='wanted_search_missing_subtitles_movies', coalesce=True, misfire_grace_time=15, id='wanted_search_missing_subtitles_movies',
name='Search for wanted Movies Subtitles', replace_existing=True) name='Search for Missing Movies Subtitles', replace_existing=True)
def __upgrade_subtitles_task(self): def __upgrade_subtitles_task(self):
if settings.general.upgrade_subs and \ if settings.general.upgrade_subs and \
@ -283,7 +306,7 @@ class Scheduler:
self.aps_scheduler.add_job( self.aps_scheduler.add_job(
upgrade_subtitles, IntervalTrigger(hours=int(settings.general.upgrade_frequency)), max_instances=1, upgrade_subtitles, IntervalTrigger(hours=int(settings.general.upgrade_frequency)), max_instances=1,
coalesce=True, misfire_grace_time=15, id='upgrade_subtitles', coalesce=True, misfire_grace_time=15, id='upgrade_subtitles',
name='Upgrade previously downloaded Subtitles', replace_existing=True) name='Upgrade Previously Downloaded Subtitles', replace_existing=True)
else: else:
try: try:
self.aps_scheduler.remove_job(job_id='upgrade_subtitles') self.aps_scheduler.remove_job(job_id='upgrade_subtitles')
@ -293,6 +316,9 @@ class Scheduler:
def __randomize_interval_task(self): def __randomize_interval_task(self):
for job in self.aps_scheduler.get_jobs(): for job in self.aps_scheduler.get_jobs():
if isinstance(job.trigger, IntervalTrigger): if isinstance(job.trigger, IntervalTrigger):
# do not randomize the Never jobs
if job.trigger.interval.total_seconds() > ONE_YEAR_IN_SECONDS:
continue
self.aps_scheduler.modify_job(job.id, self.aps_scheduler.modify_job(job.id,
next_run_time=datetime.now(tz=self.timezone) + next_run_time=datetime.now(tz=self.timezone) +
timedelta(seconds=randrange( timedelta(seconds=randrange(

View File

@ -12,7 +12,6 @@ import {
backupOptions, backupOptions,
dayOptions, dayOptions,
diskUpdateOptions, diskUpdateOptions,
episodesSyncOptions,
moviesSyncOptions, moviesSyncOptions,
seriesSyncOptions, seriesSyncOptions,
upgradeOptions, upgradeOptions,
@ -32,26 +31,19 @@ const SettingsSchedulerView: FunctionComponent = () => {
<Layout name="Scheduler"> <Layout name="Scheduler">
<Section header="Sonarr/Radarr Sync"> <Section header="Sonarr/Radarr Sync">
<Selector <Selector
label="Update Series List from Sonarr" label="Sync with Sonarr"
options={seriesSyncOptions} options={seriesSyncOptions}
settingKey="settings-sonarr-series_sync" settingKey="settings-sonarr-series_sync"
></Selector> ></Selector>
<Selector <Selector
label="Update Episodes List from Sonarr" label="Sync with Radarr"
options={episodesSyncOptions}
settingKey="settings-sonarr-episodes_sync"
></Selector>
<Selector
label="Update Movies List from Radarr"
options={moviesSyncOptions} options={moviesSyncOptions}
settingKey="settings-radarr-movies_sync" settingKey="settings-radarr-movies_sync"
></Selector> ></Selector>
</Section> </Section>
<Section header="Disk Indexing"> <Section header="Disk Indexing">
<Selector <Selector
label="Update all Episode Subtitles from Disk" label="Update All Episode Subtitles from Disk"
settingKey="settings-sonarr-full_update" settingKey="settings-sonarr-full_update"
options={diskUpdateOptions} options={diskUpdateOptions}
></Selector> ></Selector>
@ -88,7 +80,7 @@ const SettingsSchedulerView: FunctionComponent = () => {
</Message> </Message>
<Selector <Selector
label="Update all Movie Subtitles from Disk" label="Update All Movie Subtitles from Disk"
settingKey="settings-radarr-full_update" settingKey="settings-radarr-full_update"
options={diskUpdateOptions} options={diskUpdateOptions}
></Selector> ></Selector>
@ -144,7 +136,7 @@ const SettingsSchedulerView: FunctionComponent = () => {
</Section> </Section>
<Section header="Backup"> <Section header="Backup">
<Selector <Selector
label="Backup config and database" label="Backup Database and Configuration File"
settingKey="settings-backup-frequency" settingKey="settings-backup-frequency"
options={backupOptions} options={backupOptions}
></Selector> ></Selector>

View File

@ -1,6 +1,7 @@
import { SelectorOption } from "@/components"; import { SelectorOption } from "@/components";
export const seriesSyncOptions: SelectorOption<number>[] = [ export const seriesSyncOptions: SelectorOption<number>[] = [
{ label: "Manually", value: 52560000 },
{ label: "15 Minutes", value: 15 }, { label: "15 Minutes", value: 15 },
{ label: "1 Hour", value: 60 }, { label: "1 Hour", value: 60 },
{ label: "3 Hours", value: 180 }, { label: "3 Hours", value: 180 },
@ -9,8 +10,6 @@ export const seriesSyncOptions: SelectorOption<number>[] = [
{ label: "24 Hours", value: 1440 }, { label: "24 Hours", value: 1440 },
]; ];
export const episodesSyncOptions = seriesSyncOptions;
export const moviesSyncOptions = seriesSyncOptions; export const moviesSyncOptions = seriesSyncOptions;
export const diskUpdateOptions: SelectorOption<string>[] = [ export const diskUpdateOptions: SelectorOption<string>[] = [
@ -32,6 +31,7 @@ export const dayOptions: SelectorOption<number>[] = [
]; ];
export const upgradeOptions: SelectorOption<number>[] = [ export const upgradeOptions: SelectorOption<number>[] = [
{ label: "Manually", value: 876000 },
{ label: "6 Hours", value: 6 }, { label: "6 Hours", value: 6 },
{ label: "12 Hours", value: 12 }, { label: "12 Hours", value: 12 },
{ label: "24 Hours", value: 24 }, { label: "24 Hours", value: 24 },

View File

@ -146,6 +146,7 @@ export const Slider: FunctionComponent<SliderProps> = (props) => {
<MantineSlider <MantineSlider
{...sliderProps} {...sliderProps}
marks={marks} marks={marks}
labelAlwaysOn
onChange={update} onChange={update}
value={value ?? 0} value={value ?? 0}
></MantineSlider> ></MantineSlider>

View File

@ -144,7 +144,6 @@ declare namespace Settings {
full_update_hour: number; full_update_hour: number;
only_monitored: boolean; only_monitored: boolean;
series_sync: number; series_sync: number;
episodes_sync: number;
excluded_tags: string[]; excluded_tags: string[];
excluded_series_types: SonarrSeriesType[]; excluded_series_types: SonarrSeriesType[];
} }