mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-01-17 15:32:11 -08:00
105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
// Fetch and parse card sets
|
|
|
|
class CardImporterService {
|
|
importCards(url): Promise<any> {
|
|
const error = 'Card import must be in valid MTG JSON format';
|
|
|
|
return fetch(url)
|
|
.then(response => {
|
|
if (response.headers.get('Content-Type') !== 'application/json') {
|
|
throw new Error(error);
|
|
}
|
|
|
|
return response.json();
|
|
})
|
|
.then((json) => {
|
|
try {
|
|
const sortedSets = Object.keys(json.data)
|
|
.map(key => json.data[key])
|
|
.sort((a, b) => new Date(a.releaseDate).getTime() - new Date(b.releaseDate).getTime());
|
|
|
|
const sets = sortedSets.map(({ cards, tokens, ...set }) => ({
|
|
...set,
|
|
cards: cards.map(({ name }) => name),
|
|
tokens: tokens.map(({ name }) => name),
|
|
}));
|
|
|
|
const unsortedCards = sortedSets.reduce((acc, set) => {
|
|
set.cards.forEach(card => acc[card.name] = card);
|
|
return acc;
|
|
}, {});
|
|
|
|
const cards = Object.keys(unsortedCards)
|
|
.sort((a, b) => a.localeCompare(b))
|
|
.map(key => unsortedCards[key]);
|
|
|
|
return { cards, sets };
|
|
} catch (e) {
|
|
throw new Error(error);
|
|
}
|
|
});
|
|
}
|
|
|
|
importTokens(url): Promise<any> {
|
|
const error = 'Token import must be in valid MTG XML format';
|
|
|
|
return fetch(url)
|
|
.then(response => {
|
|
if (!response.ok) {
|
|
throw new Error('Failed to fetch');
|
|
}
|
|
|
|
return response.text()
|
|
})
|
|
.then((xmlString) => {
|
|
try {
|
|
const parser = new DOMParser();
|
|
const dom = parser.parseFromString(xmlString, 'application/xml');
|
|
|
|
const tokens = Array.from(dom.querySelectorAll('card')).map(
|
|
(tokenElement) => this.parseXmlAttributes(tokenElement)
|
|
);
|
|
|
|
return tokens;
|
|
} catch (e) {
|
|
throw new Error(error);
|
|
}
|
|
})
|
|
}
|
|
|
|
private parseXmlAttributes(dom: Element) {
|
|
return Array.from(dom.children).reduce((attributes, child) => {
|
|
const value = child.children.length ? this.parseXmlAttributes(child) : child.innerHTML;
|
|
|
|
let parsedAttributes = { value };
|
|
|
|
if (child.attributes.length) {
|
|
const childAttributes = Array.from(child.attributes).reduce((acc, { name, value }) => {
|
|
acc[name] = value;
|
|
return acc;
|
|
}, {});
|
|
|
|
parsedAttributes = {
|
|
...parsedAttributes,
|
|
...childAttributes,
|
|
};
|
|
}
|
|
|
|
// @TODO: clean this up and normalize what i'm returning
|
|
if (attributes[child.tagName]) {
|
|
if (Array.isArray(attributes[child.tagName])) {
|
|
attributes[child.tagName].push(parsedAttributes)
|
|
} else {
|
|
attributes[child.tagName] = [parsedAttributes];
|
|
}
|
|
} else {
|
|
attributes[child.tagName] = parsedAttributes;
|
|
}
|
|
|
|
return attributes;
|
|
}, {});
|
|
}
|
|
}
|
|
|
|
export const cardImporterService = new CardImporterService();
|