Add scryfall DB for links and images
This commit is contained in:
parent
e7e7426da1
commit
1727882fb5
6 changed files with 222 additions and 20 deletions
|
@ -29,7 +29,8 @@ export ACCESS_SECRET=<Access token secret>
|
|||
To use the rare finder, you'll need to build the rare db
|
||||
|
||||
1. Download this: https://www.mtgjson.com/files/AllPrintings.json
|
||||
2. Run `yarn import-db`
|
||||
2. Also download this: https://archive.scryfall.com/json/scryfall-default-cards.json
|
||||
3. Run `yarn build-db`
|
||||
|
||||
It will create a file called `mcmCards.json`
|
||||
|
||||
|
|
|
@ -1,31 +1,56 @@
|
|||
import { existsSync } from "fs";
|
||||
|
||||
import { asyncLoadJSON, asyncSaveJSON } from "../lib";
|
||||
|
||||
interface JSONCard {
|
||||
mcmId: number;
|
||||
set: string;
|
||||
}
|
||||
import { asyncLoadJSON, asyncSaveJSON, MCMCard, MCMDB, ScryfallCard, ScryfallDB } from "../lib";
|
||||
|
||||
interface JSONSet {
|
||||
cards: JSONCard[];
|
||||
cards: MCMCard[];
|
||||
}
|
||||
|
||||
type JSONDB = Record<string, JSONSet>;
|
||||
|
||||
const mtgjsonFile = "AllPrintings.json";
|
||||
const scryfallJSONFile = "scryfall-default-cards.json";
|
||||
|
||||
async function run() {
|
||||
if (!existsSync("AllPrintings.json")) {
|
||||
if (!existsSync(mtgjsonFile)) {
|
||||
console.error(
|
||||
"AllPrintings.json not found. Download from: https://www.mtgjson.com/files/AllPrintings.json"
|
||||
mtgjsonFile +
|
||||
" not found. Download from: https://www.mtgjson.com/files/AllPrintings.json"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
console.info("Loading AllPrintings.json");
|
||||
const db = await asyncLoadJSON<JSONDB>("AllPrintings.json");
|
||||
let acc = {};
|
||||
for (const set in db) {
|
||||
db[set].cards.forEach(c => {
|
||||
if (!existsSync(scryfallJSONFile)) {
|
||||
console.error(
|
||||
scryfallJSONFile +
|
||||
" not found. Download from: https://archive.scryfall.com/json/scryfall-default-cards.json"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
console.info("Loading " + mtgjsonFile);
|
||||
const mtgdb = await asyncLoadJSON<JSONDB>(mtgjsonFile);
|
||||
console.info("Loading " + scryfallJSONFile);
|
||||
const scrydb = await asyncLoadJSON<ScryfallDB>(scryfallJSONFile);
|
||||
let scrycards: Record<string, ScryfallCard> = {};
|
||||
scrydb.forEach(c => (scrycards[c.id] = c));
|
||||
let acc: MCMDB = {};
|
||||
for (const set in mtgdb) {
|
||||
mtgdb[set].cards.forEach(c => {
|
||||
c.set = set;
|
||||
if (c.scryfallId in scrycards) {
|
||||
c.scryfallUrl = scrycards[c.scryfallId].scryfall_uri;
|
||||
if ("image_uris" in scrycards[c.scryfallId]) {
|
||||
c.scryfallImageUrl = scrycards[c.scryfallId].image_uris.normal;
|
||||
} else if (
|
||||
"card_faces" in scrycards[c.scryfallId] &&
|
||||
"image_uris" in scrycards[c.scryfallId].card_faces[0]
|
||||
) {
|
||||
c.scryfallImageUrl =
|
||||
scrycards[c.scryfallId].card_faces[0].image_uris.normal;
|
||||
} else {
|
||||
console.log(scrycards[c.scryfallId]);
|
||||
}
|
||||
}
|
||||
// Search for scryfall card
|
||||
acc[c.mcmId] = c;
|
||||
});
|
||||
}
|
||||
|
|
110
lib/types.ts
110
lib/types.ts
|
@ -62,6 +62,8 @@ export interface MCMCard {
|
|||
scryfallId: string;
|
||||
scryfallIllustrationId: string;
|
||||
scryfallOracleId: string;
|
||||
scryfallImageUrl: string;
|
||||
scryfallUrl: string;
|
||||
subtypes: string[];
|
||||
supertypes: any[];
|
||||
tcgplayerProductId: number;
|
||||
|
@ -86,12 +88,15 @@ export interface LeanMCMCard {
|
|||
name: string;
|
||||
rarity: string;
|
||||
scryfallId: string;
|
||||
scryfallImageUrl: string;
|
||||
scryfallUrl: string;
|
||||
subtypes: string[];
|
||||
supertypes: any[];
|
||||
text: string;
|
||||
type: string;
|
||||
types: string[];
|
||||
set: string;
|
||||
number: string;
|
||||
}
|
||||
|
||||
export interface Language {
|
||||
|
@ -133,3 +138,108 @@ export interface LeanArticle {
|
|||
}
|
||||
|
||||
export type CardItem = LeanMCMCard & LeanArticle;
|
||||
|
||||
export interface ImageUris {
|
||||
small: string;
|
||||
normal: string;
|
||||
large: string;
|
||||
png: string;
|
||||
art_crop: string;
|
||||
border_crop: string;
|
||||
}
|
||||
|
||||
export interface Legalities {
|
||||
standard: string;
|
||||
future: string;
|
||||
historic: string;
|
||||
pioneer: string;
|
||||
modern: string;
|
||||
legacy: string;
|
||||
pauper: string;
|
||||
vintage: string;
|
||||
penny: string;
|
||||
commander: string;
|
||||
brawl: string;
|
||||
duel: string;
|
||||
oldschool: string;
|
||||
}
|
||||
|
||||
export interface RelatedUris {
|
||||
tcgplayer_decks: string;
|
||||
edhrec: string;
|
||||
mtgtop8: string;
|
||||
}
|
||||
|
||||
export interface CardFace {
|
||||
object: string;
|
||||
name: string;
|
||||
mana_cost: string;
|
||||
type_line: string;
|
||||
oracle_text: string;
|
||||
colors: string[];
|
||||
power: string;
|
||||
toughness: string;
|
||||
artist: string;
|
||||
artist_id: string;
|
||||
illustration_id: string;
|
||||
image_uris: ImageUris;
|
||||
color_indicator: string[];
|
||||
loyalty: string;
|
||||
}
|
||||
|
||||
export interface ScryfallCard {
|
||||
object: string;
|
||||
id: string;
|
||||
oracle_id: string;
|
||||
multiverse_ids: any[];
|
||||
tcgplayer_id: number;
|
||||
name: string;
|
||||
lang: string;
|
||||
released_at: string;
|
||||
uri: string;
|
||||
scryfall_uri: string;
|
||||
layout: string;
|
||||
highres_image: boolean;
|
||||
image_uris: ImageUris;
|
||||
card_faces?: CardFace[];
|
||||
mana_cost: string;
|
||||
cmc: number;
|
||||
type_line: string;
|
||||
oracle_text: string;
|
||||
colors: any[];
|
||||
color_identity: string[];
|
||||
legalities: Legalities;
|
||||
games: string[];
|
||||
reserved: boolean;
|
||||
foil: boolean;
|
||||
nonfoil: boolean;
|
||||
oversized: boolean;
|
||||
promo: boolean;
|
||||
reprint: boolean;
|
||||
variation: boolean;
|
||||
set: string;
|
||||
set_name: string;
|
||||
set_type: string;
|
||||
set_uri: string;
|
||||
set_search_uri: string;
|
||||
scryfall_set_uri: string;
|
||||
rulings_uri: string;
|
||||
prints_search_uri: string;
|
||||
collector_number: string;
|
||||
digital: boolean;
|
||||
rarity: string;
|
||||
card_back_id: string;
|
||||
artist: string;
|
||||
artist_ids: string[];
|
||||
illustration_id: string;
|
||||
border_color: string;
|
||||
frame: string;
|
||||
full_art: boolean;
|
||||
textless: boolean;
|
||||
booster: boolean;
|
||||
story_spotlight: boolean;
|
||||
edhrec_rank: number;
|
||||
related_uris: RelatedUris;
|
||||
}
|
||||
|
||||
export type ScryfallDB = ScryfallCard[];
|
||||
|
|
|
@ -36,6 +36,7 @@ export function leanCard(card: MCMCard): LeanMCMCard {
|
|||
manaCost: card.manaCost,
|
||||
mcmId: card.mcmId,
|
||||
name: card.name,
|
||||
number: card.number,
|
||||
rarity: card.rarity,
|
||||
scryfallId: card.scryfallId,
|
||||
subtypes: card.subtypes,
|
||||
|
@ -43,7 +44,9 @@ export function leanCard(card: MCMCard): LeanMCMCard {
|
|||
text: card.text,
|
||||
type: card.type,
|
||||
types: card.types,
|
||||
set: card.set
|
||||
set: card.set,
|
||||
scryfallImageUrl: card.scryfallImageUrl,
|
||||
scryfallUrl: card.scryfallUrl
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"fetch": "ts-node cmd/fetch.ts",
|
||||
"init-db": "ts-node cmd/convert.ts",
|
||||
"build-db": "ts-node cmd/convert.ts",
|
||||
"find": "ts-node cmd/find.ts",
|
||||
"cube": "ts-node cmd/cube.ts",
|
||||
"cube-watch": "ts-node cmd/cube-dev.ts"
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
|
||||
.color-section {
|
||||
flex: 1;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.color-section header {
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.color-W header.color-header {
|
||||
|
@ -77,7 +77,7 @@
|
|||
border: 1px solid #aaa;
|
||||
border-radius: 5px;
|
||||
font-size: 10pt;
|
||||
margin: 5px 0;
|
||||
margin: 10px 5px;
|
||||
}
|
||||
|
||||
.type-section header.type-header {
|
||||
|
@ -87,6 +87,17 @@
|
|||
padding: 5px;
|
||||
}
|
||||
|
||||
.cards {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cmc-index {
|
||||
position: absolute;
|
||||
opacity: 0.1;
|
||||
right: 5px;
|
||||
font-size: 15pt;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -95,12 +106,35 @@
|
|||
}
|
||||
|
||||
ul li {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
padding: 5px;
|
||||
flex: 1;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul li a:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
ul:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.img-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.img-overlay img {
|
||||
width: auto;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
@ -123,9 +157,15 @@
|
|||
(<%=utils.deepSum(typecards)%>)</header>
|
||||
<section class="cards">
|
||||
<% Object.entries(typecards).forEach(([cmc, finalcards]) => { %>
|
||||
<div class="cmc-index"><%=cmc%></div>
|
||||
<ul>
|
||||
<% finalcards.forEach(card => { %>
|
||||
<li><%= card.name %></li>
|
||||
<li data-set="<%=card.set%>" data-num="<%=card.number%>">
|
||||
<a target="_blank" data-image="<%=card.scryfallImageUrl%>"
|
||||
href="<%= card.scryfallUrl %>">
|
||||
<%= card.name %>
|
||||
</a>
|
||||
</li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
<% }); %>
|
||||
|
@ -136,6 +176,29 @@
|
|||
<% }); %>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const overlay = document.createElement("div");
|
||||
const img = document.createElement("img");
|
||||
overlay.appendChild(img);
|
||||
overlay.classList.add("img-overlay");
|
||||
document.body.appendChild(overlay);
|
||||
overlay.style.display = "none";
|
||||
Array.prototype.slice.call(document.querySelectorAll("li a[data-image]"), 0).forEach(el => {
|
||||
el.addEventListener("mouseenter", ev => {
|
||||
overlay.style.display = "block";
|
||||
img.src = el.dataset.image;
|
||||
});
|
||||
el.addEventListener("mouseleave", ev => {
|
||||
overlay.style.display = "none";
|
||||
});
|
||||
el.addEventListener("mousemove", ev => {
|
||||
overlay.style.left = `${ev.clientX}px`;
|
||||
overlay.style.top = `${ev.clientY - 320}px`;
|
||||
console.log(ev);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in a new issue