bgg-ottawa-sell-club/src/fetchCollection.js

92 lines
2.5 KiB
JavaScript
Raw Normal View History

2024-01-30 20:01:27 +00:00
import { load } from 'cheerio';
import fetch from 'node-fetch';
2024-01-30 20:54:24 +00:00
2024-02-04 17:39:47 +00:00
export async function fetch_guild_users(db, guild_id) {
2024-02-01 20:27:38 +00:00
const res = await fetch(
`https://boardgamegeek.com/xmlapi2/guild?members=1&id=` + guild_id,
);
2024-02-01 15:04:14 +00:00
2024-02-01 20:27:38 +00:00
if (res.status === 200) {
const $page = load(await res.text());
const users = [];
$page('member').each(function (i, member) {
users.push($page(this).attr('name'));
});
2024-02-01 15:04:14 +00:00
2024-02-01 20:27:38 +00:00
const insert = db.prepare(
'INSERT OR IGNORE INTO bgg_user (username) VALUES(@username)',
);
2024-02-01 15:04:14 +00:00
2024-02-01 20:27:38 +00:00
users.forEach((username) => insert.run({ username }));
2024-02-01 15:04:14 +00:00
2024-02-01 20:27:38 +00:00
return users;
}
2024-02-01 15:04:14 +00:00
2024-02-01 20:27:38 +00:00
throw new Error('sad');
2024-02-01 15:04:14 +00:00
}
2024-01-30 20:01:27 +00:00
export function extract_user_forsale(page) {
2024-02-01 20:27:38 +00:00
const $ = load(page);
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
const games = [];
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
const data = $('item').map(function (i, item) {
const data = {};
data.bgg_id = $(this).attr('objectid');
data.name = $(this).find('name').text();
data.thumbnail = $(this).find('thumbnail').text();
data.notes = $(this).find('conditiontext').text();
const find_price = data.notes.match(/\$(\d+)/);
data.price = undefined;
if (find_price) data.price = parseInt(find_price[1]);
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
games.push(data);
});
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
return games;
2024-01-30 20:01:27 +00:00
}
2024-02-01 18:49:55 +00:00
async function fetch_user_forsale(username, n = 1) {
2024-02-01 20:27:38 +00:00
if (n > 5) throw new Error("couldn't get collection");
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
const res = await fetch(
`https://boardgamegeek.com/xmlapi2/collection?trade=1&username=${username}`,
);
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
if (res.status === 202) {
return new Promise((accept, reject) => {
setTimeout(() => {
fetch_user_forsale(username, n + 1).then(accept);
}, 2000);
});
}
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
if (res.status === 200) return extract_user_forsale(await res.text());
2024-01-30 20:01:27 +00:00
2024-02-01 20:27:38 +00:00
throw new Error("couldn't get the collection for " + username);
2024-01-30 20:01:27 +00:00
}
2024-02-04 17:39:47 +00:00
export async function update_user_games(db, username) {
2024-02-01 20:27:38 +00:00
const games = await fetch_user_forsale(username);
const updated_at = new Date().toISOString();
// TODO only change the games that changed
// TODO only change users that got added or removed
const insert = db.prepare(
'INSERT into game (username, bgg_id, name, thumbnail, notes,price,updated_at) VALUES(@username,@bgg_id,@name,@thumbnail,@notes,@price,@updated_at)',
);
await db
.prepare('DELETE FROM game where username = @username')
.run({ username });
for (let game of games) {
insert.run({
username,
updated_at,
...game,
});
}
2024-01-30 20:54:24 +00:00
}