add '--filter' command-line option

This allows for image filtering via Python expressions by the same
metadata that is also used to build filenames (--list-keywords).

The usually shunned eval() function is used to evaluate
filter-expressions, but it seemed quite appropriate in this case and
shouldn't introduce any new security issues, as any attacker that could do
> gallery-dl --filter "delete-everything()" ...
could as well do
> python -c "delete-everything()"
This commit is contained in:
Mike Fährmann
2017-09-08 17:52:00 +02:00
parent 31731cbefe
commit 9b21d3f13c
7 changed files with 86 additions and 21 deletions

View File

@@ -57,6 +57,25 @@ def sanatize_input(file):
yield line
def prepare_range(rangespec, target):
if rangespec:
range = util.optimize_range(util.parse_range(rangespec))
if range:
config.set(("_", target, "range"), range)
else:
log.warning("invalid/empty %s range", target)
def prepare_filter(filterexpr, target):
if filterexpr:
try:
name = "<{} filter>".format(target)
codeobj = compile(filterexpr, name, "eval")
config.set(("_", target, "filter"), codeobj)
except (SyntaxError, ValueError, TypeError) as exc:
log.warning(exc)
def main():
try:
initialize_logging()
@@ -64,6 +83,7 @@ def main():
args = parser.parse_args()
logging.getLogger().setLevel(args.loglevel)
# configuration
if args.load_config:
config.load()
if args.cfgfiles:
@@ -72,6 +92,9 @@ def main():
config.load(*args.yamlfiles, format="yaml", strict=True)
for key, value in args.options:
config.set(key, value)
config.set(("_",), {})
# logging
if args.loglevel >= logging.ERROR:
config.set(("output", "mode"), "null")
elif args.loglevel <= logging.DEBUG:
@@ -128,6 +151,11 @@ def main():
except OSError as exc:
log.warning("unsupported-URL file: %s", exc)
prepare_range(args.image_range, "image")
prepare_range(args.chapter_range, "chapter")
prepare_filter(args.image_filter, "image")
# prepare_filter(args.chapter_filter, "chapter")
pformat = config.get(("output", "progress"), True)
if pformat and len(urls) > 1 and args.loglevel < logging.ERROR:
urls = progress(urls, pformat)