您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Remove obfuscation around TCG Player Sales Data
当前为
// ==UserScript==
// @name TCG Player Sales Display Data
// @namespace https://www.tcgplayer.com/
// @version 0.43
// @description Remove obfuscation around TCG Player Sales Data
// @author Peter Creutzberger
// @match https://www.tcgplayer.com/product/*
// @icon https://www.tcgplayer.com/favicon.ico
// @grant none
// @downloadURL https://update.greasyfork.org/scripts/427950/TCG%20Player%20Sales%20Display%20Data.user.js
// @updateURL https://update.greasyfork.org/scripts/427950/TCG%20Player%20Sales%20Display%20Data.meta.js
// ==/UserScript==
(function() {
'use strict';
writeDataRequestButton();
const addCondition = () => ({
totalSpend: 0,
totalQtySold: 0,
totalOrders:0,
historicSalesData: {daysAgo:{}},
orderQtyOverFour: 0,
avgQtyPerOrder: function(totalQtySold,totalOrders ) {
return (totalQtySold / totalOrders) > 0 ? (totalQtySold / totalOrders).toFixed(2) : 0;
},
marketPriceByOrder: function(totalSpend, totalOrders) {
return (totalSpend / totalOrders).toFixed(2);
}
});
const cleanPriceValue = (price) => +price.replace(/[^0-9.]/g,'');
const strToInt = (str) => +str;
const shapeSalesData = (salesData) => salesData.length === 4 ? {date: salesData[0].innerText, condition: salesData[1].innerText, quantity: salesData[2].innerText, price: salesData[3].innerText} :
{date: salesData[0].innerText, condition: `${salesData[2].innerText} with Photo`, quantity: salesData[3].innerText, price: salesData[4].innerText};
const checkSaleDate = (salesArray, saleDate, price) => {
if (!salesArray.earliestSaleDateData || !salesArray.latestSaleDateData) { return {earliestSaleDateData: {date: saleDate, price: price}, latestSaleDateData: {date: saleDate, price: price}}; }
const dateFromSaleDate = new Date(saleDate).getTime();
const dateFromEarliestSaleDate = new Date(salesArray.earliestSaleDateData.date).getTime();
if (dateFromSaleDate < dateFromEarliestSaleDate || dateFromSaleDate === dateFromEarliestSaleDate) { return Object.assign(salesArray, {earliestSaleDateData: {date: saleDate, price: price}}); }
const dateFromLatestSaleDate = new Date(salesArray.latestSaleDateData.date).getTime();
if (dateFromSaleDate > dateFromLatestSaleDate || dateFromSaleDate === dateFromLatestSaleDate) { return Object.assign(salesArray, {latestSaleDateData: {date: saleDate, price: price}}); }
}
const checkOrderQty = (salesArray, date, qty, price) => { if ( !salesArray.largestQtySold || salesArray.largestQtySold.qty < qty) { return {largestQtySold: {date: date, qty: qty, price: price}}; } }
const historicDataSetting = (salesArray, saleDate, dateDiff, price, qty) => {
if (!salesArray.historicSalesData.daysAgo || !salesArray.historicSalesData.daysAgo[dateDiff]) { return {totalSpend: price, totalQtySold: qty, totalOrders: 1, saleDate: saleDate}; }
const historicSalesDataStatus = salesArray.historicSalesData.daysAgo[dateDiff];
return {totalSpend: historicSalesDataStatus.totalSpend += price, totalQtySold: historicSalesDataStatus.totalQtySold += qty, totalOrders: historicSalesDataStatus.totalOrders += 1, saleDate: saleDate};
}
const updateSalesTotals = (salesArray, price, qty) => {
salesArray.totalSpend += (price * qty);
salesArray.totalQtySold += qty;
salesArray.totalOrders += 1;
salesArray.orderQtyOverFour += qty < 4 ? 0 : 1
}
// moved this to its own function as it appears the TCGP ui is updating and this conditional check will cover the check
const getModalDisplayLength = () => {
const modalLength = Array.from(document.getElementsByClassName("is-modal")).length;
return modalLength > 2 ? modalLength - 2 : modalLength - 1;
}
const gatherSalesData = () => {
const salesByCondition = {};
const modalDisplayLength = getModalDisplayLength(); //Array.from(document.getElementsByClassName("is-modal")).length -= 2; //1;
const historicDateArr = setHistoricDateArr(daysToLookBack());
Array.from(document.getElementsByClassName("is-modal")[modalDisplayLength].children).forEach( (children, index) => {
const listOfSales = Array.from(document.getElementsByClassName("is-modal")[modalDisplayLength].children);
if (listOfSales[index]?.children[1]) {
const reshapedSalesData = shapeSalesData( Array.from(listOfSales[index].children) );
const currentCondition = reshapedSalesData.condition;
if ( !Object.keys(salesByCondition).includes(currentCondition) ) { salesByCondition[currentCondition] = addCondition(); }
const cleanPrice = cleanPriceValue(reshapedSalesData.price);
Object.assign(salesByCondition[currentCondition],
checkOrderQty(salesByCondition[currentCondition], reshapedSalesData.date, strToInt(reshapedSalesData.quantity), cleanPrice),
checkSaleDate(salesByCondition[currentCondition], reshapedSalesData.date, cleanPrice)
);
updateSalesTotals(salesByCondition[currentCondition], cleanPrice, strToInt(reshapedSalesData.quantity));
const saleDateDiff = historicDateArr.includes(reshapedSalesData.date) ? getSaleDateDiff(todaysDate, reshapedSalesData.date) : -1;
if ( saleDateDiff > -1 ) {
salesByCondition[currentCondition].historicSalesData.daysAgo[saleDateDiff] = historicDataSetting(salesByCondition[currentCondition], reshapedSalesData.date, saleDateDiff, cleanPrice, strToInt(reshapedSalesData.quantity));
}
}
});
return salesByCondition;
}
const adjustSalesDataDivHeight = (div, timesToAdjustHeight) => (parseInt(div.style.height.replace(/[^0-9]/g,'')) + 115 * timesToAdjustHeight) + "px";
const writeSalesDataContainer = () => {
const div = document.createElement('div');
const setBottom = document.getElementsByClassName("_hj_feedback_container")[0] ? 'bottom:100px' : 'bottom:0';
div.innerHTML = (`
`);
document.body.prepend(div);
}
const displaySalesData = (salesByCondition) => {
const div = document.getElementsByClassName('salesDataDisplay')[0];
const qtyInViewByCondition = getQtyInViewByCondition();
const totalQtyInView = getTotalQtyInView(qtyInViewByCondition);
div.innerHTML += `Total copies in view: ${totalQtyInView}
\
Condition breakout:
${buildQtyInViewDisplay(qtyInViewByCondition)}
`;
salesByCondition.forEach(cardConditionData => {
const cardDisplayData = buildSalesDataDisplay(cardConditionData[0], cardConditionData[1]);
div.innerHTML += cardDisplayData.cardDisplayData;
div.style.height = adjustSalesDataDivHeight(div, cardDisplayData.timesToAdjustHeight);
});
}
const buildSalesDataDisplay = (cardCondition, cardConditionData) => {
let heightAdjustmentCount = 1;
let cardDisplayString = `
`;
return {cardDisplayData: cardDisplayString, timesToAdjustHeight: heightAdjustmentCount};
}
const decorateSalesHistoryHeader = (clickCount = 0) => {
const fontColor = '#fa7ad0';
const backgroundColor = '#7afaa4';
document.getElementsByClassName('modal__title')[0].children[0].innerHTML = `