2024-11-22 23:26:42 +03:00
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#include <codecvt>
|
2024-11-27 01:46:36 +03:00
|
|
|
#include <cstring>
|
|
|
|
#include <iostream>
|
2024-11-22 23:26:42 +03:00
|
|
|
#include <locale>
|
2024-11-27 01:46:36 +03:00
|
|
|
#include <regex>
|
2024-11-22 23:26:42 +03:00
|
|
|
#include <string>
|
2024-11-28 00:28:37 +03:00
|
|
|
#include "../exceptions/ofdrequestexception.h"
|
2024-11-22 23:26:42 +03:00
|
|
|
|
|
|
|
std::string to_utf8(std::wstring wide_string) {
|
|
|
|
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
|
|
|
return utf8_conv.to_bytes(wide_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring from_utf8(std::string string) {
|
|
|
|
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
|
|
|
return utf8_conv.from_bytes(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string get_path_relative_to_home(std::string path) {
|
|
|
|
return std::string(std::getenv("HOME")) + "/" + path;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool vector_contains_element(const std::vector<T>& vector, const T& to_find) {
|
|
|
|
for (const T& element : vector) {
|
|
|
|
if (element == to_find) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//ужас
|
|
|
|
template bool vector_contains_element<std::string>(const std::vector<std::string>& vector, const std::string& to_find);
|
|
|
|
|
|
|
|
std::vector<std::string> split(std::string s, std::string delimiter) {
|
|
|
|
std::vector<std::string> result;
|
|
|
|
size_t pos = 0;
|
|
|
|
std::string token;
|
|
|
|
while ((pos = s.find(delimiter)) != std::string::npos) {
|
|
|
|
token = s.substr(0, pos);
|
|
|
|
result.push_back(token);
|
|
|
|
s.erase(0, pos + delimiter.length());
|
|
|
|
}
|
|
|
|
result.push_back(s);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2024-11-27 01:46:36 +03:00
|
|
|
|
|
|
|
std::wstring substring_from_to(std::wstring& text, std::wstring from, std::wstring to) {
|
|
|
|
unsigned int start_pos = 0;
|
|
|
|
unsigned int end_pos = 0;
|
|
|
|
|
|
|
|
std::wstring substring;
|
|
|
|
|
|
|
|
std::wregex start_regex(from);
|
|
|
|
std::wregex end_regex(to);
|
|
|
|
|
|
|
|
for (std::wsregex_iterator it{text.begin(), text.end(), start_regex}, end{};
|
|
|
|
it != end; it++) {
|
|
|
|
start_pos = it->position() + it->str().size();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(text == from_utf8("")) return text;
|
|
|
|
substring = text.substr(start_pos, text.size());
|
|
|
|
|
|
|
|
for (std::wsregex_iterator it{substring.begin(), substring.end(), end_regex}, end{};
|
|
|
|
it != end; it++) {
|
|
|
|
end_pos = it->position();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (end_pos == 0) return substring;
|
|
|
|
|
|
|
|
substring = substring.substr(0, end_pos);
|
|
|
|
|
|
|
|
return substring;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring trim_html_response(std::wstring& check) {
|
|
|
|
std::wstring begin_check_marker = from_utf8("<!-- Products -->");
|
|
|
|
std::wstring end_check_marker = from_utf8("<!-- \\/Products -->");
|
|
|
|
std::wstring trimmed = substring_from_to(check, begin_check_marker, end_check_marker);
|
|
|
|
trimmed += from_utf8("\n</div>");
|
|
|
|
return trimmed;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::wstring> find_in_html(std::string& html, std::string regex, std::string html_start, std::string html_end) {
|
|
|
|
std::regex searching_regex(regex);
|
|
|
|
|
|
|
|
std::vector<std::wstring> parsed;
|
|
|
|
for (std::sregex_iterator it{html.begin(), html.end(), searching_regex}, end{};
|
|
|
|
it != end; it++) {
|
|
|
|
|
|
|
|
std::wstring found_entry = from_utf8(it->str());
|
|
|
|
std::wstring extracted = substring_from_to(found_entry, from_utf8(html_start), from_utf8(html_end));
|
|
|
|
|
|
|
|
parsed.push_back(extracted);
|
|
|
|
}
|
|
|
|
return parsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::wstring> find_products_in_html(std::string html) {
|
|
|
|
return find_in_html(html, "<div class=\"ifw-col ifw-col-1 text-left\"><b>.*<\\/b><\\/div>", "<div class=\"ifw-col ifw-col-1 text-left\"><b>", "<\\/b><\\/div>");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::wstring> find_amounts_in_html(std::string html) {
|
|
|
|
return find_in_html(html, "<span>\\d+<\\/span>", "<span>", "<\\/span>");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::wstring> find_prices_in_html(std::string html) {
|
|
|
|
return find_in_html(html, "X <\\/span><span>\\d+\\.\\d{2}<\\/span>", "X <\\/span><span>", "<\\/span>");
|
|
|
|
}
|
|
|
|
|
|
|
|
Check parseOfdRuAnswer(std::string html) {
|
|
|
|
std::wstring wstr_html = from_utf8(html);
|
|
|
|
std::string trimmed = to_utf8(trim_html_response(wstr_html));
|
|
|
|
|
|
|
|
std::vector<std::wstring> products = find_products_in_html(trimmed);
|
|
|
|
std::vector<std::wstring> amounts = find_amounts_in_html(trimmed);
|
|
|
|
std::vector<std::wstring> prices = find_prices_in_html(trimmed);
|
|
|
|
|
2024-11-28 00:28:37 +03:00
|
|
|
if ((products.size() + amounts.size() + prices.size()) == 0) {
|
|
|
|
if (html == "Bad Request4") { // Failed to solve a captcha
|
|
|
|
throw OfdRequestException("Incorrect captcha");
|
|
|
|
} else { // Most likely that the check does not exist
|
|
|
|
throw OfdRequestException("Does not exist");
|
|
|
|
}
|
|
|
|
return Check();
|
|
|
|
}
|
|
|
|
|
2024-11-27 01:46:36 +03:00
|
|
|
if ((products.size() + amounts.size() + prices.size())/products.size() != 3) {
|
|
|
|
std::cerr << "An error has occured during the parsing of html. Please, contact the developer." << std::endl;
|
|
|
|
std::exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Check c;
|
|
|
|
|
|
|
|
for (int i = 0; i < products.size(); i ++) {
|
|
|
|
Goods goods(to_utf8(products[i]), std::stod(prices[i]), std::stod(amounts[i]));
|
|
|
|
c.add_goods(goods);
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|