Support GTE and LTE on color and rarity
This commit is contained in:
parent
dc3cc6427b
commit
a1cf52312e
2 changed files with 92 additions and 48 deletions
|
@ -102,38 +102,56 @@ async def advanced_search(
|
|||
params = {}
|
||||
sets = []
|
||||
|
||||
logging.debug("Performing search for: %s", search)
|
||||
logger.debug("Performing search for: %s", search)
|
||||
for i, criterion in enumerate(search.criteria):
|
||||
param = f"param_{i}"
|
||||
if isinstance(criterion, tutor.search.Name):
|
||||
constraints.append(f"cards.name LIKE :{param}")
|
||||
params[param] = f"%{criterion.name}%"
|
||||
params[param] = f"%{criterion.text}%"
|
||||
if isinstance(criterion, tutor.search.Type):
|
||||
constraints.append(f"cards.type_line LIKE :{param}")
|
||||
params[param] = f"%{criterion.name}%"
|
||||
if isinstance(criterion, tutor.search.IsExpansion):
|
||||
params[param] = f"%{criterion.text}%"
|
||||
if isinstance(criterion, tutor.search.Expansion):
|
||||
constraints.append(f"cards.set_code LIKE :{param}")
|
||||
params[param] = criterion.set_code
|
||||
if isinstance(criterion, tutor.search.InExpansion):
|
||||
sets.append(criterion.set_code)
|
||||
if isinstance(criterion, tutor.search.IsColor):
|
||||
constraints.append(f"cards.color_identity LIKE :{param}")
|
||||
params[param] = tutor.models.Color.to_string(criterion.colors)
|
||||
if isinstance(criterion, tutor.search.IsRarity):
|
||||
constraints.append(f"cards.rarity LIKE :{param}")
|
||||
params[param] = str(criterion.rarity)
|
||||
if isinstance(criterion, tutor.search.Color):
|
||||
if criterion.operator == tutor.search.Operator.matches:
|
||||
constraints.append(f"cards.color_identity LIKE :{param}")
|
||||
params[param] = tutor.models.Color.to_string(criterion.colors)
|
||||
if criterion.operator == tutor.search.Operator.lte:
|
||||
constraints.append(
|
||||
"({})".format(
|
||||
" OR ".join(
|
||||
[
|
||||
f"cards.color_identity LIKE :{param}_{color}"
|
||||
for color in criterion.colors
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
params.update(
|
||||
{f"{param}_{color}": str(color) for color in criterion.colors}
|
||||
)
|
||||
params[param] = tutor.models.Color.to_string(criterion.colors)
|
||||
if criterion.operator == tutor.search.Operator.gte:
|
||||
constraints.append(f"cards.color_identity LIKE :{param}")
|
||||
params[param] = "%{}%".format(
|
||||
"%".join(tutor.models.Color.to_string(criterion.colors))
|
||||
)
|
||||
if isinstance(criterion, tutor.search.Rarity):
|
||||
if criterion.operator == tutor.search.Operator.matches:
|
||||
constraints.append(f"cards.rarity LIKE :{param}")
|
||||
params[param] = str(criterion.rarity)
|
||||
if criterion.operator == tutor.search.Operator.lte:
|
||||
constraints.append(f"rarities.rarity_ord <= :{param}")
|
||||
params[param] = criterion.rarity.value
|
||||
if criterion.operator == tutor.search.Operator.gte:
|
||||
constraints.append(f"rarities.rarity_ord >= :{param}")
|
||||
params[param] = criterion.rarity.value
|
||||
if isinstance(criterion, tutor.search.Oracle):
|
||||
constraints.append(f"cards.oracle_text LIKE :{param}")
|
||||
params[param] = f"%{criterion.text}%"
|
||||
|
||||
if sets:
|
||||
set_params = {f"set_{i}": set_code for i, set_code in enumerate(sets)}
|
||||
constraints.append(
|
||||
"cards.set_code IN ({})".format(
|
||||
", ".join([f":{key}" for key in set_params.keys()])
|
||||
)
|
||||
)
|
||||
params.update(set_params)
|
||||
if in_collection is not None:
|
||||
if in_collection:
|
||||
joins.append("JOIN copies ON (cards.scryfall_id = copies.scryfall_id)")
|
||||
|
@ -157,6 +175,7 @@ async def advanced_search(
|
|||
f"LIMIT {offset},{limit}",
|
||||
]
|
||||
)
|
||||
logger.debug("Query: %s", (query, params))
|
||||
cursor = await db.execute(query, params)
|
||||
rows = await cursor.fetchall()
|
||||
return [
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import dataclasses
|
||||
import enum
|
||||
import functools
|
||||
import typing
|
||||
|
||||
|
@ -7,38 +8,35 @@ import parsy
|
|||
import tutor.models
|
||||
|
||||
|
||||
class Operator(enum.Enum):
|
||||
matches = ":"
|
||||
gte = ">="
|
||||
lte = "<="
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Criterion:
|
||||
...
|
||||
operator: Operator
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class IsExpansion(Criterion):
|
||||
class Expansion(Criterion):
|
||||
set_code: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class InExpansion(Criterion):
|
||||
set_code: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class IsColor(Criterion):
|
||||
class Color(Criterion):
|
||||
colors: typing.Set[tutor.models.Color]
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class IsRarity(Criterion):
|
||||
class Rarity(Criterion):
|
||||
rarity: tutor.models.Rarity
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Name(Criterion):
|
||||
name: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Type(Criterion):
|
||||
name: parsy.string
|
||||
text: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
|
@ -46,6 +44,12 @@ class Oracle(Criterion):
|
|||
text: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Name(Criterion):
|
||||
operator: Operator = Operator.matches
|
||||
text: parsy.string = ""
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Search:
|
||||
criteria: typing.List[Criterion]
|
||||
|
@ -63,7 +67,10 @@ W, U, B, G, R = (
|
|||
tutor.models.Color.Green,
|
||||
tutor.models.Color.Red,
|
||||
)
|
||||
matches = parsy.string(":")
|
||||
|
||||
matches = parsy.string(":").map(Operator)
|
||||
gte = parsy.string(">=").map(Operator)
|
||||
lte = parsy.string("<=").map(Operator)
|
||||
|
||||
color = (
|
||||
ustring("w").result(W)
|
||||
|
@ -112,38 +119,56 @@ wedge = (
|
|||
| lstring("temur").result({U, R, G})
|
||||
)
|
||||
|
||||
colors = single_color | guild | shard | wedge | multicolor
|
||||
any_color = single_color | guild | shard | wedge | multicolor
|
||||
|
||||
colors = parsy.seq(
|
||||
_keyword=lstring_from("c", "color", "colors"),
|
||||
operator=matches | gte | lte,
|
||||
colors=any_color,
|
||||
).combine_dict(Color)
|
||||
|
||||
expansion_string = (
|
||||
parsy.regex(r"[a-zA-Z0-9]+").map(lambda s: s.upper()).desc("expansion set code")
|
||||
)
|
||||
|
||||
is_expansion = lstring_from("e", "expansion", "s", "set") >> matches >> expansion_string.map(IsExpansion)
|
||||
expansion = parsy.seq(
|
||||
_keyword=lstring_from("e", "expansion", "s", "set"),
|
||||
operator=matches,
|
||||
set_code=expansion_string,
|
||||
).combine_dict(Expansion)
|
||||
|
||||
in_expansion = lstring("in") >> matches >> expansion_string.map(InExpansion)
|
||||
# in_expansion = lstring("in") >> matches >> expansion_string.map(InExpansion)
|
||||
|
||||
rarity = (
|
||||
any_rarity = (
|
||||
lstring_from("c", "common").result(tutor.models.Rarity.Common)
|
||||
| lstring_from("u", "uncommon").result(tutor.models.Rarity.Uncommon)
|
||||
| lstring_from("r", "rare").result(tutor.models.Rarity.Rare)
|
||||
| lstring_from("m", "mythic").result(tutor.models.Rarity.Mythic)
|
||||
)
|
||||
|
||||
is_rarity = lstring_from("r", "rarity") >> matches >> rarity.map(IsRarity)
|
||||
|
||||
is_color = lstring_from("c", "color", "colors") >> matches >> colors.map(IsColor)
|
||||
rarity = parsy.seq(
|
||||
_keyword=lstring_from("r", "rarity"),
|
||||
operator=matches | gte | lte,
|
||||
rarity=any_rarity,
|
||||
).combine_dict(Rarity)
|
||||
|
||||
string_literal = parsy.regex(r'"[^"]*"').map(lambda s: s[1:-1]) | parsy.regex(r"[^\s]+")
|
||||
|
||||
has_type = lstring_from("t", "type") >> matches >> string_literal.map(Type)
|
||||
type_line = parsy.seq(
|
||||
_keyword=lstring_from("t", "type"),
|
||||
operator=matches,
|
||||
text=string_literal,
|
||||
).combine_dict(Type)
|
||||
|
||||
has_oracle = lstring_from("o", "oracle") >> matches >> string_literal.map(Oracle)
|
||||
oracle = parsy.seq(
|
||||
_keyword=lstring_from("o", "oracle"),
|
||||
operator=matches,
|
||||
text=string_literal,
|
||||
).combine_dict(Oracle)
|
||||
|
||||
name = string_literal.map(Name)
|
||||
|
||||
criterion = (
|
||||
is_expansion | in_expansion | is_rarity | is_color | has_type | has_oracle | name
|
||||
)
|
||||
criterion = colors | expansion | rarity | type_line | oracle | name
|
||||
|
||||
padding = parsy.regex(r"\s*")
|
||||
search = padding >> (criterion << padding).many().map(Search)
|
||||
|
|
Loading…
Reference in a new issue