Add try/catch

This commit is contained in:
zv0n 2022-09-24 23:13:42 +02:00
parent ae57b4c06e
commit 913c8fd168
5 changed files with 188 additions and 153 deletions

View File

@ -10,30 +10,37 @@ void LunchRest::MahostinaRestaurant::parse() {
if (html == "") if (html == "")
return; return;
clearMenus(); clearMenus();
HtmlParser hparse(html); try {
auto &root = hparse.getRoot(); HtmlParser hparse(html);
auto today_lists = root.find( auto &root = hparse.getRoot();
"//div[@id='dnesnibasta-section']//ul[@data-rte-list='default']"); auto today_lists = root.find(
if (today_lists.empty()) { "//div[@id='dnesnibasta-section']//ul[@data-rte-list='default']");
std::cout << "No meals :(" << std::endl; if (today_lists.empty()) {
return; std::cout << "No meals :(" << std::endl;
} return;
}
time_t t = time(nullptr);
tm *timePtr = localtime(&t); time_t t = time(nullptr);
auto day = (timePtr->tm_wday + 6) % 7; 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); for (auto &meal : today_lists[0]->find("./li/p/text()")) {
auto price_end = text.find(",-"); auto text = nodeToText(meal);
auto price_start = price_end - 1; auto price_end = text.find(",-");
while (text[price_start] >= '0' && text[price_start] <= '9') { auto price_start = price_end - 1;
price_start -= 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);
} }
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);
} }

View File

@ -1,4 +1,5 @@
#include "menicka.hpp" #include "menicka.hpp"
#include "restaurants.hpp"
#include "../network/network.hpp" #include "../network/network.hpp"
#include "../htmlparser.hpp" #include "../htmlparser.hpp"
#include "functions.hpp" #include "functions.hpp"
@ -24,50 +25,57 @@ void LunchRest::MenickaRestaurant::parse() {
if(html == "") if(html == "")
return; return;
clearMenus(); clearMenus();
HtmlParser hparse(html); try {
auto &root = hparse.getRoot(); HtmlParser hparse(html);
auto days = root.find("//div[@class='menicka']"); auto &root = hparse.getRoot();
for(auto &day : days) { auto days = root.find("//div[@class='menicka']");
auto daytext = day->find("./div[@class='nadpis']/text()"); for(auto &day : days) {
auto soup = day->find("./ul/li[@class='polevka']"); auto daytext = day->find("./div[@class='nadpis']/text()");
auto meals = day->find("./ul/li[@class='jidlo']"); auto soup = day->find("./ul/li[@class='polevka']");
if(daytext.size() == 0) { auto meals = day->find("./ul/li[@class='jidlo']");
continue; if(daytext.size() == 0) {
} continue;
}
auto daystr = nodeToText(daytext[0]); auto daystr = nodeToText(daytext[0]);
int cur_day = 0; int cur_day = 0;
switch (daystr[0]) { switch (daystr[0]) {
case 'P': case 'P':
if (daystr[1] != 'o') { if (daystr[1] != 'o') {
cur_day = 4; cur_day = 4;
}
break;
case "Ú"[0]:
cur_day = 1;
break;
case 'S':
cur_day = 2;
break;
case "Č"[0]:
cur_day = 3;
default:
break;
} }
break; if(soup.size() != 0) {
case "Ú"[0]: auto soupData = getNameAndPrice(soup[0]);
cur_day = 1; if(!soupData.first.empty()) {
break; menus[cur_day].addMeal(Meal(true, soupData.first, "", soupData.second));
case 'S': }
cur_day = 2; }
break; for(auto &meal : meals) {
case "Č"[0]: auto mealData = getNameAndPrice(meal);
cur_day = 3; if(!mealData.first.empty()) {
default: menus[cur_day].addMeal(Meal(false, mealData.first, "", mealData.second));
break; }
} }
if(soup.size() != 0) { if(!menus[cur_day].getMeals().empty()) {
auto soupData = getNameAndPrice(soup[0]); menus[cur_day].setInvalidMenu(false);
if(!soupData.first.empty()) {
menus[cur_day].addMeal(Meal(true, soupData.first, "", soupData.second));
} }
} }
for(auto &meal : meals) { } catch (std::exception &/*UNUSED*/) {
auto mealData = getNameAndPrice(meal); clearMenus();
if(!mealData.first.empty()) { for(int i = 0; i < menus.size(); i++) {
menus[cur_day].addMeal(Meal(false, mealData.first, "", mealData.second)); menus[i].addMeal(false, parseError, parseInfo, 0);
}
}
if(!menus[cur_day].getMeals().empty()) {
menus[cur_day].setInvalidMenu(false);
} }
} }
} }

View File

@ -2,6 +2,8 @@
#include <libxml++/libxml++.h> #include <libxml++/libxml++.h>
namespace LunchRest { namespace LunchRest {
const std::string parseError = "Could not retreive menu";
const std::string parseInfo = "Please contact the developer, likely the restaurant website changed and requires a new parser";
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") {}

View File

@ -37,79 +37,86 @@ void LunchRest::TaoRestaurant::parse() {
if (html == "") if (html == "")
return; return;
clearMenus(); clearMenus();
HtmlParser hparse(html); try {
auto &root = hparse.getRoot(); HtmlParser hparse(html);
auto week_meals_html = auto &root = hparse.getRoot();
root.find("//div[@class='ct-div-block']/div[@class='ct-div-block " auto week_meals_html =
"tydenni-menu-div']"); root.find("//div[@class='ct-div-block']/div[@class='ct-div-block "
if (week_meals_html.empty()) { "tydenni-menu-div']");
std::cout << "No week meals :(" << std::endl; if (week_meals_html.empty()) {
return; std::cout << "No week meals :(" << std::endl;
} return;
auto daily_meals_html = }
root.find("//div[@class='ct-section-inner-wrap']/" auto daily_meals_html =
"div[@class='ct-div-block tydenni-menu-div']"); root.find("//div[@class='ct-section-inner-wrap']/"
if (daily_meals_html.empty()) { "div[@class='ct-div-block tydenni-menu-div']");
std::cout << "No daily meals :(" << std::endl; if (daily_meals_html.empty()) {
return; 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; std::vector<Meal> week_meals{};
switch (day[0]) { for (auto &meal : week_meals_html) {
case 'P': auto texts = meal->find(".//span/text()");
if (day[1] != 'o') { if (!texts.empty()) {
cur_day = 4; 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;
} }
break; auto end_pos = getEndOfTextPos(text, price_positions.first);
case "Ú"[0]: week_meals.emplace_back(
cur_day = 1; false, text.substr(0, end_pos), "",
break; std::stoi(text.substr(price_positions.first,
case 'S': price_positions.second)));
cur_day = 2;
break;
case "Č"[0]:
cur_day = 3;
default:
break;
} }
}
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);
Meal cur_meal(false, text.substr(0, end_pos), "", int cur_day = 0;
std::stoi(text.substr(price_positions.first, switch (day[0]) {
price_positions.second))); case 'P':
menus[cur_day].addMeal(cur_meal); if (day[1] != 'o') {
for (auto &meal : week_meals) { cur_day = 4;
menus[cur_day].addMeal(meal); }
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);
} }
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);
} }
} }
} }

View File

@ -10,29 +10,40 @@ void LunchRest::UKarlaRestaurant::parse() {
if(html == "") if(html == "")
return; return;
clearMenus(); clearMenus();
HtmlParser hparse(html); try {
auto &root = hparse.getRoot(); HtmlParser hparse(html);
auto days = root.find("//li[@class='item-day']"); auto &root = hparse.getRoot();
int validdays = 0; auto days = root.find("//li[@class='item-day']");
for(auto &day : days) { int validdays = 0;
validdays++; for(auto &day : days) {
auto meals = day->find("./div[@class='row']"); validdays++;
for(auto &meal : meals) { auto meals = day->find("./div[@class='row']");
auto soup = false; for(auto &meal : meals) {
auto texts = meal->find("./div/text()"); auto soup = false;
std::string name = trim(nodeToText(texts[0])); auto texts = meal->find("./div/text()");
if(name[0] == 'P') { if(texts.empty()) {
soup = true; menus[menu_index].addMeal(false, parseError, parseInfo, 0);
name = name.substr(10); continue;
} else { }
name = name.substr(3); std::string name = trim(nodeToText(texts[0]));
if(name[0] == 'P') {
soup = true;
name = name.substr(10);
} else {
name = name.substr(3);
}
int price = -1;
if(texts.size() > 1)
price = std::stoi(trim(nodeToText(texts[1])));
menus[menu_index].addMeal(soup, name, "", price);
menus[menu_index].setInvalidMenu(false);
} }
int price = -1; menu_index++;
if(texts.size() > 1) }
price = std::stoi(trim(nodeToText(texts[1]))); } catch (std::exception &/*UNUSED*/) {
menus[menu_index].addMeal(soup, name, "", price); clearMenus();
menus[menu_index].setInvalidMenu(false); for(int i = 0; i < menus.size(); i++) {
menus[i].addMeal(false, parseError, parseInfo, 0);
} }
menu_index++;
} }
} }