Skip to content

Instantly share code, notes, and snippets.

@gullinbursti
Last active October 17, 2023 15:15
Show Gist options
  • Save gullinbursti/fa92002312dfca992fc9d73d08103c6b to your computer and use it in GitHub Desktop.
Save gullinbursti/fa92002312dfca992fc9d73d08103c6b to your computer and use it in GitHub Desktop.
Factory MOPAR Direct
const parseParts = ()=> {
let products = [];
Array.from(document.querySelectorAll('.catalog-products > .catalog-product')).forEach((el, i)=> {
const prodID = el.querySelector('.catalog-product-id a').text;
const prodName = el.querySelector('.product-title a').text;
const description = (el.querySelector('.product-more-info > .catalog-also-known-as:not(:first-child)')) ? el.querySelector('.product-more-info > .catalog-also-known-as:not(:first-child) > .info-row-content').innerHTML.split('<')[0].replace(/^\s*\b(.+)\b\s*$/, '$1').trim() : null;
const notes = (el.querySelector('.product-more-info > .catalog-product-note')) ? el.querySelector('.product-more-info > .catalog-product-note > .info-row-content').innerHTML.replace(/\<button.*$/, '').replace(/\<\/?[a-z0-9]+\>/g, '').trim() : null;
const url = el.querySelector('.product-image-link').href;
const img = el.querySelector('.product-image-link img').src;
const inStock = Boolean((el.querySelector('.cannot-purchase') === null) << 0);
const addBtn = el.querySelector('.product-purchase-button button');
const msrp = (addBtn) ? parseFloat(addBtn.getAttribute('data-msrp')) : -1;
const price = (addBtn) ? parseFloat(addBtn.getAttribute('data-sale-price')) : -1;
const wholesale = (addBtn) ? parseFloat(addBtn.getAttribute('data-price-wholesale')) : -1;
const core = (addBtn) ? parseFloat(addBtn.getAttribute('data-core-charge')) : -1;
//console.log(el);
products.push({
'Part #' : `=HYPERLINK(_|_${url}_|_;_|_${prodID}_|_)`,
// 'Name' : (inStock) ? `=HYPERLINK(_|_${url}_|_;_|_${prodName}_|_)` : prodName,
'Name' : prodName,
// 'Description' : (description || ''),
// 'Notes' : (notes || ''),
'Price' : (price >= 0) ? `$${price.toFixed(2)}` : ''
// 'Image' : `IMAGE(_|_${img})_|_)`
});
});
return (products);
};
const jsonToCSV = (items)=> {
const header = Object.keys(items[0]);
const headerString = header.join(',');
const replacer = (key, value) => value ?? '';
const rowItems = items.map((row) =>
header.map((fieldName) => JSON.stringify(row[fieldName], replacer).replaceAll('_|_', '""')).join(',')
);
return ([headerString, ...rowItems].join('\r\n'));
};
const dloadCSV = (csv, filename)=> {
const blob = new Blob([csv], { type : 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', `${(filename || 'export')}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
const runDate = new Date(Date.now());
const filename = `${document.location.hostname}_${document.location.href.split('/').pop()}_${(runDate.getMonth() < 10) ? '0' : ''}${runDate.getMonth()}-${(runDate.getDate() < 10) ? '0' : ''}${runDate.getDate()}-${runDate.getFullYear()}_${(runDate.getHours() < 10) ? '0' : ''}${runDate.getHours()}${(runDate.getMinutes() < 10) ? '0' : ''}${runDate.getMinutes()}${(runDate.getSeconds() < 10) ? '0' : ''}${runDate.getSeconds()}`;
//console.log('csv', jsonToCSV(parseParts(parseParts())));
dloadCSV(jsonToCSV(parseParts()), filename);
const searchURI = '/search';
const searchKey = 'search_str';
const vinSearch = ($vin)=> {
fetch(`${document.location.origin}${searchURI}?${new URLSearchParams({ searchKey : $vin })}`, {
method : 'GET',
mode : 'cors',
headers : {
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding' : 'gzip, deflate, br',
'Accept-Language' : 'en-US,en;q=0.9',
'Cache-Control' : 'no-cache',
'Pragma' : 'no-cache',
'Referer' : `${document.location.origin}${searchURI}?${searchKey}=${encodeURI($vin)}`,
'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
}).then((response)=> ((response.text()))).then((response)=> {
const htmlDoc = (new DOMParser()).parseFromString(response, 'text/html');
const products = Array.from(htmlDoc.querySelectorAll('.main .page-content .catalog-products > *.catalog-product'));
const titles = products.map((product)=> ((product.querySelector('.catalog-product > .product-details-col > .product-title > a').innerText)));
console.log('titles', [...titles ]);
}).catch((err)=> {
console.log('Failed to fetch results: ', { ...err });
});
};
vinSearch(window.prompt('Enter (partial) VIN', 'JAL'));
const searchURI = '/search';
const vinSearch = ($vin)=> {
fetch(`${document.location.origin}${searchURI}?search_str=${encodeURI($vin)}`, {
method : 'GET',
mode : 'cors',
headers : {
'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Encoding' : 'gzip, deflate, br',
'Accept-Language' : 'en-US,en;q=0.9',
'Cache-Control' : 'no-cache',
'Pragma' : 'no-cache',
'Referer' : `${document.location.origin}${searchURI}?search_str=${encodeURI($vin)}`,
'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
}
}).then((response)=> ((response.text()))).then((response)=> {
const htmlDoc = (new DOMParser()).parseFromString(response, 'text/html');
const products = Array.from(htmlDoc.querySelectorAll('.main .page-content .catalog-products > *.catalog-product'));
const titles = products.map((product)=> ((product.querySelector('.catalog-product > .product-details-col > .product-title > a').innerText)));
console.log('titles', [...titles ]);
}).catch((err)=> {
console.log('Failed to fetch results: ', { ...err });
});
};
vinSearch(window.prompt('Enter (partial) VIN', 'JAL'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment