Fix binary encoding of unit.

This commit is contained in:
Mario Zechner 2023-06-18 14:45:35 +02:00
parent c578a7e5bc
commit d01d984706
4 changed files with 172 additions and 72 deletions

View File

@ -193,7 +193,10 @@ function compressBinary(items) {
if (item.bio) flagsByte |= 1;
if (item.isWeighted) flagsByte |= 2;
if (item.unit === "ml") flagsByte |= 4;
if (item.unit === "stk") flagsByte |= 8;
if (item.unit === "g") flagsByte |= 8;
if (item.unit === "stk") flagsByte |= 16;
if (item.unit === "cm") flagsByte |= 32;
if (item.unit === "wg") flagsByte |= 64;
buffer.push(flagsByte);
const quantityBuffer = Buffer.allocUnsafe(2);

View File

@ -5,112 +5,187 @@
exports.categories = [
{
name: "Obst & Gemüse",
subcategories: ["Obst", "Gemüse", "Salate", "Trockenfrüchte & Nüsse"],
subcategories: [
/*00*/ "Obst",
/*01*/ "Gemüse",
/*02*/ "Salate",
/*03*/ "Trockenfrüchte & Nüsse", // I don't know how to make formatting stop.
],
},
{
name: "Brot & Gebäck",
subcategories: ["Aufbackbrötchen & Toast", "Brot & Gebäck", "Knäckebrot & Zwieback", "Kuchen & Co.", "Semmelwürfel & Brösel"],
subcategories: [
/*10*/ "Aufbackbrötchen & Toast",
/*11*/ "Brot & Gebäck",
/*12*/ "Knäckebrot & Zwieback",
/*13*/ "Kuchen & Co.",
/*14*/ "Semmelwürfel & Brösel", // I don't know how to make formatting stop.
],
},
{
name: "Getränke",
subcategories: ["Alkoholfreie Getränke", "Bier & Radler", "Kaffee, Tee & Co.", "Sekt & Champagner", "Spirituosen", "Wein", "Mineralwasser"],
subcategories: [
/*20*/ "Alkoholfreie Getränke",
/*21*/ "Bier & Radler",
/*22*/ "Kaffee, Tee & Co.",
/*23*/ "Sekt & Champagner",
/*24*/ "Spirituosen",
/*25*/ "Wein",
/*26*/ "Mineralwasser", // I don't know how to make formatting stop.
],
},
{
name: "Kühlwaren",
subcategories: [
"Schnelle Küche",
"Eier",
"Fleisch",
"Käse, Aufstriche & Salate",
"Milchprodukte",
"Feinkostplatten & Brötchen",
"Blätterteig, Strudelteig",
"Wurst, Schinken & Speck",
"Feinkost",
"Fisch",
"Unbekannt", // Not available in Billa hierarchy, left blank
"Tofu",
/*30*/ "Schnelle Küche",
/*31*/ "Eier",
/*32*/ "Fleisch",
/*33*/ "Käse, Aufstriche & Salate",
/*34*/ "Milchprodukte",
/*35*/ "Feinkostplatten & Brötchen",
/*36*/ "Blätterteig, Strudelteig",
/*37*/ "Wurst, Schinken & Speck",
/*38*/ "Feinkost",
/*39*/ "Fisch",
/*3A*/ "Unbekannt", // Not available in Billa hierarchy, left blank
/*3B*/ "Vegetarisch, Tofu, Soja & Co",
],
},
{
name: "Tiefkühl",
subcategories: [
"Eis",
"Unbekannt", // Not available in Billa hierarchy, left blank
"Fertiggerichte",
"Fisch & Garnelen",
"Gemüse & Kräuter",
"Pommes Frites & Co.",
"Pizza & Baguette",
"Desserts & Früchte",
/*40*/ "Eis",
/*41*/ "Unbekannt", // Not available in Billa hierarchy, left blank
/*42*/ "Fertiggerichte",
/*43*/ "Fisch & Garnelen",
/*44*/ "Gemüse & Kräuter",
/*45*/ "Pommes Frites & Co.",
/*46*/ "Pizza & Baguette",
/*47*/ "Desserts & Früchte",
],
},
{
name: "Grundnahrungsmittel",
subcategories: [
"Asia & Mexican Produkte",
"Baby",
"Backen",
"Essig & Öl",
"Fertiggerichte",
"Gewürze & Würzmittel",
"Honig, Marmelade & Co.",
"Konserven & Sauerwaren",
"Kuchen & Co.",
"Mehl & Getreideprodukte",
"Müsli & Cerealien",
"Reis, Teigwaren & Sugo",
"Saucen & Dressings",
"Spezielle Ernährung",
"Zucker & Süßstoffe",
"Fixprodukte",
/*50*/ "Asia & Mexican Produkte",
/*51*/ "Baby",
/*52*/ "Backen",
/*53*/ "Essig & Öl",
/*54*/ "Fertiggerichte",
/*55*/ "Gewürze & Würzmittel",
/*56*/ "Honig, Marmelade & Co.",
/*57*/ "Konserven & Sauerwaren",
/*58*/ "Kuchen & Co.",
/*59*/ "Mehl & Getreideprodukte",
/*5A*/ "Müsli & Cerealien",
/*5B*/ "Reis, Teigwaren & Sugo",
/*5C*/ "Saucen & Dressings",
/*5D*/ "Spezielle Ernährung",
/*5E*/ "Zucker & Süßstoffe",
/*5F*/ "Fixprodukte",
],
},
{
name: "Süßes & Salziges",
subcategories: ["Biskotten & Eiswaffeln", "Für kluge Naschkatzen", "Müsliriegel", "Chips & Co.", "Süßes"],
subcategories: [
/*60*/ "Biskotten & Eiswaffeln",
/*61*/ "Für kluge Naschkatzen",
/*62*/ "Müsliriegel",
/*63*/ "Chips & Co.",
/*64*/ "Süßes", // I don't know how to make formatting stop.
],
},
{
name: "Pflege",
subcategories: [
"Baby",
"Damenhygiene",
"Deodorants",
"Haarpflege & Haarfarben",
"Pflaster & Verbandsmaterial",
"Haut- & Lippenpflege",
"Mund- & Zahnhygiene",
"Rasierbedarf",
"Seife & Duschbäder",
"Sonnen- & Gelsenschutzmittel",
"Verhütungsmittel",
"Fußpflege",
"Strumpfhosen & Socken",
/*70*/ "Baby",
/*71*/ "Damenhygiene",
/*72*/ "Deodorants",
/*73*/ "Haarpflege & Haarfarben",
/*74*/ "Pflaster & Verbandsmaterial",
/*75*/ "Haut- & Lippenpflege",
/*76*/ "Mund- & Zahnhygiene",
/*77*/ "Rasierbedarf",
/*78*/ "Seife & Duschbäder",
/*79*/ "Sonnen- & Gelsenschutzmittel",
/*7A*/ "Verhütungsmittel",
/*7B*/ "Fußpflege",
/*7C*/ "Strumpfhosen & Socken",
],
},
{
name: "Haushalt",
subcategories: [
"Büro- & Schulartikel",
"Garten",
"Kleben & Befestigen",
"Küchenartikel",
"Küchenrollen & WC-Papier",
"Lampen & Batterien",
"Müllsäcke, Gefrierbeutel & Co.",
"Raumsprays & Kerzen",
"Reinigen & Pflegen",
"Taschentücher & Servietten",
"Waschmittel & Weichspüler",
"Schuhpflege",
"Kunststoffbehälter",
"Insektenschutz",
"Spielwaren",
"Hygiene-Schutzartikel",
/*80*/ "Büro- & Schulartikel",
/*81*/ "Garten",
/*82*/ "Kleben & Befestigen",
/*83*/ "Küchenartikel",
/*84*/ "Küchenrollen & WC-Papier",
/*85*/ "Lampen & Batterien",
/*86*/ "Müllsäcke, Gefrierbeutel & Co.",
/*87*/ "Raumsprays & Kerzen",
/*88*/ "Reinigen & Pflegen",
/*89*/ "Taschentücher & Servietten",
/*8A*/ "Waschmittel & Weichspüler",
/*8B*/ "Schuhpflege",
/*8C*/ "Kunststoffbehälter",
/*8D*/ "Insektenschutz",
/*8E*/ "Spielwaren",
/*8F*/ "Hygiene-Schutzartikel",
],
},
{
name: "Haustier",
subcategories: ["Hunde", "Katzen", "Nager", "Vögel"],
subcategories: [
/*90*/ "Hunde",
/*91*/ "Katzen",
/*92*/ "Nager",
/*93*/ "Vögel", // I don't know how to make formatting stop.
],
},
{
name: "Unbekannt",
subcategories: [/*A0*/ "Unbekannt"],
},
];
exports.toCategoryCode = (i, j) => {
return (
(i < 10 ? "" + i : String.fromCharCode("A".charCodeAt(0) + (i - 10))) + (j < 10 ? "" + j : String.fromCharCode("A".charCodeAt(0) + (j - 10)))
);
};
exports.fromCategoryCode = (code) => {
if (code.length != 2) return [exports.categories.length - 1, 0];
const codeI = code.charCodeAt(0);
const codeJ = code.charCodeAt(1);
return [
codeI - (codeI < "A".charCodeAt(0) ? "0".charCodeAt(0) : "A".charCodeAt(0) - 10),
codeJ - (codeJ < "A".charCodeAt(0) ? "0".charCodeAt(0) : "A".charCodeAt(0) - 10),
];
};
exports.isValidCode = (code) => {
const [i, j] = exports.fromCategoryCode(code);
if (i < 0 || i >= exports.categories.length) return false;
const category = exports.categories[i];
if (j < 0 || j >= exports.categories.subcategories) return false;
return true;
};
exports.getCategory = (code) => {
const [i, j] = exports.fromCategoryCode(code);
return [exports.categories[i], exports.categories[i].subcategories[j]];
};
exports.UNKNOWN_CATEGORY = exports.toCategoryCode(exports.categories.length - 1, 0);
if (require.main === module) {
const code = exports.toCategoryCode(10, 1);
console.log(code);
const [i, j] = exports.fromCategoryCode("A1");
console.log(i + ", " + j);
console.log(exports.isValidCode("F1"));
console.log(exports.isValidCode("11"));
console.log(exports.getCategory("A1"));
}

View File

@ -40,7 +40,11 @@ function decompressBinary(buffer) {
const flagsByte = view.getUint8(offset++);
obj.bio = (flagsByte & 1) !== 0;
obj.isWeighted = (flagsByte & 2) !== 0;
obj.unit = (flagsByte & 4) !== 0 ? "ml" : (flagsByte & 8) !== 0 ? "stk" : "g";
if (flagsByte & 4) obj.unit = "ml";
if (flagsByte & 8) obj.unit = "g";
if (flagsByte & 16) obj.unit = "stk";
if (flagsByte & 32) obj.unit = "cm";
if (flagsByte & 64) obj.unit = "wg";
obj.quantity = view.getUint16(offset, true);
offset += 2;

View File

@ -1,5 +1,6 @@
const axios = require("axios");
const utils = require("./utils");
const { toCategoryCode, fromCategoryCode, getCategory } = require("../site/model/categories");
const HITS = Math.floor(30000 + Math.random() * 2000);
const units = {
@ -22,11 +23,28 @@ exports.getCanonical = function (item, today) {
if (grammage) [quantity, unit] = grammage.trim().split(" ").splice(0, 2);
}
let billaCategory = null;
for (const groupId of item.data.articleGroupIds) {
if (billaCategory == null) {
billaCategory = groupId;
continue;
}
if (groupId.charCodeAt(3) < billaCategory.charCodeAt(3)) {
billaCategory = groupId;
}
}
let categoryCode = billaCategory.replace("B2-", "").substring(0, 2);
let [ci, cj] = fromCategoryCode(categoryCode);
categoryCode = toCategoryCode(ci - 1, cj - 1);
const category = getCategory(categoryCode);
return utils.convertUnit(
{
id: item.data.articleId,
name: item.data.name,
description: item.data.description ?? "",
category,
price: item.data.price.final,
priceHistory: [{ date: today, price: item.data.price.final }],
isWeighted: item.data.isWeightArticle,