Prvotní nástřel pizza parseru

This commit is contained in:
Martin Berka
2023-04-15 08:05:46 +02:00
parent 81f48ebbe2
commit bf379e13ed
13 changed files with 10876 additions and 29175 deletions

106
server/src/chefie.ts Normal file
View File

@@ -0,0 +1,106 @@
import $ from 'cheerio';
import rp from 'request-promise';
import os from 'os';
import path from 'path';
import fs from 'fs';
type PizzaSize = {
size: string,
pizzaPrice: string,
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`;
const buildPizzaUrl = (pizzaUrl: string) => {
return `${baseUrl}/${pizzaUrl}`;
}
// Ceny krabic dle velikosti
const boxPrices = {
"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 rp(pizzyUrl);
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 rp(pizzaUrl);
// Název
const name = $('.produkt > h2', pizzaHtml).first().text()
// Přísady
const ingredients = []
const ingredientsHtml = $('.prisady > li', pizzaHtml);
ingredientsHtml.each((i, elm) => {
ingredients.push($(elm).text());
})
// Velikosti
const sizes = [];
const a = $('.varianty > li > a', pizzaHtml);
a.each((i, elm) => {
const size = $('span', elm).text();
const priceKc = $(elm).text().split(size).pop().trim();
const price = Number.parseInt(priceKc.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;
}
}

66
server/src/index.ts Normal file
View File

@@ -0,0 +1,66 @@
import express from "express";
import { Server } from "socket.io";
import bodyParser from "body-parser";
import { fetchPizzy } from "./chefie";
const app = express();
const server = require("http").createServer(app);
const io = new Server(server, {
cors: {
origin: "*",
},
});
// Body-parser middleware for parsing JSON
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors({
origin: '*'
}));
app.get("/api/pizza", (req, res) => {
fetchPizzy().then(pizzaList => {
console.log("Výsledek", pizzaList);
res.status(200).json(pizzaList);
});
});
app.post("/api/zprava", (req, res) => {
const { username, message } = req.body;
if (
typeof username !== "string" ||
typeof message !== "string" ||
username.length > 500 ||
message.length > 500
) {
return res.status(400).json({ error: "Invalid input" });
}
console.log(`posílám ${username} ${message} `);
io.emit("externalMessage", `${username} -> ${message}`);
res.status(200).json({ success: "Message sent" });
});
io.on("connection", (socket) => {
console.log(`New client connected: ${socket.id}`);
socket.on("message", (message) => {
io.emit("message", message);
});
socket.on("jduKafe", ({ username, timeString }) => {
console.log(`Received message: ${username}`);
socket.broadcast.emit("jduKafe", `${timeString}: ${username} -> jdu Kafe`);
});
socket.on("disconnect", () => {
console.log(`Client disconnected: ${socket.id}`);
});
});
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});