import $ from 'cheerio'; import os from 'os'; import path from 'path'; import fs from 'fs'; import axios from 'axios'; type PizzaSize = { size: string, pizzaPrice: number, boxPrice: number, price: number } type Pizza = { name: string, ingredients: string[], sizes: PizzaSize[], } // TODO mělo by být konfigurovatelné proměnnou z prostředí s tímhle jako default const baseUrl = 'https://www.pizzachefie.cz'; const pizzyUrl = `${baseUrl}/pizzy.html?pobocka=plzen`; // URL na Food API - získání jídelních lístků restaurací const foodUrl = process.env.FOOD_API_URL || 'http://localhost:3002'; const buildPizzaUrl = (pizzaUrl: string) => { return `${baseUrl}/${pizzaUrl}`; } // Ceny krabic dle velikosti const boxPrices: { [key: string]: number } = { "30cm": 13, "35cm": 15, "40cm": 18, "50cm": 25 } /** * Stáhne a scrapne aktuální pizzy ze stránek Pizza Chefie. */ const downloadPizzy = async () => { // Získáme seznam pizz const html = await axios.get(pizzyUrl).then(res => res.data); const links = $('.vypisproduktu > div > h4 > a', html) const urls = []; for (let i = 0; i < links.length; i++) { if (links[i].name === 'a' && links[i].attribs?.href) { const pizzaUrl = links[i].attribs?.href; urls.push(buildPizzaUrl(pizzaUrl)); } } // Scrapneme jednotlivé pizzy const result: Pizza[] = []; for (let i = 0; i < urls.length; i++) { const pizzaUrl = urls[i]; const pizzaHtml = await axios.get(pizzaUrl).then(res => res.data); // Název const name = $('.produkt > h2', pizzaHtml).first().text() // Přísady const ingredients: string[] = [] const ingredientsHtml = $('.prisady > li', pizzaHtml); ingredientsHtml.each((i, elm) => { ingredients.push($(elm).text()); }) // Velikosti const sizes: PizzaSize[] = []; const a = $('.varianty > li > a', pizzaHtml); a.each((i, elm) => { const size = $($(elm).contents().get(0)).text().trim(); const price = Number.parseInt($($(elm).contents().get(1)).text().trim().split(" Kč")[0]); sizes.push({ size: size, pizzaPrice: price, boxPrice: boxPrices[size], price: price + boxPrices[size] }); }) result.push({ name: name, ingredients: ingredients, sizes: sizes, }); } return result; } /** * Vrátí pizzy z tempu, nebo čerstvě stažené, pokud v tempu nejsou. */ export const fetchPizzy = async () => { const tmpDir = os.tmpdir(); const date_ob = new Date(); const date = ("0" + date_ob.getDate()).slice(-2); const month = ("0" + (date_ob.getMonth() + 1)).slice(-2); const year = date_ob.getFullYear(); const dateStr = year + "-" + month + "-" + date; const dataPath = path.join(tmpDir, `chefie-${dateStr}.json`); if (fs.existsSync(dataPath)) { console.log(`Soubor pro ${dataPath} již existuje, bude použit.`); const rawdata = fs.readFileSync(dataPath); return JSON.parse(rawdata.toString()); } else { console.log(`Soubor pro ${dataPath} neexistuje, stahuji...`); const pizzy = await downloadPizzy(); fs.writeFileSync(dataPath, JSON.stringify(pizzy)); console.log(`Zapsán ${dataPath}`); return pizzy; } }