mirror of
https://github.com/morpheus65535/bazarr
synced 2025-02-22 05:51:10 +00:00
Add chmod, provider throttle, multithread options
This commit is contained in:
parent
8472a48e28
commit
acbbf6e58b
5 changed files with 225 additions and 119 deletions
|
@ -32,7 +32,10 @@ defaults = {
|
||||||
'minimum_score_movie': '70',
|
'minimum_score_movie': '70',
|
||||||
'use_embedded_subs': 'True',
|
'use_embedded_subs': 'True',
|
||||||
'adaptive_searching': 'False',
|
'adaptive_searching': 'False',
|
||||||
'enabled_providers': ''
|
'enabled_providers': '',
|
||||||
|
'throtteled_providers': '',
|
||||||
|
'multithreading': 'True',
|
||||||
|
'chmod': '0640'
|
||||||
},
|
},
|
||||||
'auth': {
|
'auth': {
|
||||||
'type': 'None',
|
'type': 'None',
|
||||||
|
@ -69,16 +72,16 @@ defaults = {
|
||||||
'username': '',
|
'username': '',
|
||||||
'password': '',
|
'password': '',
|
||||||
'use_tag_search': 'False',
|
'use_tag_search': 'False',
|
||||||
'vip': 'False',
|
'vip': 'True',
|
||||||
'ssl': 'False',
|
'ssl': 'True',
|
||||||
'timeout': '15',
|
'timeout': '15',
|
||||||
'skip_wrong_fps': 'False'
|
'skip_wrong_fps': 'False'
|
||||||
},
|
},
|
||||||
'addic7ed': {
|
'addic7ed': {
|
||||||
'username': '',
|
'username': '',
|
||||||
'password': '',
|
'password': '',
|
||||||
'random_agents': 'False'
|
'random_agents': 'True'
|
||||||
},
|
},
|
||||||
'legendastv': {
|
'legendastv': {
|
||||||
'username': '',
|
'username': '',
|
||||||
'password': ''
|
'password': ''
|
||||||
|
|
|
@ -1,17 +1,79 @@
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
import logging
|
||||||
|
import subliminal_patch
|
||||||
|
|
||||||
|
from get_args import args
|
||||||
from config import settings
|
from config import settings
|
||||||
from subliminal_patch.exceptions import TooManyRequests, APIThrottled
|
from subliminal_patch.exceptions import TooManyRequests, APIThrottled
|
||||||
from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable
|
from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable
|
||||||
|
|
||||||
|
VALID_THROTTLE_EXCEPTIONS = (TooManyRequests, DownloadLimitExceeded, ServiceUnavailable, APIThrottled)
|
||||||
|
|
||||||
|
PROVIDER_THROTTLE_MAP = {
|
||||||
|
"default": {
|
||||||
|
TooManyRequests: (datetime.timedelta(hours=1), "1 hour"),
|
||||||
|
DownloadLimitExceeded: (datetime.timedelta(hours=3), "3 hours"),
|
||||||
|
ServiceUnavailable: (datetime.timedelta(minutes=20), "20 minutes"),
|
||||||
|
APIThrottled: (datetime.timedelta(minutes=10), "10 minutes"),
|
||||||
|
},
|
||||||
|
"opensubtitles": {
|
||||||
|
TooManyRequests: (datetime.timedelta(hours=3), "3 hours"),
|
||||||
|
DownloadLimitExceeded: (datetime.timedelta(hours=6), "6 hours"),
|
||||||
|
APIThrottled: (datetime.timedelta(seconds=15), "15 seconds"),
|
||||||
|
},
|
||||||
|
"addic7ed": {
|
||||||
|
DownloadLimitExceeded: (datetime.timedelta(hours=3), "3 hours"),
|
||||||
|
TooManyRequests: (datetime.timedelta(minutes=5), "5 minutes"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROVIDERS_FORCED_OFF = ["addic7ed", "tvsubtitles", "legendastv", "napiprojekt", "shooter", "hosszupuska",
|
||||||
|
"supersubtitles", "titlovi", "argenteam", "assrt", "subscene"]
|
||||||
|
|
||||||
|
if not settings.general.throtteled_providers:
|
||||||
|
tp = {}
|
||||||
|
else:
|
||||||
|
tp = eval(str(settings.general.throtteled_providers))
|
||||||
|
|
||||||
|
|
||||||
|
def provider_pool():
|
||||||
|
if settings.general.getboolean('multithreading'):
|
||||||
|
return subliminal_patch.core.SZAsyncProviderPool
|
||||||
|
return subliminal_patch.core.SZProviderPool
|
||||||
|
|
||||||
|
|
||||||
def get_providers():
|
def get_providers():
|
||||||
|
changed = False
|
||||||
providers_list = []
|
providers_list = []
|
||||||
if settings.general.enabled_providers:
|
if settings.general.enabled_providers:
|
||||||
for provider in settings.general.enabled_providers.lower().split(','):
|
for provider in settings.general.enabled_providers.lower().split(','):
|
||||||
|
reason, until, throttle_desc = tp.get(provider, (None, None, None))
|
||||||
providers_list.append(provider)
|
providers_list.append(provider)
|
||||||
else:
|
|
||||||
|
if reason:
|
||||||
|
now = datetime.datetime.now()
|
||||||
|
if now < until:
|
||||||
|
logging.info("Not using %s until %s, because of: %s", provider,
|
||||||
|
until.strftime("%y/%m/%d %H:%M"), reason)
|
||||||
|
providers_list.remove(provider)
|
||||||
|
else:
|
||||||
|
logging.info("Using %s again after %s, (disabled because: %s)", provider, throttle_desc, reason)
|
||||||
|
del tp[provider]
|
||||||
|
settings.general.throtteled_providers = str(tp)
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if changed:
|
||||||
|
with open(os.path.join(args.config_dir, 'config', 'config.ini'), 'w+') as handle:
|
||||||
|
settings.write(handle)
|
||||||
|
|
||||||
|
# if forced only is enabled: # fixme: Prepared for forced only implementation to remove providers with don't support forced only subtitles
|
||||||
|
# for provider in providers_list:
|
||||||
|
# if provider in PROVIDERS_FORCED_OFF:
|
||||||
|
# providers_list.remove(provider)
|
||||||
|
|
||||||
|
if not providers_list:
|
||||||
providers_list = None
|
providers_list = None
|
||||||
|
|
||||||
return providers_list
|
return providers_list
|
||||||
|
@ -47,3 +109,30 @@ def get_providers_auth():
|
||||||
}
|
}
|
||||||
|
|
||||||
return providers_auth
|
return providers_auth
|
||||||
|
|
||||||
|
|
||||||
|
def provider_throttle(name, exception):
|
||||||
|
cls = getattr(exception, "__class__")
|
||||||
|
cls_name = getattr(cls, "__name__")
|
||||||
|
if cls not in VALID_THROTTLE_EXCEPTIONS:
|
||||||
|
for valid_cls in VALID_THROTTLE_EXCEPTIONS:
|
||||||
|
if isinstance(cls, valid_cls):
|
||||||
|
cls = valid_cls
|
||||||
|
|
||||||
|
throttle_data = PROVIDER_THROTTLE_MAP.get(name, PROVIDER_THROTTLE_MAP["default"]).get(cls, None) or \
|
||||||
|
PROVIDER_THROTTLE_MAP["default"].get(cls, None)
|
||||||
|
|
||||||
|
if not throttle_data:
|
||||||
|
return
|
||||||
|
|
||||||
|
throttle_delta, throttle_description = throttle_data
|
||||||
|
throttle_until = datetime.datetime.now() + throttle_delta
|
||||||
|
|
||||||
|
tp[name] = (cls_name, throttle_until, throttle_description)
|
||||||
|
|
||||||
|
settings.general.throtteled_providers = str(tp)
|
||||||
|
with open(os.path.join(args.config_dir, 'config', 'config.ini'), 'w+') as handle:
|
||||||
|
settings.write(handle)
|
||||||
|
|
||||||
|
logging.info("Throttling %s for %s, until %s, because of: %s. Exception info: %r", name, throttle_description,
|
||||||
|
throttle_until.strftime("%y/%m/%d %H:%M"), cls_name, exception.message)
|
||||||
|
|
|
@ -28,9 +28,11 @@ from helper import path_replace, path_replace_movie, path_replace_reverse, \
|
||||||
from list_subtitles import store_subtitles, list_missing_subtitles, store_subtitles_movie, list_missing_subtitles_movies
|
from list_subtitles import store_subtitles, list_missing_subtitles, store_subtitles_movie, list_missing_subtitles_movies
|
||||||
from utils import history_log, history_log_movie
|
from utils import history_log, history_log_movie
|
||||||
from notifier import send_notifications, send_notifications_movie
|
from notifier import send_notifications, send_notifications_movie
|
||||||
from get_providers import get_providers, get_providers_auth
|
from get_providers import get_providers, get_providers_auth, provider_throttle, provider_pool
|
||||||
from get_args import args
|
from get_args import args
|
||||||
from queueconfig import q4ws
|
from queueconfig import q4ws
|
||||||
|
from subliminal_patch.exceptions import TooManyRequests, APIThrottled
|
||||||
|
from subliminal.exceptions import DownloadLimitExceeded, ServiceUnavailable
|
||||||
|
|
||||||
# configure the cache
|
# configure the cache
|
||||||
|
|
||||||
|
@ -57,13 +59,17 @@ def get_video(path, title, sceneName, use_scenename, providers=None, media_type=
|
||||||
# use the sceneName but keep the folder structure for better guessing
|
# use the sceneName but keep the folder structure for better guessing
|
||||||
path = os.path.join(os.path.dirname(path), sceneName + os.path.splitext(path)[1])
|
path = os.path.join(os.path.dirname(path), sceneName + os.path.splitext(path)[1])
|
||||||
dont_use_actual_file = True
|
dont_use_actual_file = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
video = parse_video(path, hints=hints, providers=providers, dry_run=dont_use_actual_file)
|
if providers:
|
||||||
video.used_scene_name = dont_use_actual_file
|
video = parse_video(path, hints=hints, providers=providers, dry_run=dont_use_actual_file)
|
||||||
video.original_name = original_name
|
video.used_scene_name = dont_use_actual_file
|
||||||
video.original_path = original_path
|
video.original_name = original_name
|
||||||
return video
|
video.original_path = original_path
|
||||||
|
return video
|
||||||
|
else:
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
logging.exception("BAZARR Error trying to get video information for this file: " + path)
|
logging.exception("BAZARR Error trying to get video information for this file: " + path)
|
||||||
|
@ -144,102 +150,31 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName,
|
||||||
AsyncProviderPool:
|
AsyncProviderPool:
|
||||||
implement:
|
implement:
|
||||||
blacklist=None,
|
blacklist=None,
|
||||||
throttle_callback=None,
|
|
||||||
pre_download_hook=None,
|
pre_download_hook=None,
|
||||||
post_download_hook=None,
|
post_download_hook=None,
|
||||||
language_hook=None
|
language_hook=None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
|
||||||
throttle_callback:
|
|
||||||
|
|
||||||
VALID_THROTTLE_EXCEPTIONS = (TooManyRequests, DownloadLimitExceeded, ServiceUnavailable, APIThrottled)
|
|
||||||
|
|
||||||
PROVIDER_THROTTLE_MAP = {
|
|
||||||
"default": {
|
|
||||||
TooManyRequests: (datetime.timedelta(hours=1), "1 hour"),
|
|
||||||
DownloadLimitExceeded: (datetime.timedelta(hours=3), "3 hours"),
|
|
||||||
ServiceUnavailable: (datetime.timedelta(minutes=20), "20 minutes"),
|
|
||||||
APIThrottled: (datetime.timedelta(minutes=10), "10 minutes"),
|
|
||||||
},
|
|
||||||
"opensubtitles": {
|
|
||||||
TooManyRequests: (datetime.timedelta(hours=3), "3 hours"),
|
|
||||||
DownloadLimitExceeded: (datetime.timedelta(hours=6), "6 hours"),
|
|
||||||
APIThrottled: (datetime.timedelta(seconds=15), "15 seconds"),
|
|
||||||
},
|
|
||||||
"addic7ed": {
|
|
||||||
DownloadLimitExceeded: (datetime.timedelta(hours=3), "3 hours"),
|
|
||||||
TooManyRequests: (datetime.timedelta(minutes=5), "5 minutes"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throttle_callback gist:
|
|
||||||
def provider_throttle(self, name, exception):
|
|
||||||
cls = getattr(exception, "__class__")
|
|
||||||
cls_name = getattr(cls, "__name__")
|
|
||||||
if cls not in VALID_THROTTLE_EXCEPTIONS:
|
|
||||||
for valid_cls in VALID_THROTTLE_EXCEPTIONS:
|
|
||||||
if isinstance(cls, valid_cls):
|
|
||||||
cls = valid_cls
|
|
||||||
|
|
||||||
throttle_data = PROVIDER_THROTTLE_MAP.get(name, PROVIDER_THROTTLE_MAP["default"]).get(cls, None) or \
|
|
||||||
PROVIDER_THROTTLE_MAP["default"].get(cls, None)
|
|
||||||
|
|
||||||
if not throttle_data:
|
|
||||||
return
|
|
||||||
|
|
||||||
throttle_delta, throttle_description = throttle_data
|
|
||||||
throttle_until = datetime.datetime.now() + throttle_delta
|
|
||||||
|
|
||||||
# save throttle_until together with provider name somewhere, then implement dynamic provider_list based on
|
|
||||||
# that
|
|
||||||
|
|
||||||
provider_configs=
|
|
||||||
{'addic7ed': {'username': Prefs['provider.addic7ed.username'],
|
|
||||||
'password': Prefs['provider.addic7ed.password'],
|
|
||||||
'use_random_agents': cast_bool(Prefs['provider.addic7ed.use_random_agents1']),
|
|
||||||
},
|
|
||||||
'opensubtitles': {'username': Prefs['provider.opensubtitles.username'],
|
|
||||||
'password': Prefs['provider.opensubtitles.password'],
|
|
||||||
'use_tag_search': self.exact_filenames,
|
|
||||||
'only_foreign': self.forced_only,
|
|
||||||
'also_foreign': self.forced_also,
|
|
||||||
'is_vip': cast_bool(Prefs['provider.opensubtitles.is_vip']),
|
|
||||||
'use_ssl': os_use_https,
|
|
||||||
'timeout': self.advanced.providers.opensubtitles.timeout or 15,
|
|
||||||
'skip_wrong_fps': os_skip_wrong_fps,
|
|
||||||
},
|
|
||||||
'podnapisi': {
|
|
||||||
'only_foreign': self.forced_only,
|
|
||||||
'also_foreign': self.forced_also,
|
|
||||||
},
|
|
||||||
'subscene': {
|
|
||||||
'only_foreign': self.forced_only,
|
|
||||||
},
|
|
||||||
'legendastv': {'username': Prefs['provider.legendastv.username'],
|
|
||||||
'password': Prefs['provider.legendastv.password'],
|
|
||||||
},
|
|
||||||
'assrt': {'token': Prefs['provider.assrt.token'], }
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type)
|
video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type)
|
||||||
if video:
|
if video:
|
||||||
min_score, max_score, scores = get_scores(video, media_type, min_score_movie_perc=int(minimum_score_movie),
|
min_score, max_score, scores = get_scores(video, media_type, min_score_movie_perc=int(minimum_score_movie),
|
||||||
min_score_series_perc=int(minimum_score))
|
min_score_series_perc=int(minimum_score))
|
||||||
|
|
||||||
downloaded_subtitles = download_best_subtitles({video}, language_set, int(min_score), hi,
|
if providers:
|
||||||
providers=providers,
|
downloaded_subtitles = download_best_subtitles({video}, language_set, int(min_score), hi,
|
||||||
provider_configs=providers_auth,
|
providers=providers,
|
||||||
pool_class=SZAsyncProviderPool,
|
provider_configs=providers_auth,
|
||||||
compute_score=compute_score,
|
pool_class=provider_pool(),
|
||||||
throttle_time=None, # fixme
|
compute_score=compute_score,
|
||||||
blacklist=None, # fixme
|
throttle_time=None, # fixme
|
||||||
throttle_callback=None, # fixme
|
blacklist=None, # fixme
|
||||||
pre_download_hook=None, # fixme
|
throttle_callback=provider_throttle,
|
||||||
post_download_hook=None, # fixme
|
pre_download_hook=None, # fixme
|
||||||
language_hook=None) # fixme
|
post_download_hook=None, # fixme
|
||||||
|
language_hook=None) # fixme
|
||||||
|
else:
|
||||||
|
downloaded_subtitles = None
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
|
|
||||||
saved_any = False
|
saved_any = False
|
||||||
if downloaded_subtitles:
|
if downloaded_subtitles:
|
||||||
|
@ -251,7 +186,7 @@ def download_subtitle(path, language, hi, providers, providers_auth, sceneName,
|
||||||
saved_subtitles = save_subtitles(video.original_path, subtitles, single=single,
|
saved_subtitles = save_subtitles(video.original_path, subtitles, single=single,
|
||||||
tags=None, # fixme
|
tags=None, # fixme
|
||||||
directory=None, # fixme
|
directory=None, # fixme
|
||||||
chmod=None, # fixme
|
chmod=int(settings.general.chmod), # fixme
|
||||||
# formats=("srt", "vtt")
|
# formats=("srt", "vtt")
|
||||||
path_decoder=force_unicode
|
path_decoder=force_unicode
|
||||||
)
|
)
|
||||||
|
@ -344,12 +279,16 @@ def manual_search(path, language, hi, providers, providers_auth, sceneName, titl
|
||||||
min_score_series_perc=int(minimum_score))
|
min_score_series_perc=int(minimum_score))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subtitles = list_subtitles([video], language_set,
|
if providers:
|
||||||
providers=providers,
|
subtitles = list_subtitles([video], language_set,
|
||||||
provider_configs=providers_auth,
|
providers=providers,
|
||||||
pool_class=SZAsyncProviderPool, # fixme: make async optional
|
provider_configs=providers_auth,
|
||||||
throttle_callback=None, # fixme
|
pool_class=provider_pool(),
|
||||||
language_hook=None) # fixme
|
throttle_callback=provider_throttle,
|
||||||
|
language_hook=None) # fixme
|
||||||
|
else:
|
||||||
|
subtitles = []
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path)
|
logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path)
|
||||||
else:
|
else:
|
||||||
|
@ -402,12 +341,16 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a
|
||||||
if video:
|
if video:
|
||||||
min_score, max_score, scores = get_scores(video, media_type)
|
min_score, max_score, scores = get_scores(video, media_type)
|
||||||
try:
|
try:
|
||||||
download_subtitles([subtitle], providers={provider}, provider_configs=providers_auth,
|
if provider:
|
||||||
pool_class=SZAsyncProviderPool,
|
download_subtitles([subtitle], providers={provider}, provider_configs=providers_auth,
|
||||||
throttle_callback=None) # fixme
|
pool_class=provider_pool(),
|
||||||
logging.debug('BAZARR Subtitles file downloaded for this file:' + path)
|
throttle_callback=provider_throttle)
|
||||||
|
logging.debug('BAZARR Subtitles file downloaded for this file:' + path)
|
||||||
|
else:
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception('BAZARR Error downloading subtitles for this file ' + path)
|
logging.exception('BAZARR Error downloading subtitles for this file ' + path + e)
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
if not subtitle.is_valid():
|
if not subtitle.is_valid():
|
||||||
|
@ -468,7 +411,8 @@ def manual_download_subtitle(path, language, hi, subtitle, provider, providers_a
|
||||||
return message
|
return message
|
||||||
else:
|
else:
|
||||||
logging.error(
|
logging.error(
|
||||||
"BAZARR Tried to manually download a subtitles for file: " + path + " but we weren't able to do (probably throttled by " + str(subtitle.provider_name) + ". Please retry later or select a subtitles from another provider.")
|
"BAZARR Tried to manually download a subtitles for file: " + path + " but we weren't able to do (probably throttled by " + str(
|
||||||
|
subtitle.provider_name) + ". Please retry later or select a subtitles from another provider.")
|
||||||
return None
|
return None
|
||||||
logging.debug('BAZARR Ended manually downloading subtitles for file: ' + path)
|
logging.debug('BAZARR Ended manually downloading subtitles for file: ' + path)
|
||||||
|
|
||||||
|
@ -559,7 +503,7 @@ def wanted_download_subtitles(path):
|
||||||
|
|
||||||
for i in range(len(attempt)):
|
for i in range(len(attempt)):
|
||||||
if attempt[i][0] == language:
|
if attempt[i][0] == language:
|
||||||
if search_active(attempt[i][1]) is True:
|
if search_active(attempt[i][1]):
|
||||||
q4ws.append(
|
q4ws.append(
|
||||||
'Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path)
|
'Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path)
|
||||||
message = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)),
|
message = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)),
|
||||||
|
@ -648,14 +592,22 @@ def wanted_search_missing_subtitles():
|
||||||
movies = c.fetchall()
|
movies = c.fetchall()
|
||||||
|
|
||||||
c.close()
|
c.close()
|
||||||
|
providers = get_providers()
|
||||||
if settings.general.getboolean('use_sonarr'):
|
if settings.general.getboolean('use_sonarr'):
|
||||||
for episode in episodes:
|
if providers:
|
||||||
wanted_download_subtitles(episode[0])
|
for episode in episodes:
|
||||||
|
wanted_download_subtitles(episode[0])
|
||||||
|
else:
|
||||||
|
q4ws.append('BAZARR All providers are throttled')
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
|
|
||||||
if settings.general.getboolean('use_radarr'):
|
if settings.general.getboolean('use_radarr'):
|
||||||
for movie in movies:
|
if providers:
|
||||||
wanted_download_subtitles_movie(movie[0])
|
for movie in movies:
|
||||||
|
wanted_download_subtitles_movie(movie[0])
|
||||||
|
else:
|
||||||
|
q4ws.append('BAZARR All providers are throttled')
|
||||||
|
logging.info("BAZARR All providers are throttled")
|
||||||
|
|
||||||
logging.info('BAZARR Finished searching for missing subtitles. Check histories for more information.')
|
logging.info('BAZARR Finished searching for missing subtitles. Check histories for more information.')
|
||||||
|
|
||||||
|
|
|
@ -1103,6 +1103,7 @@ def save_settings():
|
||||||
settings_general_debug = 'False'
|
settings_general_debug = 'False'
|
||||||
else:
|
else:
|
||||||
settings_general_debug = 'True'
|
settings_general_debug = 'True'
|
||||||
|
settings_general_chmod = request.forms.get('settings_general_chmod')
|
||||||
settings_general_sourcepath = request.forms.getall('settings_general_sourcepath')
|
settings_general_sourcepath = request.forms.getall('settings_general_sourcepath')
|
||||||
settings_general_destpath = request.forms.getall('settings_general_destpath')
|
settings_general_destpath = request.forms.getall('settings_general_destpath')
|
||||||
settings_general_pathmapping = []
|
settings_general_pathmapping = []
|
||||||
|
@ -1138,6 +1139,11 @@ def save_settings():
|
||||||
settings_general_adaptive_searching = 'False'
|
settings_general_adaptive_searching = 'False'
|
||||||
else:
|
else:
|
||||||
settings_general_adaptive_searching = 'True'
|
settings_general_adaptive_searching = 'True'
|
||||||
|
settings_general_multithreading = request.forms.get('settings_general_multithreading')
|
||||||
|
if settings_general_multithreading is None:
|
||||||
|
settings_general_multithreading = 'False'
|
||||||
|
else:
|
||||||
|
settings_general_multithreading = 'True'
|
||||||
settings_general_minimum_score = request.forms.get('settings_general_minimum_score')
|
settings_general_minimum_score = request.forms.get('settings_general_minimum_score')
|
||||||
settings_general_minimum_score_movies = request.forms.get('settings_general_minimum_score_movies')
|
settings_general_minimum_score_movies = request.forms.get('settings_general_minimum_score_movies')
|
||||||
settings_general_use_postprocessing = request.forms.get('settings_general_use_postprocessing')
|
settings_general_use_postprocessing = request.forms.get('settings_general_use_postprocessing')
|
||||||
|
@ -1170,6 +1176,7 @@ def save_settings():
|
||||||
settings.general.base_url = text_type(settings_general_baseurl)
|
settings.general.base_url = text_type(settings_general_baseurl)
|
||||||
settings.general.path_mappings = text_type(settings_general_pathmapping)
|
settings.general.path_mappings = text_type(settings_general_pathmapping)
|
||||||
settings.general.debug = text_type(settings_general_debug)
|
settings.general.debug = text_type(settings_general_debug)
|
||||||
|
settings.general.chmod = text_type(settings_general_chmod)
|
||||||
settings.general.branch = text_type(settings_general_branch)
|
settings.general.branch = text_type(settings_general_branch)
|
||||||
settings.general.auto_update = text_type(settings_general_automatic)
|
settings.general.auto_update = text_type(settings_general_automatic)
|
||||||
settings.general.single_language = text_type(settings_general_single_language)
|
settings.general.single_language = text_type(settings_general_single_language)
|
||||||
|
@ -1184,6 +1191,7 @@ def save_settings():
|
||||||
settings.general.minimum_score_movie = text_type(settings_general_minimum_score_movies)
|
settings.general.minimum_score_movie = text_type(settings_general_minimum_score_movies)
|
||||||
settings.general.use_embedded_subs = text_type(settings_general_embedded)
|
settings.general.use_embedded_subs = text_type(settings_general_embedded)
|
||||||
settings.general.adaptive_searching = text_type(settings_general_adaptive_searching)
|
settings.general.adaptive_searching = text_type(settings_general_adaptive_searching)
|
||||||
|
settings.general.multithreading = text_type(settings_general_multithreading)
|
||||||
|
|
||||||
if after != before:
|
if after != before:
|
||||||
configured()
|
configured()
|
||||||
|
|
|
@ -153,6 +153,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Set subtitle file permissions to</label>
|
||||||
|
</div>
|
||||||
|
<div class="five wide column">
|
||||||
|
<div class='field'>
|
||||||
|
<div id="settings_chmod" class="ui fluid input">
|
||||||
|
<input name="settings_general_chmod" type="text"
|
||||||
|
value={{ settings.general.chmod }}>
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Integer, e.g.: 0775" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="middle aligned row">
|
<div class="middle aligned row">
|
||||||
<div class="right aligned four wide column">
|
<div class="right aligned four wide column">
|
||||||
<label>Page size</label>
|
<label>Page size</label>
|
||||||
|
@ -1076,6 +1096,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="middle aligned row">
|
||||||
|
<div class="right aligned four wide column">
|
||||||
|
<label>Search enabled providers simultaneously</label>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column">
|
||||||
|
<div id="settings_multithreading" class="ui toggle checkbox"
|
||||||
|
data-multithreading={{ settings.general.getboolean('multithreading') }}>
|
||||||
|
<input name="settings_general_multithreading" type="checkbox">
|
||||||
|
<label></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="collapsed column">
|
||||||
|
<div class="collapsed center aligned column">
|
||||||
|
<div class="ui basic icon" data-tooltip="Multithreading" data-inverted="">
|
||||||
|
<i class="help circle large icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui dividing header">Subtitles providers</div>
|
<div class="ui dividing header">Subtitles providers</div>
|
||||||
|
@ -1760,6 +1800,12 @@
|
||||||
$("#settings_adaptive_searching").checkbox('uncheck');
|
$("#settings_adaptive_searching").checkbox('uncheck');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($('#settings_multithreading').data("multithreading") === "True") {
|
||||||
|
$("#settings_multithreading").checkbox('check');
|
||||||
|
} else {
|
||||||
|
$("#settings_multithreading").checkbox('uncheck');
|
||||||
|
}
|
||||||
|
|
||||||
if ($('#settings_addic7ed_random_agents').data("randomagents") === "True") {
|
if ($('#settings_addic7ed_random_agents').data("randomagents") === "True") {
|
||||||
$("#settings_addic7ed_random_agents").checkbox('check');
|
$("#settings_addic7ed_random_agents").checkbox('check');
|
||||||
} else {
|
} else {
|
||||||
|
@ -2057,6 +2103,14 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
settings_general_chmod: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
type: 'regExp[^(0[0-7]{3})$]',
|
||||||
|
prompt: 'Please use only 4-digit integers with leading 0 (e.g.: 775)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
settings_auth_password : {
|
settings_auth_password : {
|
||||||
depends: 'settings_auth_username',
|
depends: 'settings_auth_username',
|
||||||
rules : [
|
rules : [
|
||||||
|
|
Loading…
Reference in a new issue