From db58afadfdb796e62dad51b918b0a473676c4a0f Mon Sep 17 00:00:00 2001 From: dmkskn Date: Tue, 15 Sep 2020 13:49:48 +0300 Subject: [PATCH] Add _iter_args --- mdfind/_api.py | 29 ++++++++++++++++++++++------- tests/test_mdfind.py | 13 +++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/mdfind/_api.py b/mdfind/_api.py index 49e03b9..5e5de7f 100644 --- a/mdfind/_api.py +++ b/mdfind/_api.py @@ -1,29 +1,44 @@ """An `mdfind` wrapper""" import subprocess as sp -from typing import List, Optional +from typing import List, Optional, Union, Iterator __all__ = ["query", "count", "name"] NUL = "\x00" +_Kwarg = Optional[Union[str, bool]] + def _mdfind(*args: str) -> sp.CompletedProcess: return sp.run(["mdfind", *args], capture_output=True, text=True, check=True) -def query(query: str, onlyin: Optional[str] = None) -> List[str]: +def _iter_args(*args: str, **kwargs: _Kwarg) -> Iterator[str]: + """Returns args and kwargs as a flat list of strings. Filters a kwarg + if its value is None. Fliters a kwarg if its value is False. Adds + a hyphen to the kwarg key (if it doesn't have one).""" + yield from args + for key, value in kwargs.items(): + if value is None or value is False: + continue + yield key if key.startswith("-") else f"-{key}" + if isinstance(value, str): + yield value + + +def query(query: str, onlyin: Optional[str] = None, **kwargs: _Kwarg) -> List[str]: """Get a list of files that match the given metadata query.""" - output = _mdfind("-0", query, *iter(["-onlyin", onlyin] if onlyin else [])) + output = _mdfind(*_iter_args("-0", query, onlyin=onlyin, **kwargs)) return output.stdout.strip(NUL).split(NUL) -def count(query: str, onlyin: Optional[str] = None) -> int: +def count(query: str, onlyin: Optional[str] = None, **kwargs: _Kwarg) -> int: """Get the total number of matches.""" - output = _mdfind("-count", query, *iter(["-onlyin", onlyin] if onlyin else [])) + output = _mdfind(*_iter_args("-count", query, onlyin=onlyin, **kwargs)) return int(output.stdout) -def name(query: str, onlyin: Optional[str] = None) -> List[str]: +def name(query: str, onlyin: Optional[str] = None, **kwargs: _Kwarg) -> List[str]: """Get a list of files that match the given name.""" - output = _mdfind("-0", "-name", query, *iter(["-onlyin", onlyin] if onlyin else [])) + output = _mdfind(*_iter_args("-0", "-name", query, onlyin=onlyin, **kwargs)) return output.stdout.strip(NUL).split(NUL) diff --git a/tests/test_mdfind.py b/tests/test_mdfind.py index 2fc9a1e..0b68e81 100644 --- a/tests/test_mdfind.py +++ b/tests/test_mdfind.py @@ -57,3 +57,16 @@ def test_name_calls_mdfind_correct(_mdfind): def test_name_return_splitted_list(_mdfind): result = mdfind.name("foo", onlyin="~") assert result == PATHS_STDOUT.split(NUL) + + +def test_iter_args(): + args = ["-0", "-count", "kind:image"] + kwargs = {"onlyin": "/path", "literal": True, "interpret": False, "live": None} + assert list(mdfind._api._iter_args(*args, **kwargs)) == [ + "-0", + "-count", + "kind:image", + "-onlyin", + "/path", + "-literal", + ]