Updated validate code

This commit is contained in:
Rhet Turnbull
2020-12-09 20:17:49 -08:00
parent 37b1e5ca47
commit d7c81adae8
2 changed files with 62 additions and 20 deletions

View File

@@ -1720,19 +1720,20 @@ def export(
("has_comment", "no_comment"),
("has_likes", "no_likes"),
]
dependent_options = [
("missing", ("download_missing", "use_photos_export")),
("jpeg_quality", ("convert_to_jpeg")),
]
try:
cfg.validate(exclusive_options, cli=True)
cfg.validate(
exclusive=exclusive_options,
dependent=dependent_options,
cli=True,
)
except ConfigOptionsInvalidError as e:
click.echo(f"Incompatible export options: {e.message}", err=True)
raise click.Abort()
if missing and not download_missing:
click.echo(
"Incompatible export options: --missing must be used with --download-missing",
err=True,
)
raise click.Abort()
if save_config:
verbose_(f"Saving options to file {save_config}")
cfg.write_to_file(save_config)

View File

@@ -51,11 +51,18 @@ class ConfigOptions:
except KeyError:
raise KeyError(f"Missing argument: {attr}")
def validate(self, exclusive, cli=False):
def validate(self, exclusive=None, inclusive=None, dependent=None, cli=False):
""" validate combinations of otions
Args:
cli: bool, set to True if called to validate CLI options; will prepend '--' to option names in InvalidOptions.message
exclusive: list of tuples in form [("option_1", "option_2")...] which are exclusive;
ie. either option_1 can be set or option_2 but not both;
inclusive: list of tuples in form [("option_1", "option_2")...] which are inclusive;
ie. if either option_1 or option_2 is set, the other must be set
dependent: list of tuples in form [("option_1", ("option_2", "option_3"))...]
where if option_1 is set, then at least one of the options in the second tuple must also be set
cli: bool, set to True if called to validate CLI options;
will prepend '--' to option names in InvalidOptions.message and change _ to - in option names
Returns:
True if all options valid
@@ -64,19 +71,52 @@ class ConfigOptions:
InvalidOption if any combination of options is invalid
InvalidOption.message will be descriptive message of invalid options
"""
if not exclusive:
if not any([exclusive, inclusive, dependent]):
return True
prefix = "--" if cli else ""
for opt_pair in exclusive:
val0 = getattr(self, opt_pair[0])
val1 = getattr(self, opt_pair[1])
val0 = any(val0) if self._attrs[opt_pair[0]] == () else val0
val1 = any(val1) if self._attrs[opt_pair[1]] == () else val1
if val0 and val1:
raise ConfigOptionsInvalidError(
f"{prefix}{opt_pair[0]} and {prefix}{opt_pair[1]} options cannot be used together"
)
if exclusive:
for a, b in exclusive:
vala = getattr(self, a)
valb = getattr(self, b)
vala = any(vala) if isinstance(vala, tuple) else vala
valb = any(valb) if isinstance(valb, tuple) else valb
if vala and valb:
stra = a.replace("_", "-") if cli else a
strb = b.replace("_", "-") if cli else b
raise ConfigOptionsInvalidError(
f"{prefix}{stra} and {prefix}{strb} options cannot be used together."
)
if inclusive:
for a, b in inclusive:
vala = getattr(self, a)
valb = getattr(self, b)
vala = any(vala) if isinstance(vala, tuple) else vala
valb = any(valb) if isinstance(valb, tuple) else valb
if any([vala, valb]) and not all([vala, valb]):
stra = a.replace("_", "-") if cli else a
strb = b.replace("_", "-") if cli else b
raise ConfigOptionsInvalidError(
f"{prefix}{stra} and {prefix}{strb} options must be used together."
)
if dependent:
for a, b in dependent:
vala = getattr(self, a)
if not isinstance(b, tuple):
# python unrolls the tuple if there's a single element
b = (b,)
valb = [getattr(self, x) for x in b]
valb = [any(x) if isinstance(x, tuple) else x for x in valb]
if vala and not any(valb):
if cli:
stra = prefix + a.replace("_", "-")
strb = ", ".join(prefix + x.replace("_", "-") for x in b)
else:
stra = a
strb = ", ".join(x for x in b)
raise ConfigOptionsInvalidError(
f"{stra} must be used with at least one of: {strb}."
)
return True
def write_to_file(self, filename):
@@ -85,6 +125,7 @@ class ConfigOptions:
Args:
filename: full path to TOML file to write; filename will be overwritten if it exists
"""
# todo: add overwrite and option to merge contents already in TOML file (under different [section] with new content)
data = {}
for attr in sorted(self._attrs.keys()):
val = getattr(self, attr)