Umask support, fix overrides formatter variable error message (#46)
* umask support, fix error message * fix error location * make pylint disable area smaller, remove int
This commit is contained in:
parent
ec1cc534ea
commit
a80a834924
6 changed files with 53 additions and 11 deletions
4
Makefile
4
Makefile
|
|
@ -4,5 +4,7 @@ wheel:
|
||||||
docker: wheel
|
docker: wheel
|
||||||
cp dist/*.whl docker/root/
|
cp dist/*.whl docker/root/
|
||||||
sudo docker build --no-cache -t ytdl-sub:0.1 docker/
|
sudo docker build --no-cache -t ytdl-sub:0.1 docker/
|
||||||
|
docs:
|
||||||
|
sphinx-build -a -b html docs docs/_html
|
||||||
|
|
||||||
.PHONY: wheel docker
|
.PHONY: wheel docker docs
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,11 @@ configuration
|
||||||
The ``configuration`` section contains app-wide configs applied to all presets
|
The ``configuration`` section contains app-wide configs applied to all presets
|
||||||
and subscriptions.
|
and subscriptions.
|
||||||
|
|
||||||
|
.. autoclass:: ytdl_sub.config.config_file.ConfigOptions()
|
||||||
|
:members:
|
||||||
|
:member-order: bysource
|
||||||
|
|
||||||
|
|
||||||
presets
|
presets
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
``presets`` define a `formula` for how to format downloaded media and metadata.
|
``presets`` define a `formula` for how to format downloaded media and metadata.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
import os
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from ytdl_sub.utils.yaml import load_yaml
|
from ytdl_sub.utils.yaml import load_yaml
|
||||||
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
||||||
|
|
@ -7,16 +9,33 @@ from ytdl_sub.validators.validators import StringValidator
|
||||||
|
|
||||||
|
|
||||||
class ConfigOptions(StrictDictValidator):
|
class ConfigOptions(StrictDictValidator):
|
||||||
"""Validation for global config options"""
|
|
||||||
|
|
||||||
_required_keys = {"working_directory"}
|
_required_keys = {"working_directory"}
|
||||||
|
_optional_keys = {"umask"}
|
||||||
|
|
||||||
def __init__(self, name: str, value: Any):
|
def __init__(self, name: str, value: Any):
|
||||||
super().__init__(name, value)
|
super().__init__(name, value)
|
||||||
|
|
||||||
self.working_directory = self._validate_key(
|
self._working_directory = self._validate_key(
|
||||||
key="working_directory", validator=StringValidator
|
key="working_directory", validator=StringValidator
|
||||||
)
|
)
|
||||||
|
self._umask = self._validate_key_if_present(
|
||||||
|
key="umask", validator=StringValidator, default="022"
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def working_directory(self) -> str:
|
||||||
|
"""
|
||||||
|
The directory to temporarily store downloaded files before moving them into their final
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
|
return self._working_directory.value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def umask(self) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Umask (octal format) to apply to every created file. Defaults to "022".
|
||||||
|
"""
|
||||||
|
return self._umask.value
|
||||||
|
|
||||||
|
|
||||||
class ConfigFile(StrictDictValidator):
|
class ConfigFile(StrictDictValidator):
|
||||||
|
|
@ -29,6 +48,19 @@ class ConfigFile(StrictDictValidator):
|
||||||
# Make sure presets is a dictionary. Will be validated in `PresetValidator`
|
# Make sure presets is a dictionary. Will be validated in `PresetValidator`
|
||||||
self.presets = self._validate_key("presets", LiteralDictValidator)
|
self.presets = self._validate_key("presets", LiteralDictValidator)
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
"""
|
||||||
|
Configures things (umask, pgid) prior to any downloading
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
self
|
||||||
|
"""
|
||||||
|
if self.config_options.umask:
|
||||||
|
os.umask(int(self.config_options.umask, 8))
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, config_dict: dict) -> "ConfigFile":
|
def from_dict(cls, config_dict: dict) -> "ConfigFile":
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -157,14 +157,17 @@ class Preset(StrictDictValidator):
|
||||||
|
|
||||||
for variable_name in formatter_validator.format_variables:
|
for variable_name in formatter_validator.format_variables:
|
||||||
if variable_name not in resolvable_override_variables:
|
if variable_name not in resolvable_override_variables:
|
||||||
|
# pylint: disable=protected-access
|
||||||
raise StringFormattingVariableNotFoundException(
|
raise StringFormattingVariableNotFoundException(
|
||||||
f"This variable can only use override variables that resolve without needing "
|
f"Validation error in {formatter_validator._name}: "
|
||||||
f"variables from a downloaded file. The only override variables defined that "
|
f"This can only use override variables. Available override variables are: "
|
||||||
f"meet this condition are: {', '.join(sorted(resolvable_override_variables))}"
|
f"{', '.join(sorted(resolvable_override_variables))}",
|
||||||
)
|
)
|
||||||
|
# pylint: enable=protected-access
|
||||||
|
|
||||||
def __recursive_preset_validate(
|
def __recursive_preset_validate(
|
||||||
self, validator_dict: Optional[Dict[str, Validator]] = None
|
self,
|
||||||
|
validator_dict: Optional[Dict[str, Validator]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Ensure all OverridesStringFormatterValidator's only contain variables from the overrides
|
Ensure all OverridesStringFormatterValidator's only contain variables from the overrides
|
||||||
|
|
@ -175,9 +178,9 @@ class Preset(StrictDictValidator):
|
||||||
|
|
||||||
for validator in validator_dict.values():
|
for validator in validator_dict.values():
|
||||||
if isinstance(validator, DictValidator):
|
if isinstance(validator, DictValidator):
|
||||||
|
# pylint: disable=protected-access
|
||||||
# Usage of protected variables in other validators is fine. The reason to keep them
|
# Usage of protected variables in other validators is fine. The reason to keep them
|
||||||
# protected is for readability when using them in subscriptions.
|
# protected is for readability when using them in subscriptions.
|
||||||
# pylint: disable=protected-access
|
|
||||||
self.__recursive_preset_validate(validator._validator_dict)
|
self.__recursive_preset_validate(validator._validator_dict)
|
||||||
# pylint: enable=protected-access
|
# pylint: enable=protected-access
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ def _main():
|
||||||
|
|
||||||
args, extra_args = parser.parse_known_args()
|
args, extra_args = parser.parse_known_args()
|
||||||
|
|
||||||
config: ConfigFile = ConfigFile.from_file_path(args.config)
|
config: ConfigFile = ConfigFile.from_file_path(args.config).initialize()
|
||||||
if args.subparser == "sub":
|
if args.subparser == "sub":
|
||||||
_download_subscriptions_from_yaml_files(config=config, args=args)
|
_download_subscriptions_from_yaml_files(config=config, args=args)
|
||||||
logger.info("Subscription download complete!")
|
logger.info("Subscription download complete!")
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ class Subscription:
|
||||||
-------
|
-------
|
||||||
The directory that the downloader saves files to
|
The directory that the downloader saves files to
|
||||||
"""
|
"""
|
||||||
return str(Path(self.__config_options.working_directory.value) / Path(self.name))
|
return str(Path(self.__config_options.working_directory) / Path(self.name))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def output_directory(self) -> str:
|
def output_directory(self) -> str:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue