Greasy Fork is available in English.
9/11/2022, 4:27:46 PM
// ==UserScript==// @name eshop EUR prices with API// @namespace Violentmonkey Scripts// @include https://deathangels.shop*// @include https://www.blue-tomato.com*// @include https://doomer.shop*// @grant GM_getValue// @grant GM_setValue// @grant GM_xmlhttpRequest// @version 3.2// @license MIT// @author KraXen72// @description 9/11/2022, 4:27:46 PM// @icon https://cdn.shopify.com/s/files/1/0569/8407/6311/files/23.png?crop=center&height=32&v=1660122641&width=32// ==/UserScript==function injectCSS(css) {const styleTag = document.createElement("style")styleTag.innerHTML = cssdocument.head.appendChild(styleTag)}function prependText(text, pelem, parent) {const elem = document.createElement("span")elem.textContent = textparent.insertBefore(elem, pelem)}function checkNumber(num) {return typeof num === 'number' && !isNaN(num)}function sameDay(d1, d2) {// console.log("sameday", d1, d2, {year: [d1.getFullYear(), d2.getFullYear()], month: [d1.getUTCMonth(), d2.getUTCMonth()], date: [d1.getUTCDate(), d2.getUTCDate()]})return d1.getFullYear() === d2.getFullYear() &&d1.getMonth() === d2.getMonth() &&d1.getDate() === d2.getDate();}let thisDate = new Date(Date.now())let lastDate = new Date(GM_getValue("lastDate", new Date().setDate(new Date().getDate() - 1)))const defaultPriceRegex = /\d*[,.]*\d{1,}/gilet conversionTableEURto = {}if (!(typeof lastDate.getMonth === 'function')) lastDate = new Date(lastDate)function getStuffFromApi() {console.log("getting stuff from api")const apiKey = GM_getValue("apiKey", false)if (!apiKey) throw "set API key for exchangerate-api.com in values"const req = GM_xmlhttpRequest({url: `https://v6.exchangerate-api.com/v6/${apiKey}/latest/EUR`,method: "GET",responseType: "json",onload: (responseBody) => {const data = JSON.parse(responseBody.responseText)console.log("!!!got api response", thisDate, lastDate, data)GM_setValue("lastDate", thisDate.toDateString())GM_setValue("conversionJSON",data["conversion_rates"])window.location.reload()}})}if (GM_getValue("conversionJSON", false) !== false) {console.log("getvalue", GM_getValue("conversionJSON", false), sameDay(thisDate, lastDate))if (sameDay(thisDate, lastDate)) {conversionTableEURto = GM_getValue("conversionJSON",{})console.log("had cached stuff:", conversionTableEURto)} else {getStuffFromApi()}} else {getStuffFromApi()}// console.log("date sanity check", thisDate, lastDate, sameDay(lastDate, thisDate), GM_getValue("lastDate"))function applyPrice(conversionConstant, initialPrice, element, mode = "normal", parentElem = element.parentElement) {if (initialPrice === null) returnconst eurPrice = (initialPrice / conversionConstant).toFixed(2)// console.log({ eurPrice, initialPrice, conversionConstant})element.title = `${eurPrice}€`element.innerHTML += ` = ${eurPrice}€`}function getPrice(element, regex = defaultPriceRegex, deleteComma = true, debug = false) {const text = element.innerText.trim()let res = text.match(regex)if (res === null) return resif (checkNumber(res)) return resif (Array.isArray(res)) res = res[0]if (typeof res === "string" && res.includes(",")) {if (deleteComma) {res = res.replaceAll(",", "")} else {res = res.replaceAll(",", ".")}}if (debug) console.log("[regex]", text, res);if (!isNaN(parseInt(res))) {if (res.includes(".")) {return parseFloat(res)} else {return parseInt(res)}} else {console.warn(`failed to parse ${res} as a number. it's ${parseInt(res)} on text "${text}"`, element)return res}}if (window.location.hostname === "deathangels.shop") {const prices = [...document.querySelectorAll(".price__regular .price-item.price-item--regular, .cart-item .price.price--end")]prices.forEach(priceElem => {const price = getPrice(priceElem)applyPrice(conversionTableEURto["JPY"], price, priceElem)})} else if (window.location.hostname === "www.blue-tomato.com") {const prices = [... document.querySelectorAll(".productdesc .price")]prices.forEach(priceElem => {// console.log(priceElem, priceElem.children.length)let price = getPrice(priceElem)applyPrice(conversionTableEURto["GBP"], price, priceElem)})if (document.querySelector(".js-price > .c-details-box__price-current") !== null) {console.log("detail view found")const detailHolder =document.querySelector(".js-price > .c-details-box__price-current").parentElementconst callback = (mutationList, observer) => {for (const mutation of mutationList) {if (mutation.type === 'childList') {console.log('mo: childList modification. refreshing', mutation);observer.disconnect();[...document.querySelectorAll(".js-price > .c-details-box__price-current")].forEach(priceElem => {const price = getPrice(priceElem)applyPrice(conversionTableEURto["GBP"], price, priceElem)})}}};const config = { attributes: false, childList: true, subtree: true };const priceObserver = new MutationObserver(callback);priceObserver.observe(detailHolder, config);} else {console.log("no detail view found")}} else if (window.location.hostname === "doomer.shop") {const prices = [...document.querySelectorAll(".price-item.price-item--regular")]prices.forEach(priceElem => {const price = getPrice(priceElem)if (price !== "") {applyPrice(conversionTableEURto["USD"], price, priceElem)}})}