From b4114a2440493e0fe01be73981f39d45bb8faf79 Mon Sep 17 00:00:00 2001 From: ntr Date: Sat, 6 Aug 2022 21:49:40 +1000 Subject: [PATCH] non discogs users --- client/src/routes/home.tsx | 4 ++- client/src/style/index.less | 1 + server/global.d.ts | 1 + server/index.ts | 31 +------------------- server/prisma/schema.prisma | 4 +-- server/src/api.ts | 58 +++++++++++++++++++++++++++++++++++-- server/src/discogs.ts | 16 ++++++++-- server/src/pg.ts | 27 ++++++++++------- 8 files changed, 93 insertions(+), 49 deletions(-) diff --git a/client/src/routes/home.tsx b/client/src/routes/home.tsx index f3251a9..73cbe63 100644 --- a/client/src/routes/home.tsx +++ b/client/src/routes/home.tsx @@ -14,14 +14,16 @@ function Bundle(bundle) { return (

{bundle.username} - {bundle.seller}

-

{bundle.total} {bundle.currency}

+

{bundle.items.length} items - {bundle.total} {bundle.currency}

Ships: {bundle.mentionsAustralia && 'AU'} {bundle.mentionsWorldwide && 'WORLD'}

{bundle.items.map(i => (

{i.description}

+
{i.user}
{i.price} {i.currency}
+
))}
diff --git a/client/src/style/index.less b/client/src/style/index.less index 61c32c0..eca50c8 100644 --- a/client/src/style/index.less +++ b/client/src/style/index.less @@ -28,6 +28,7 @@ html, body { .bundle { flex: 1; + padding-right: 1em; } } diff --git a/server/global.d.ts b/server/global.d.ts index d29ff47..6052638 100644 --- a/server/global.d.ts +++ b/server/global.d.ts @@ -4,6 +4,7 @@ type UUID = string; type DiscogsName = string; type DiscogsListing = number; +type DiscogsRelease = number; type DiscogsSeller = number; type BundleCandidate = { diff --git a/server/index.ts b/server/index.ts index f8ce6f0..1ada495 100644 --- a/server/index.ts +++ b/server/index.ts @@ -14,38 +14,9 @@ async function start(log) { const prisma = new PrismaClient(); const pg = pgService(log, prisma); const discogs = discogsService(log, pg); - const api = createApi(log, pg); - - const usernames = [ - 'vanderbabe', - 'margh', - 'jmcdermid1', - ]; - - async function populateUserListings(user) { - log.info(user); - const wants = await discogs.wantlist(user); - - // const latest = await discogs.wantlistLatest(user); - // if (wants.length !== latest.length) - log.info({ username: user.discogs, wantCount: wants.length }); - - return Promise.mapSeries(wants, async want => { - const listings = await discogs.listings(want); - const populated = listings.filter(l => l); - log.info({ id: want.id, release: want.release, populated: populated.length, total: listings.length }); - return populated; - }); - } - - // await Promise.mapSeries(usernames, async u => { - // const user = await discogs.user(u) - // return populateUserListings(user); - // }); + const api = createApi(log, pg, discogs); await api.listen(); - - // return getBundles(); } async function run() { diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 8f02d3a..fea6d9f 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -25,9 +25,9 @@ model Listing { model User { id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid - discogs String? @unique name String @default("unknown") - data Json + discogs String? @unique + data Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/server/src/api.ts b/server/src/api.ts index 87a3fac..aea5030 100644 --- a/server/src/api.ts +++ b/server/src/api.ts @@ -2,13 +2,14 @@ import express from 'express'; import http from 'http'; import cors from 'cors'; import { groupBy } from 'lodash'; +import Bluebird from 'bluebird'; import type Log from 'bunyan'; import { Pg } from './pg'; -import type { Listing, User, Prisma } from '@prisma/client'; +import type { Listing, User, Want, Prisma } from '@prisma/client'; -export default function createApi(log: Log, pg: Pg) { +export default function createApi(log: Log, pg: Pg, discogs) { const PORT = 41337; const app = express(); @@ -32,7 +33,7 @@ export default function createApi(log: Log, pg: Pg) { currency: l.data.original_price.curr_abbr, condition: l.data.condition, uri: l.data.uri, - user: l.want.user.discogs, + user: l.want.user.name, })); const shipping = b[0]?.data.seller.shipping; @@ -57,6 +58,24 @@ export default function createApi(log: Log, pg: Pg) { } + async function populateUserListings(user: User) { + log.info(user); + + const wants = await discogs.wantlist(user); + + // const latest = await discogs.wantlistLatest(user); + // if (wants.length !== latest.length) + + log.info({ username: user.discogs, wantCount: wants.length }); + + return Bluebird.mapSeries(wants, async want => { + const listings = await discogs.listings(want); + const populated = listings.filter(l => l); + log.info({ id: want.id, release: want.release, populated: populated.length, total: listings.length }); + return populated; + }); + } + function listen() { return new Promise((resolve, reject) => { server.on('error', err => { @@ -70,6 +89,7 @@ export default function createApi(log: Log, pg: Pg) { } app.use(cors()); + app.use(express.json()) app.get('/bundles', async (req, res, next) => { const bundles = await getBundles(); @@ -77,6 +97,38 @@ export default function createApi(log: Log, pg: Pg) { res.json(bundles); }) + app.get('/user/:id/offers', async function userOffersGet(req, res, next) { + const { id } = req.params; + const user = await pg.userFindId(id); + res.json(user); + }); + + app.post('/user', async function usersPost(req, res, next) { + const { name } = req.body; + const user = await pg.userUpsert(null, name, null); + res.json(user); + }); + + app.post('/user/populate', async function usersPopulate(req, res, next) { + const { userId } = req.body; + const user = await pg.userFindId(userId); + const listings = await populateUserListings(user); + res.json(listings); + }); + + app.post('/want', async function wantPost(req, res, next) { + const { userId, releaseId } = req.body; + const user = await pg.userFindId(userId); + const release = await discogs.release(releaseId); + const want = await pg.wantUpsert(release, user); + return res.json(want); + }); + + app.use(function errorHandler(req, res, next, error) { + log.warn(error); + res.status(500).send({ error }); + }); + return { app, listen, diff --git a/server/src/discogs.ts b/server/src/discogs.ts index 44fd437..9caeff3 100644 --- a/server/src/discogs.ts +++ b/server/src/discogs.ts @@ -35,13 +35,19 @@ export default function discogs(log: Log, pg: Pg) { const user = await pg.userFindName(discogs); if (user) return user; log.debug('fetching user', discogs); - const res = await api.get(`${apiBase}/users/${discogs}`); - return pg.userUpsert(res.data); + const { data } = await api.get(`${apiBase}/users/${discogs}`); + return pg.userUpsert(data.username, data.username, data); } async function wantlist(user: User): Promise { const stored = await pg.userWants(user); if (stored.length) return stored; + + if (!user.discogs) { + log.error(user, 'attempted to fetch wantlist of non discogs user'); + throw new Error('User is not associated with a discogs account'); + } + return wantlistLatest(user); } @@ -51,6 +57,11 @@ export default function discogs(log: Log, pg: Pg) { return Bluebird.mapSeries(wants, async r => pg.wantUpsert(r, user)); } + async function release(id: DiscogsRelease): Promise { + const { data } = await api.get(`${apiBase}/releases/${id}`); + return data; + } + async function inventory(user: string) { const res = await api.get(`${apiBase}/users/${user}/inventory`); return res.data.listings; @@ -91,5 +102,6 @@ export default function discogs(log: Log, pg: Pg) { inventory, listings, listing, + release, }; } \ No newline at end of file diff --git a/server/src/pg.ts b/server/src/pg.ts index ca23502..5083366 100644 --- a/server/src/pg.ts +++ b/server/src/pg.ts @@ -5,7 +5,7 @@ import * as Bluebird from 'bluebird'; export interface Pg { userFindId: (id: UUID) => Promise, userFindName: (name: DiscogsName) => Promise, - userUpsert: (user: User) => Promise, + userUpsert: (discogs: DiscogsName | null, name: string, data: any) => Promise, userWants: (user: User) => Promise, wantUpsert: (want: Want, user: User) => Promise, @@ -17,7 +17,7 @@ export interface Pg { } export default function createPg(log: Log, prisma: PrismaClient): Pg { - async function userFindId(id) { + async function userFindId(id: UUID) { return prisma.user.findUnique({ where: { id }}); } @@ -29,18 +29,23 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg { return prisma.want.findMany({ where: { userId: user.id }}); } - async function userUpsert(user) { - const data = { - discogs: user.username, - data: user as Prisma.JsonObject, + async function userUpsert(discogs: DiscogsName | null, name: string, data: any) { + const insert = { + discogs, + name, + data, }; - return prisma.user.upsert({ + if (discogs) return prisma.user.upsert({ where: { - discogs: user.username, + discogs, }, - update: data, - create: data, + update: insert, + create: insert, + }); + + return prisma.user.create({ + data: { name }, }); } @@ -111,7 +116,7 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg { select seller, count(distinct("wantId")), array_agg(id) as listings from - "Listing" + listings group by seller order by