get the games for sale

This commit is contained in:
Yanick Champoux 2024-01-30 15:01:27 -05:00
parent 14778e69dc
commit a0596cef25
6 changed files with 90 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
pnpm-lock.yaml

10
NOTES Normal file
View File

@ -0,0 +1,10 @@
Root Path
The root path for all requests in the XMLAPI2 are prefixed as follows. These queries can be made on any domain and are interchangeable. Example paths:
https://boardgamegeek.com/xmlapi2/
https://rpggeek.com/xmlapi2/
https://videogamegeek.com/xmlapi2/

8
package.json Normal file
View File

@ -0,0 +1,8 @@
{
"type":"module",
"dependencies": {
"cheerio": "1.0.0-rc.12",
"node-fetch": "^3.3.2",
"vitest": "^1.2.2"
}
}

18
src/collection/example.js Normal file
View File

@ -0,0 +1,18 @@
const collection_example = `<?xml version="1.0" encoding="utf-8" standalone="yes"?><items totalitems="2" termsofuse="https://boardgamegeek.com/xmlapi/termsofuse" pubdate="Tue, 30 Jan 2024 19:04:26 +0000">
<item objecttype="thing" objectid="179275" subtype="boardgame" collid="95623997">
<name sortindex="1">One Deck Dungeon</name>
<yearpublished>2016</yearpublished> <image>https://cf.geekdo-images.com/quvyGpE7kwbd2Mt1H5iLwQ__original/img/pjwQVzsCHiXg8qFTZpVoJYx6SOE=/0x0/filters:format(jpeg)/pic3019101.jpg</image>
<thumbnail>https://cf.geekdo-images.com/quvyGpE7kwbd2Mt1H5iLwQ__thumb/img/Vf5PvYElsfOG28LqJimwPC6rqw4=/fit-in/200x150/filters:strip_icc()/pic3019101.jpg</thumbnail>
<status own="1" prevowned="0" fortrade="1" want="0" wanttoplay="0" wanttobuy="0" wishlist="0" preordered="0" lastmodified="2024-01-30 13:02:38" />
<numplays>6</numplays> <conditiontext>text for trade goes here (testing)</conditiontext> </item>
<item objecttype="thing" objectid="224821" subtype="boardgame" collid="95624005">
<name sortindex="1">One Deck Dungeon: Forest of Shadows</name>
<yearpublished>2017</yearpublished> <image>https://cf.geekdo-images.com/rfkpP2id0JwDWw5694PRQQ__original/img/Od_smbHwsk-3Qw2HntZbU-oUg4I=/0x0/filters:format(jpeg)/pic3496794.jpg</image>
<thumbnail>https://cf.geekdo-images.com/rfkpP2id0JwDWw5694PRQQ__thumb/img/5A9VoUaZ1B5Wx1t0n74mfLBHW2o=/fit-in/200x150/filters:strip_icc()/pic3496794.jpg</thumbnail>
<status own="1" prevowned="0" fortrade="1" want="0" wanttoplay="0" wanttobuy="0" wishlist="0" preordered="0" lastmodified="2024-01-30 13:04:15" />
<numplays>1</numplays> </item>
</items>
`;
export default collection_example;

44
src/fetchCollection.js Normal file
View File

@ -0,0 +1,44 @@
import { load } from 'cheerio';
import fetch from 'node-fetch';
export function extract_user_forsale(page) {
const $ = load(page);
const games = [];
const data = $('item').map( function (i,item) {
const data = {};
data.game_id = $(this).attr('objectid');
data.game_name = $(this).find('name').text();
data.thumbnail = $(this).find('thumbnail').text();
data.notes = $(this).find('conditiontext').text();
const find_price = data.notes.match(/\$(\d+)/);
if(find_price ) data.price = find_price[1];
games.push(data);
})
return games;
}
async function fetch_user_forsale(username,n=1) {
if(n>5) throw new Error("couldn't get collection");
const res = await fetch(`https://boardgamegeek.com/xmlapi2/collection?trade=1&username=${username}`);
if ( res.status === 202 ) {
return new Promise( (accept,reject) => {
setTimeout(()=> {
fetch_user_forsale(username,n+1).then(accept)
}, 2000)
})
}
if( res.status === 200 )
return extract_user_forsale( await res.text() );
throw new Error("couldn't get the collection");
}
console.log( await fetch_user_forsale('yenzie') );

View File

@ -0,0 +1,8 @@
import { test, expect } from 'vitest';
import collection_example from './collection/example.js'
import { extract_user_forsale } from './fetchCollection.js';
test( 'basic collection parsing', () => {
extract_user_forsale(collection_example);
} );