heissepreise/stores/hofer.js
Mario Zechner effcb81c23 Fix Hofer.
2023-10-17 01:18:27 +02:00

135 lines
4.6 KiB
JavaScript

const fs = require("fs");
const path = require("path");
const axios = require("axios");
const utils = require("./utils");
const analysis = require("../analysis");
const units = {
"": { unit: "stk", factor: 1 },
gg: { unit: "g", factor: 1 },
er: { unit: "stk", factor: 1 },
teebeutel: { unit: "stk", factor: 1 },
};
exports.getCanonical = function (item, today) {
// try to read quantity and unit from product name
const name = item.productName;
let [quantity, unit] = utils.parseUnitAndQuantityAtEnd(name);
return utils.convertUnit(
{
id: item.productID,
name,
// description: "", not available
price: item.price,
priceHistory: [{ date: today, price: item.price }],
isWeighted: item.isBulk,
unit: !unit ? item.unitType : unit,
quantity: !quantity ? item.unit : quantity,
bio: item.isBio,
url: `${item.categorySEOName}/${item.sEOName}`,
},
units,
"hofer",
{
quantity: item.unit,
unit: item.unitType,
}
);
};
const HOFER_BASE_URL = `https://shopservice.roksh.at`;
const CATEGORIES = HOFER_BASE_URL + `/category/GetFullCategoryList/`;
const CONFIG = { headers: { authorization: null } };
const TOKEN_DATA = {
OwnWebshopProviderCode: "",
SetUserSelectedShopsOnFirstSiteLoad: true,
RedirectToDashboardNeeded: false,
ShopsSelectedForRoot: "hofer",
BrandProviderSelectedForRoot: null,
UserSelectedShops: [],
};
const ITEMS = HOFER_BASE_URL + `/productlist/CategoryProductList`;
exports.fetchData = async function () {
const { subCategories } = await exports.getCategories();
let hoferItems = [];
for (let subCategory of subCategories) {
let categoryData = (await axios.get(`${ITEMS}?progId=${subCategory.ProgID}&firstLoadProductListResultNum=4&listResultProductNum=24`, CONFIG))
.data;
const numPages = categoryData.ProductListResults[0].ListContext.TotalPages;
for (let iPage = 1; iPage <= numPages; iPage++) {
let items = (
await axios.post(`${HOFER_BASE_URL}/productlist/GetProductList`, { CategoryProgId: subCategory.ProgID, Page: iPage }, CONFIG)
).data;
hoferItems = hoferItems.concat(items.ProductList);
}
}
return hoferItems;
};
exports.getCategories = async () => {
const token = (
await axios.post("https://shopservice.roksh.at/session/configure", TOKEN_DATA, {
headers: { Accept: "application/json", "Content-Type": "application/json" },
})
).headers["jwt-auth"];
CONFIG.headers.authorization = "Bearer " + token;
// concat all subcategories (categories.[i].ChildList)
const categories = (await axios.post(CATEGORIES, {}, CONFIG)).data;
const subCategories = categories.reduce((acc, category) => acc.concat(category.ChildList), []);
return { categories, subCategories };
};
exports.urlBase = "https://www.roksh.at/hofer/produkte/";
exports.initializeCategoryMapping = async (rawItems) => {
rawItems = rawItems ?? (await exports.fetchData());
const rawCategories = (await exports.getCategories()).categories;
const lookup = {};
const processCategory = (category) => {
lookup[category.ProgID] = {
id: category.ProgID,
description: category.CategoryName,
url: "https://www.roksh.at/" + category.Url,
code: null,
};
for (const child of category.ChildList) {
processCategory(child);
}
};
for (const category of rawCategories) {
processCategory(category);
}
for (const item of rawItems) {
if (!lookup[item.CategorySEOName]) {
// console.log(`Couldn't find category '${item.CategorySEOName}' for Hofer product ${item.ProductName}`);
lookup[item.CategorySEOName] = {
id: item.CategorySEOName,
url: "https://www.roksh.at/hofer/angebot/" + item.CategorySEOName,
code: "",
};
} else {
const category = lookup[item.CategorySEOName];
}
}
let categories = [];
Object.keys(lookup).forEach((key) => categories.push(lookup[key]));
categories = utils.mergeAndSaveCategories("hofer", categories);
exports.categoryLookup = {};
for (const category of categories) {
exports.categoryLookup[category.id] = category;
}
};
exports.mapCategory = (rawItem) => {
const category = exports.categoryLookup[rawItem.CategorySEOName];
return category?.code;
};