auth init

This commit is contained in:
ntr committed 2022-08-08 19:51:17 +10:00
1 parent faa2e70e08
commit 413aeedadf
29 files changed
+2854 -649

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
import fs from 'fs/promises';
import axios from 'axios';
import cheerio from 'cheerio';
import Bluebird from 'bluebird';
import type Log from 'bunyan';
import type { PrismaClient, Want, User, Listing } from '@prisma/client';
import { logAxiosError } from './utils';
import { Pg } from './pg';
export default function discogs(log: Log, pg: Pg) {
const TOKEN = 'Discogs token=wRTXuYZGOPsIQgKRGKCAkUkidGtvpSfQgPWkYIpD';
const apiBase = 'https://api.discogs.com'
const discogsBase = 'https://www.discogs.com'
const api = axios.create({
headers: {
'Authorization': TOKEN,
// discogs only returns the first page without a desktop u/a
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0',
},
});
async function handleApiError(e) {
logAxiosError(e);
if (e.response.status === 429) {
throw new Error('rate limited');
}
return null;
}
// async function user(discogs: string) {
// const user = await pg.userFindName(discogs);
// if (user) return user;
// log.debug('fetching user', discogs);
// const { data } = await api.get(`${apiBase}/users/${discogs}`);
// return pg.userUpsert(data.username, data.username, data);
// }
async function wantlist(user: User): Promise<Want[]> {
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);
}
async function wantlistLatest(user: User): Promise<Want[]> {
const { username } = user.data as { username: string };
const { data: { wants, pagination }} = await api.get(`${apiBase}/users/${username}/wants`);
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 search(artist: string, title: string) {
const url = new URL(`${apiBase}/database/search`);
url.searchParams.append('artist', artist);
url.searchParams.append('title', title);
url.searchParams.append('type', 'release');
url.searchParams.append('format', 'vinyl');
const { data: { results } } = await api.get(url.href);
return results;
}
async function inventory(user: string) {
const res = await api.get(`${apiBase}/users/${user}/inventory`);
return res.data.listings;
}
async function listings(want: Want) {
const res = await api.get(`https://www.discogs.com/sell/release/${want.release}?limit=250`);
const $ = cheerio.load(res.data);
const ids = $('.item_description_title[href]')
.map(function getListingId() {
const id = Number.parseInt(this.attribs.href.replace('/sell/item/', ''), 10);
return id;
})
.get();
const unlisted = await pg.listingRmUnlisted(want, ids);
if (unlisted) log.info({ wantId: want.id, unlisted: unlisted }, 'missing listings removed');
return Bluebird.mapSeries(ids, async id => listing(id, want));
}
async function listing(id, want) {
const listing = await pg.listingFind(id);
if (listing) return listing;
try {
log.debug('fetching listing', id);
const res = await api.get(`${apiBase}/marketplace/listings/${id}`);
return pg.listingUpsert(res.data, want);
} catch (e) {
return handleApiError(e);
}
}
return {
// user,
wantlist,
wantlistLatest,
inventory,
listings,
listing,
release,
search,
};
}