Compare commits
No commits in common. "master" and "5a097a5ce799a45f762bd832b6b82eeb239579dd" have entirely different histories.
master
...
5a097a5ce7
4
.gitignore
vendored
4
.gitignore
vendored
@ -4,7 +4,3 @@ menuprint
|
|||||||
.lvimrc
|
.lvimrc
|
||||||
example.*
|
example.*
|
||||||
dhparam*
|
dhparam*
|
||||||
.cache
|
|
||||||
.clang-format
|
|
||||||
build
|
|
||||||
compile_commands.json
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
enable_language(CXX)
|
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
|
||||||
pkg_check_modules(LIBXML REQUIRED libxml-2.0)
|
|
||||||
pkg_check_modules(LIBXMLPP REQUIRED libxml++-3.0)
|
|
||||||
find_library(Restbed restbed
|
|
||||||
PATHS /usr/lib)
|
|
||||||
find_library(Curl curl
|
|
||||||
PATHS /usr/lib)
|
|
||||||
|
|
||||||
include_directories(/usr/local/include /opt/homebrew/include)
|
|
||||||
link_directories(/opt/homebrew/lib)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
|
|
||||||
|
|
||||||
project(LunchRest)
|
|
||||||
|
|
||||||
list(APPEND Restaurants
|
|
||||||
restaurants/ukarla.cpp
|
|
||||||
restaurants/tao.cpp
|
|
||||||
restaurants/mahostina.cpp
|
|
||||||
restaurants/menicka.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(lunchrest)
|
|
||||||
|
|
||||||
target_sources(lunchrest
|
|
||||||
PRIVATE ${Restaurants}
|
|
||||||
PRIVATE main.cpp
|
|
||||||
PRIVATE meal.cpp
|
|
||||||
PRIVATE menu.cpp
|
|
||||||
PRIVATE network/network.cpp
|
|
||||||
PRIVATE environment.cpp
|
|
||||||
PRIVATE restaurants/functions.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(lunchrest ${LIBXML_LIBRARIES} ${LIBXMLPP_LIBRARIES} ${Restbed} ${Curl})
|
|
||||||
target_include_directories(lunchrest PUBLIC ${LIBXML_INCLUDE_DIRS} ${LIBXMLPP_INCLUDE_DIRS})
|
|
44
Makefile
Normal file
44
Makefile
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
CXX ?= g++
|
||||||
|
CFLAGS ?= -O2 -Wall -Wextra `pkg-config libxml-2.0 --cflags` `pkg-config libxml++-3.0 --cflags` -g
|
||||||
|
PREFIX ?= /usr/local/bin
|
||||||
|
LDFLAGS ?= -lcurl -lrestbed `pkg-config libxml-2.0 --libs` `pkg-config libxml++-3.0 --libs`
|
||||||
|
|
||||||
|
PARSERS = udrevaka.o padagali.o lightofindia.o ukarla.o alcapone.o plac.o zo.o suzzies.o
|
||||||
|
|
||||||
|
.PHONY: default
|
||||||
|
default: menuprint
|
||||||
|
|
||||||
|
menuprint: main.o meal.o menu.o network.o restaurants.o environment.o $(PARSERS)
|
||||||
|
$(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS}
|
||||||
|
|
||||||
|
main.o: main.cpp restaurant.hpp menu.hpp meal.hpp restaurants/restaurants.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
meal.o: meal.cpp meal.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
menu.o: menu.cpp menu.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
network.o: network/network.cpp network/network.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
restaurants.o: restaurants/restaurants.cpp restaurants/restaurants.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
environment.o: environment.cpp environment.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
udrevaka.o: restaurants/udrevaka.cpp restaurants.o restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
padagali.o: restaurants/padagali.cpp restaurants.o restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
lightofindia.o: restaurants/lightofindia.cpp restaurants.o restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
ukarla.o: restaurants/ukarla.cpp restaurants.o restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
alcapone.o: restaurants/alcapone.cpp restaurants.o restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
plac.o: restaurants/plac.cpp restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
zo.o: restaurants/zo.cpp restaurants/restaurants.hpp network/network.hpp htmlparser.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
suzzies.o: restaurants/suzzies.cpp restaurants/restaurants.hpp network/network.hpp environment.hpp
|
||||||
|
$(CXX) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -Rf *.o menuprint
|
161
main.cpp
161
main.cpp
@ -1,8 +1,7 @@
|
|||||||
#include "environment.hpp"
|
#include "environment.hpp"
|
||||||
#include "meal.hpp"
|
|
||||||
#include "menu.hpp"
|
|
||||||
#include "restaurant.hpp"
|
#include "restaurant.hpp"
|
||||||
#include "restaurants/menicka.hpp"
|
#include "menu.hpp"
|
||||||
|
#include "meal.hpp"
|
||||||
#include "restaurants/restaurants.hpp"
|
#include "restaurants/restaurants.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -15,137 +14,157 @@
|
|||||||
|
|
||||||
std::map<std::string, std::unique_ptr<LunchRest::Restaurant>> restaurants;
|
std::map<std::string, std::unique_ptr<LunchRest::Restaurant>> restaurants;
|
||||||
|
|
||||||
void sendResponse(const std::string &response, int status_code,
|
std::string file_info_name = "data_backup";
|
||||||
const std::shared_ptr<restbed::Session> session,
|
struct tm last_save;
|
||||||
const std::string &content_type = "text/plain") {
|
|
||||||
session->close(status_code, response,
|
void sendResponse(const std::string &response, int status_code, const std::shared_ptr< restbed::Session > session) {
|
||||||
{ { "Content-Length", std::to_string(response.length()) },
|
session->close(status_code, response, { { "Content-Length", std::to_string(response.length()) }, { "Access-Control-Allow-Origin", "*" } });
|
||||||
{ "Access-Control-Allow-Origin", "*" },
|
|
||||||
{ "Content-Type", content_type } });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void refresh(const std::shared_ptr<restbed::Session> session) {
|
void refresh( const std::shared_ptr< restbed::Session > session ) {
|
||||||
for (auto &restaurant : restaurants)
|
for(auto &restaurant : restaurants)
|
||||||
restaurant.second->parse();
|
restaurant.second->parse();
|
||||||
std::string response = "Refreshed menus!";
|
std::string response = "Refreshed menus!";
|
||||||
sendResponse("Refreshed menus!", restbed::OK, session);
|
sendResponse( "Refreshed menus!", restbed::OK, session );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_all_json(const std::vector<int> &days = { 0, 1, 2, 3, 4, 5,
|
std::string get_all_json() {
|
||||||
6 }) {
|
|
||||||
std::stringstream ss{};
|
std::stringstream ss{};
|
||||||
bool atleastonerest = false;
|
bool atleastonerest = false;
|
||||||
ss << "[";
|
ss << "[";
|
||||||
for (auto &restaurant : restaurants) {
|
for(auto &restaurant : restaurants) {
|
||||||
atleastonerest = true;
|
atleastonerest = true;
|
||||||
ss << restaurant.second->jsonify(days) << ",";
|
ss << restaurant.second->jsonify() << ",";
|
||||||
}
|
}
|
||||||
if (atleastonerest)
|
if(atleastonerest)
|
||||||
ss.seekp(-1, ss.cur);
|
ss.seekp(-1, ss.cur);
|
||||||
ss << "]";
|
ss << "]";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_all(const std::shared_ptr<restbed::Session> session) {
|
void backupData() {
|
||||||
sendResponse(get_all_json(), restbed::OK, session, "application/json");
|
time_t now = time(NULL);
|
||||||
|
struct tm *local = localtime(&now);
|
||||||
|
if(last_save.tm_year == local->tm_year && last_save.tm_mon == local->tm_mon && last_save.tm_mday == local->tm_mday)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::ofstream output_file;
|
||||||
|
output_file.open(file_info_name, std::ios_base::app);
|
||||||
|
auto write_buffer = get_all_json();
|
||||||
|
write_buffer += "\n";
|
||||||
|
output_file.write(write_buffer.c_str(), write_buffer.size());
|
||||||
|
|
||||||
|
last_save.tm_year = local->tm_year;
|
||||||
|
last_save.tm_mon = local->tm_mon;
|
||||||
|
last_save.tm_mday = local->tm_mday;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get(const std::shared_ptr<restbed::Session> session) {
|
void get_all( const std::shared_ptr< restbed::Session > session ) {
|
||||||
|
sendResponse(get_all_json(), restbed::OK, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get( const std::shared_ptr< restbed::Session > session ) {
|
||||||
// TODO better
|
// TODO better
|
||||||
int day = -1;
|
int day = -1;
|
||||||
std::string restaurant = "";
|
std::string restaurant = "";
|
||||||
auto request = session->get_request();
|
auto request = session->get_request();
|
||||||
for (const auto &query_param : request->get_query_parameters()) {
|
for(const auto &query_param : request->get_query_parameters()) {
|
||||||
if (query_param.first == "day") {
|
if(query_param.first == "day") {
|
||||||
if (query_param.second == "monday") {
|
if(query_param.second == "monday") {
|
||||||
day = 0;
|
day = 0;
|
||||||
} else if (query_param.second == "tuesday") {
|
} else if(query_param.second == "tuesday") {
|
||||||
day = 1;
|
day = 1;
|
||||||
} else if (query_param.second == "wednesday") {
|
} else if(query_param.second == "wednesday") {
|
||||||
day = 2;
|
day = 2;
|
||||||
} else if (query_param.second == "thursday") {
|
} else if(query_param.second == "thursday") {
|
||||||
day = 3;
|
day = 3;
|
||||||
} else if (query_param.second == "friday") {
|
} else if(query_param.second == "friday") {
|
||||||
day = 4;
|
day = 4;
|
||||||
} else if (query_param.second == "saturday") {
|
} else if(query_param.second == "saturday") {
|
||||||
day = 5;
|
day = 5;
|
||||||
} else {
|
} else {
|
||||||
day = 6;
|
day = 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (query_param.first == "restaurant")
|
if(query_param.first == "restaurant")
|
||||||
restaurant = query_param.second;
|
restaurant = query_param.second;
|
||||||
}
|
}
|
||||||
if (day == -1 && restaurant == "") {
|
if(day == -1 && restaurant == "") {
|
||||||
sendResponse("DIDN'T SPECIFY DAY OR RESTAURANT", restbed::BAD_REQUEST,
|
sendResponse("DIDN'T SPECIFY DAY OR RESTAURANT", restbed::BAD_REQUEST, session);
|
||||||
session);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restaurant != "" && restaurants.find(restaurant) == restaurants.end()) {
|
if(restaurant != "" && restaurants.find(restaurant) == restaurants.end()) {
|
||||||
sendResponse("YOU DIDN'T SPECIFY A VALID RESTAURANT!",
|
sendResponse("YOU DIDN'T SPECIFY A VALID RESTAURANT!", restbed::BAD_REQUEST, session);
|
||||||
restbed::BAD_REQUEST, session);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string response{};
|
std::stringstream ss{};
|
||||||
if (day != -1 && restaurant != "") {
|
if(day != -1 && restaurant != "") {
|
||||||
response = "[" + restaurants[restaurant]->jsonify({ day }) + "]";
|
ss << "[" << restaurants[restaurant]->jsonify({day}) << "]";
|
||||||
} else if (day != -1) {
|
} else if(day != -1) {
|
||||||
response = get_all_json({ day });
|
ss << "[";
|
||||||
} else if (restaurant != "") {
|
bool atleastone = false;
|
||||||
response = "[" + restaurants[restaurant]->jsonify() + "]";
|
for(auto &restaurant : restaurants) {
|
||||||
|
atleastone = true;
|
||||||
|
ss << restaurant.second->jsonify({day}) << ",";
|
||||||
}
|
}
|
||||||
sendResponse(response, restbed::OK, session, "application/json");
|
if(atleastone)
|
||||||
|
ss.seekp(-1, ss.cur);
|
||||||
|
ss << "]";
|
||||||
|
} else if(restaurant != "") {
|
||||||
|
ss << "[" << restaurants[restaurant]->jsonify() << "]";
|
||||||
|
}
|
||||||
|
sendResponse(ss.str(), restbed::OK, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int /*UNUSED*/, char ** /*UNUSED*/, char **env) {
|
int main(int argc, char **argv, char **env) {
|
||||||
setupEnv(env);
|
setupEnv(env);
|
||||||
restaurants["udrevaka"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/2752-u-drevaka-beergrill.html", "U Dřeváka");
|
restaurants["udrevaka"] = std::make_unique<LunchRest::UDrevakaRestaurant>();
|
||||||
restaurants["padagali"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/4116-padagali.html", "Padagali");
|
restaurants["padagali"] = std::make_unique<LunchRest::PadagaliRestaurant>();
|
||||||
restaurants["lightofindia"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/5448-light-of-india.html", "Light of India");
|
restaurants["lightofindia"] = std::make_unique<LunchRest::LightOfIndiaRestaurant>();
|
||||||
restaurants["ukarla"] = std::make_unique<LunchRest::UKarlaRestaurant>();
|
restaurants["ukarla"] = std::make_unique<LunchRest::UKarlaRestaurant>();
|
||||||
restaurants["alcapone"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/2609-pizzeria-al-capone.html", "Al Capone");
|
restaurants["alcapone"] = std::make_unique<LunchRest::AlCaponeRestaurant>();
|
||||||
restaurants["suzies"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/3830-suzies-steak-pub.html", "Suzies");
|
restaurants["plac"] = std::make_unique<LunchRest::PlacRestaurant>();
|
||||||
restaurants["tao"] = std::make_unique<LunchRest::TaoRestaurant>();
|
restaurants["zo"] = std::make_unique<LunchRest::ZoRestaurant>();
|
||||||
restaurants["mahostina"] = std::make_unique<LunchRest::MahostinaRestaurant>();
|
restaurants["suzzies"] = std::make_unique<LunchRest::SuzziesRestaurant>();
|
||||||
restaurants["divabara"] = std::make_unique<LunchRest::MenickaRestaurant>("https://www.menicka.cz/6468-diva-bara.html", "Divá Bára");
|
|
||||||
std::cout << "Initial parsing" << std::endl;
|
std::cout << "Initial parsing" << std::endl;
|
||||||
for (auto &restaurant : restaurants)
|
for(auto &restaurant : restaurants)
|
||||||
restaurant.second->parse();
|
restaurant.second->parse();
|
||||||
std::cout << "Finished parsing" << std::endl;
|
std::cout << "Finished parsing" << std::endl;
|
||||||
|
last_save.tm_year = 0;
|
||||||
|
last_save.tm_mon = 0;
|
||||||
|
last_save.tm_mday = 0;
|
||||||
|
backupData();
|
||||||
|
|
||||||
restbed::Service service;
|
restbed::Service service;
|
||||||
|
|
||||||
auto getallserv = std::make_shared<restbed::Resource>();
|
auto getallserv = std::make_shared< restbed::Resource >();
|
||||||
getallserv->set_path("/get_all");
|
getallserv->set_path("/get_all");
|
||||||
getallserv->set_method_handler("GET", get_all);
|
getallserv->set_method_handler( "GET", get_all );
|
||||||
service.publish(getallserv);
|
service.publish(getallserv);
|
||||||
|
|
||||||
auto getserv = std::make_shared<restbed::Resource>();
|
auto getserv = std::make_shared< restbed::Resource >();
|
||||||
getserv->set_path("/get");
|
getserv->set_path("/get");
|
||||||
getserv->set_method_handler("GET", get);
|
getserv->set_method_handler( "GET", get );
|
||||||
service.publish(getserv);
|
service.publish(getserv);
|
||||||
|
|
||||||
auto refreshserv = std::make_shared<restbed::Resource>();
|
auto refreshserv = std::make_shared< restbed::Resource >();
|
||||||
refreshserv->set_path("/refresh");
|
refreshserv->set_path("/refresh");
|
||||||
refreshserv->set_method_handler("GET", refresh);
|
refreshserv->set_method_handler( "GET", refresh );
|
||||||
service.publish(refreshserv);
|
service.publish(refreshserv);
|
||||||
|
|
||||||
/* auto ssl_settings = std::make_shared<restbed::SSLSettings>();
|
auto ssl_settings = std::make_shared<restbed::SSLSettings>();
|
||||||
ssl_settings->set_http_disabled(true);
|
ssl_settings->set_http_disabled(true);
|
||||||
ssl_settings->set_private_key(restbed::Uri(
|
ssl_settings->set_private_key(restbed::Uri("file:///home/zvon/data/programming/lunch-rest/example.key"));
|
||||||
"file:///home/zvon/data/programming/lunch-rest/example.key"));
|
ssl_settings->set_certificate(restbed::Uri("file:///home/zvon/data/programming/lunch-rest/example.crt"));
|
||||||
ssl_settings->set_certificate(restbed::Uri(
|
ssl_settings->set_temporary_diffie_hellman(restbed::Uri("file:///home/zvon/data/programming/lunch-rest/dhparams.pem"));
|
||||||
"file:///home/zvon/data/programming/lunch-rest/example.crt"));
|
ssl_settings->set_port(1985);
|
||||||
ssl_settings->set_temporary_diffie_hellman(restbed::Uri(
|
|
||||||
"file:///home/zvon/data/programming/lunch-rest/dhparams.pem"));
|
|
||||||
ssl_settings->set_port(1985);*/
|
|
||||||
|
|
||||||
auto settings = std::make_shared<restbed::Settings>();
|
auto settings = std::make_shared< restbed::Settings >();
|
||||||
settings->set_port(1984);
|
settings->set_port(1984);
|
||||||
settings->set_default_header("Connection", "close");
|
settings->set_default_header( "Connection", "close" );
|
||||||
// settings->set_ssl_settings(ssl_settings);
|
settings->set_ssl_settings(ssl_settings);
|
||||||
|
|
||||||
service.start(settings);
|
service.start(settings);
|
||||||
|
|
||||||
|
55
restaurants/alcapone.cpp
Normal file
55
restaurants/alcapone.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
std::string removeAlergens(const std::string &name) {
|
||||||
|
int pos = name.length() - 1;
|
||||||
|
while(name[pos] == ',' || std::isdigit(name[pos]))
|
||||||
|
pos--;
|
||||||
|
return name.substr(0,pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LunchRest::AlCaponeRestaurant::parse() {
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html == "")
|
||||||
|
return;
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto rows = root.find("//table[@class='table table-responsive']/tbody/tr");
|
||||||
|
int cur_day = -1;
|
||||||
|
for(auto &row : rows) {
|
||||||
|
if(row->find("./td[@class='bg1']").size() != 0) {
|
||||||
|
std::string day = nodeToText(row->find("./td[@class='bg1']/text()")[0]);
|
||||||
|
if(day.find("pondělí") != std::string::npos)
|
||||||
|
cur_day = 0;
|
||||||
|
else if(day.find("úterý") != std::string::npos)
|
||||||
|
cur_day = 1;
|
||||||
|
else if(day.find("středa") != std::string::npos)
|
||||||
|
cur_day = 2;
|
||||||
|
else if(day.find("čtvrtek") != std::string::npos)
|
||||||
|
cur_day = 3;
|
||||||
|
else if(day.find("pátek") != std::string::npos)
|
||||||
|
cur_day = 4;
|
||||||
|
else if(day.find("sobota") != std::string::npos)
|
||||||
|
cur_day = 5;
|
||||||
|
else if(day.find("neděle") != std::string::npos)
|
||||||
|
cur_day = 6;
|
||||||
|
menus[cur_day].setInvalidMenu(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(cur_day < 0)
|
||||||
|
continue;
|
||||||
|
auto menu_info = row->find("./td/text()");
|
||||||
|
auto meal_data = row->find("./td/h3/text()");
|
||||||
|
std::string menu = nodeToText(menu_info[0]);
|
||||||
|
std::string name = nodeToText(meal_data[0]);
|
||||||
|
name = removeAlergens(name);
|
||||||
|
if(menu == "Polévka") {
|
||||||
|
menus[cur_day].addMeal(true, name, "", 0);
|
||||||
|
} else {
|
||||||
|
menus[cur_day].addMeal(false, name, "", std::stoi(nodeToText(meal_data[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef LUNCH_REST_FUNCTIONS
|
|
||||||
#define LUNCH_REST_FUNCTIONS
|
|
||||||
#include <string>
|
|
||||||
#include <libxml++/libxml++.h>
|
|
||||||
|
|
||||||
namespace LunchRest {
|
|
||||||
std::string nodeToText(xmlpp::Node *node);
|
|
||||||
std::string trim(const std::string &input);
|
|
||||||
}
|
|
||||||
#endif
|
|
44
restaurants/lightofindia.cpp
Normal file
44
restaurants/lightofindia.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
bool isWhiteSpaceOnly(const std::string &text) {
|
||||||
|
if(text == "")
|
||||||
|
return true;
|
||||||
|
for(auto &x : text) {
|
||||||
|
if(!std::isspace(x))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LunchRest::LightOfIndiaRestaurant::parse() {
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html == "")
|
||||||
|
return;
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto container = root.find("//div[@id='content_container']")[0];
|
||||||
|
auto texts = container->find(".//td/text()");
|
||||||
|
int index = -1;
|
||||||
|
for(auto text : texts) {
|
||||||
|
std::string text_text = nodeToText(text);
|
||||||
|
if(isWhiteSpaceOnly(text_text) || text_text.find("Week") != std::string::npos)
|
||||||
|
continue;
|
||||||
|
if(text_text[0] == '1')
|
||||||
|
index++;
|
||||||
|
auto end = text_text.find(')');
|
||||||
|
if(end == std::string::npos)
|
||||||
|
continue;
|
||||||
|
auto possible_end = text_text.find('g', end);
|
||||||
|
if(possible_end != std::string::npos)
|
||||||
|
end = possible_end;
|
||||||
|
std::string name = text_text.substr(4, end - 3);
|
||||||
|
int price = std::stoi(text_text.substr(end+1));
|
||||||
|
bool soup = name.find("soup") == std::string::npos ? false : true;
|
||||||
|
menus[index].addMeal(soup, name, "", price);
|
||||||
|
menus[index].setInvalidMenu(false);
|
||||||
|
}
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
#include "functions.hpp"
|
|
||||||
#include "restaurants.hpp"
|
|
||||||
#include "../network/network.hpp"
|
|
||||||
#include "../htmlparser.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void LunchRest::MahostinaRestaurant::parse() {
|
|
||||||
Request r;
|
|
||||||
auto html = r.get(_url);
|
|
||||||
if (html == "")
|
|
||||||
return;
|
|
||||||
clearMenus();
|
|
||||||
try {
|
|
||||||
HtmlParser hparse(html);
|
|
||||||
auto &root = hparse.getRoot();
|
|
||||||
auto today_lists = root.find(
|
|
||||||
"//div[@id='dnesnibasta-section']//ul[@data-rte-list='default']");
|
|
||||||
if (today_lists.empty()) {
|
|
||||||
std::cout << "No meals :(" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t t = time(nullptr);
|
|
||||||
tm *timePtr = localtime(&t);
|
|
||||||
auto day = (timePtr->tm_wday + 6) % 7;
|
|
||||||
|
|
||||||
for (auto &meal : today_lists[0]->find("./li/p/text()")) {
|
|
||||||
auto text = nodeToText(meal);
|
|
||||||
auto price_end = text.find(",-");
|
|
||||||
auto price_start = price_end - 1;
|
|
||||||
while (text[price_start] >= '0' && text[price_start] <= '9') {
|
|
||||||
price_start -= 1;
|
|
||||||
}
|
|
||||||
price_start += 1;
|
|
||||||
menus[day].addMeal(
|
|
||||||
false, text.substr(0, price_start - 1), "",
|
|
||||||
std::stoi(text.substr(price_start, price_end - price_start)));
|
|
||||||
}
|
|
||||||
menus[day].setInvalidMenu(false);
|
|
||||||
} catch (std::exception &/*UNUSED*/) {
|
|
||||||
clearMenus();
|
|
||||||
for(int i = 0; i < menus.size(); i++) {
|
|
||||||
menus[i].addMeal(false, parseError, parseInfo, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
#include "menicka.hpp"
|
|
||||||
#include "restaurants.hpp"
|
|
||||||
#include "../network/network.hpp"
|
|
||||||
#include "../htmlparser.hpp"
|
|
||||||
#include "functions.hpp"
|
|
||||||
|
|
||||||
std::pair<std::string, int> getNameAndPrice(xmlpp::Node *meal) {
|
|
||||||
auto souptext = meal->find("./div[@class='polozka']/text()");
|
|
||||||
auto soupprice = meal->find("./div[@class='cena']/text()");
|
|
||||||
std::string name = "";
|
|
||||||
int price = -1;
|
|
||||||
if(souptext.size() != 0) {
|
|
||||||
name = LunchRest::nodeToText(souptext[0]);
|
|
||||||
}
|
|
||||||
if(soupprice.size() != 0) {
|
|
||||||
price = std::stoi(LunchRest::nodeToText(soupprice[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {name, price};
|
|
||||||
}
|
|
||||||
|
|
||||||
void LunchRest::MenickaRestaurant::parse() {
|
|
||||||
Request r;
|
|
||||||
auto html = r.get(_url);
|
|
||||||
if(html == "")
|
|
||||||
return;
|
|
||||||
clearMenus();
|
|
||||||
try {
|
|
||||||
HtmlParser hparse(html);
|
|
||||||
auto &root = hparse.getRoot();
|
|
||||||
auto days = root.find("//div[@class='menicka']");
|
|
||||||
for(auto &day : days) {
|
|
||||||
auto daytext = day->find("./div[@class='nadpis']/text()");
|
|
||||||
auto soup = day->find("./ul/li[@class='polevka']");
|
|
||||||
auto meals = day->find("./ul/li[@class='jidlo']");
|
|
||||||
if(daytext.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto daystr = nodeToText(daytext[0]);
|
|
||||||
int cur_day = 0;
|
|
||||||
switch (daystr[0]) {
|
|
||||||
case 'P':
|
|
||||||
if (daystr[1] != 'o') {
|
|
||||||
cur_day = 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Ú"[0]:
|
|
||||||
cur_day = 1;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
cur_day = 2;
|
|
||||||
break;
|
|
||||||
case "Č"[0]:
|
|
||||||
cur_day = 3;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(soup.size() != 0) {
|
|
||||||
auto soupData = getNameAndPrice(soup[0]);
|
|
||||||
if(!soupData.first.empty()) {
|
|
||||||
menus[cur_day].addMeal(Meal(true, soupData.first, "", soupData.second));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(auto &meal : meals) {
|
|
||||||
auto mealData = getNameAndPrice(meal);
|
|
||||||
if(!mealData.first.empty()) {
|
|
||||||
menus[cur_day].addMeal(Meal(false, mealData.first, "", mealData.second));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!menus[cur_day].getMeals().empty()) {
|
|
||||||
menus[cur_day].setInvalidMenu(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (std::exception &/*UNUSED*/) {
|
|
||||||
clearMenus();
|
|
||||||
for(int i = 0; i < menus.size(); i++) {
|
|
||||||
menus[i].addMeal(false, parseError, parseInfo, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef LUNCH_REST_MENICKA
|
|
||||||
#define LUNCH_REST_MENICKA
|
|
||||||
#include "../restaurant.hpp"
|
|
||||||
|
|
||||||
namespace LunchRest {
|
|
||||||
class MenickaRestaurant : public Restaurant {
|
|
||||||
public:
|
|
||||||
MenickaRestaurant(const std::string &url, const std::string &name) : Restaurant(url, name) {}
|
|
||||||
virtual ~MenickaRestaurant() = default;
|
|
||||||
virtual void parse() override;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
53
restaurants/padagali.cpp
Normal file
53
restaurants/padagali.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
int dayToNum(const std::string &day) {
|
||||||
|
if(day.find("POND") != std::string::npos) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (day.find("ÚTER") != std::string::npos) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (day.find("STŘE") != std::string::npos) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (day.find("ČTVR") != std::string::npos) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
if (day.find("PÁTE") != std::string::npos) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LunchRest::PadagaliRestaurant::parse() {
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto days = root.find("//div[@class='glf-mor-restaurant-menu-category']");
|
||||||
|
auto menu_index = dayToNum(nodeToText(days[0]->find("./h3/text()")[0]));
|
||||||
|
if(menu_index == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto max_div = 5 - menu_index;
|
||||||
|
for(int i = 0; i < max_div; i++) {
|
||||||
|
auto *day = days[i];
|
||||||
|
auto meals = day->find("./div");
|
||||||
|
for(auto &meal : meals) {
|
||||||
|
auto info = meal->find("./div/div/div");
|
||||||
|
std::string desc = nodeToText(info[1]->find("./text()")[0]);
|
||||||
|
std::string name = nodeToText(info[0]->find("./h5/text()")[0]);
|
||||||
|
int price = std::stoi(nodeToText(info[0]->find("./div/span/text()")[0]));
|
||||||
|
bool soup = name.find("Soup") != std::string::npos;
|
||||||
|
menus[menu_index].addMeal(soup, name, desc, price);
|
||||||
|
menus[menu_index].setInvalidMenu(false);
|
||||||
|
}
|
||||||
|
menu_index++;
|
||||||
|
}
|
||||||
|
}
|
50
restaurants/plac.cpp
Normal file
50
restaurants/plac.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
void LunchRest::PlacRestaurant::parse() {
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html == "")
|
||||||
|
return;
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto pizzas = root.find("//div[@class='mt-c cf']//div[@class='mt-i cf']");
|
||||||
|
if(pizzas.size() == 0)
|
||||||
|
return;
|
||||||
|
auto soups = pizzas[0]->find(".//div[@class='b b-text cf']");
|
||||||
|
|
||||||
|
int soup_price = std::stoi(nodeToText(soups[1]->find(".//strong/text()")[0]));
|
||||||
|
|
||||||
|
int cur_day = -1;
|
||||||
|
for(auto &soup : soups[0]->find(".//p/text()")) {
|
||||||
|
std::string soup_text = nodeToText(soup);
|
||||||
|
auto soup_day = soup_text.substr(0,2);
|
||||||
|
if(soup_day == "Po")
|
||||||
|
cur_day = 0;
|
||||||
|
if(cur_day < 0)
|
||||||
|
continue;
|
||||||
|
menus[cur_day].setInvalidMenu(false);
|
||||||
|
auto soupname = soup_text.substr(5);
|
||||||
|
while(std::isspace(soupname[0]))
|
||||||
|
soupname = soupname.substr(1);
|
||||||
|
menus[cur_day].addMeal(true, soupname, "", soup_price);
|
||||||
|
cur_day++;
|
||||||
|
if(cur_day > 4)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned long int i = 2; i < pizzas.size(); i++) {
|
||||||
|
auto content = pizzas[i]->find(".//div[@class='b b-text cf']");
|
||||||
|
auto name_candidates = content[0]->find(".//h3/text()");
|
||||||
|
std::string name = nodeToText(name_candidates[0]);
|
||||||
|
auto desc_candidates = content[0]->find(".//p//text()");
|
||||||
|
std::string desc = nodeToText(desc_candidates[0]);
|
||||||
|
auto price_candidates = content[1]->find(".//p/strong/text()");
|
||||||
|
int price = std::stoi(nodeToText(price_candidates[0]));
|
||||||
|
name = trim(name);
|
||||||
|
desc = trim(desc);
|
||||||
|
addPermanent(false, name, desc, price);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
#include "functions.hpp"
|
#include "restaurants.hpp"
|
||||||
|
|
||||||
std::string LunchRest::nodeToText(xmlpp::Node *node) {
|
std::string LunchRest::nodeToText(xmlpp::Node *node) {
|
||||||
return dynamic_cast<const xmlpp::ContentNode *>(node)->get_content();
|
return dynamic_cast<const xmlpp::ContentNode *>(node)->get_content();
|
@ -2,25 +2,57 @@
|
|||||||
#include <libxml++/libxml++.h>
|
#include <libxml++/libxml++.h>
|
||||||
|
|
||||||
namespace LunchRest {
|
namespace LunchRest {
|
||||||
const std::string parseError = "Could not retreive menu";
|
std::string nodeToText(xmlpp::Node *node);
|
||||||
const std::string parseInfo = "Please contact the developer, likely the restaurant website changed and requires a new parser";
|
std::string trim(const std::string &input);
|
||||||
|
class UDrevakaRestaurant : public Restaurant {
|
||||||
|
public:
|
||||||
|
UDrevakaRestaurant() : Restaurant("https://udrevaka.cz/denni-menu/", "U Dřeváka") {}
|
||||||
|
virtual ~UDrevakaRestaurant() = default;
|
||||||
|
virtual void parse() override;
|
||||||
|
};
|
||||||
|
class PadagaliRestaurant : public Restaurant {
|
||||||
|
public:
|
||||||
|
PadagaliRestaurant() : Restaurant("https://padagali.cz/denni-menu/", "Padagali") {}
|
||||||
|
virtual ~PadagaliRestaurant() = default;
|
||||||
|
virtual void parse() override;
|
||||||
|
};
|
||||||
|
class LightOfIndiaRestaurant : public Restaurant {
|
||||||
|
public:
|
||||||
|
LightOfIndiaRestaurant() : Restaurant("http://lightofindia.cz/lang-en/denni-menu", "Light of India") {}
|
||||||
|
virtual ~LightOfIndiaRestaurant() = default;
|
||||||
|
virtual void parse() override;
|
||||||
|
};
|
||||||
class UKarlaRestaurant : public Restaurant {
|
class UKarlaRestaurant : public Restaurant {
|
||||||
public:
|
public:
|
||||||
UKarlaRestaurant() : Restaurant("https://ukarlabrno.cz/denni-menu/", "U Karla") {}
|
UKarlaRestaurant() : Restaurant("https://ukarlabrno.cz/denni-menu/", "U Karla") {}
|
||||||
virtual ~UKarlaRestaurant() = default;
|
virtual ~UKarlaRestaurant() = default;
|
||||||
virtual void parse() override;
|
virtual void parse() override;
|
||||||
};
|
};
|
||||||
class TaoRestaurant : public Restaurant {
|
class AlCaponeRestaurant : public Restaurant {
|
||||||
public:
|
public:
|
||||||
TaoRestaurant() : Restaurant("https://www.taorestaurant.cz/tydenni_menu/nabidka/", "Táo Viet Nam") {}
|
AlCaponeRestaurant() : Restaurant("https://www.pizzaalcapone.cz/cz/poledni-menu", "Al Capone") {}
|
||||||
virtual ~TaoRestaurant() = default;
|
virtual ~AlCaponeRestaurant() = default;
|
||||||
virtual void parse() override;
|
virtual void parse() override;
|
||||||
};
|
};
|
||||||
class MahostinaRestaurant : public Restaurant {
|
class PlacRestaurant : public Restaurant {
|
||||||
public:
|
public:
|
||||||
MahostinaRestaurant() : Restaurant("https://www.mahostina.cz/", "Má Hostina") {}
|
PlacRestaurant() : Restaurant("https://www.bistroplac.cz/poledni-nabidka/", "Bistro Plac") {}
|
||||||
virtual ~MahostinaRestaurant() = default;
|
virtual ~PlacRestaurant() = default;
|
||||||
virtual void parse() override;
|
virtual void parse() override;
|
||||||
};
|
};
|
||||||
|
class ZoRestaurant : public Restaurant {
|
||||||
|
public:
|
||||||
|
ZoRestaurant();
|
||||||
|
virtual ~ZoRestaurant() = default;
|
||||||
|
virtual void parse() override {};
|
||||||
|
};
|
||||||
|
class SuzziesRestaurant : public Restaurant {
|
||||||
|
public:
|
||||||
|
SuzziesRestaurant() : Restaurant("http://suzies.cz/poledni-menu.html", "Suzzie's") {}
|
||||||
|
virtual ~SuzziesRestaurant() = default;
|
||||||
|
virtual void parse() override;
|
||||||
|
private:
|
||||||
|
std::string api_key;
|
||||||
|
};
|
||||||
} // end of namespace LunchRest
|
} // end of namespace LunchRest
|
||||||
|
|
||||||
|
61
restaurants/suzzies.cpp
Normal file
61
restaurants/suzzies.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
int weekDay(const std::string &date_str) {
|
||||||
|
struct tm date_tm;
|
||||||
|
strptime(date_str.c_str(), "%Y-%m-%d %H:%M:%S", &date_tm);
|
||||||
|
return (date_tm.tm_wday + 6) % 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LunchRest::SuzziesRestaurant::parse() {
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html == "")
|
||||||
|
return;
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto days = root.find("//div[@class='day']");
|
||||||
|
for(auto &day : days) {
|
||||||
|
auto *daynum = xmlGetProp(day->cobj(), (xmlChar*)"data-day");
|
||||||
|
int cur_day = 0;
|
||||||
|
switch(daynum[0]) {
|
||||||
|
case '2':
|
||||||
|
cur_day = 1;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
cur_day = 2;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
cur_day = 3;
|
||||||
|
break;
|
||||||
|
case '5':
|
||||||
|
cur_day = 4;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(auto &meal : day->find(".//div[@class='item']")) {
|
||||||
|
Meal meal_obj{};
|
||||||
|
auto type = trim(nodeToText(meal->find(".//h6/text()")[0]));
|
||||||
|
auto name_nodes = meal->find(".//div[@class='title']/text()");
|
||||||
|
auto text_nodes = meal->find(".//div[@class='text']/text()");
|
||||||
|
auto price_nodes = meal->find(".//div[@class='price']/text()");
|
||||||
|
if(price_nodes.size() > 0) {
|
||||||
|
// not soup
|
||||||
|
auto name = type;
|
||||||
|
if(name_nodes.size() > 0)
|
||||||
|
name += " - " + trim(nodeToText(name_nodes[0]));
|
||||||
|
meal_obj.setName(name);
|
||||||
|
if(text_nodes.size() > 0)
|
||||||
|
meal_obj.setDesc(trim(nodeToText(text_nodes[0])));
|
||||||
|
meal_obj.setPrice(std::stoi(trim(nodeToText(price_nodes[0]))));
|
||||||
|
} else {
|
||||||
|
meal_obj.setName(trim(nodeToText(name_nodes[0])));
|
||||||
|
meal_obj.setSoup();
|
||||||
|
}
|
||||||
|
menus[cur_day].addMeal(meal_obj);
|
||||||
|
}
|
||||||
|
menus[cur_day].setInvalidMenu(false);
|
||||||
|
}
|
||||||
|
}
|
@ -1,122 +0,0 @@
|
|||||||
#include "functions.hpp"
|
|
||||||
#include "restaurants.hpp"
|
|
||||||
#include "../network/network.hpp"
|
|
||||||
#include "../htmlparser.hpp"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
std::pair<size_t, size_t> getPricePosFromText(const std::string &text) {
|
|
||||||
size_t price_pos = 0, possible_price = 0;
|
|
||||||
while (possible_price != std::string::npos) {
|
|
||||||
price_pos = possible_price;
|
|
||||||
possible_price = text.find('k', possible_price + 1);
|
|
||||||
}
|
|
||||||
if(price_pos == 0 || price_pos == std::string::npos) {
|
|
||||||
return {-1, -1};
|
|
||||||
}
|
|
||||||
auto end_pos = price_pos;
|
|
||||||
price_pos -= 1;
|
|
||||||
while (text[price_pos] >= '0' && text[price_pos] <= '9') {
|
|
||||||
price_pos -= 1;
|
|
||||||
}
|
|
||||||
price_pos += 1;
|
|
||||||
return { price_pos, end_pos - price_pos };
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getEndOfTextPos(const std::string &text, size_t price_pos) {
|
|
||||||
auto end_pos = price_pos -= 1;
|
|
||||||
while (text[end_pos] == '.' || text[end_pos] == ' ') {
|
|
||||||
end_pos -= 1;
|
|
||||||
}
|
|
||||||
end_pos += 1;
|
|
||||||
return end_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LunchRest::TaoRestaurant::parse() {
|
|
||||||
Request r;
|
|
||||||
auto html = r.get(_url);
|
|
||||||
if (html == "")
|
|
||||||
return;
|
|
||||||
clearMenus();
|
|
||||||
try {
|
|
||||||
HtmlParser hparse(html);
|
|
||||||
auto &root = hparse.getRoot();
|
|
||||||
auto week_meals_html =
|
|
||||||
root.find("//div[@class='ct-div-block']/div[@class='ct-div-block "
|
|
||||||
"tydenni-menu-div']");
|
|
||||||
if (week_meals_html.empty()) {
|
|
||||||
std::cout << "No week meals :(" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto daily_meals_html =
|
|
||||||
root.find("//div[@class='ct-section-inner-wrap']/"
|
|
||||||
"div[@class='ct-div-block tydenni-menu-div']");
|
|
||||||
if (daily_meals_html.empty()) {
|
|
||||||
std::cout << "No daily meals :(" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Meal> week_meals{};
|
|
||||||
for (auto &meal : week_meals_html) {
|
|
||||||
auto texts = meal->find(".//span/text()");
|
|
||||||
if (!texts.empty()) {
|
|
||||||
auto text = nodeToText(texts[0]);
|
|
||||||
auto price_positions = getPricePosFromText(text);
|
|
||||||
if(price_positions.first == (size_t)-1) {
|
|
||||||
week_meals.emplace_back(false, text, "", 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto end_pos = getEndOfTextPos(text, price_positions.first);
|
|
||||||
week_meals.emplace_back(
|
|
||||||
false, text.substr(0, end_pos), "",
|
|
||||||
std::stoi(text.substr(price_positions.first,
|
|
||||||
price_positions.second)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto &meal : daily_meals_html) {
|
|
||||||
auto texts = meal->find(".//span/text()");
|
|
||||||
auto days = meal->find(".//div/b/text()");
|
|
||||||
if (!texts.empty() && !days.empty()) {
|
|
||||||
auto text = nodeToText(texts[0]);
|
|
||||||
auto day = nodeToText(days[0]);
|
|
||||||
auto price_positions = getPricePosFromText(text);
|
|
||||||
if(price_positions.first == (size_t)-1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto end_pos = getEndOfTextPos(text, price_positions.first);
|
|
||||||
|
|
||||||
int cur_day = 0;
|
|
||||||
switch (day[0]) {
|
|
||||||
case 'P':
|
|
||||||
if (day[1] != 'o') {
|
|
||||||
cur_day = 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "Ú"[0]:
|
|
||||||
cur_day = 1;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
cur_day = 2;
|
|
||||||
break;
|
|
||||||
case "Č"[0]:
|
|
||||||
cur_day = 3;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Meal cur_meal(false, text.substr(0, end_pos), "",
|
|
||||||
std::stoi(text.substr(price_positions.first,
|
|
||||||
price_positions.second)));
|
|
||||||
menus[cur_day].addMeal(cur_meal);
|
|
||||||
for (auto &meal : week_meals) {
|
|
||||||
menus[cur_day].addMeal(meal);
|
|
||||||
}
|
|
||||||
menus[cur_day].setInvalidMenu(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (std::exception &/*UNUSED*/) {
|
|
||||||
clearMenus();
|
|
||||||
for(int i = 0; i < menus.size(); i++) {
|
|
||||||
menus[i].addMeal(false, parseError, parseInfo, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
36
restaurants/udrevaka.cpp
Normal file
36
restaurants/udrevaka.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
#include "../network/network.hpp"
|
||||||
|
#include "../htmlparser.hpp"
|
||||||
|
|
||||||
|
void LunchRest::UDrevakaRestaurant::parse() {
|
||||||
|
int menu_index = 0;
|
||||||
|
Request r;
|
||||||
|
auto html = r.get(_url);
|
||||||
|
if(html == "")
|
||||||
|
return;
|
||||||
|
clearMenus();
|
||||||
|
HtmlParser hparse(html);
|
||||||
|
auto &root = hparse.getRoot();
|
||||||
|
auto days = root.find("//li[@class='item-day']");
|
||||||
|
for(auto &day : days) {
|
||||||
|
auto meals = day->find("./div[@class='row']");
|
||||||
|
for(auto &meal : meals) {
|
||||||
|
auto divs = meal->find(".//div/text()");
|
||||||
|
Meal meal_obj{};
|
||||||
|
std::string name = trim(nodeToText(divs[0]));
|
||||||
|
auto soup_pos = name.find("Polévka");
|
||||||
|
if(soup_pos != std::string::npos) {
|
||||||
|
meal_obj.setSoup();
|
||||||
|
meal_obj.setName(name.substr(10, name.find('(') - 11));
|
||||||
|
} else {
|
||||||
|
meal_obj.setName(name.substr(3, name.find('(') - 4));
|
||||||
|
}
|
||||||
|
if(divs.size() > 1) {
|
||||||
|
meal_obj.setPrice(std::stoi(trim(nodeToText(divs[1]))));
|
||||||
|
}
|
||||||
|
menus[menu_index].addMeal(meal_obj);
|
||||||
|
menus[menu_index].setInvalidMenu(false);
|
||||||
|
}
|
||||||
|
menu_index++;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
#include "functions.hpp"
|
|
||||||
#include "restaurants.hpp"
|
#include "restaurants.hpp"
|
||||||
#include "../network/network.hpp"
|
#include "../network/network.hpp"
|
||||||
#include "../htmlparser.hpp"
|
#include "../htmlparser.hpp"
|
||||||
@ -10,7 +9,6 @@ void LunchRest::UKarlaRestaurant::parse() {
|
|||||||
if(html == "")
|
if(html == "")
|
||||||
return;
|
return;
|
||||||
clearMenus();
|
clearMenus();
|
||||||
try {
|
|
||||||
HtmlParser hparse(html);
|
HtmlParser hparse(html);
|
||||||
auto &root = hparse.getRoot();
|
auto &root = hparse.getRoot();
|
||||||
auto days = root.find("//li[@class='item-day']");
|
auto days = root.find("//li[@class='item-day']");
|
||||||
@ -21,10 +19,6 @@ void LunchRest::UKarlaRestaurant::parse() {
|
|||||||
for(auto &meal : meals) {
|
for(auto &meal : meals) {
|
||||||
auto soup = false;
|
auto soup = false;
|
||||||
auto texts = meal->find("./div/text()");
|
auto texts = meal->find("./div/text()");
|
||||||
if(texts.empty()) {
|
|
||||||
menus[menu_index].addMeal(false, parseError, parseInfo, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::string name = trim(nodeToText(texts[0]));
|
std::string name = trim(nodeToText(texts[0]));
|
||||||
if(name[0] == 'P') {
|
if(name[0] == 'P') {
|
||||||
soup = true;
|
soup = true;
|
||||||
@ -40,10 +34,4 @@ void LunchRest::UKarlaRestaurant::parse() {
|
|||||||
}
|
}
|
||||||
menu_index++;
|
menu_index++;
|
||||||
}
|
}
|
||||||
} catch (std::exception &/*UNUSED*/) {
|
|
||||||
clearMenus();
|
|
||||||
for(int i = 0; i < menus.size(); i++) {
|
|
||||||
menus[i].addMeal(false, parseError, parseInfo, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
31
restaurants/zo.cpp
Normal file
31
restaurants/zo.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "restaurants.hpp"
|
||||||
|
|
||||||
|
LunchRest::ZoRestaurant::ZoRestaurant() : Restaurant("", "Zo!") {
|
||||||
|
clearMenus();
|
||||||
|
addPermanent(true, "Pho Bo", "Rýžové nudle pho v hovězím vývaru, hovězí maso, vietnamské bylinky", 120);
|
||||||
|
addPermanent(true, "Pho Bo Tai Lan", "Rýžové nudle pho v hovězím vývaru, RESTOVANÉ hovězí maso, vietnamské bylinky", 120);
|
||||||
|
addPermanent(true, "Bun Bo Hue", "Rýžové nudle bun v hovězím vývaru po Hue, masové kuličky, krevetová pasta", 120);
|
||||||
|
addPermanent(true, "Bun Tom", "Rýžové nudle bun s krevety", 120);
|
||||||
|
addPermanent(true, "Bun Dau", "Rýžové nudle bun v zeleninovém vývaru, tofu", 120);
|
||||||
|
addPermanent(true, "Pho Bo Bam", "Rýžové nudle pho, syrové nasekané hovězí maso zalité hovězím vývarem, vietnamské bylinky", 135);
|
||||||
|
addPermanent(true, "Bun Moc", "Rýžové nudle bun, kuřecí vývar s masovými kuličky, houbami a bylinkami", 125);
|
||||||
|
addPermanent(false, "Bun Bo Nam Bo", "Rýžové nudle bun, hovězí maso, vietnamské bylinky, sladkokyselá zálivka", 135);
|
||||||
|
addPermanent(false, "Bun Ga Tron", "Rýžové nudle bun s restovaným kuřecím masem, vietnamské bylinky, omáčka ZO!", 135);
|
||||||
|
addPermanent(false, "Bun Dau Zo", "Podobné jako Bun Bo Nam Bo, ale s tofu", 120);
|
||||||
|
addPermanent(false, "Bun Tom Tron", "Rýžové nudle bun s krevety, vietnamské bylinky, omáčka ZO!", 135);
|
||||||
|
addPermanent(false, "Zo Bowl", "Miska plná rýžových nudlí a zeleniny, hrášek, houby shitake, brokolice, mungo, arašídová omáčka", 135);
|
||||||
|
addPermanent(false, "Mi Orizo", "Orestované nudle z naší kuchyně, Vyberte si: kuřecí (120), hovězí (130)", 120);
|
||||||
|
addPermanent(false, "Ban Da Xao", "Orestované jižanské placaté rýžové nudle, Vyberte si: kuřecí (120), hovězí (135)", 120);
|
||||||
|
addPermanent(false, "Mi Udozo", "Orestované udon nudle po našem stylu, Vyberte si: kuřecí, hovězí", 135);
|
||||||
|
addPermanent(false, "Bun Ngan Nuong", "Grilované kachní maso, rýžové nudle bun, vietnamské bylinky, sojová omáčka", 155);
|
||||||
|
addPermanent(false, "Bun Cha", "Grilované vepřové maso, rýžové nudle bun, vietnamské bylinky, sladkokyselá zálivka", 135);
|
||||||
|
addPermanent(false, "Salát Bo Zo", "Smažené obalené kousky avokáda, zelenina, ředkev", 135);
|
||||||
|
addPermanent(false, "Com Xuat dle šéfkuchaře", "Vyberte si základ (kuřecí, vepřové, hovězí, krevetové, tofu), my domyslíme zbytek, rýže, zelenina", 135);
|
||||||
|
addPermanent(false, "Rýže s kari omáčkou", "Vyberte si: kuřecí, hovězí, krevety, tofu", 120);
|
||||||
|
addPermanent(false, "Vitský", "Smažená kachna podávaná s bambusovými výhonky a rýží", 155);
|
||||||
|
addPermanent(false, "Nem Ran 2ks", "Smažené rolky", 50);
|
||||||
|
addPermanent(false, "Nem Cuon Tom 2ks", "Smažené rolky plněné krevetami", 50);
|
||||||
|
addPermanent(false, "Nem Cuon Bo 2ks", "Nesmažené rolky plněné avokádem podle Zo", 70);
|
||||||
|
addPermanent(false, "Nem Cuon Vege 2ks", "Nesmažené rolky plněné tofu", 50);
|
||||||
|
addPermanent(false, "Nem Ran Vege 2ks", "Smažené rolky plněné zeleninou (bez masa)", 50);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user