diff --git a/client/src/App.tsx b/client/src/App.tsx
index bad6994..6ab5167 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -351,7 +351,7 @@ function App() {
} else {
content =
diff --git a/server/src/mock.ts b/server/src/mock.ts
index 0db8d04..961f724 100644
--- a/server/src/mock.ts
+++ b/server/src/mock.ts
@@ -427,6 +427,96 @@ const MOCK_DATA = {
isSoup: false,
}
]
+ ],
+ 'zastavkaUmichala': [
+ [
+ {
+ amount: "-",
+ name: "Fazolačka s klobásou & zakysačkou",
+ price: "39\xA0Kč",
+ isSoup: true,
+ },
+ {
+ amount: "-",
+ name: "Zeleninová musaka – lilek, cuketa, tomatové sugo & sýrový bešamel",
+ price: "135\xA0Kč",
+ isSoup: false,
+ },
+ {
+ amount: "-",
+ name: "Slovácké strapačky s uzenou slaninou, zelím, mletým pepřem & sekanou petrželkou",
+ price: "140\xA0Kč",
+ isSoup: false,
+ },
+ {
+ amount: "-",
+ name: "Hovězí guláš s vejcem, zeleninovou garniturkou & žemlovými knedlíky",
+ price: "145\xA0Kč",
+ isSoup: false,
+ },
+ {
+ amount: "-",
+ name: "Kuřecí roláda s kaštanovou nádivkou, demi-glace & smetanovou bramborovou kaší",
+ price: "150\xA0Kč",
+ isSoup: false,
+ }
+ ],
+ [
+ {
+ amount: "-",
+ name: "Hovězí vývar se zeleninou a játrovou rýží",
+ price: "39\xA0Kč",
+ isSoup: true,
+ },
+ {
+ amount: "-",
+ name: "Pečené vepřové koleno, křen, hořčice, chléb",
+ price: "320\xA0Kč",
+ isSoup: false,
+ }
+ ],
+ [
+ {
+ amount: "-",
+ name: "Zeleninová polévka s kuskusem",
+ price: "39\xA0Kč",
+ isSoup: true,
+ },
+ {
+ amount: "-",
+ name: "Poutine (trhané vepřové, hranolky, sýr, čalamáda, pikantní omáčka)",
+ price: "190\xA0Kč",
+ isSoup: false,
+ }
+ ],
+ [
+ {
+ amount: "-",
+ name: "Hrachová polévka s uzeninou",
+ price: "39\xA0Kč",
+ isSoup: true,
+ },
+ {
+ amount: "-",
+ name: "Vepřový řízek z kotlety, domácí bramborový salát",
+ price: "170\xA0Kč",
+ isSoup: false,
+ }
+ ],
+ [
+ {
+ amount: "-",
+ name: "Cibulačka se sýrem",
+ price: "39\xA0Kč",
+ isSoup: true,
+ },
+ {
+ amount: "-",
+ name: "Burger z Chuck rollu, hranolky, tatarská omáčka",
+ price: "200\xA0Kč",
+ isSoup: false,
+ }
+ ],
]
}
@@ -1180,8 +1270,11 @@ const MOCK_PIZZA_LIST = [
}
]
-export const getTodayMock = () => {
- return '2023-05-31'; // středa
+/**
+ * Funkce vrací mock datu ve formátu YYYY-MM-DD
+ */
+export const getTodayMock = (): Date => {
+ return new Date('2025-01-10'); // pátek
}
export const getMenuSladovnickaMock = () => {
@@ -1196,6 +1289,10 @@ export const getMenuTechTowerMock = () => {
return MOCK_DATA['techTower'];
}
+export const getMenuZastavkaUmichalaMock = () => {
+ return MOCK_DATA['zastavkaUmichala'];
+}
+
export const getPizzaListMock = () => {
return MOCK_PIZZA_LIST;
}
\ No newline at end of file
diff --git a/server/src/restaurants.ts b/server/src/restaurants.ts
index 00de3d1..fafd1ae 100644
--- a/server/src/restaurants.ts
+++ b/server/src/restaurants.ts
@@ -1,7 +1,8 @@
import axios from "axios";
import { load } from 'cheerio';
import { Food } from "../../types";
-import { getMenuSladovnickaMock, getMenuTechTowerMock, getMenuUMotlikuMock } from "./mock";
+import {getMenuSladovnickaMock, getMenuTechTowerMock, getMenuUMotlikuMock, getMenuZastavkaUmichalaMock} from "./mock";
+import {formatDate, getDayOfWeekIndex, getIsWeekend} from "./utils";
// Fráze v názvech jídel, které naznačují že se jedná o polévku
const SOUP_NAMES = [
@@ -25,6 +26,8 @@ const DAYS_IN_WEEK = ['pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', '
const SLADOVNICKA_URL = 'https://sladovnicka.unasplzenchutna.cz/cz/denni-nabidka';
const U_MOTLIKU_URL = 'https://www.umotliku.cz/menu';
const TECHTOWER_URL = 'https://www.equifarm.cz/restaurace-techtower';
+const ZASTAVKAUMICHALA_URL = 'https://www.zastavkaumichala.cz';
+const SENKSERIKOVA_URL = 'https://www.menicka.cz/6561-pivovarsky-senk-serikova.html';
/**
* Vrátí true, pokud předaný text obsahuje některé ze slov, které naznačuje, že se jedná o polévku.
@@ -326,4 +329,54 @@ export const getMenuTechTower = async (firstDayOfWeek: Date, mock: boolean = fal
}
}
return result;
-}
\ No newline at end of file
+}
+
+/**
+ * Získá obědovou nabídku ZastavkaUmichala pro jeden týden.
+ *
+ * @param firstDayOfWeek první den v týdnu, pro který získat menu
+ * @param mock zda vrátit mock data
+ * @returns seznam jídel pro dané datum
+ */
+export const getMenuZastavkaUmichala = async (firstDayOfWeek: Date, mock: boolean = false): Promise => {
+ if (mock) {
+ return getMenuZastavkaUmichalaMock();
+ }
+
+ const nowDate = new Date().getDate();
+ const result: Food[][] = [];
+ for (let dayIndex = 0; dayIndex < 5; dayIndex++) {
+ const currentDate = new Date(firstDayOfWeek);
+ currentDate.setDate(firstDayOfWeek.getDate() + dayIndex);
+
+ // if (currentDate < now) {
+ if (currentDate.getDate() !== nowDate) {
+ result[dayIndex] = [{
+ amount: undefined,
+ name: "Pro tento den není uveřejněna nabídka jídel",
+ price: "",
+ isSoup: false,
+ }];
+ continue;
+ } else {
+ // let dateString = formatDate(currentDate, 'DD.MM.YYYY');
+ // const html = await getHtml(ZASTAVKAUMICHALA_URL + '/?do=dailyMenu-changeDate&dailyMenu-dateString=' + dateString);
+ const html = await getHtml(ZASTAVKAUMICHALA_URL);
+ const $ = load(html);
+
+ // const row = $($('.foodsList li')[0]).text();
+
+ const currentDayFood: Food[] = [];
+ $('.foodsList li').each((index, element) => {
+ currentDayFood.push({
+ amount: '-',
+ name: sanitizeText($(element).contents().not('span').text()),
+ price: sanitizeText($(element).find('span').text()),
+ isSoup: (index === 0),
+ });
+ });
+ result[dayIndex] = currentDayFood;
+ }
+ }
+ return result;
+}
diff --git a/server/src/service.ts b/server/src/service.ts
index eb0fcb6..0daa62f 100644
--- a/server/src/service.ts
+++ b/server/src/service.ts
@@ -1,7 +1,7 @@
import { InsufficientPermissions, formatDate, getDayOfWeekIndex, getFirstWorkDayOfWeek, getHumanDate, getIsWeekend, getWeekNumber } from "./utils";
import { ClientData, Restaurants, DayMenu, DepartureTime, DayData, WeekMenu, LocationKey } from "../../types";
import getStorage from "./storage";
-import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
+import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku, getMenuZastavkaUmichala } from "./restaurants";
import { getTodayMock } from "./mock";
const storage = getStorage();
@@ -10,7 +10,7 @@ const MENU_PREFIX = 'menu';
/** Vrátí dnešní datum, případně fiktivní datum pro účely vývoje a testování. */
export function getToday(): Date {
if (process.env.MOCK_DATA === 'true') {
- return new Date(getTodayMock());
+ return getTodayMock();
}
return new Date();
}
@@ -61,6 +61,7 @@ export async function getData(date?: Date): Promise {
[Restaurants.SLADOVNICKA]: await getRestaurantMenu(Restaurants.SLADOVNICKA, date),
// [Restaurants.UMOTLIKU]: await getRestaurantMenu(Restaurants.UMOTLIKU, date),
[Restaurants.TECHTOWER]: await getRestaurantMenu(Restaurants.TECHTOWER, date),
+ [Restaurants.ZASTAVKAUMICHALA]: await getRestaurantMenu(Restaurants.ZASTAVKAUMICHALA, date),
}
clientData = await addVolatileData(clientData);
return clientData;
@@ -168,6 +169,19 @@ export async function getRestaurantMenu(restaurant: Restaurants, date?: Date): P
} catch (e: any) {
console.error("Selhalo načtení jídel pro podnik TechTower", e);
}
+ case Restaurants.ZASTAVKAUMICHALA:
+ try {
+ const zastavkaUmichalaFood = await getMenuZastavkaUmichala(firstDay, mock);
+ for (let i = 0; i < zastavkaUmichalaFood.length; i++) {
+ menus[i][restaurant]!.food = zastavkaUmichalaFood[i];
+ if (zastavkaUmichalaFood[i]?.length === 1 && zastavkaUmichalaFood[i][0].name === 'Pro tento den není uveřejněna nabídka jídel.') {
+ menus[i][restaurant]!.closed = true;
+ }
+ }
+ break;
+ } catch (e: any) {
+ console.error("Selhalo načtení jídel pro podnik Zastávka u Michala", e);
+ }
}
await storage.setData(getMenuKey(usedDate), menus);
}
diff --git a/server/src/utils.ts b/server/src/utils.ts
index 98d031e..e8e8e35 100644
--- a/server/src/utils.ts
+++ b/server/src/utils.ts
@@ -1,11 +1,13 @@
import { Choices, LocationKey } from "../../types";
/** Vrátí datum v ISO formátu. */
-export function formatDate(date: Date) {
- let currentDay = String(date.getDate()).padStart(2, '0');
- let currentMonth = String(date.getMonth() + 1).padStart(2, "0");
- let currentYear = date.getFullYear();
- return `${currentYear}-${currentMonth}-${currentDay}`;
+export function formatDate(date: Date, format?: string) {
+ let day = String(date.getDate()).padStart(2, '0');
+ let month = String(date.getMonth() + 1).padStart(2, "0");
+ let year = String(date.getFullYear());
+
+ const f = (format === undefined) ? 'YYYY-MM-DD' : format;
+ return f.replace('DD', day).replace('MM', month).replace('YYYY', year);
}
/** Vrátí human-readable reprezentaci předaného data pro zobrazení. */
diff --git a/types/Types.ts b/types/Types.ts
index d9764e2..bcd3b8b 100644
--- a/types/Types.ts
+++ b/types/Types.ts
@@ -3,6 +3,7 @@ export enum Restaurants {
SLADOVNICKA = 'sladovnicka',
// UMOTLIKU = 'uMotliku',
TECHTOWER = 'techTower',
+ ZASTAVKAUMICHALA = 'zastavkaUmichala',
}
export type FoodChoices = {