diff --git a/lib/bookPriceFor.js b/lib/bookPriceFor.js index 29c0fe4..6d4b858 100644 --- a/lib/bookPriceFor.js +++ b/lib/bookPriceFor.js @@ -1,4 +1,3 @@ -import currency from "currency.js"; import { bookUrl } from "./bookUrl"; import { extractPriceFrom } from "./extractPriceFrom"; import { getRate } from "./rates"; @@ -22,18 +21,13 @@ export const bookPriceFor = async (country) => { let convertedPrice; if (countryPrice) { + l("found price", countryPrice, url); const rate = await getRate(country.currencyCode); - - l("rate for", country.currencyCode, "is", rate); - - convertedPrice = currency(countryPrice).divide(rate); - - convertedPrice = { - intValue: convertedPrice.intValue, - format: convertedPrice.format(), - }; - - l("converted price for", country.currencyCode, convertedPrice); + convertedPrice = await convertedPrice( + countryPrice, + country.currencyCode, + rate, + ); } const newPrice = { diff --git a/lib/convertPrice.js b/lib/convertPrice.js new file mode 100644 index 0000000..8cace3a --- /dev/null +++ b/lib/convertPrice.js @@ -0,0 +1,46 @@ +import currency from "currency.js"; + +export const convertPrice = async (price, curr, rate) => { + l("rate for", curr, "is", rate); + + let useVedic = false; + + switch (curr) { + case "inr": + case "php": { + useVedic = true; + break; + } + case "jpy": { + break; + } + case "zar": { + price = price.replace(",", "."); + break; + } + case "dkk": { + price = price.replace("kr.", "").replace(",", "."); + break; + } + case "pen": { + price = price.replace("S/.", ""); + break; + } + case "clp": + case "cop": + case "twd": { + break; + } + default: + price = price.replace(/[^\d,.-]/, "").replace(",", "."); + } + + const convertedPrice = currency(price, { useVedic }).divide(rate); + + l("converted price for", curr, convertedPrice); + + return { + intValue: convertedPrice.intValue, + formatted: convertedPrice.format(), + }; +}; diff --git a/lib/countries.js b/lib/countries.js index f08eb7e..5f9836b 100644 --- a/lib/countries.js +++ b/lib/countries.js @@ -6,44 +6,44 @@ export const COUNTRIES = [ { countryCode: "za", currencyCode: "zar" }, { countryCode: "au", currencyCode: "aud" }, { countryCode: "hk", currencyCode: "hkd" }, - { countryCode: "jp", currencyCode: "JPY" }, - // { countryCode: "my", currencyCode: "EUR" }, - // { countryCode: "nz", currencyCode: "EUR" }, - // { countryCode: "ph", currencyCode: "EUR" }, - // { countryCode: "sg", currencyCode: "EUR" }, - // { countryCode: "tw", currencyCode: "EUR" }, - // { countryCode: "th", currencyCode: "EUR" }, - // { countryCode: "at", currencyCode: "EUR" }, - // { countryCode: "be", currencyCode: "EUR" }, - // { countryCode: "cy", currencyCode: "EUR" }, - // { countryCode: "cz", currencyCode: "EUR" }, - // { countryCode: "dk", currencyCode: "EUR" }, - // { countryCode: "ee", currencyCode: "EUR" }, - // { countryCode: "fi", currencyCode: "EUR" }, - // { countryCode: "fr", currencyCode: "EUR" }, - // { countryCode: "de", currencyCode: "EUR" }, - // { countryCode: "gr", currencyCode: "EUR" }, - // { countryCode: "ie", currencyCode: "EUR" }, - // { countryCode: "it", currencyCode: "EUR" }, - // { countryCode: "lt", currencyCode: "EUR" }, - // { countryCode: "lu", currencyCode: "EUR" }, - // { countryCode: "mt", currencyCode: "EUR" }, - // { countryCode: "nl", currencyCode: "EUR" }, - // { countryCode: "no", currencyCode: "EUR" }, - // { countryCode: "pl", currencyCode: "EUR" }, - // { countryCode: "pt", currencyCode: "EUR" }, - // { countryCode: "ro", currencyCode: "EUR" }, - // { countryCode: "sk", currencyCode: "EUR" }, - // { countryCode: "si", currencyCode: "EUR" }, - // { countryCode: "es", currencyCode: "EUR" }, - // { countryCode: "se", currencyCode: "EUR" }, - // { countryCode: "ch", currencyCode: "EUR" }, - // { countryCode: "tr", currencyCode: "EUR" }, - // { countryCode: "gb", currencyCode: "EUR" }, - // { countryCode: "ar", currencyCode: "EUR" }, - // { countryCode: "br", currencyCode: "EUR" }, - // { countryCode: "cl", currencyCode: "EUR" }, - // { countryCode: "co", currencyCode: "EUR" }, - // { countryCode: "mx", currencyCode: "EUR" }, - // { countryCode: "pe", currencyCode: "EUR" }, + { countryCode: "jp", currencyCode: "jpy" }, + { countryCode: "my", currencyCode: "myr" }, + { countryCode: "nz", currencyCode: "nzd" }, + { countryCode: "ph", currencyCode: "php" }, + { countryCode: "sg", currencyCode: "sgd" }, + { countryCode: "tw", currencyCode: "twd" }, + { countryCode: "th", currencyCode: "usd" }, + { countryCode: "at", currencyCode: "eur" }, + { countryCode: "be", currencyCode: "eur" }, + { countryCode: "cy", currencyCode: "eur" }, + { countryCode: "cz", currencyCode: "czk" }, + { countryCode: "dk", currencyCode: "dkk" }, + { countryCode: "ee", currencyCode: "eur" }, + { countryCode: "fi", currencyCode: "eur" }, + { countryCode: "fr", currencyCode: "eur" }, + { countryCode: "de", currencyCode: "eur" }, + { countryCode: "gr", currencyCode: "eur" }, + { countryCode: "ie", currencyCode: "eur" }, + { countryCode: "it", currencyCode: "eur" }, + { countryCode: "lt", currencyCode: "eur" }, + { countryCode: "lu", currencyCode: "eur" }, + { countryCode: "mt", currencyCode: "eur" }, + { countryCode: "nl", currencyCode: "eur" }, + { countryCode: "no", currencyCode: "nok" }, + { countryCode: "pl", currencyCode: "pln" }, + { countryCode: "pt", currencyCode: "eur" }, + { countryCode: "ro", currencyCode: "ron" }, + { countryCode: "sk", currencyCode: "eur" }, + { countryCode: "si", currencyCode: "eur" }, + { countryCode: "es", currencyCode: "eur" }, + { countryCode: "se", currencyCode: "sek" }, + { countryCode: "ch", currencyCode: "chf" }, + { countryCode: "tr", currencyCode: "try" }, + { countryCode: "gb", currencyCode: "gbp" }, + { countryCode: "ar", currencyCode: "usd" }, + { countryCode: "br", currencyCode: "brl" }, + { countryCode: "cl", currencyCode: "clp" }, + { countryCode: "co", currencyCode: "cop" }, + { countryCode: "mx", currencyCode: "mxn" }, + { countryCode: "pe", currencyCode: "pen" }, ]; diff --git a/lib/extractPriceFrom.js b/lib/extractPriceFrom.js index 5a4196e..4ca55d6 100644 --- a/lib/extractPriceFrom.js +++ b/lib/extractPriceFrom.js @@ -40,7 +40,11 @@ export const extractPriceFrom = async (url) => { l("starting observing price on", url); - return await observePriceOnPage(iframe.contentDocument.body, url); + const price = await observePriceOnPage(iframe.contentDocument.body, url); + + document.body.removeChild(iframe); + + return price; } catch (e) { l("getPriceForCountry", e, url); return ""; diff --git a/lib/index.js b/lib/index.js index 0c6e442..7e43481 100644 --- a/lib/index.js +++ b/lib/index.js @@ -5,28 +5,26 @@ import { bookPriceFor } from "./bookPriceFor"; /* TODO: -- not all currencies parsed as expected: - https://www.kobo.com/za/en/ebook/nine-minds - ZA: R300,60 -> $1,674.58 - JP: 2,246 円 -> $Infinity - publish to stores -- check in chrome - more durable source for rates - React for UI -- More informative, show loading progress +- More informative UI, show loading progress - clear stale cache +- readme how to use and debug +- configuration (purge cache, change base currency) */ const createPricesContainer = () => { - const pricingActionContainer = document - .querySelector(".primary-right-container") - .querySelector(".pricing-details") - .querySelector(".action-container"); + const pricingActionContainer = document.querySelector( + ".primary-right-container", + ); const container = document.createElement("div"); container.style.display = "flex"; container.style.flexDirection = "column"; + container.style.border = "1px solid black"; + container.style.padding = "10px"; return pricingActionContainer.parentNode.insertBefore( container, @@ -34,7 +32,7 @@ const createPricesContainer = () => { ); }; -const getCountriesPrice = async () => { +const getPrices = async () => { const prices = []; for (const country of COUNTRIES) { // intentionally blocking execution @@ -46,14 +44,6 @@ const getCountriesPrice = async () => { return prices; }; -const formatPrice = (price) => { - const convertedPrice = price?.convertedPrice?.format ?? "NO PRICE"; - - const countryPrice = price?.countryPrice ?? "NO PRICE"; - - return `${price.countryCode.toUpperCase()}: ${countryPrice} -> ${convertedPrice}`; -}; - const sortPrices = (prices) => prices.sort( (a, b) => @@ -68,19 +58,28 @@ const showPrices = (container, prices) => { link.href = price.url; link.target = "_blank"; link.style.marginBottom = "5px"; - link.innerText = formatPrice(price); + link.style.display = "flex"; + link.style.justifyContent = "space-between"; + const oldPrice = document.createElement("p"); + oldPrice.innerText = `${price.countryCode.toUpperCase()}: ${price?.countryPrice || "NO PRICE"}`; + const newPrice = document.createElement("p"); + newPrice.innerText = price?.convertedPrice?.formatted ?? "NO PRICE"; + newPrice.style.fontWeight = "bold"; + link.appendChild(oldPrice); + link.appendChild(newPrice); container.appendChild(link); }); }; + async function main() { + const container = createPricesContainer(); + + container.innerText = "LOADING PRICES..."; + try { initCache(); - const container = createPricesContainer(); - - container.innerText = "LOADING PRICES..."; - - const countriesPrice = await getCountriesPrice(); + const countriesPrice = await getPrices(); l("country prices", countriesPrice); @@ -91,6 +90,7 @@ async function main() { showPrices(container, countriesPrice); } catch (e) { l("error", e); + container.innerText = "FAILED TO LOAD PRICES. CHECK CONSOLE FOR MORE INFO"; } finally { l("done"); } diff --git a/lib/rates.js b/lib/rates.js index f862684..cc6ab19 100644 --- a/lib/rates.js +++ b/lib/rates.js @@ -4,12 +4,10 @@ import { getRates, cacheRates } from "./cache"; export const baseCurrency = "usd"; export const loadCurrencyRates = async () => { - l("loading currency rates"); - try { - const res = await fetch( - `https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/${baseCurrency}.json`, - ); + const url = `https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/${baseCurrency}.json`; + l("loading currency rates", url); + const res = await fetch(url); return await res.json(); } catch (e) { l("loadCurrencyRates", e);