Merge branch 'last-updated'

This commit is contained in:
Yanick Champoux 2024-02-01 15:27:43 -05:00
commit 1a476ddc1d
4 changed files with 82 additions and 57 deletions

View File

@ -0,0 +1,8 @@
-- migrate:up
alter table game
add column updated_at text;
-- migrate:down
alter table game drop column updated_at;

View File

@ -8,11 +8,12 @@ CREATE TABLE game (
thumbnail text, thumbnail text,
bgg_id text, bgg_id text,
name text, name text,
notes text, price integer, notes text, price integer, updated_at text,
FOREIGN KEY(username) REFERENCES bgg_user(username) FOREIGN KEY(username) REFERENCES bgg_user(username)
); );
-- Dbmate schema migrations -- Dbmate schema migrations
INSERT INTO "schema_migrations" (version) VALUES INSERT INTO "schema_migrations" (version) VALUES
('20240130203355'), ('20240130203355'),
('20240130203603'), ('20240130203603'),
('20240130205124'); ('20240130205124'),
('20240201201248');

View File

@ -7,88 +7,97 @@ const db = DB(db_file);
db.pragma('journal_mode = WAL'); db.pragma('journal_mode = WAL');
export async function fetch_guild_users(guild_id) { export async function fetch_guild_users(guild_id) {
const res = await fetch(`https://boardgamegeek.com/xmlapi2/guild?members=1&id=` + guild_id); const res = await fetch(
`https://boardgamegeek.com/xmlapi2/guild?members=1&id=` + guild_id,
);
if (res.status === 200) { if (res.status === 200) {
const $page = load(await res.text()); const $page = load(await res.text());
const users = []; const users = [];
$page('member').each(function (i, member) { $page('member').each(function (i, member) {
users.push($page(this).attr('name')); users.push($page(this).attr('name'));
}); });
const insert = db.prepare('INSERT OR IGNORE INTO bgg_user (username) VALUES(@username)'); const insert = db.prepare(
'INSERT OR IGNORE INTO bgg_user (username) VALUES(@username)',
);
users.forEach((username) => insert.run({ username })); users.forEach((username) => insert.run({ username }));
return users; return users;
} }
throw new Error('sad'); throw new Error('sad');
} }
export function extract_user_forsale(page) { export function extract_user_forsale(page) {
const $ = load(page); const $ = load(page);
const games = []; const games = [];
const data = $('item').map(function (i, item) { const data = $('item').map(function (i, item) {
const data = {}; const data = {};
data.bgg_id = $(this).attr('objectid'); data.bgg_id = $(this).attr('objectid');
data.name = $(this).find('name').text(); data.name = $(this).find('name').text();
data.thumbnail = $(this).find('thumbnail').text(); data.thumbnail = $(this).find('thumbnail').text();
data.notes = $(this).find('conditiontext').text(); data.notes = $(this).find('conditiontext').text();
const find_price = data.notes.match(/\$(\d+)/); const find_price = data.notes.match(/\$(\d+)/);
data.price = undefined; data.price = undefined;
if (find_price) data.price = parseInt(find_price[1]); if (find_price) data.price = parseInt(find_price[1]);
games.push(data); games.push(data);
}); });
return games; return games;
} }
async function fetch_user_forsale(username, n = 1) { async function fetch_user_forsale(username, n = 1) {
if (n > 5) throw new Error("couldn't get collection"); if (n > 5) throw new Error("couldn't get collection");
const res = await fetch( const res = await fetch(
`https://boardgamegeek.com/xmlapi2/collection?trade=1&username=${username}` `https://boardgamegeek.com/xmlapi2/collection?trade=1&username=${username}`,
); );
if (res.status === 202) { if (res.status === 202) {
return new Promise((accept, reject) => { return new Promise((accept, reject) => {
setTimeout(() => { setTimeout(() => {
fetch_user_forsale(username, n + 1).then(accept); fetch_user_forsale(username, n + 1).then(accept);
}, 2000); }, 2000);
}); });
} }
if (res.status === 200) return extract_user_forsale(await res.text()); if (res.status === 200) return extract_user_forsale(await res.text());
throw new Error("couldn't get the collection for " + username); throw new Error("couldn't get the collection for " + username);
} }
async function update_user_games(username) { async function update_user_games(username) {
const games = await fetch_user_forsale(username); const games = await fetch_user_forsale(username);
// TODO only change the games that changed const updated_at = new Date().toISOString();
// TODO only change users that got added or removed
const insert = db.prepare(
'INSERT into game (username, bgg_id, name, thumbnail, notes,price) VALUES(@username,@bgg_id,@name,@thumbnail,@notes,@price)'
);
await db.prepare('DELETE FROM game where username = @username').run({ username }); // 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)',
);
for (let game of games) { await db
console.log(game); .prepare('DELETE FROM game where username = @username')
insert.run({ .run({ username });
username,
...game for (let game of games) {
}); console.log(game);
} insert.run({
username,
updated_at,
...game,
});
}
} }
await update_user_games('yenzie') await update_user_games('yenzie')
.then(() => console.log('is done')) .then(() => console.log('is done'))
.catch((e) => console.error(e)); .catch((e) => console.error(e));
/* /*
const usernames = await fetch_guild_users('1610'); const usernames = await fetch_guild_users('1610');

View File

@ -39,6 +39,7 @@
<Th {handler} orderBy="name">game</Th> <Th {handler} orderBy="name">game</Th>
<th>notes</th> <th>notes</th>
<Th {handler} orderBy="price">price</Th> <Th {handler} orderBy="price">price</Th>
<th>last updated</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -69,6 +70,7 @@
</td> </td>
<td>{row.notes}</td> <td>{row.notes}</td>
<td>{row.price ?? ''}</td> <td>{row.price ?? ''}</td>
<td><small>{pretty_date(row.updated_at)}</small></td>
</tr> </tr>
{/each} {/each}
</tbody> </tbody>
@ -85,6 +87,11 @@
export let data; export let data;
function pretty_date(date) {
if (!date) return '';
return date.replace(/T.*/, '');
}
const handler = new DataHandler(data.games, { rowsPerPage: 500 }); const handler = new DataHandler(data.games, { rowsPerPage: 500 });
const rows = handler.getRows(); const rows = handler.getRows();
</script> </script>