[feat] price history
This commit is contained in:
97
scripts/preload-pricehistory.ts
Normal file
97
scripts/preload-pricehistory.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import chalk from 'chalk';
|
||||
import { db, ClosePool } from '../src/db/index.ts';
|
||||
import { sql } from 'drizzle-orm';
|
||||
import { skus, priceHistory } from '../src/db/schema.ts';
|
||||
import { toSnakeCase } from 'drizzle-orm/casing';
|
||||
|
||||
|
||||
const sleep = (ms: number) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36'
|
||||
}
|
||||
|
||||
const GetHistory = async (productId:number) => {
|
||||
|
||||
const monthResponse = await fetch(`https://infinite-api.tcgplayer.com/price/history/283926/detailed?range=month`, { headers: headers });
|
||||
if (!monthResponse.ok) {
|
||||
console.error('Error fetching month data:', monthResponse.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const monthData = await monthResponse.json();
|
||||
|
||||
const quarterResponse = await fetch(`https://infinite-api.tcgplayer.com/price/history/${productId}/detailed?range=quarter`, { headers: headers });
|
||||
if (!quarterResponse.ok) {
|
||||
console.error('Error fetching quarter data:', quarterResponse.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const quarterData = await quarterResponse.json();
|
||||
|
||||
const annualResponse = await fetch(`https://infinite-api.tcgplayer.com/price/history/${productId}/detailed?range=annual`, { headers: headers });
|
||||
if (!annualResponse.ok) {
|
||||
console.error('Error fetching annual data:', annualResponse.statusText);
|
||||
process.exit(1);
|
||||
}
|
||||
const annualData = await annualResponse.json();
|
||||
|
||||
let skuCount = 0;
|
||||
let priceCount = 0;
|
||||
for (const annual of annualData.result) {
|
||||
const quarter = quarterData.result.find((r:any) => r.skuId == annual.skuId);
|
||||
const month = monthData.result.find((r:any) => r.skuId == annual.skuId);
|
||||
|
||||
const allPrices = [
|
||||
...annual?.buckets?.map((r:any) => { return { skuId:Number(annual.skuId), calculatedAt:r.bucketStartDate, marketPrice:Number(r.marketPrice) }; }) || [],
|
||||
...quarter?.buckets?.map((r:any) => { return { skuId:Number(annual.skuId), calculatedAt:r.bucketStartDate, marketPrice:Number(r.marketPrice) }; }) || [],
|
||||
...month?.buckets?.map((r:any) => { return { skuId:Number(annual.skuId), calculatedAt:r.bucketStartDate, marketPrice:Number(r.marketPrice) }; }) || []
|
||||
].sort((a:any,b:any) => { if(a.calculatedAt<b.calculatedAt) return -1; if(a.calculatedAt>b.calculatedAt) return 1; return 0; });;
|
||||
|
||||
|
||||
const priceUpdates = allPrices.reduce((accumulator:any[],currentItem:any) => {
|
||||
if (accumulator.length === 0 || (accumulator[accumulator.length-1].marketPrice !== currentItem.marketPrice && accumulator[accumulator.length-1].calculatedAt != currentItem.calculatedAt)) {
|
||||
accumulator.push(currentItem);
|
||||
}
|
||||
return accumulator;
|
||||
},[]);
|
||||
|
||||
skuCount++;
|
||||
priceCount += priceUpdates.length;
|
||||
console.log(chalk.gray(`\tSkuId: ${annual.skuId} with ${priceUpdates.length} updates`));
|
||||
|
||||
// if (skuCount === 1) console.log(priceUpdates);
|
||||
|
||||
await db.insert(priceHistory).values(priceUpdates).onConflictDoUpdate({
|
||||
target: [priceHistory.skuId, priceHistory.calculatedAt ],
|
||||
set: {
|
||||
marketPrice: sql.raw(`excluded.${toSnakeCase(skus.marketPrice.name)}`),
|
||||
},
|
||||
}).returning();
|
||||
|
||||
}
|
||||
|
||||
return { skuCount:skuCount, priceCount:priceCount };
|
||||
}
|
||||
|
||||
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
const productIds = await db.query.tcgcards.findMany({ columns: { productId: true }});
|
||||
const total = productIds.length;
|
||||
let count = 0;
|
||||
for (const product of productIds) {
|
||||
count++;
|
||||
const productId = product.productId;
|
||||
console.log(chalk.blue(`ProductId: ${productId} (${count}/${total})`));
|
||||
const results = await GetHistory(productId);
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
await ClosePool();
|
||||
const end = Date.now();
|
||||
const duration = (end - start) / 1000;
|
||||
console.log(chalk.green(`Price history preloaded in ${duration.toFixed(2)} seconds.`));
|
||||
|
||||
export {};
|
||||
Reference in New Issue
Block a user