From 5c65236f6c2217781fdf29234b993c40b441177d Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 12 Jun 2023 13:08:51 +0200 Subject: [PATCH] Spar Slovenia. --- site/model/stores.js | 6 +++ site/utils.js | 6 +++ site/views/items-list.js | 2 +- stores/index.js | 1 + stores/spar-si.js | 79 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 stores/spar-si.js diff --git a/site/model/stores.js b/site/model/stores.js index 99e2a6c..2263be5 100644 --- a/site/model/stores.js +++ b/site/model/stores.js @@ -61,6 +61,12 @@ exports.stores = { color: "stone", getUrl: (item) => `https://shop.rewe.de/p/${item.name.toLowerCase().replace(allSpacesRegex, "-")}/${item.id}`, }, + sparSi: { + name: "Spar SI", + budgetBrands: ["s-budget"], + color: "green", + getUrl: (item) => `https://www.spar.si/online/${item.url}`, + }, }; exports.STORE_KEYS = Object.keys(exports.stores); diff --git a/site/utils.js b/site/utils.js index 7555f15..07c0c50 100644 --- a/site/utils.js +++ b/site/utils.js @@ -59,6 +59,12 @@ const stores = { color: "stone", getUrl: (item) => `https://shop.rewe.de/p/${item.name.toLowerCase().replace(/ /g, "-")}/${item.id}`, }, + sparSi: { + name: "Spar SI", + budgetBrands: ["s-budget"], + color: "green", + getUrl: (item) => `https://www.spar.si/online/${item.url}`, + }, }; const STORE_KEYS = Object.keys(stores); diff --git a/site/views/items-list.js b/site/views/items-list.js index c815bd7..d13a578 100644 --- a/site/views/items-list.js +++ b/site/views/items-list.js @@ -281,7 +281,7 @@ class ItemsList extends View { render() { const start = performance.now(); const elements = this.elements; - if (this.model.filteredItems.length != 0 && this.model.filteredItems.length <= (isMobile() ? 200 : 1000)) { + if (this.model.filteredItems.length != 0 && this.model.filteredItems.length <= (isMobile() ? 200 : 1500)) { elements.nameSimilarity.removeAttribute("disabled"); } else { elements.nameSimilarity.setAttribute("disabled", "true"); diff --git a/stores/index.js b/stores/index.js index a1c4b3e..7d705b4 100644 --- a/stores/index.js +++ b/stores/index.js @@ -5,6 +5,7 @@ exports.hofer = require("./hofer"); exports.lidl = require("./lidl"); exports.mpreis = require("./mpreis"); exports.spar = require("./spar"); +exports.sparSi = require("./spar-si"); exports.unimarkt = require("./unimarkt"); exports.reweDe = require("./rewe-de"); exports.penny = require("./penny"); diff --git a/stores/spar-si.js b/stores/spar-si.js new file mode 100644 index 0000000..c89aaef --- /dev/null +++ b/stores/spar-si.js @@ -0,0 +1,79 @@ +const axios = require("axios"); +const utils = require("./utils"); +const HITS = Math.floor(30000 + Math.random() * 2000); + +const units = { + "100ml": { unit: "ml", factor: 100 }, + "500ml": { unit: "ml", factor: 100 }, + "100g": { unit: "g", factor: 100 }, +}; + +exports.getCanonical = function (item, today) { + let price, unit, quantity; + if (item.masterValues["quantity-selector"]) { + const [str_price, str_unit] = item.masterValues["price-per-unit"].split("/"); + price = parseFloat(str_price.replace("€", "")); + } else { + price = item.masterValues.price; + } + let description = item.masterValues["short-description-3"] ?? item.masterValues["short-description-2"]; + if (!description || description.length == 0) { + description = (item.masterValues["short-description"] ?? item.masterValues.name).toLowerCase(); + if (description.endsWith("per kg")) [quantity, unit] = [1, "kg"]; + else if (description.endsWith("im topf")) [quantity, unit] = [1, "kg"]; + else [quantity, unit] = [1, "stk."]; + } else { + const s = description.replace(" EINWEG", "").replace(" MEHRWEG", "").replace("per kg", "1 kg").trim().replace(".", ""); + const q = utils.parseUnitAndQuantityAtEnd(s); + quantity = q[0]; + unit = q[1]; + } + + let fallback; + if (item.masterValues["price-per-unit"]) { + let [unitPrice, unit_] = item.masterValues["price-per-unit"].split("/"); + unitPrice = parseFloat(unitPrice.replace("€", "")); + fallback = { + quantity: parseFloat((price / unitPrice).toFixed(3)), + unit: unit_.toLowerCase(), + }; + } else { + // Needed for Dossier data + fallback = { + quantity: 1, + unit: "kg", + }; + } + + const isWeighted = item.masterValues["item-type"] === "WeightProduct"; + if (isWeighted) { + unit = fallback.unit; + quantity = fallback.quantity; + } + + return utils.convertUnit( + { + id: item.masterValues["code-internal"], + sparId: item.masterValues["product-number"], + name: item.masterValues.title + " " + (item.masterValues["short-description"] ?? item.masterValues.name), + price, + priceHistory: [{ date: today, price }], + unit, + quantity, + isWeighted, + bio: item.masterValues.biolevel === "Bio", + url: item.masterValues.url, + }, + units, + "sparSi", + fallback + ); +}; + +exports.fetchData = async function () { + const SPAR_SEARCH = `https://search-spar.spar-ics.com/fact-finder/rest/v4/search/products_lmos_si?query=*&q=*&page=1&hitsPerPage=${HITS}`; + const rawItems = (await axios.get(SPAR_SEARCH)).data.hits; + return rawItems?.hits || rawItems; +}; + +exports.urlBase = "https://www.spar.si/online";