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+(?\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+(?\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=(?.+)&idColor=(?\d+)/gm; const quantityRegex = /\ (?\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); }) }) } }