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

@@ -150,8 +150,8 @@ def build_predicate(predicates):
class RangePredicate():
"""Predicate; True if the current index is in the given range"""
def __init__(self, rangespec):
self.ranges = optimize_range(parse_range(rangespec))
def __init__(self, ranges):
self.ranges = ranges
self.index = 0
if self.ranges:
self.lower, self.upper = self.ranges[0][0], self.ranges[-1][1]
@@ -182,6 +182,20 @@ class UniquePredicate():
return False
class FilterPredicate():
"""Predicate; True if evaluating the given expression returns True"""
globalsdict = {"__builtins__": {}}
def __init__(self, codeobj):
self.codeobj = codeobj
def __call__(self, url, kwds):
try:
return eval(self.codeobj, self.globalsdict, kwds)
except Exception as exc:
raise exception.FilterError(exc)
class ChainPredicate():
"""Predicate; True if all of its predicates return True"""
def __init__(self, predicates):