koboprice/lib/index.js

104 lines
2.4 KiB
JavaScript

import "./logger";
import { COUNTRIES } from "./countries";
import { initCache } from "./cache";
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
- clear stale cache
*/
const createPricesContainer = () => {
const pricingActionContainer = document
.querySelector(".primary-right-container")
.querySelector(".pricing-details")
.querySelector(".action-container");
const container = document.createElement("div");
container.style.display = "flex";
container.style.flexDirection = "column";
return pricingActionContainer.parentNode.insertBefore(
container,
pricingActionContainer,
);
};
const getCountriesPrice = async () => {
const prices = [];
for (const country of COUNTRIES) {
// intentionally blocking execution
// to resolve sequentially.
// It should prevent DOS and triggering captcha
prices.push(await bookPriceFor(country));
}
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) =>
(a?.convertedPrice?.intValue || Infinity) -
(b?.convertedPrice?.intValue || Infinity),
);
const showPrices = (container, prices) => {
container.innerText = null;
prices.forEach((price) => {
const link = document.createElement("a");
link.href = price.url;
link.target = "_blank";
link.style.marginBottom = "5px";
link.innerText = formatPrice(price);
container.appendChild(link);
});
};
async function main() {
try {
initCache();
const container = createPricesContainer();
container.innerText = "LOADING PRICES...";
const countriesPrice = await getCountriesPrice();
l("country prices", countriesPrice);
sortPrices(countriesPrice);
l("sorted prices", countriesPrice);
showPrices(container, countriesPrice);
} catch (e) {
l("error", e);
} finally {
l("done");
}
}
l("starting...");
window.onload = () => {
l("page is fully loaded");
void main();
};