Skip to content

Instantly share code, notes, and snippets.

@PhyberApex
Created December 31, 2022 13:55
Show Gist options
  • Save PhyberApex/d83da3a73d21addbf90ece8d41740741 to your computer and use it in GitHub Desktop.
Save PhyberApex/d83da3a73d21addbf90ece8d41740741 to your computer and use it in GitHub Desktop.
const notice = (msg) => new Notice(msg, 5000);
const log = (msg) => console.log(msg);
const parser = new DOMParser();
const API_URL = "https://api.geekdo.com/xmlapi2";
module.exports = {
entry: start,
settings: {
name: "BoardGameGeek",
author: "Janis Walliser",
},
};
let QuickAdd;
let Settings;
async function start(params, settings) {
QuickAdd = params;
Settings = settings;
const query = await QuickAdd.quickAddApi.inputPrompt(
"Enter board game title or BGG ID: "
);
if (!query) {
notice("No query entered.");
throw new Error("No query entered.");
}
let selectedGame;
if (isBGGId(query)) {
selectedGame = await getByBGGId(query);
} else {
const results = await getByQuery(query);
const choice = await QuickAdd.quickAddApi.suggester(
results.map(formatTitleForSuggestion),
results
);
if (!choice) {
notice("No choice selected.");
throw new Error("No choice selected.");
}
selectedGame = await getByBGGId(choice.id);
}
QuickAdd.variables = {
...selectedGame,
fileName: replaceIllegalFileNameCharactersInString(selectedGame.name),
};
}
function isBGGId(str) {
return /^\d+$/.test(str);
}
function formatTitleForSuggestion(resultItem) {
return resultItem.name;
}
async function getByQuery(query) {
const resXML = await apiGet(`${API_URL}/search`, {
query: query,
type: 'boardgame',
});
const res = getSearchResultJSONFromResultXML(resXML);
if (!res || !res.length) {
notice("No results found.");
throw new Error("No results found.");
}
return res;
}
async function getByBGGId(id) {
const resXML = await apiGet(`${API_URL}/things`, {
id: id,
});
log(resXML)
const res = getBoardgameJSONFromResultXML(resXML);
log(JSON.stringify(res))
if (!res) {
notice("No results found.");
throw new Error("No results found.");
}
return res;
}
function replaceIllegalFileNameCharactersInString(string) {
return string.replace(/[\\,#%&\{\}\/*<>?$\'\":@]*/g, "");
}
async function apiGet(url, data) {
let finalURL = new URL(url);
if (data)
Object.keys(data).forEach((key) =>
finalURL.searchParams.append(key, data[key])
);
const res = await request({
url: finalURL.href,
method: "GET",
cache: "no-cache",
headers: {
"Content-Type": "application/xml",
},
});
return res;
}
function getSearchResultJSONFromResultXML(xml){
const result = [];
const xmlDoc = parser.parseFromString(xml, 'text/xml');
const xmlItems = xmlDoc.getElementsByTagName("item");
for (i = 0; i < xmlItems.length; i++) {
result.push({
id: xmlItems[i].getAttribute('id'),
name: xmlItems[i].getElementsByTagName('name')[0].getAttribute('value'),
})
}
return result;
}
function getBoardgameJSONFromResultXML(xml){
const xmlDoc = parser.parseFromString(xml, 'text/xml');
const xmlItem = xmlDoc.getElementsByTagName("item");
if (!xmlItem || xmlItem.length != 1)
return {};
log(xmlItem[0].getElementsByTagName('thumbnail'))
return {
id: xmlItem[0].getAttribute('id'),
name: xmlItem[0].getElementsByTagName('name')[0].getAttribute('value'),
thumbnail: xmlItem[0].getElementsByTagName('image')[0].innerHTML,
description: xmlItem[0].getElementsByTagName('description')[0].innerHTML,
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment