From 83fded33e014fea15781be18bd67398b9d5106be Mon Sep 17 00:00:00 2001 From: zvon Date: Tue, 15 Sep 2020 16:05:16 +0200 Subject: [PATCH] Add get function, alcapone parser --- Makefile | 6 +- main.cpp | 137 +++++++++++++++++++++++++++++---------- menu.cpp | 6 +- menu.hpp | 2 +- parser.hpp | 6 ++ parsers/alcapone.cpp | 54 +++++++++++++++ parsers/lightofindia.cpp | 7 +- parsers/padagali.cpp | 11 ++-- parsers/parsers.hpp | 8 ++- parsers/udrevaka.cpp | 11 ++-- parsers/ukarla.cpp | 15 ++--- 11 files changed, 203 insertions(+), 60 deletions(-) create mode 100644 parsers/alcapone.cpp diff --git a/Makefile b/Makefile index 21ed062..d4c568f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ CXX ?= g++ -CFLAGS ?= -O2 -Wall -Wextra `pkg-config libxml-2.0 --cflags` `pkg-config libxml++-3.0 --cflags` +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 +PARSERS = udrevaka.o padagali.o lightofindia.o ukarla.o alcapone.o .PHONY: default default: menuprint @@ -27,6 +27,8 @@ lightofindia.o: parsers/lightofindia.cpp parsers/parsers.hpp network/network.hpp $(CXX) $(CFLAGS) -c -o $@ $< ukarla.o: parsers/ukarla.cpp parsers/parsers.hpp network/network.hpp htmlparser.hpp $(CXX) $(CFLAGS) -c -o $@ $< +alcapone.o: parsers/alcapone.cpp parsers/parsers.hpp network/network.hpp htmlparser.hpp + $(CXX) $(CFLAGS) -c -o $@ $< clean: rm -Rf *.o menuprint diff --git a/main.cpp b/main.cpp index 9ab3037..4a48da9 100644 --- a/main.cpp +++ b/main.cpp @@ -11,70 +11,137 @@ std::vector days = {"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY"}; std::vector> parsers; -/*int main() { - std::vector> parsers; - parsers.emplace_back(new LunchRest::UDrevakaParser()); - parsers.emplace_back(new LunchRest::PadagaliParser()); - parsers.emplace_back(new LunchRest::LightOfIndiaParser()); - parsers.emplace_back(new LunchRest::UKarlaParser()); - // add parsers here - for(auto &x : parsers) { - x->parse(); - std::cout << "RESTAURANT " << x->getRestaurant() << std::endl; - for(unsigned long int i = 0; i < x->getMenus().size(); i++) { - auto y = x->getMenus()[i]; - if(y.isValid()) { - std::cout << days[i] << std::endl; - auto soupInd = y.getSoupIndex(); - std::cout << "\t" << y.getMeals()[soupInd] << std::endl; - for(unsigned long int i = 0; i < y.getMeals().size(); i++) { - if(i != soupInd) - std::cout << "\t" << y.getMeals()[i] << std::endl; - } - } - } - } -}*/ - void get_all( const std::shared_ptr< restbed::Session > session ) { std::stringstream ss{}; + bool atleastonerest = false; ss << "["; for(auto &x : parsers) { + atleastonerest = true; ss << "{\"restaurant\": \"" << x->getRestaurant() << "\", \"menus\": ["; + bool atleastonemenu = false; for(const auto &y : x->getMenus()) { - if(y.isValid()) { - ss << y.jsonify() << ","; - } + atleastonemenu = true; + ss << y.jsonify() << ","; } - ss.seekp(-1, ss.cur); + if(atleastonemenu) + ss.seekp(-1, ss.cur); ss << "]},"; } - ss.seekp(-1, ss.cur); + if(atleastonerest) + ss.seekp(-1, ss.cur); ss << "]"; auto res = ss.str(); session->close(restbed::OK, res, { { "Content-Length", std::to_string(res.length()) } }); } +void get( const std::shared_ptr< restbed::Session > session ) { + // TODO better + int day = -1; + int restaurant = -1; + auto request = session->get_request(); + for(const auto query_param : request->get_query_parameters()) { + if(query_param.first == "day") { + if(query_param.second == "monday") { + day = 0; + } else if(query_param.second == "tuesday") { + day = 1; + } else if(query_param.second == "wednesday") { + day = 2; + } else if(query_param.second == "thursday") { + day = 3; + } else { + day = 4; + } + } + if(query_param.first == "restaurant") { + if(query_param.second == "udrevaka") { + restaurant = 0; + } else if(query_param.second == "padagali") { + restaurant = 1; + } else if(query_param.second == "lightofindia") { + restaurant = 2; + } else if(query_param.second == "ukarla") { + restaurant = 3; + } else { + restaurant = 4; + } + } + } + std::string error = "DIDN'T SPECIFY DAY OR RESTAURANT"; + if(day == -1 && restaurant == -1) { + session->close(restbed::OK, error, { { "Content-Length", std::to_string(error.length()) } }); + return; + } + + std::stringstream ss{}; + if(day != -1 && restaurant != -1) { + auto &x = parsers[restaurant]; + ss << "[{\"restaurant\": \"" << x->getRestaurant() << "\", \"menus\": ["; + ss << x->getMenus()[day].jsonify(); + ss << "]}]"; + } else if(day != -1) { + ss << "["; + bool atleastone = false; + for(auto &x : parsers) { + atleastone = true; + ss << "{\"restaurant\": \"" << x->getRestaurant() << "\", \"menus\": ["; + ss << x->getMenus()[day].jsonify(); + ss << "]},"; + } + if(atleastone) + ss.seekp(-1, ss.cur); + ss << "]"; + } else if(restaurant != -1) { + auto &x = parsers[restaurant]; + ss << "[{\"restaurant\": \"" << x->getRestaurant() << "\", \"menus\": ["; + bool atleastone = false; + for(auto &y : x->getMenus()) { + atleastone = true; + ss << y.jsonify() << ","; + } + if(atleastone) + ss.seekp(-1, ss.cur); + ss << "]}]"; + } + auto res = ss.str(); + session->close(restbed::OK, res, { { "Content-Length", std::to_string(res.length()) } }); +} + int main() { parsers.emplace_back(new LunchRest::UDrevakaParser()); parsers.emplace_back(new LunchRest::PadagaliParser()); parsers.emplace_back(new LunchRest::LightOfIndiaParser()); parsers.emplace_back(new LunchRest::UKarlaParser()); + parsers.emplace_back(new LunchRest::AlCaponeParser()); std::cout << "Initial parsing" << std::endl; for(auto &x : parsers) x->parse(); std::cout << "Finished parsing" << std::endl; - auto resource = std::make_shared< restbed::Resource >(); - resource->set_path("/get_all"); - resource->set_method_handler( "GET", get_all ); + restbed::Service service; + + auto getallserv = std::make_shared< restbed::Resource >(); + getallserv->set_path("/get_all"); + getallserv->set_method_handler( "GET", get_all ); + service.publish(getallserv); + + auto getserv = std::make_shared< restbed::Resource >(); + getserv->set_path("/get"); + getserv->set_method_handler( "GET", get ); + service.publish(getserv); + + 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< restbed::Settings >(); settings->set_port(1984); settings->set_default_header( "Connection", "close" ); + settings->set_ssl_settings(ssl_settings); - restbed::Service service; - service.publish(resource); service.start(settings); return 0; diff --git a/menu.cpp b/menu.cpp index 4c0b6e1..2d572fb 100644 --- a/menu.cpp +++ b/menu.cpp @@ -46,8 +46,8 @@ unsigned long int LunchRest::Menu::getSoupIndex() const { return -1; } -void LunchRest::Menu::setInvalidMenu() { - _valid = false; +void LunchRest::Menu::setInvalidMenu(bool invalid) { + _valid = !invalid; } bool LunchRest::Menu::isValid() const { @@ -55,6 +55,8 @@ bool LunchRest::Menu::isValid() const { } std::string LunchRest::Menu::jsonify() const { + if(!isValid()) + return "[]"; std::stringstream ss{}; ss << "["; auto soupInd = getSoupIndex(); diff --git a/menu.hpp b/menu.hpp index bd61a03..4c70b05 100644 --- a/menu.hpp +++ b/menu.hpp @@ -19,7 +19,7 @@ public: std::vector getNonSoupMeals(); const std::vector &getMeals() const; unsigned long int getSoupIndex() const; - void setInvalidMenu(); + void setInvalidMenu( bool invalid = true ); bool isValid() const; std::string jsonify() const; private: diff --git a/parser.hpp b/parser.hpp index e47de3f..822a703 100644 --- a/parser.hpp +++ b/parser.hpp @@ -17,6 +17,12 @@ public: return _restaurant; } virtual void parse() = 0; + void clearMenus() { + menus.clear(); + menus.resize(5); + for(auto &x : menus) + x.setInvalidMenu(); + } protected: std::string _url; std::string _restaurant; diff --git a/parsers/alcapone.cpp b/parsers/alcapone.cpp new file mode 100644 index 0000000..0210767 --- /dev/null +++ b/parsers/alcapone.cpp @@ -0,0 +1,54 @@ +#include "parsers.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::AlCaponeParser::parse() { + menus.clear(); + Request r; + auto html = r.get(_url); + if(html == "") + return; + menus.resize(5); + for(auto &menu : menus) + menu.setInvalidMenu(); + 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 = dynamic_cast(row->find("./td[@class='bg1']/text()")[0])->get_content(); + 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; + 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 = dynamic_cast(menu_info[0])->get_content(); + std::string name = dynamic_cast(meal_data[0])->get_content(); + name = removeAlergens(name); + if(menu == "Polévka") { + menus[cur_day].addMeal(true, name, "", 0); + } else { + menus[cur_day].addMeal(false, name, "", std::stoi(dynamic_cast(meal_data[1])->get_content())); + } + } +} diff --git a/parsers/lightofindia.cpp b/parsers/lightofindia.cpp index 8493057..c8ce542 100644 --- a/parsers/lightofindia.cpp +++ b/parsers/lightofindia.cpp @@ -13,17 +13,17 @@ bool isWhiteSpaceOnly(const std::string &text) { } void LunchRest::LightOfIndiaParser::parse() { - menus.clear(); - menus.resize(5); + clearMenus(); Request r; auto html = r.get(_url); + if(html == "") + return; 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) { - Menu m{}; std::string text_text = dynamic_cast(text)->get_content(); if(isWhiteSpaceOnly(text_text) || text_text.find("Week") != std::string::npos) continue; @@ -39,5 +39,6 @@ void LunchRest::LightOfIndiaParser::parse() { 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); } } diff --git a/parsers/padagali.cpp b/parsers/padagali.cpp index b901b73..2422528 100644 --- a/parsers/padagali.cpp +++ b/parsers/padagali.cpp @@ -3,15 +3,17 @@ #include "../htmlparser.hpp" void LunchRest::PadagaliParser::parse() { - menus.clear(); + clearMenus(); + int menu_index = 0; Request r; auto html = r.get(_url); + if(html == "") + return; HtmlParser hparse(html); auto &root = hparse.getRoot(); auto days = root.find("//div[@class='glf-mor-restaurant-menu-category']"); for(int i = 0; i < 5; i++) { auto day = days[i]; - Menu m{}; auto meals = day->find("./div"); for(auto &meal : meals) { auto info = meal->find("./div/div/div"); @@ -19,8 +21,9 @@ void LunchRest::PadagaliParser::parse() { std::string name = dynamic_cast(info[0]->find("./h5/text()")[0])->get_content(); int price = std::stoi(dynamic_cast(info[0]->find("./div/text()")[0])->get_content()); bool soup = name.find("Soup") == std::string::npos ? false : true; - m.addMeal(soup, name, desc, price); + menus[menu_index].addMeal(soup, name, desc, price); + menus[menu_index].setInvalidMenu(false); } - menus.push_back(m); + menu_index++; } } diff --git a/parsers/parsers.hpp b/parsers/parsers.hpp index a27fe63..d12d253 100644 --- a/parsers/parsers.hpp +++ b/parsers/parsers.hpp @@ -21,9 +21,15 @@ public: }; class UKarlaParser : public Parser { public: - UKarlaParser() : Parser("https://www.ukarlabrno.cz/denni-menu/", "Light of India") {} + UKarlaParser() : Parser("https://www.ukarlabrno.cz/denni-menu/", "U Karla") {} virtual ~UKarlaParser() = default; virtual void parse() override; }; +class AlCaponeParser : public Parser { +public: + AlCaponeParser() : Parser("https://www.pizzaalcapone.cz/cz/poledni-menu", "Al Capone") {} + virtual ~AlCaponeParser() = default; + virtual void parse() override; +}; } // end of namespace LunchRest diff --git a/parsers/udrevaka.cpp b/parsers/udrevaka.cpp index dfe3964..3baab7e 100644 --- a/parsers/udrevaka.cpp +++ b/parsers/udrevaka.cpp @@ -3,14 +3,16 @@ #include "../htmlparser.hpp" void LunchRest::UDrevakaParser::parse() { - menus.clear(); + clearMenus(); + int menu_index = 0; Request r; auto html = r.get(_url); + if(html == "") + return; HtmlParser hparse(html); auto &root = hparse.getRoot(); auto days = root.find("//li[@class='item-day']"); for(auto &day : days) { - Menu m{}; auto meals = day->find("./div[@class='row']"); for(auto meal : meals) { auto divs = meal->find(".//div/text()"); @@ -27,8 +29,9 @@ void LunchRest::UDrevakaParser::parse() { std::string price = dynamic_cast(divs[1])->get_content();; meal_obj.setPrice(std::stoi(price)); } - m.addMeal(meal_obj); + menus[menu_index].addMeal(meal_obj); + menus[menu_index].setInvalidMenu(false); } - menus.push_back(m); + menu_index++; } } diff --git a/parsers/ukarla.cpp b/parsers/ukarla.cpp index c921c24..d23ae3e 100644 --- a/parsers/ukarla.cpp +++ b/parsers/ukarla.cpp @@ -3,16 +3,18 @@ #include "../htmlparser.hpp" void LunchRest::UKarlaParser::parse() { - menus.clear(); + clearMenus(); + int menu_index = 0; Request r; auto html = r.get(_url); + if(html == "") + return; HtmlParser hparse(html); auto &root = hparse.getRoot(); auto days = root.find("//li[@class='item-day']"); int validdays = 0; for(auto &day : days) { validdays++; - Menu m{}; auto meals = day->find("./div[@class='row']"); for(auto &meal : meals) { auto soup = false; @@ -25,12 +27,9 @@ void LunchRest::UKarlaParser::parse() { int price = -1; if(texts.size() > 1) price = std::stoi(dynamic_cast(texts[1])->get_content()); - m.addMeal(soup, name, "", price); + menus[menu_index].addMeal(soup, name, "", price); + menus[menu_index].setInvalidMenu(false); } - menus.push_back(m); - } - for(int i = validdays; i < 5; i++) { - menus.push_back(Menu{}); - menus.back().setInvalidMenu(); + menu_index++; } }