You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
4.2 KiB
JavaScript

const superagent = require('superagent');
const LotListing = require('./LotListing')
const brickLinkAgent = superagent.agent();
const htmlParser = require('node-html-parser');
module.exports = {
getInternalPartId(legoPartNumber) {
return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://www.bricklink.com/v2/catalog/catalogitem.page?P=${legoPartNumber}`)
// .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0')
.then((response => {
if(response.statusCode !== 200) throw response.statusCode
const partIdRegex = /idItem:\s+(?<idItem>\d+)/gm;
const matches = partIdRegex.exec(response.text);
resolve(matches.groups?.idItem)
})).catch(error => {
reject(error);
})
})
},
getListings(internalPartId, colorId) {
return new Promise(async (resolve, reject) => {
await new Promise((resolve) => setTimeout(resolve, Math.random() * 500 + 100));
var query = {
itemid: internalPartId,
loc: 'US',
rpp: 100
// cond: 'U'
}
if(colorId){
query.color = colorId
}
brickLinkAgent.get(`https://www.bricklink.com/ajax/clone/catalogifs.ajax`)
.query(query)
// .set('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0')
.set('Accept', 'application/json').then(response => {
if(!response.body.list) {
console.log(response.body, query)
return reject('no list found');
}
resolve(response.body.list.map(l => new LotListing(l)));
}).catch(error => {
console.error('HTTP error from getListings', error)
reject(error);
})
})
},
getListingsByLegoPartNumber(legoPartNumber, colorId){
return module.exports.getInternalPartId(legoPartNumber).then((blPartNumber) => module.exports.getListings(blPartNumber, colorId)).then(listings => {
return listings.map(listing => {
listing.legoPartNumber = legoPartNumber
return listing;
})
})
},
getStoreId(sellerUsername) {
return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://store.bricklink.com/${sellerUsername}`)
.then((response => {
const storeIdRegex = /username:\s+'.+',\s+id:\s+(?<storeId>\d+)/gm;
const matches = storeIdRegex.exec(response.text);
resolve(matches.groups?.storeId)
})).catch(error => {
console.error('HTTP error from getStoreId', error)
reject(error);
})
})
},
getSetInventory(setId) {
return new Promise((resolve, reject) => {
brickLinkAgent.get(`https://www.bricklink.com/catalogItemInv.asp`)
.query({
S: setId
})
.then((response => {
var root = htmlParser.parse(response.text);
const rows = root.querySelectorAll('.IV_ITEM')
const parsed = rows.map(row => {
const partRegex = /\/v2\/catalog\/catalogitem.page\?P=(?<legoPartNumber>.+)&idColor=(?<colorId>\d+)/gm;
const quantityRegex = /<TD ALIGN="RIGHT">\&nbsp;(?<quantity>\d+)/gm
const matches = partRegex.exec(row.innerHTML);
const quantityMatches = quantityRegex.exec(row.innerHTML);
if(!matches) return null;
return {
partNumber: matches.groups?.legoPartNumber,
colorId: parseInt(matches.groups?.colorId),
quantity: parseInt(quantityMatches.groups?.quantity)
}
}).filter(r => r !== null);
resolve(parsed)
})).catch(error => {
console.error('HTTP error from getStoreId', error)
reject(error);
})
})
}
}