Add get function, alcapone parser

This commit is contained in:
zvon 2020-09-15 16:05:16 +02:00
parent 0349b3a300
commit 83fded33e0
11 changed files with 203 additions and 60 deletions

View File

@ -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

137
main.cpp
View File

@ -11,70 +11,137 @@
std::vector<std::string> days = {"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY"};
std::vector<std::unique_ptr<LunchRest::Parser>> parsers;
/*int main() {
std::vector<std::unique_ptr<LunchRest::Parser>> 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<restbed::SSLSettings>();
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;

View File

@ -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();

View File

@ -19,7 +19,7 @@ public:
std::vector<Meal> getNonSoupMeals();
const std::vector<Meal> &getMeals() const;
unsigned long int getSoupIndex() const;
void setInvalidMenu();
void setInvalidMenu( bool invalid = true );
bool isValid() const;
std::string jsonify() const;
private:

View File

@ -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;

54
parsers/alcapone.cpp Normal file
View File

@ -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<const xmlpp::ContentNode *>(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<const xmlpp::ContentNode *>(menu_info[0])->get_content();
std::string name = dynamic_cast<const xmlpp::ContentNode *>(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<const xmlpp::ContentNode *>(meal_data[1])->get_content()));
}
}
}

View File

@ -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<const xmlpp::ContentNode *>(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);
}
}

View File

@ -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<const xmlpp::ContentNode *>(info[0]->find("./h5/text()")[0])->get_content();
int price = std::stoi(dynamic_cast<const xmlpp::ContentNode *>(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++;
}
}

View File

@ -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

View File

@ -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<const xmlpp::ContentNode *>(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++;
}
}

View File

@ -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<const xmlpp::ContentNode *>(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++;
}
}