diff --git a/Makefile b/Makefile index ccec818..3a3e548 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS ?= -O2 -Wall -Wextra `pkg-config libxml-2.0 --cflags` `pkg-config libxml+ 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 suzies.o +PARSERS = udrevaka.o padagali.o lightofindia.o ukarla.o alcapone.o plac.o zo.o suzies.o tao.o .PHONY: default default: menuprint @@ -37,7 +37,9 @@ plac.o: restaurants/plac.cpp restaurants/restaurants.hpp network/network.hpp htm $(CXX) $(CFLAGS) -c -o $@ $< zo.o: restaurants/zo.cpp restaurants/restaurants.hpp network/network.hpp htmlparser.hpp $(CXX) $(CFLAGS) -c -o $@ $< -suzies.o: restaurants/suzies.cpp restaurants/restaurants.hpp network/network.hpp environment.hpp +suzies.o: restaurants/suzies.cpp restaurants/restaurants.hpp network/network.hpp htmlparser.hpp + $(CXX) $(CFLAGS) -c -o $@ $< +tao.o: restaurants/tao.cpp restaurants/restaurants.hpp network/network.hpp htmlparser.hpp $(CXX) $(CFLAGS) -c -o $@ $< clean: diff --git a/main.cpp b/main.cpp index b3c3560..97dc28d 100644 --- a/main.cpp +++ b/main.cpp @@ -109,6 +109,7 @@ int main(int /*UNUSED*/, char ** /*UNUSED*/, char **env) { restaurants["plac"] = std::make_unique(); restaurants["zo"] = std::make_unique(); restaurants["suzies"] = std::make_unique(); + restaurants["tao"] = std::make_unique(); std::cout << "Initial parsing" << std::endl; for (auto &restaurant : restaurants) restaurant.second->parse(); @@ -131,20 +132,20 @@ int main(int /*UNUSED*/, char ** /*UNUSED*/, char **env) { refreshserv->set_method_handler("GET", refresh); service.publish(refreshserv); -/* auto ssl_settings = std::make_shared(); - ssl_settings->set_http_disabled(true); - ssl_settings->set_private_key(restbed::Uri( - "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_temporary_diffie_hellman(restbed::Uri( - "file:///home/zvon/data/programming/lunch-rest/dhparams.pem")); - ssl_settings->set_port(1985);*/ + /* auto ssl_settings = std::make_shared(); + ssl_settings->set_http_disabled(true); + ssl_settings->set_private_key(restbed::Uri( + "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_temporary_diffie_hellman(restbed::Uri( + "file:///home/zvon/data/programming/lunch-rest/dhparams.pem")); + ssl_settings->set_port(1985);*/ auto settings = std::make_shared(); settings->set_port(1984); settings->set_default_header("Connection", "close"); -// settings->set_ssl_settings(ssl_settings); + // settings->set_ssl_settings(ssl_settings); service.start(settings); diff --git a/restaurants/restaurants.hpp b/restaurants/restaurants.hpp index fa2b2a4..ddf8504 100644 --- a/restaurants/restaurants.hpp +++ b/restaurants/restaurants.hpp @@ -51,8 +51,12 @@ public: SuziesRestaurant() : Restaurant("https://www.suzies.cz/poledni-menu", "Suzie's") {} virtual ~SuziesRestaurant() = default; virtual void parse() override; -private: - std::string api_key; +}; +class TaoRestaurant : public Restaurant { +public: + TaoRestaurant() : Restaurant("https://www.taorestaurant.cz/tydenni_menu/nabidka/", "Táo Viet Nam") {} + virtual ~TaoRestaurant() = default; + virtual void parse() override; }; } // end of namespace LunchRest diff --git a/restaurants/suzies.cpp b/restaurants/suzies.cpp index 29bd1ee..5541e20 100644 --- a/restaurants/suzies.cpp +++ b/restaurants/suzies.cpp @@ -3,12 +3,6 @@ #include "../htmlparser.hpp" #include -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::SuziesRestaurant::parse() { Request r; auto html = r.get(_url); diff --git a/restaurants/tao.cpp b/restaurants/tao.cpp new file mode 100644 index 0000000..9a20eb7 --- /dev/null +++ b/restaurants/tao.cpp @@ -0,0 +1,102 @@ +#include "restaurants.hpp" +#include "../network/network.hpp" +#include "../htmlparser.hpp" +#include + +std::pair 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); + } + 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(); + 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; + } + 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; + } + + std::vector 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); + 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); + 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); + } + } +}