This commit is contained in:
Yanick Champoux 2024-02-01 10:04:14 -05:00
parent 47f9d02ef4
commit 075b83e0bf
6 changed files with 63 additions and 2745 deletions

2
.gitignore vendored
View File

@ -9,3 +9,5 @@ node_modules
vite.config.js.timestamp-* vite.config.js.timestamp-*
vite.config.ts.timestamp-* vite.config.ts.timestamp-*
pnpm-lock.yaml pnpm-lock.yaml
pnpm-lock.yaml
games.db

BIN
games.db

Binary file not shown.

View File

@ -36,6 +36,7 @@
"@vincjo/datatables": "^1.14.4", "@vincjo/datatables": "^1.14.4",
"beercss": "^3.4.13", "beercss": "^3.4.13",
"better-sqlite3": "^9.3.0", "better-sqlite3": "^9.3.0",
"cheerio": "1.0.0-rc.12" "cheerio": "1.0.0-rc.12",
"node-fetch": "^3.3.2"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,26 @@ import DB from 'better-sqlite3';
const db = DB('games.db'); const db = DB('games.db');
db.pragma('journal_mode = WAL'); db.pragma('journal_mode = WAL');
export async function fetch_guild_users (guild_id) {
const res = await fetch(`https://boardgamegeek.com/xmlapi2/guild?members=1&id=`+guild_id);
if( res.status === 200 ) {
const $page = load(await res.text());
const users = [];
$page('member').each( function(i,member) {
users.push( $page(this).attr('name'));
});
const insert = db.prepare( 'INSERT OR IGNORE INTO bgg_user (username) VALUES(@username)' );
users.forEach( username => insert.run({username}));
return users;
}
throw new Error('sad');
}
export function extract_user_forsale(page) { export function extract_user_forsale(page) {
const $ = load(page); const $ = load(page);
@ -18,7 +38,8 @@ export function extract_user_forsale(page) {
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+)/);
if(find_price ) data.price = find_price[1]; data.price = undefined;
if(find_price ) data.price = parseInt(find_price[1]);
games.push(data); games.push(data);
}) })
@ -42,17 +63,20 @@ async function fetch_user_forsale(username,n=1) {
if( res.status === 200 ) if( res.status === 200 )
return extract_user_forsale( await res.text() ); return extract_user_forsale( await res.text() );
throw new Error("couldn't get the collection"); 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);
const insert = db.prepare( 'INSERT into game (username, bgg_id, name, thumbnail, notes) VALUES(@username,@bgg_id,@name,@thumbnail,@notes)' ); // 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) VALUES(@username,@bgg_id,@name,@thumbnail,@notes,@price)' );
db.prepare('DELETE FROM game where username = @username').run({username}); await db.prepare('DELETE FROM game where username = @username').run({username});
for ( let game of games ) { for ( let game of games ) {
console.log(game);
insert.run({ insert.run({
username, username,
...game ...game
@ -61,5 +85,14 @@ async function update_user_games(username) {
} }
await update_user_games('yenzie').then( () => console.log('is done')).catch( e => console.error(e));
console.log( await update_user_games('yenzie') ); /*
const usernames = await fetch_guild_users('1610');
await Promise.all(
usernames.map( username => {
return update_user_games(username).then( () => console.log(username, 'is done')).catch( e => console.error(e));
})
)
*/

View File

@ -1,10 +1,15 @@
<article> <article>
<h1>Ottawa board games for sale</h1> <h1>Ottawa board games for sale and to trade</h1>
<p>This is a list of games for sale or trade of people living in the Ottawa <p>This is a list of games for sale or trade of people living in the Ottawa
region, taken from their profiles on region, taken from their profiles on
<a href="https://boardgamegeek.com">Board Game Geek</a>. <a href="https://boardgamegeek.com">Board Game Geek</a>.</p>
</p>
<p>If you want to be added to the list of sellers, you can send me a
<a target="_blank" href="https://boardgamegeek.com/geekmail/compose?touser=yenzie"> <i>BGG mail</i></a>.
Discussion of this service happens in the <a
href='https://boardgamegeek.com/thread/3238117/auto-generating-ottawa-specific-saletrade-page'>Ottawa Guild</a>.</p>
<header > <header >
<Search {handler} /> <Search {handler} />
@ -24,19 +29,21 @@
<tbody> <tbody>
{#each $rows as row} {#each $rows as row}
<tr> <tr>
<td><a target="_top" href={`https://boardgamegeek.com/user/${row.username}`}>{row.username}</a></td> <td><a target="_blank"
href={`https://boardgamegeek.com/collection/user/${row.username}?trade=1&subtype=boardgame&ff=1`}>{row.username}</a>
&nbsp;
<a
target="_blank"
href={`https://boardgamegeek.com/geekmail/compose?touser=${row.username}`}>
<i>email</i></a></td>
<td> <a <td> <a
target="_top" target="_blank"
href={`https://boardgamegeek.com/geekmail/compose?touser=${row.username}`}>bgg
mail</a></td>
<td> <a
target="_top"
href={`https://boardgamegeek.com/boardgame/${row.bgg_id}`}> href={`https://boardgamegeek.com/boardgame/${row.bgg_id}`}>
{row.name}</a> {row.name}</a>
</td> </td>
<td> <td>
<a <a
target="_top" target="_blank"
href={`https://boardgamegeek.com/boardgame/${row.bgg_id}`}> href={`https://boardgamegeek.com/boardgame/${row.bgg_id}`}>
<img src={row.thumbnail} height="60"/></a> <img src={row.thumbnail} height="60"/></a>
</td> </td>
@ -50,14 +57,15 @@
<script> <script>
// TODO BGG mail the user // TODO sort
// TODO hide games I'm not interested in
// TODO add cart // TODO add cart
// prettify // TODO prettify via beercss
import { DataHandler, Search } from '@vincjo/datatables' import { DataHandler, Search } from '@vincjo/datatables'
export let data; export let data;
const handler = new DataHandler(data.games, { rowsPerPage: 50 }) const handler = new DataHandler(data.games, { rowsPerPage: 500 })
const rows = handler.getRows() const rows = handler.getRows()
</script> </script>