Add card artists
This commit is contained in:
parent
fc5c212db5
commit
fba63c1e1f
9 changed files with 109 additions and 3 deletions
62
postgres/006-card-artists.sql
Normal file
62
postgres/006-card-artists.sql
Normal file
|
@ -0,0 +1,62 @@
|
|||
ALTER TABLE "scryfall"
|
||||
ADD COLUMN IF NOT EXISTS "artist" TEXT;
|
||||
|
||||
DROP MATERIALIZED VIEW IF EXISTS "cards";
|
||||
CREATE MATERIALIZED VIEW "cards" AS
|
||||
SELECT "oracle"."oracle_id"
|
||||
, "oracle"."name"
|
||||
, "oracle"."color_identity"
|
||||
, "oracle"."cmc"
|
||||
, "oracle"."mana_cost"
|
||||
, "oracle"."type_line"
|
||||
, "oracle"."edhrec_rank"
|
||||
, "oracle"."oracle_text"
|
||||
, "scryfall"."scryfall_id"
|
||||
, "scryfall"."set_code"
|
||||
, "scryfall"."collector_number"
|
||||
, "scryfall"."release_date"
|
||||
, "scryfall"."rarity"
|
||||
, "scryfall"."artist"
|
||||
, "sets"."name" AS "set_name"
|
||||
, "card_prices"."usd" AS "price_usd"
|
||||
, "card_prices"."usd_foil" AS "price_usd_foil"
|
||||
, "card_prices"."eur" AS "price_eur"
|
||||
, "card_prices"."eur_foil" AS "price_eur_foil"
|
||||
, "card_prices"."tix" AS "price_tix"
|
||||
FROM "oracle"
|
||||
JOIN "scryfall" USING ("oracle_id")
|
||||
LEFT JOIN "card_prices" ON ("scryfall"."scryfall_id" = "card_prices"."scryfall_id"
|
||||
AND "card_prices"."date" = (SELECT VALUE FROM "vars" WHERE "key" = 'last_update'))
|
||||
JOIN "sets" USING ("set_code");
|
||||
|
||||
DROP MATERIALIZED VIEW IF EXISTS "oracle_latest";
|
||||
CREATE MATERIALIZED VIEW "oracle_latest" AS
|
||||
SELECT "oracle"."oracle_id"
|
||||
, "oracle"."name"
|
||||
, "oracle"."color_identity"
|
||||
, "oracle"."cmc"
|
||||
, "oracle"."mana_cost"
|
||||
, "oracle"."type_line"
|
||||
, "oracle"."edhrec_rank"
|
||||
, "oracle"."oracle_text"
|
||||
, "scryfall"."scryfall_id"
|
||||
, "scryfall"."set_code"
|
||||
, "scryfall"."collector_number"
|
||||
, "scryfall"."release_date"
|
||||
, "scryfall"."rarity"
|
||||
, "scryfall"."artist"
|
||||
, "sets"."name" AS "set_name"
|
||||
, "card_prices"."usd" AS "price_usd"
|
||||
, "card_prices"."usd_foil" AS "price_usd_foil"
|
||||
, "card_prices"."eur" AS "price_eur"
|
||||
, "card_prices"."eur_foil" AS "price_eur_foil"
|
||||
, "card_prices"."tix" AS "price_tix"
|
||||
FROM "oracle"
|
||||
JOIN (
|
||||
SELECT DISTINCT ON ("oracle_id") *
|
||||
FROM "scryfall"
|
||||
ORDER BY "oracle_id", "release_date" DESC
|
||||
) "scryfall" USING ("oracle_id")
|
||||
LEFT JOIN "card_prices" ON ("scryfall"."scryfall_id" = "card_prices"."scryfall_id"
|
||||
AND "card_prices"."date" = (SELECT VALUE FROM "vars" WHERE "key" = 'last_update'))
|
||||
JOIN "sets" USING ("set_code");
|
10
tutor/cli.py
10
tutor/cli.py
|
@ -289,12 +289,21 @@ def update_scryfall(ctx, filename):
|
|||
await cursor.execute(
|
||||
"""
|
||||
INSERT INTO "scryfall"
|
||||
( "scryfall_id"
|
||||
, "oracle_id"
|
||||
, "set_code"
|
||||
, "collector_number"
|
||||
, "release_date"
|
||||
, "rarity"
|
||||
, "artist"
|
||||
)
|
||||
SELECT "scryfall_id"
|
||||
, "oracle_id"
|
||||
, "set_code"
|
||||
, "collector_number"
|
||||
, "release_date"
|
||||
, "rarity"
|
||||
, "artist"
|
||||
FROM "tmp_cards"
|
||||
ON CONFLICT (scryfall_id) DO UPDATE
|
||||
SET "oracle_id" = "excluded"."oracle_id"
|
||||
|
@ -302,6 +311,7 @@ def update_scryfall(ctx, filename):
|
|||
, "collector_number" = "excluded"."collector_number"
|
||||
, "release_date" = "excluded"."release_date"
|
||||
, "rarity" = "excluded"."rarity"
|
||||
, "artist" = "excluded"."artist"
|
||||
"""
|
||||
)
|
||||
print("Updating card price data & indexes")
|
||||
|
|
|
@ -95,6 +95,7 @@ async def search(
|
|||
games=set(),
|
||||
legalities={},
|
||||
edhrec_rank=row["edhrec_rank"],
|
||||
artist=row["artist"],
|
||||
oracle_text=row["oracle_text"],
|
||||
)
|
||||
for row in rows
|
||||
|
@ -184,6 +185,9 @@ async def advanced_search(
|
|||
f'OR (NOT "copies"."isFoil" AND cards.price_usd <= %({param})s))'
|
||||
)
|
||||
params[param] = criterion.price
|
||||
if isinstance(criterion, tutor.search.Artist):
|
||||
constraints.append(f"cards.artist ILIKE %({param})s")
|
||||
params[param] = f"%{criterion.text}%"
|
||||
if isinstance(criterion, tutor.search.Oracle):
|
||||
constraints.append(f"cards.oracle_text ILIKE %({param})s")
|
||||
params[param] = f"%{criterion.text}%"
|
||||
|
@ -255,6 +259,7 @@ async def advanced_search(
|
|||
games=set(),
|
||||
legalities={},
|
||||
edhrec_rank=row["edhrec_rank"],
|
||||
artist=row["artist"],
|
||||
oracle_text=row["oracle_text"],
|
||||
price_usd=convert_price(row["price_usd"]),
|
||||
price_usd_foil=convert_price(row["price_usd_foil"]),
|
||||
|
@ -290,11 +295,11 @@ async def store_card(db: psycopg.AsyncCursor, card: tutor.models.Card) -> None:
|
|||
INSERT INTO tmp_cards
|
||||
("scryfall_id", "oracle_id", "name", "set_code", "collector_number",
|
||||
"rarity", "color_identity", "cmc", "mana_cost", "type_line",
|
||||
"release_date", "edhrec_rank", "oracle_text")
|
||||
"release_date", "edhrec_rank", "artist", "oracle_text")
|
||||
VALUES (%(scryfall_id)s, %(oracle_id)s, %(name)s, %(set_code)s,
|
||||
%(collector_number)s, %(rarity)s, %(color_identity)s, %(cmc)s,
|
||||
%(mana_cost)s, %(type_line)s, %(release_date)s, %(edhrec_rank)s,
|
||||
%(oracle_text)s)
|
||||
%(artist)s, %(oracle_text)s)
|
||||
""",
|
||||
{
|
||||
"scryfall_id": str(card.scryfall_id),
|
||||
|
@ -309,6 +314,7 @@ async def store_card(db: psycopg.AsyncCursor, card: tutor.models.Card) -> None:
|
|||
"type_line": card.type_line,
|
||||
"release_date": str(card.release_date) if card.release_date else None,
|
||||
"edhrec_rank": card.edhrec_rank,
|
||||
"artist": card.artist,
|
||||
"oracle_text": card.oracle_text,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -94,6 +94,7 @@ class Card:
|
|||
legalities: typing.Dict[str, Legality]
|
||||
mana_cost: typing.Optional[str] = None
|
||||
edhrec_rank: typing.Optional[int] = None
|
||||
artist: typing.Optional[str] = None
|
||||
oracle_text: typing.Optional[str] = None
|
||||
price_usd: typing.Optional[decimal.Decimal] = None
|
||||
price_usd_foil: typing.Optional[decimal.Decimal] = None
|
||||
|
|
|
@ -38,6 +38,7 @@ def to_card(data: dict) -> Maybe[tutor.models.Card]:
|
|||
edhrec_rank=Maybe.from_optional(data.get("edhrec_rank"))
|
||||
.map(int)
|
||||
.value_or(None),
|
||||
artist=data.get("artist"),
|
||||
oracle_text=data.get("oracle_text"),
|
||||
price_usd=prices.get("usd"),
|
||||
price_usd_foil=prices.get("usd_foil"),
|
||||
|
|
|
@ -39,6 +39,11 @@ class Type(Criterion):
|
|||
text: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Artist(Criterion):
|
||||
text: parsy.string
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Oracle(Criterion):
|
||||
text: parsy.string
|
||||
|
@ -173,6 +178,12 @@ type_line = parsy.seq(
|
|||
text=string_literal,
|
||||
).combine_dict(Type)
|
||||
|
||||
artist = parsy.seq(
|
||||
_keyword=lstring_from("a", "artist"),
|
||||
operator=matches,
|
||||
text=string_literal,
|
||||
).combine_dict(Artist)
|
||||
|
||||
oracle = parsy.seq(
|
||||
_keyword=lstring_from("o", "oracle"),
|
||||
operator=matches,
|
||||
|
@ -200,7 +211,15 @@ partial_name = parsy.seq(text=string_literal).combine_dict(Name)
|
|||
name = exact_name | partial_name
|
||||
|
||||
criterion = (
|
||||
colors | expansion | rarity | type_line | oracle | collection | price_usd | name
|
||||
colors
|
||||
| expansion
|
||||
| rarity
|
||||
| type_line
|
||||
| artist
|
||||
| oracle
|
||||
| collection
|
||||
| price_usd
|
||||
| name
|
||||
)
|
||||
|
||||
padding = parsy.regex(r"\s*")
|
||||
|
|
|
@ -92,6 +92,7 @@ class JSONEncoder(json.JSONEncoder):
|
|||
"cmc": float(card.cmc),
|
||||
"mana_cost": card.mana_cost,
|
||||
"type_line": card.type_line,
|
||||
"artist": card.artist,
|
||||
"oracle_text": card.oracle_text,
|
||||
"prices": {
|
||||
"usd": price(card.price_usd),
|
||||
|
|
|
@ -31,6 +31,7 @@ type alias Card =
|
|||
, manaCost : String
|
||||
, cmc : Float
|
||||
, typeLine : String
|
||||
, artist: String
|
||||
, oracleText : String
|
||||
, prices : Prices
|
||||
}
|
||||
|
@ -73,6 +74,10 @@ decode =
|
|||
)
|
||||
|> JDP.required "cmc" Json.Decode.float
|
||||
|> JDP.required "type_line" Json.Decode.string
|
||||
|> JDP.required "artist"
|
||||
(Json.Decode.nullable Json.Decode.string
|
||||
|> Json.Decode.map (Maybe.withDefault "")
|
||||
)
|
||||
|> JDP.required "oracle_text"
|
||||
(Json.Decode.nullable Json.Decode.string
|
||||
|> Json.Decode.map (Maybe.withDefault "")
|
||||
|
|
|
@ -620,6 +620,7 @@ viewCardDetails model =
|
|||
[ E.text copy.card.name ]
|
||||
, E.row [ E.spacing 5, E.centerX ] <|
|
||||
List.map UI.priceBadge (prices copy.card copy.foil)
|
||||
, E.paragraph [Font.size 16, Font.italic, Font.center] [ UI.text "Artist: ", UI.text copy.card.artist ]
|
||||
, E.paragraph [] <| [ Symbol.text model.symbols 20 copy.card.manaCost, UI.text <| " " ++ copy.card.typeLine ]
|
||||
, E.column [ E.spacing 10 ] <|
|
||||
List.map (Symbol.text model.symbols 16) (String.lines copy.card.oracleText)
|
||||
|
|
Loading…
Reference in a new issue