koboprice/lib/index.js

105 lines
2.6 KiB
JavaScript
Raw Normal View History

2024-07-14 22:36:08 +03:00
import "./logger";
2024-07-14 16:49:40 +03:00
import { COUNTRIES } from "./countries";
2024-07-14 22:36:08 +03:00
import { initCache } from "./cache";
import { bookPriceFor } from "./bookPriceFor";
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
/*
TODO:
- publish to stores
- more durable source for rates
- React for UI
2024-07-15 14:32:15 +03:00
- More informative UI, show loading progress
2024-07-14 22:36:08 +03:00
- clear stale cache
2024-07-15 14:32:15 +03:00
- readme how to use and debug
- configuration (purge cache, change base currency)
2024-07-14 22:36:08 +03:00
*/
const createPricesContainer = () => {
2024-07-15 14:32:15 +03:00
const pricingActionContainer = document.querySelector(
".primary-right-container",
);
2024-07-14 22:36:08 +03:00
const container = document.createElement("div");
container.style.display = "flex";
container.style.flexDirection = "column";
2024-07-15 14:32:15 +03:00
container.style.border = "1px solid black";
container.style.padding = "10px";
2024-07-14 22:36:08 +03:00
return pricingActionContainer.parentNode.insertBefore(
container,
pricingActionContainer,
);
};
2024-07-15 14:32:15 +03:00
const getPrices = async () => {
2024-07-14 22:36:08 +03:00
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 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";
2024-07-15 14:32:15 +03:00
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);
2024-07-14 22:36:08 +03:00
container.appendChild(link);
});
};
2024-07-15 14:32:15 +03:00
2024-07-14 16:49:40 +03:00
async function main() {
2024-07-15 14:32:15 +03:00
const container = createPricesContainer();
2024-07-14 22:36:08 +03:00
2024-07-15 14:32:15 +03:00
container.innerText = "LOADING PRICES...";
2024-07-14 22:36:08 +03:00
2024-07-15 14:32:15 +03:00
try {
initCache();
2024-07-14 22:36:08 +03:00
2024-07-15 14:32:15 +03:00
const countriesPrice = await getPrices();
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
l("country prices", countriesPrice);
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
sortPrices(countriesPrice);
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
l("sorted prices", countriesPrice);
2024-07-14 16:49:40 +03:00
2024-07-14 22:36:08 +03:00
showPrices(container, countriesPrice);
2024-07-14 16:49:40 +03:00
} catch (e) {
l("error", e);
2024-07-15 14:32:15 +03:00
container.innerText = "FAILED TO LOAD PRICES. CHECK CONSOLE FOR MORE INFO";
2024-07-14 16:49:40 +03:00
} finally {
l("done");
}
}
l("starting...");
window.onload = () => {
l("page is fully loaded");
void main();
};