Handle nullable scryfall card fields

This commit is contained in:
Correl Roush 2022-02-10 17:03:03 -05:00
parent eee0edf2da
commit 1e275a8288
4 changed files with 45 additions and 35 deletions

View file

@ -10,6 +10,7 @@ CREATE TABLE IF NOT EXISTS `rarities` (
DELETE FROM `rarities`;
INSERT INTO `rarities` (`rarity`, `rarity_ord`) VALUES
('n/a', 0),
('common', 1),
('uncommon', 2),
('rare', 3),
@ -19,11 +20,11 @@ INSERT INTO `rarities` (`rarity`, `rarity_ord`) VALUES
CREATE TABLE IF NOT EXISTS `cards` (
`scryfall_id` TEXT PRIMARY KEY,
`oracle_id` TEXT NOT NULL,
`oracle_id` TEXT,
`name` TEXT NOT NULL,
`set_code` TEXT NOT NULL,
`collector_number` TEXT NOT NULL,
`release_date` TEXT NOT NULL,
`set_code` TEXT,
`collector_number` TEXT,
`release_date` TEXT,
`rarity` TEXT NOT NULL,
`color_identity` TEXT NOT NULL,
`cmc` TEXT NOT NULL, -- Decimal value

View file

@ -143,7 +143,7 @@ def update_scryfall(ctx, filename):
with open(filename) as f:
cards = json.loads(f.read())
else:
response = httpx.get("https://api.scryfall.com/bulk-data/oracle_cards")
response = httpx.get("https://api.scryfall.com/bulk-data/all-cards")
info = response.json()
buffer = b""

View file

@ -227,27 +227,30 @@ async def advanced_search(
async def store_card(db: aiosqlite.Connection, card: tutor.models.Card) -> None:
await db.execute(
"INSERT INTO cards "
"(`scryfall_id`, `oracle_id`, `name`, `set_code`, `collector_number`,"
" `rarity`, `color_identity`, `cmc`, `type_line`, `release_date`,"
" `edhrec_rank`, `oracle_text`) "
"VALUES (:scryfall_id, :oracle_id, :name, :set_code, :collector_number,"
" :rarity, :color_identity, :cmc, :type_line, :release_date, :edhrec_rank,"
" :oracle_text) "
"ON CONFLICT (scryfall_id) DO UPDATE "
"SET `name` = :name"
" , `set_code` = :set_code"
" , `collector_number` = :collector_number"
" , `rarity` = :rarity"
" , `color_identity` = :color_identity"
" , `cmc` = :cmc"
" , `type_line` = :type_line"
" , `release_date` = :release_date"
" , `edhrec_rank` = :edhrec_rank"
" , `oracle_text` = :oracle_text",
"""
INSERT INTO cards
(`scryfall_id`, `oracle_id`, `name`, `set_code`, `collector_number`,
`rarity`, `color_identity`, `cmc`, `type_line`, `release_date`,
`edhrec_rank`, `oracle_text`)
VALUES (:scryfall_id, :oracle_id, :name, :set_code, :collector_number,
:rarity, :color_identity, :cmc, :type_line, :release_date, :edhrec_rank,
:oracle_text)
ON CONFLICT (scryfall_id) DO UPDATE
SET `oracle_id` = :oracle_id
, `name` = :name
, `set_code` = :set_code
, `collector_number` = :collector_number
, `rarity` = :rarity
, `color_identity` = :color_identity
, `cmc` = :cmc
, `type_line` = :type_line
, `release_date` = :release_date
, `edhrec_rank` = :edhrec_rank
, `oracle_text` = :oracle_text
""",
{
"scryfall_id": str(card.scryfall_id),
"oracle_id": str(card.oracle_id),
"oracle_id": str(card.oracle_id) if card.oracle_id else None,
"name": card.name,
"set_code": card.set_code,
"collector_number": card.collector_number,
@ -255,7 +258,7 @@ async def store_card(db: aiosqlite.Connection, card: tutor.models.Card) -> None:
"color_identity": tutor.models.Color.to_string(card.color_identity),
"cmc": str(card.cmc),
"type_line": card.type_line,
"release_date": str(card.release_date),
"release_date": str(card.release_date) if card.release_date else None,
"edhrec_rank": card.edhrec_rank,
"oracle_text": card.oracle_text,
},

View file

@ -10,19 +10,25 @@ def to_card(data: dict) -> tutor.models.Card:
}
return tutor.models.Card(
scryfall_id=data["id"],
oracle_id=data["oracle_id"],
oracle_id=data.get("oracle_id"),
name=data["name"],
set_code=data["set"].upper(),
collector_number=data["collector_number"],
rarity=tutor.models.Rarity.from_string(data["rarity"]),
color_identity=tutor.models.Color.from_string("".join(data["color_identity"])),
cmc=decimal.Decimal(data["cmc"]),
type_line=data["type_line"],
release_date=datetime.date.fromisoformat(data["released_at"]),
games={game for game in tutor.models.Game if game.value in data["games"]},
set_code=data["set"].upper() if "set" in data else None,
collector_number=data.get("collector_number"),
rarity=tutor.models.Rarity.from_string(data.get("rarity", "n/a")),
color_identity=tutor.models.Color.from_string(
"".join(data.get("color_identity", []))
),
cmc=decimal.Decimal(data.get("cmc", "0")),
type_line=data.get("type_line", ""),
release_date=datetime.date.fromisoformat(data["released_at"])
if "released_at" in data
else None,
games={
game for game in tutor.models.Game if game.value in data.get("games", [])
},
legalities={
game_format: {l.value: l for l in tutor.models.Legality}[legality]
for game_format, legality in data["legalities"].items()
for game_format, legality in data.get("legalities", {}).items()
},
edhrec_rank=(
int(data.get("edhrec_rank"))