Skip to content

Commit

Permalink
fix(search): parse_facets now interprets quoted values correctly (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenrdz authored Sep 20, 2024
1 parent 625ea8d commit 08a3749
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 24 deletions.
42 changes: 18 additions & 24 deletions esgpull/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from esgpull import Esgpull
from esgpull.graph import Graph
from esgpull.models import Dataset, File, Option, Options, Query, Selection
from esgpull.tui import UI, TempUI, Verbosity
from esgpull.tui import UI, TempUI, Verbosity, logger
from esgpull.utils import format_size


Expand Down Expand Up @@ -121,9 +121,15 @@ def totable(docs: list[OrderedDict[str, Any]]) -> Table:
return table


def safe_value(value: str) -> str:
if " " in value:
return f'"{value}"'
else:
return value


def parse_facets(facets: list[str]) -> Selection:
facet_dict: dict[str, list[str]] = {}
exact_terms: list[str] | None = None
for facet in facets:
match facet.split(":"):
case [value]:
Expand All @@ -132,28 +138,9 @@ def parse_facets(facets: list[str]) -> Selection:
...
case _:
raise BadArgumentUsage(f"{facet!r} is not valid syntax.")
if value.startswith("/"):
if exact_terms is not None:
raise BadArgumentUsage("Nested exact string is forbidden.")
exact_terms = []
if exact_terms is not None:
if name != "query":
raise BadArgumentUsage(
"Cannot use facet term inside an exact string."
)
exact_terms.append(value)
if value.endswith("/"):
final_exact_str = " ".join(exact_terms)
value = '"' + final_exact_str.strip("/") + '"'
exact_terms = None
else:
continue
facet_dict.setdefault(name, [])
facet_dict[name].append(value)
else:
values = value.split(",")
facet_dict.setdefault(name, [])
facet_dict[name].extend(values)
values = list(map(safe_value, value.split(",")))
facet_dict.setdefault(name, [])
facet_dict[name].extend(values)
selection = Selection()
for name, values in facet_dict.items():
selection[name] = values
Expand All @@ -170,6 +157,13 @@ def parse_query(
replica: str | None,
retracted: str | None,
) -> Query:
logger.info(f"{facets=}")
logger.info(f"{tags=}")
logger.info(f"{require=}")
logger.info(f"{distrib=}")
logger.info(f"{latest=}")
logger.info(f"{replica=}")
logger.info(f"{retracted=}")
options = Options(
distrib=distrib or Option.notset,
latest=latest or Option.notset,
Expand Down
40 changes: 40 additions & 0 deletions tests/cli/test_parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest

from esgpull.cli.utils import parse_facets
from esgpull.models import Selection

test_cases = [
(["ocean", "temperature"], Selection(query=["ocean", "temperature"])),
(["ocean temperature"], Selection(query='"ocean temperature"')),
(
[
"project:CMIP6",
"experiment_id:ssp126,ssp245,ssp585",
"variable_id:hurt,lai,pr,sfcWind,tasmax,tasmin,ts,tos",
"frequency:day",
"nominal_resolution:100 km",
],
Selection(
project="CMIP6",
experiment_id=["ssp126", "ssp245", "ssp585"],
variable_id=[
"hurt",
"lai",
"pr",
"sfcWind",
"tasmax",
"tasmin",
"ts",
"tos",
],
frequency="day",
nominal_resolution='"100 km"',
),
),
]


@pytest.mark.parametrize("facets, expected_query", test_cases)
def test_parse_facets(facets, expected_query):
result = parse_facets(facets)
assert result == expected_query

0 comments on commit 08a3749

Please sign in to comment.