mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-03-10 16:39:01 +00:00
feat: add service-specific configuration overrides
Implement comprehensive per-service config override system that allows any configuration section (dl, n_m3u8dl_re, aria2c, subtitle, etc.) to be customized on a per-service basis. Fixes #13
This commit is contained in:
@@ -318,6 +318,38 @@ class dl:
|
|||||||
self.log = logging.getLogger("download")
|
self.log = logging.getLogger("download")
|
||||||
|
|
||||||
self.service = Services.get_tag(ctx.invoked_subcommand)
|
self.service = Services.get_tag(ctx.invoked_subcommand)
|
||||||
|
service_dl_config = config.services.get(self.service, {}).get("dl", {})
|
||||||
|
if service_dl_config:
|
||||||
|
param_types = {param.name: param.type for param in ctx.command.params if param.name}
|
||||||
|
|
||||||
|
for param_name, service_value in service_dl_config.items():
|
||||||
|
if param_name not in ctx.params:
|
||||||
|
continue
|
||||||
|
|
||||||
|
current_value = ctx.params[param_name]
|
||||||
|
global_default = config.dl.get(param_name)
|
||||||
|
param_type = param_types.get(param_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if param_type and global_default is not None:
|
||||||
|
global_default = param_type.convert(global_default, None, ctx)
|
||||||
|
except Exception as e:
|
||||||
|
self.log.debug(f"Failed to convert global default for '{param_name}': {e}")
|
||||||
|
|
||||||
|
if current_value == global_default or (current_value is None and global_default is None):
|
||||||
|
try:
|
||||||
|
converted_value = service_value
|
||||||
|
if param_type and service_value is not None:
|
||||||
|
converted_value = param_type.convert(service_value, None, ctx)
|
||||||
|
|
||||||
|
ctx.params[param_name] = converted_value
|
||||||
|
self.log.debug(f"Applied service-specific '{param_name}' override: {converted_value}")
|
||||||
|
except Exception as e:
|
||||||
|
self.log.warning(
|
||||||
|
f"Failed to apply service-specific '{param_name}' override: {e}. "
|
||||||
|
f"Check that the value '{service_value}' is valid for this parameter."
|
||||||
|
)
|
||||||
|
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.tmdb_id = tmdb_id
|
self.tmdb_id = tmdb_id
|
||||||
self.tmdb_name = tmdb_name
|
self.tmdb_name = tmdb_name
|
||||||
@@ -383,31 +415,34 @@ class dl:
|
|||||||
config.decryption = config.decryption_map.get(self.service, config.decryption)
|
config.decryption = config.decryption_map.get(self.service, config.decryption)
|
||||||
|
|
||||||
service_config = config.services.get(self.service, {})
|
service_config = config.services.get(self.service, {})
|
||||||
|
if service_config:
|
||||||
|
reserved_keys = {
|
||||||
|
"profiles",
|
||||||
|
"api_key",
|
||||||
|
"certificate",
|
||||||
|
"api_endpoint",
|
||||||
|
"region",
|
||||||
|
"device",
|
||||||
|
"endpoints",
|
||||||
|
"client",
|
||||||
|
"dl",
|
||||||
|
}
|
||||||
|
|
||||||
reserved_keys = {
|
for config_key, override_value in service_config.items():
|
||||||
"profiles",
|
if config_key in reserved_keys or not isinstance(override_value, dict):
|
||||||
"api_key",
|
continue
|
||||||
"certificate",
|
|
||||||
"api_endpoint",
|
|
||||||
"region",
|
|
||||||
"device",
|
|
||||||
"endpoints",
|
|
||||||
"client",
|
|
||||||
}
|
|
||||||
|
|
||||||
for config_key, override_value in service_config.items():
|
if hasattr(config, config_key):
|
||||||
if config_key in reserved_keys:
|
current_config = getattr(config, config_key, {})
|
||||||
continue
|
|
||||||
|
|
||||||
if isinstance(override_value, dict) and hasattr(config, config_key):
|
if isinstance(current_config, dict):
|
||||||
current_config = getattr(config, config_key, {})
|
merged_config = deepcopy(current_config)
|
||||||
if isinstance(current_config, dict):
|
merge_dict(override_value, merged_config)
|
||||||
merged_config = {**current_config, **override_value}
|
setattr(config, config_key, merged_config)
|
||||||
setattr(config, config_key, merged_config)
|
|
||||||
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
f"Applied service-specific '{config_key}' overrides for {self.service}: {override_value}"
|
f"Applied service-specific '{config_key}' overrides for {self.service}: {override_value}"
|
||||||
)
|
)
|
||||||
|
|
||||||
with console.status("Loading Key Vaults...", spinner="dots"):
|
with console.status("Loading Key Vaults...", spinner="dots"):
|
||||||
self.vaults = Vaults(self.service)
|
self.vaults = Vaults(self.service)
|
||||||
|
|||||||
@@ -450,12 +450,24 @@ services:
|
|||||||
region: "GB"
|
region: "GB"
|
||||||
api_endpoint: "https://api.uk.service.com"
|
api_endpoint: "https://api.uk.service.com"
|
||||||
|
|
||||||
|
# Example: Rate-limited service
|
||||||
|
RATE_LIMITED_SERVICE:
|
||||||
|
dl:
|
||||||
|
downloads: 2 # Limit concurrent downloads
|
||||||
|
workers: 4 # Reduce workers to avoid rate limits
|
||||||
|
n_m3u8dl_re:
|
||||||
|
thread_count: 4 # Very low thread count
|
||||||
|
retry_count: 20 # More retries for flaky service
|
||||||
|
aria2c:
|
||||||
|
max_concurrent_downloads: 1 # Download tracks one at a time
|
||||||
|
max_connection_per_server: 1 # Single connection only
|
||||||
|
|
||||||
# Notes on service-specific overrides:
|
# Notes on service-specific overrides:
|
||||||
# - Overrides are merged with global config, not replaced
|
# - Overrides are merged with global config, not replaced
|
||||||
# - Only specified keys are overridden, others use global defaults
|
# - Only specified keys are overridden, others use global defaults
|
||||||
# - Reserved keys (profiles, api_key, certificate, etc.) are NOT treated as overrides
|
# - Reserved keys (profiles, api_key, certificate, etc.) are NOT treated as overrides
|
||||||
# - Any dict-type config option can be overridden (dl, aria2c, n_m3u8dl_re, etc.)
|
# - Any dict-type config option can be overridden (dl, aria2c, n_m3u8dl_re, subtitle, etc.)
|
||||||
# - Use --debug flag to see which overrides are applied during downloads
|
# - CLI arguments always take priority over service-specific config
|
||||||
|
|
||||||
# External proxy provider services
|
# External proxy provider services
|
||||||
proxy_providers:
|
proxy_providers:
|
||||||
|
|||||||
Reference in New Issue
Block a user