non discogs users
This commit is contained in:
1 parent
66dcdaeb70
commit
b4114a2440
8 files changed
+93
-49
No files matched your search
@@ -14,14 +14,16 @@ function Bundle(bundle) {
|
|||||||
return (
|
return (
|
||||||
<div class="bundle">
|
<div class="bundle">
|
||||||
<h2>{bundle.username} - {bundle.seller}</h2>
|
<h2>{bundle.username} - {bundle.seller}</h2>
|
||||||
<h3>{bundle.total} {bundle.currency}</h3>
|
<h3>{bundle.items.length} items - {bundle.total} {bundle.currency}</h3>
|
||||||
<h4>Ships: {bundle.mentionsAustralia && 'AU'} {bundle.mentionsWorldwide && 'WORLD'}</h4>
|
<h4>Ships: {bundle.mentionsAustralia && 'AU'} {bundle.mentionsWorldwide && 'WORLD'}</h4>
|
||||||
{bundle.items.map(i => (
|
{bundle.items.map(i => (
|
||||||
<div key={i.id}>
|
<div key={i.id}>
|
||||||
<a href={i.uri}>
|
<a href={i.uri}>
|
||||||
<h4>{i.description}</h4>
|
<h4>{i.description}</h4>
|
||||||
</a>
|
</a>
|
||||||
|
<h5>{i.user}</h5>
|
||||||
<h5>{i.price} {i.currency}</h5>
|
<h5>{i.price} {i.currency}</h5>
|
||||||
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ html, body {
|
|||||||
|
|
||||||
.bundle {
|
.bundle {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -4,6 +4,7 @@ type UUID = string;
|
|||||||
|
|
||||||
type DiscogsName = string;
|
type DiscogsName = string;
|
||||||
type DiscogsListing = number;
|
type DiscogsListing = number;
|
||||||
|
type DiscogsRelease = number;
|
||||||
type DiscogsSeller = number;
|
type DiscogsSeller = number;
|
||||||
|
|
||||||
type BundleCandidate = {
|
type BundleCandidate = {
|
||||||
|
|||||||
+1
-30
@@ -14,38 +14,9 @@ async function start(log) {
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
const pg = pgService(log, prisma);
|
const pg = pgService(log, prisma);
|
||||||
const discogs = discogsService(log, pg);
|
const discogs = discogsService(log, pg);
|
||||||
const api = createApi(log, pg);
|
const api = createApi(log, pg, discogs);
|
||||||
|
|
||||||
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);
|
|
||||||
// });
|
|
||||||
|
|
||||||
await api.listen();
|
await api.listen();
|
||||||
|
|
||||||
// return getBundles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ model Listing {
|
|||||||
|
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||||
discogs String? @unique
|
|
||||||
name String @default("unknown")
|
name String @default("unknown")
|
||||||
data Json
|
discogs String? @unique
|
||||||
|
data Json?
|
||||||
|
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|||||||
+55
-3
@@ -2,13 +2,14 @@ import express from 'express';
|
|||||||
import http from 'http';
|
import http from 'http';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { groupBy } from 'lodash';
|
import { groupBy } from 'lodash';
|
||||||
|
import Bluebird from 'bluebird';
|
||||||
|
|
||||||
import type Log from 'bunyan';
|
import type Log from 'bunyan';
|
||||||
|
|
||||||
import { Pg } from './pg';
|
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 PORT = 41337;
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -32,7 +33,7 @@ export default function createApi(log: Log, pg: Pg) {
|
|||||||
currency: l.data.original_price.curr_abbr,
|
currency: l.data.original_price.curr_abbr,
|
||||||
condition: l.data.condition,
|
condition: l.data.condition,
|
||||||
uri: l.data.uri,
|
uri: l.data.uri,
|
||||||
user: l.want.user.discogs,
|
user: l.want.user.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const shipping = b[0]?.data.seller.shipping;
|
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<Want, Listing[]>(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() {
|
function listen() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
server.on('error', err => {
|
server.on('error', err => {
|
||||||
@@ -70,6 +89,7 @@ export default function createApi(log: Log, pg: Pg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
app.use(express.json())
|
||||||
|
|
||||||
app.get('/bundles', async (req, res, next) => {
|
app.get('/bundles', async (req, res, next) => {
|
||||||
const bundles = await getBundles();
|
const bundles = await getBundles();
|
||||||
@@ -77,6 +97,38 @@ export default function createApi(log: Log, pg: Pg) {
|
|||||||
res.json(bundles);
|
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 {
|
return {
|
||||||
app,
|
app,
|
||||||
listen,
|
listen,
|
||||||
|
|||||||
+14
-2
@@ -35,13 +35,19 @@ export default function discogs(log: Log, pg: Pg) {
|
|||||||
const user = await pg.userFindName(discogs);
|
const user = await pg.userFindName(discogs);
|
||||||
if (user) return user;
|
if (user) return user;
|
||||||
log.debug('fetching user', discogs);
|
log.debug('fetching user', discogs);
|
||||||
const res = await api.get(`${apiBase}/users/${discogs}`);
|
const { data } = await api.get(`${apiBase}/users/${discogs}`);
|
||||||
return pg.userUpsert(res.data);
|
return pg.userUpsert(data.username, data.username, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function wantlist(user: User): Promise<Want[]> {
|
async function wantlist(user: User): Promise<Want[]> {
|
||||||
const stored = await pg.userWants(user);
|
const stored = await pg.userWants(user);
|
||||||
if (stored.length) return stored;
|
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);
|
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));
|
return Bluebird.mapSeries(wants, async r => pg.wantUpsert(r, user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function release(id: DiscogsRelease): Promise<any> {
|
||||||
|
const { data } = await api.get(`${apiBase}/releases/${id}`);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
async function inventory(user: string) {
|
async function inventory(user: string) {
|
||||||
const res = await api.get(`${apiBase}/users/${user}/inventory`);
|
const res = await api.get(`${apiBase}/users/${user}/inventory`);
|
||||||
return res.data.listings;
|
return res.data.listings;
|
||||||
@@ -91,5 +102,6 @@ export default function discogs(log: Log, pg: Pg) {
|
|||||||
inventory,
|
inventory,
|
||||||
listings,
|
listings,
|
||||||
listing,
|
listing,
|
||||||
|
release,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
+16
-11
@@ -5,7 +5,7 @@ import * as Bluebird from 'bluebird';
|
|||||||
export interface Pg {
|
export interface Pg {
|
||||||
userFindId: (id: UUID) => Promise<User>,
|
userFindId: (id: UUID) => Promise<User>,
|
||||||
userFindName: (name: DiscogsName) => Promise<User>,
|
userFindName: (name: DiscogsName) => Promise<User>,
|
||||||
userUpsert: (user: User) => Promise<User>,
|
userUpsert: (discogs: DiscogsName | null, name: string, data: any) => Promise<User>,
|
||||||
userWants: (user: User) => Promise<Want[]>,
|
userWants: (user: User) => Promise<Want[]>,
|
||||||
|
|
||||||
wantUpsert: (want: Want, user: User) => Promise<Want>,
|
wantUpsert: (want: Want, user: User) => Promise<Want>,
|
||||||
@@ -17,7 +17,7 @@ export interface Pg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function createPg(log: Log, prisma: PrismaClient): 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 }});
|
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 }});
|
return prisma.want.findMany({ where: { userId: user.id }});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function userUpsert(user) {
|
async function userUpsert(discogs: DiscogsName | null, name: string, data: any) {
|
||||||
const data = {
|
const insert = {
|
||||||
discogs: user.username,
|
discogs,
|
||||||
data: user as Prisma.JsonObject,
|
name,
|
||||||
|
data,
|
||||||
};
|
};
|
||||||
|
|
||||||
return prisma.user.upsert({
|
if (discogs) return prisma.user.upsert({
|
||||||
where: {
|
where: {
|
||||||
discogs: user.username,
|
discogs,
|
||||||
},
|
},
|
||||||
update: data,
|
update: insert,
|
||||||
create: data,
|
create: insert,
|
||||||
|
});
|
||||||
|
|
||||||
|
return prisma.user.create({
|
||||||
|
data: { name },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +116,7 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
|
|||||||
select
|
select
|
||||||
seller, count(distinct("wantId")), array_agg(id) as listings
|
seller, count(distinct("wantId")), array_agg(id) as listings
|
||||||
from
|
from
|
||||||
"Listing"
|
listings
|
||||||
group by
|
group by
|
||||||
seller
|
seller
|
||||||
order by
|
order by
|
||||||
|
|||||||
Reference in new issue
Block a user