Skip to content

Commit

Permalink
[util] implement 'compile_filter()' (#5262)
Browse files Browse the repository at this point in the history
#5262 (comment)

allow (theoretically*) all filter expression statements
to be a list of individual filters

(*) except for 'filename' and 'directory' conditionals,
as dict keys cannot be lists
  • Loading branch information
mikf committed Nov 14, 2024
1 parent 0b99d9e commit 5bc3657
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
4 changes: 2 additions & 2 deletions gallery_dl/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ def initialize(self, kwdict=None):

skip_filter = cfg("skip-filter")
if skip_filter:
self._skipftr = util.compile_expression(skip_filter)
self._skipftr = util.compile_filter(skip_filter)
else:
self._skipftr = None
else:
Expand Down Expand Up @@ -660,7 +660,7 @@ def register_hooks(self, hooks, options=None):
expr = options.get("filter") if options else None

if expr:
condition = util.compile_expression(expr)
condition = util.compile_filter(expr)
for hook, callback in hooks.items():
self.hooks[hook].append(functools.partial(
self._call_hook, callback, condition))
Expand Down
4 changes: 2 additions & 2 deletions gallery_dl/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, extractor):
filename_fmt = extractor.filename_fmt
elif isinstance(filename_fmt, dict):
self.filename_conditions = [
(util.compile_expression(expr),
(util.compile_filter(expr),
formatter.parse(fmt, kwdefault).format_map)
for expr, fmt in filename_fmt.items() if expr
]
Expand All @@ -57,7 +57,7 @@ def __init__(self, extractor):
directory_fmt = extractor.directory_fmt
elif isinstance(directory_fmt, dict):
self.directory_conditions = [
(util.compile_expression(expr), [
(util.compile_filter(expr), [
formatter.parse(fmt, kwdefault).format_map
for fmt in fmts
])
Expand Down
10 changes: 7 additions & 3 deletions gallery_dl/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,12 @@ def _eval(locals=None, globals=(globals or GLOBALS), co=code_object):
compile_expression = compile_expression_tryexcept


def compile_filter(expr, name="<filter>", globals=None):
if not isinstance(expr, str):
expr = "(" + ") and (".join(expr) + ")"
return compile_expression(expr, name, globals)


def import_file(path):
"""Import a Python module from a filesystem path"""
path, name = os.path.split(path)
Expand Down Expand Up @@ -964,10 +970,8 @@ class FilterPredicate():
"""Predicate; True if evaluating the given expression returns True"""

def __init__(self, expr, target="image"):
if not isinstance(expr, str):
expr = "(" + ") and (".join(expr) + ")"
name = "<{} filter>".format(target)
self.expr = compile_expression(expr, name)
self.expr = compile_filter(expr, name)

def __call__(self, _, kwdict):
try:
Expand Down
9 changes: 9 additions & 0 deletions test/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,15 @@ def test_compile_expression_defaultdict(self):
with self.assertRaises(AttributeError):
expr({"a": 2})

def test_compile_filter(self):
expr = util.compile_filter("a + b * c")
self.assertEqual(expr({"a": 1, "b": 2, "c": 3}), 7)
self.assertEqual(expr({"a": 9, "b": 9, "c": 9}), 90)

expr = util.compile_filter(["a % 2 == 0", "b % 3 == 0", "c % 5 == 0"])
self.assertTrue(expr({"a": 4, "b": 6, "c": 10}))
self.assertFalse(expr({"a": 1, "b": 2, "c": 3}))

def test_custom_globals(self):
value = {"v": "foobar"}
result = "8843d7f92416211de9ebb963ff4ce28125932878"
Expand Down

0 comments on commit 5bc3657

Please sign in to comment.