basic email parsing
This commit is contained in:
parent
259b8543a4
commit
9da589839c
|
@ -116,7 +116,7 @@ if (BUILD_OFD_BINARYEYE_SCAN)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_EMAIL_MODE)
|
if (BUILD_EMAIL_MODE)
|
||||||
# list(APPEND PROJECT_SOURCES email_parser/emailparser.h email_parser/emailparser.cpp)
|
list(APPEND PROJECT_SOURCES email_parser/emailparser.h email_parser/emailparser.cpp)
|
||||||
list(APPEND PROJECT_SOURCES utils/base64.h utils/base64.cpp)
|
list(APPEND PROJECT_SOURCES utils/base64.h utils/base64.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ include_directories(${Boost_INCLUDE_DIRS})
|
||||||
target_link_libraries(checks-parser PUBLIC ${Boost_LIBRARIES})
|
target_link_libraries(checks-parser PUBLIC ${Boost_LIBRARIES})
|
||||||
|
|
||||||
if (BUILD_OFD_LOCAL_QR_SCAN OR BUILD_OFD_BINARYEYE_SCAN)
|
if (BUILD_OFD_LOCAL_QR_SCAN OR BUILD_OFD_BINARYEYE_SCAN)
|
||||||
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs opencv_objdetect)
|
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs opencv_objdetect videoio)
|
||||||
target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS})
|
target_link_libraries(checks-parser PRIVATE ${OpenCV_LIBS})
|
||||||
target_include_directories(checks-parser PUBLIC ${OpenCV_INCLUDE_DIRS})
|
target_include_directories(checks-parser PUBLIC ${OpenCV_INCLUDE_DIRS})
|
||||||
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
include_directories( ${OpenCV_INCLUDE_DIRS} )
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
|
#include "utils/base64.h"
|
||||||
#include <email_parser/emailparser.h>
|
#include <email_parser/emailparser.h>
|
||||||
|
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <opencv2/imgcodecs.hpp>
|
||||||
|
#include <opencv2/objdetect.hpp>
|
||||||
|
#include <opencv2/core/core.hpp>
|
||||||
|
#include <opencv2/videoio.hpp>
|
||||||
|
|
||||||
#include <utils/utils.h>
|
#include <utils/utils.h>
|
||||||
#include <check/check.h>
|
#include <check/check.h>
|
||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <sstream>
|
#include <boost/algorithm/string/regex.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <bits/stdc++.h>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#if __GNUC__ < 8 && __clang_major__ < 17
|
#if __GNUC__ < 8 && __clang_major__ < 17
|
||||||
# include <experimental/filesystem>
|
# include <experimental/filesystem>
|
||||||
using namespace std::experimental::filesystem;
|
using namespace std::experimental::filesystem;
|
||||||
|
@ -16,78 +23,12 @@
|
||||||
using namespace std::filesystem;
|
using namespace std::filesystem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string EmailParser::get_payload_in_email(std::string &email_content) {
|
|
||||||
boost::regex content_type_and_transfer_encoding_regex("Content-Type");
|
|
||||||
// boost::regex body_start_regex("\r\n\r\n"); //boost::regex_constants::egrep
|
|
||||||
// boost::smatch smatch;
|
|
||||||
// if (boost::regex_search(email_content, smatch, body_start_regex)) {
|
|
||||||
// return email_content.substr(smatch.position(), email_content.length());
|
|
||||||
// }
|
|
||||||
// return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::multimap<std::string, std::string> EmailParser::parse_email_content_types(std::string path) {
|
|
||||||
std::ifstream input_file(path, std::ios::in);
|
|
||||||
|
|
||||||
std::string line = "";
|
|
||||||
std::multimap<std::string, std::string> mail_options;
|
|
||||||
std::string latest_key;
|
|
||||||
while(std::getline(input_file, line)) {
|
|
||||||
// ;
|
|
||||||
|
|
||||||
char first_char = line.substr(0, 1)[0];
|
|
||||||
// if (line == "\0") {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::vector<std::string> split_by_colon = split(line, ":");
|
|
||||||
std::string key = split_by_colon[0];
|
|
||||||
std::string value = "";
|
|
||||||
|
|
||||||
for (int i = 1; i < split_by_colon.size(); i ++) value += split_by_colon[i];
|
|
||||||
if (key != "Content-Type" ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first_char == '\t') {
|
|
||||||
mail_options.emplace(std::make_pair(latest_key, line));
|
|
||||||
} else {
|
|
||||||
// std::cout << "key: " << key << "\nvalue: " << value << std::endl;
|
|
||||||
mail_options.emplace(std::make_pair(key, value));
|
|
||||||
latest_key = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mail_options;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::vector<int> EmailParser::find_base64_blocks_in_email(std::string &email_content) {
|
|
||||||
// std::string glued_together;
|
|
||||||
// for (auto c : email_content) {
|
|
||||||
// if (c == '\n') continue;
|
|
||||||
// glued_together.push_back(c);
|
|
||||||
// }
|
|
||||||
// boost::regex base64_regex("^[-A-Za-z0-9+/]*={0,3}$");
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EmailParser::EmailParser() {
|
EmailParser::EmailParser() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> search_content_types_in_email_content(std::string& email_content) {
|
std::map<std::string, std::string> EmailParser::parse(std::string &email_content) {
|
||||||
std::vector<int> content_type_positions = {};
|
|
||||||
boost::regex image_content_type_regex("Content-Type: image/.*");
|
|
||||||
for (boost::sregex_iterator it{email_content.begin(), email_content.end(), image_content_type_regex}, end{};
|
|
||||||
it != end; it++) {
|
|
||||||
content_type_positions.push_back(it->position());
|
|
||||||
}
|
|
||||||
return content_type_positions;
|
|
||||||
}
|
|
||||||
|
|
||||||
// void find_and_decode_email_content()
|
|
||||||
|
|
||||||
Check EmailParser::parse(std::string &email_content) {
|
|
||||||
//1. Search "Content-Type: image/.*" in the .eml file.
|
//1. Search "Content-Type: image/.*" in the .eml file.
|
||||||
// 1.1 If found 0, go to [2]
|
// 1.1 If found 0, go to [2]
|
||||||
// 1.2 If found 1, try decoding it, if it's not a QR code, go to [2]
|
// 1.2 If found 1, try decoding it, if it's not a QR code, go to [2]
|
||||||
|
@ -95,86 +36,72 @@ Check EmailParser::parse(std::string &email_content) {
|
||||||
//2. Try decoding content of the e-mail
|
//2. Try decoding content of the e-mail
|
||||||
//3. Search "t=\d{8}T\d{4,6}&s=\d{1,6}\.\d{1,2}&fn=\d{10,16}&i=\d{6}&fp=\d{10}&n=\d". Note that in some emails = and & signs could be replaced with its code in HTTP requests: %3D, %26
|
//3. Search "t=\d{8}T\d{4,6}&s=\d{1,6}\.\d{1,2}&fn=\d{10,16}&i=\d{6}&fp=\d{10}&n=\d". Note that in some emails = and & signs could be replaced with its code in HTTP requests: %3D, %26
|
||||||
// 3.1 If not found, notify the user that we could not parse the .eml file
|
// 3.1 If not found, notify the user that we could not parse the .eml file
|
||||||
std::vector<int> content_type_positions = search_content_types_in_email_content(email_content);
|
|
||||||
|
|
||||||
if (content_type_positions.size() < 0) {
|
/* Find content-types */
|
||||||
|
Check c;
|
||||||
|
std::vector<std::pair<int, int>> content_types = {};
|
||||||
|
boost::regex content_type_regex("Content-Type: image/(gif|png|jpg)");
|
||||||
|
boost::regex part_end_regex("--.{5,48}");
|
||||||
|
|
||||||
} else if (content_type_positions.size() == 1) {
|
for (boost::sregex_iterator it{email_content.begin(), email_content.end(), content_type_regex}, end{}; it != end; it ++) {
|
||||||
|
unsigned int start_position = it->position(), end_position = -1;
|
||||||
|
|
||||||
} else {
|
for (boost::sregex_iterator it2{email_content.begin() + start_position, email_content.end(), part_end_regex}, end2{}; it2 != end2; it2++) {
|
||||||
|
end_position = it2->position();
|
||||||
}
|
break;
|
||||||
|
|
||||||
// std::string payload = get_payload_in_email(email_content);
|
|
||||||
// Check c;
|
|
||||||
|
|
||||||
// std::cout << payload << std::endl;
|
|
||||||
|
|
||||||
// if (payload == "")
|
|
||||||
// return c;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
Check EmailParser::parse_file(std::string path) {
|
|
||||||
|
|
||||||
// std::vector<std::string> contents = read_file(path);
|
|
||||||
// unsigned int body_start = -1;
|
|
||||||
// for (unsigned int i = 0; i < contents.size(); i ++) {
|
|
||||||
// std::string &line = contents[i];
|
|
||||||
// if (line == "\r") {
|
|
||||||
// body_start = i;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (body_start == (unsigned int) -1) throw "Not an E-Mail";
|
|
||||||
|
|
||||||
// for (unsigned int i = 0; i < contents.size(); i ++) {
|
|
||||||
// std::string &line = contents[i];
|
|
||||||
// if (line[0] == '\t') {
|
|
||||||
// contents[i - 1] += " " + contents[i];
|
|
||||||
// contents.erase(remove(contents.begin(), contents.end(), line), contents.end());
|
|
||||||
// i -= 2;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (auto &line : contents) {
|
|
||||||
// std::cout << line << std::endl;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// std::cout << contents[body_start + 1] << std::endl;
|
|
||||||
// unsigned int body_start = contents.find("\r\n\r\n");
|
|
||||||
// if (body_start == (unsigned int)-1)
|
|
||||||
// throw "Not a E-Mail file";
|
|
||||||
// std::cout << contents.erase(0, body_start + 4);
|
|
||||||
// std::cout << contents << std::endl;
|
|
||||||
|
|
||||||
// std::vector<std::tuple<int, int>> message_parts_positions;
|
|
||||||
|
|
||||||
// while (contents.find("--") > 0) {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
return Check();
|
|
||||||
|
|
||||||
std::multimap<std::string, std::string> content_types = parse_email_content_types(path);
|
|
||||||
bool found_qr_image = false;
|
|
||||||
for (auto &content_type : content_types) {
|
|
||||||
boost::regex image_content_type_regex("image\\/(png|gif|jpg|jpeg)");
|
|
||||||
boost::cmatch cmatch;
|
|
||||||
if (boost::regex_match(content_type.second.c_str(), cmatch, image_content_type_regex)) {
|
|
||||||
std::cout << cmatch << std::endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
std::cout << content_type.first << ": " << content_type.second << std::endl;
|
content_types.push_back(std::pair<int, int>(start_position, end_position));
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::ifstream ifile(path, std::ios::in | std::ios::binary);
|
/* iterate through found content-types and try searching qr codes, decode them and see if it's the needed data */
|
||||||
// const unsigned int size = std::filesystem::file_size(path);
|
|
||||||
// std::string content(size, '\0');
|
for (unsigned int i = 0; i < content_types.size(); i ++) {
|
||||||
// ifile.read(content.data(), size);
|
boost::regex to_erase("(Content.{5,64}\\r\\n)+");
|
||||||
// return parse(content);
|
boost::regex to_erase_two("--.{5,48}");
|
||||||
return Check();
|
std::string part = email_content.substr(content_types[i].first, content_types[i].second);
|
||||||
|
boost::erase_regex(part, to_erase);
|
||||||
|
boost::erase_regex(part, to_erase_two);
|
||||||
|
part.erase(std::remove(part.begin(), part.end(), '\r'), part.end());
|
||||||
|
part.erase(std::remove(part.begin(), part.end(), '\n'), part.end());
|
||||||
|
std::string decoded = base64_decode(part);
|
||||||
|
cv::Mat image;
|
||||||
|
|
||||||
|
if (decoded.substr(1, 3) == "PNG" || decoded.substr(1, 3) == "JPG") {
|
||||||
|
std::vector<uchar> data(decoded.begin(), decoded.end());
|
||||||
|
image = cv::imdecode(cv::Mat(data), 1);
|
||||||
|
} else if (decoded.substr(0, 3) == "GIF") {
|
||||||
|
std::string gif_file_path = get_application_home_path() + "/temp.gif";
|
||||||
|
|
||||||
|
std::ofstream gif_output(gif_file_path, std::ios::binary);
|
||||||
|
gif_output << decoded;
|
||||||
|
gif_output.close();
|
||||||
|
cv::VideoCapture gif(gif_file_path, cv::CAP_FFMPEG);
|
||||||
|
gif.read(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::QRCodeDetector qrDecoder = cv::QRCodeDetector();
|
||||||
|
std::string decoded_qr_params = qrDecoder.detectAndDecode(image);
|
||||||
|
boost::regex check_data_content("t=\\d+T\\d+&s=\\d+\\.\\d+&fn=\\d{16}&i=\\d{4,5}&fp=\\d{10}&n=\\d");
|
||||||
|
if (boost::regex_match(decoded_qr_params, check_data_content)) {
|
||||||
|
std::map<std::string, std::string> paramsMap = get_params_from_string(decoded_qr_params);
|
||||||
|
|
||||||
|
return paramsMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the E-Mail has no QR code in it as a separate part, there's posibilly a QR code inserted using html's tag <img> with base64-encoded image. Try searching it */
|
||||||
|
|
||||||
|
/* If there's no such case, the last chance is <img src="..."> which will have a link with needed parameters or the qr code that should be downloaded and decoded */
|
||||||
|
|
||||||
|
/* If the code has reached this part and found nothing, it's most likely that there are no QR codes at all. */
|
||||||
|
// return Check();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> EmailParser::parse_file(std::string path) {
|
||||||
|
std::ifstream ifile(path, std::ios::in | std::ios::binary);
|
||||||
|
const unsigned int size = std::filesystem::file_size(path);
|
||||||
|
std::string content(size, '\0');
|
||||||
|
ifile.read(content.data(), size);
|
||||||
|
return parse(content);
|
||||||
|
return std::map<std::string, std::string>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,10 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class EmailParser {
|
class EmailParser {
|
||||||
std::string get_payload_in_email(std::string &email_content);
|
|
||||||
std::multimap<std::string, std::string> parse_email_content_types(std::string path);
|
|
||||||
|
|
||||||
// std::vector<int> find_base64_blocks_in_email(std::string &email_content);
|
|
||||||
public:
|
public:
|
||||||
EmailParser();
|
EmailParser();
|
||||||
Check parse(std::string &email_content);
|
std::map<std::string, std::string> parse(std::string &email_content);
|
||||||
Check parse_file(std::string path);
|
std::map<std::string, std::string> parse_file(std::string path);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
7
main.cpp
7
main.cpp
|
@ -25,12 +25,19 @@
|
||||||
#include <settingsdialog.h>
|
#include <settingsdialog.h>
|
||||||
#ifdef BUILD_EMAIL_MODE
|
#ifdef BUILD_EMAIL_MODE
|
||||||
// #include <vmime/vmime.hpp>
|
// #include <vmime/vmime.hpp>
|
||||||
|
#include <email_parser/emailparser.h>
|
||||||
#endif
|
#endif
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
#include <utils/base64.h>
|
#include <utils/base64.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
// EmailParser p;
|
||||||
|
// p.parse_file("/home/leca/example_email_receipts/magnit.eml");
|
||||||
|
// p.parse_file("/home/leca/example_email_receipts/pyaterochka.eml");
|
||||||
|
// p.parse_file("/home/leca/example_email_receipts/rzd.eml");
|
||||||
|
// return 0;
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
qRegisterMetaType<Check>("Check");
|
qRegisterMetaType<Check>("Check");
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#ifdef BUILD_OFD_LOCAL_QR_SCAN
|
#ifdef BUILD_OFD_LOCAL_QR_SCAN
|
||||||
# include <adjustpicturedialog.h>
|
# include <adjustpicturedialog.h>
|
||||||
#include <checkqueuetablemodel.h>
|
# include <checkqueuetablemodel.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <outputdialog.h>
|
#include <outputdialog.h>
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
|
#include <email_parser/emailparser.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
@ -49,6 +50,9 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
#ifdef BUILD_OFD_BINARYEYE_SCAN
|
#ifdef BUILD_OFD_BINARYEYE_SCAN
|
||||||
QObject::connect(this, &MainWindow::httpErrorOccured, this, &MainWindow::notifyHttpServerFailure);
|
QObject::connect(this, &MainWindow::httpErrorOccured, this, &MainWindow::notifyHttpServerFailure);
|
||||||
connect(this, SIGNAL(httpNewMessage(QString)), this, SLOT(httpNewMessageHandler(QString)));
|
connect(this, SIGNAL(httpNewMessage(QString)), this, SLOT(httpNewMessageHandler(QString)));
|
||||||
|
#else
|
||||||
|
ui->or_label_2->hide();
|
||||||
|
ui->binary_eye_button->hide();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BUILD_EMAIL_MODE
|
#ifndef BUILD_EMAIL_MODE
|
||||||
|
@ -56,10 +60,6 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
ui->or_label_2->hide();
|
ui->or_label_2->hide();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BUILD_OFD_BINARYEYE_SCAN
|
|
||||||
ui->or_label_2->hide();
|
|
||||||
ui->binary_eye_button->hide();
|
|
||||||
#endif
|
|
||||||
#ifndef BUILD_OFD_LOCAL_QR_SCAN
|
#ifndef BUILD_OFD_LOCAL_QR_SCAN
|
||||||
ui->or_label_1->hide();
|
ui->or_label_1->hide();
|
||||||
ui->choose_image_button->hide();
|
ui->choose_image_button->hide();
|
||||||
|
@ -127,19 +127,7 @@ void MainWindow::httpNewMessageHandler(QString message) {
|
||||||
|
|
||||||
//erase /?result= from the string
|
//erase /?result= from the string
|
||||||
parametersString.erase(0, parametersString.find("=") + 1);
|
parametersString.erase(0, parametersString.find("=") + 1);
|
||||||
//TODO: punycode %26 %3D
|
std::map<std::string, std::string> paramsMap = get_params_from_string(parametersString);
|
||||||
parametersString = boost::regex_replace(parametersString, boost::regex("%26"), "&");
|
|
||||||
parametersString = boost::regex_replace(parametersString, boost::regex("%3D"), "=");
|
|
||||||
|
|
||||||
std::vector<std::string> parameters = split(parametersString, "&");
|
|
||||||
|
|
||||||
std::map<std::string, std::string> paramsMap;
|
|
||||||
|
|
||||||
for (auto ¶meter : parameters) {
|
|
||||||
std::vector<std::string> values = split(parameter, "=");
|
|
||||||
paramsMap.insert(std::pair<std::string, std::string> (values[0], values[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
emit onDataDecode(paramsMap);
|
emit onDataDecode(paramsMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,35 +155,33 @@ void MainWindow::on_choose_image_button_clicked() {
|
||||||
#endif //ifdef BUILD_OFD_LOCAL_QR_SCAN
|
#endif //ifdef BUILD_OFD_LOCAL_QR_SCAN
|
||||||
|
|
||||||
void MainWindow::onDataDecode(std::map<std::string, std::string> data) {
|
void MainWindow::onDataDecode(std::map<std::string, std::string> data) {
|
||||||
ui->fn_line_edit->setText(QString::fromStdString(data["fn"]));
|
set_check_params(data);
|
||||||
ui->fd_line_edit->setText(QString::fromStdString(data["i"]));
|
|
||||||
ui->fi_line_edit->setText(QString::fromStdString(data["fp"]));
|
|
||||||
|
|
||||||
QString extractedDateTime = QString::fromStdString(data["t"]);
|
|
||||||
//TODO: some QRs contain datetime in format yyyyMMddThhmmss. Perhaps there is more different formats, should write function to detect them.
|
|
||||||
QDateTime datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmm");
|
|
||||||
if (datetime == QDateTime::fromString(extractedDateTime, "20000101T1200")) {
|
|
||||||
datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmmss");
|
|
||||||
}
|
|
||||||
ui->purchase_datetime_edit->setDateTime(datetime);
|
|
||||||
|
|
||||||
int type = std::stoi(data["n"]);
|
|
||||||
ui->operation_type_combo_box->setCurrentIndex(type - 1);
|
|
||||||
|
|
||||||
std::string total = data["s"];
|
|
||||||
|
|
||||||
ui->total_spin_box->setValue(std::stod(total));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_EMAIL_MODE
|
#ifdef BUILD_EMAIL_MODE
|
||||||
|
|
||||||
void MainWindow::on_parse_email_button_clicked() {
|
void MainWindow::on_parse_email_button_clicked() {
|
||||||
QMessageBox infoDialog;
|
QString filename = QFileDialog::getOpenFileName();
|
||||||
infoDialog.setText(tr("This feature is under development. Wait it to appear in next updates."));
|
|
||||||
infoDialog.setIcon(QMessageBox::Warning);
|
if (filename == "") {
|
||||||
infoDialog.setWindowTitle(tr("Under development"));
|
QMessageBox infoDialog;
|
||||||
infoDialog.exec();
|
infoDialog.setText(tr("Please, select an e-mail which contains QR code"));
|
||||||
return;
|
infoDialog.setIcon(QMessageBox::Critical);
|
||||||
|
infoDialog.setWindowTitle(tr("E-Mail was not selected"));
|
||||||
|
infoDialog.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailParser email_parser;
|
||||||
|
std::map<std::string, std::string> paramsMap = email_parser.parse_file(filename.toStdString());
|
||||||
|
|
||||||
|
set_check_params(paramsMap);
|
||||||
|
// QMessageBox infoDialog;
|
||||||
|
// infoDialog.setText(tr("This feature is under development. Wait it to appear in next updates."));
|
||||||
|
// infoDialog.setIcon(QMessageBox::Warning);
|
||||||
|
// infoDialog.setWindowTitle(tr("Under development"));
|
||||||
|
// infoDialog.exec();
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ifdef BUILD_EMAIL_MODE
|
#endif // ifdef BUILD_EMAIL_MODE
|
||||||
|
@ -270,22 +256,21 @@ Check *MainWindow::parse_new_check() {
|
||||||
|
|
||||||
return check;
|
return check;
|
||||||
} catch(OfdRequestException e) {
|
} catch(OfdRequestException e) {
|
||||||
|
QMessageBox infoDialog;
|
||||||
if (!strcmp(e.what(), "Incorrect captcha")) {
|
if (!strcmp(e.what(), "Incorrect captcha")) {
|
||||||
QMessageBox infoDialog;
|
|
||||||
infoDialog.setText(tr("Captcha was not solved correctly!"));
|
infoDialog.setText(tr("Captcha was not solved correctly!"));
|
||||||
infoDialog.setIcon(QMessageBox::Critical);
|
infoDialog.setIcon(QMessageBox::Critical);
|
||||||
infoDialog.setWindowTitle(tr("Captcha is incorrect"));
|
infoDialog.setWindowTitle(tr("Captcha is incorrect"));
|
||||||
infoDialog.exec();
|
infoDialog.exec();
|
||||||
continue;
|
continue;
|
||||||
} else if (!strcmp(e.what(), "Internal server error")) {
|
} else if (!strcmp(e.what(), "Internal server error")) {
|
||||||
QMessageBox infoDialog;
|
|
||||||
infoDialog.setText(tr("Internal server error. Please, try again later."));
|
infoDialog.setText(tr("Internal server error. Please, try again later."));
|
||||||
infoDialog.setIcon(QMessageBox::Critical);
|
infoDialog.setIcon(QMessageBox::Critical);
|
||||||
infoDialog.setWindowTitle(tr("Internal server error"));
|
infoDialog.setWindowTitle(tr("Internal server error"));
|
||||||
infoDialog.exec();
|
infoDialog.exec();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (!strcmp(e.what(), "Does not exist")) {
|
} else if (!strcmp(e.what(), "Does not exist")) {
|
||||||
QMessageBox infoDialog;
|
|
||||||
infoDialog.setText(tr("Check not found. Please, ensure correctness of entered data."));
|
infoDialog.setText(tr("Check not found. Please, ensure correctness of entered data."));
|
||||||
infoDialog.setIcon(QMessageBox::Critical);
|
infoDialog.setIcon(QMessageBox::Critical);
|
||||||
infoDialog.setWindowTitle(tr("Check was not found"));
|
infoDialog.setWindowTitle(tr("Check was not found"));
|
||||||
|
@ -316,3 +301,24 @@ void MainWindow::on_deleteSelectedButton_clicked() {
|
||||||
ui->checkQueueTable->clearSelection();
|
ui->checkQueueTable->clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::set_check_params(std::map<std::string, std::string> paramsMap) {
|
||||||
|
ui->fn_line_edit->setText(QString::fromStdString(paramsMap["fn"]));
|
||||||
|
ui->fd_line_edit->setText(QString::fromStdString(paramsMap["i"]));
|
||||||
|
ui->fi_line_edit->setText(QString::fromStdString(paramsMap["fp"]));
|
||||||
|
|
||||||
|
QString extractedDateTime = QString::fromStdString(paramsMap["t"]);
|
||||||
|
//TODO: some QRs contain datetime in format yyyyMMddThhmmss. Perhaps there is more different formats, should write function to detect them.
|
||||||
|
QDateTime datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmm");
|
||||||
|
if (datetime == QDateTime::fromString(extractedDateTime, "20000101T1200")) {
|
||||||
|
datetime = QDateTime::fromString(extractedDateTime, "yyyyMMddThhmmss");
|
||||||
|
}
|
||||||
|
ui->purchase_datetime_edit->setDateTime(datetime);
|
||||||
|
|
||||||
|
int type = std::stoi(paramsMap["n"]);
|
||||||
|
ui->operation_type_combo_box->setCurrentIndex(type - 1);
|
||||||
|
|
||||||
|
std::string total = paramsMap["s"];
|
||||||
|
|
||||||
|
ui->total_spin_box->setValue(std::stod(total));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ private slots:
|
||||||
void on_add_new_check_button_clicked();
|
void on_add_new_check_button_clicked();
|
||||||
|
|
||||||
void on_deleteSelectedButton_clicked();
|
void on_deleteSelectedButton_clicked();
|
||||||
|
void set_check_params(std::map<std::string, std::string>);
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
std::vector<Check> checks;
|
std::vector<Check> checks;
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
#include <settings/settings.h>
|
#include <settings/settings.h>
|
||||||
#include <utils/utils.h>
|
#include <utils/utils.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <outputcolumnmodel.h>
|
#include <outputcolumnmodel.h>
|
||||||
|
|
||||||
|
|
|
@ -273,57 +273,65 @@
|
||||||
<translation>Could not start http server.</translation>
|
<translation>Could not start http server.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="161"/>
|
<location filename="../mainwindow.cpp" line="149"/>
|
||||||
<source>Selected image: </source>
|
<source>Selected image: </source>
|
||||||
<translation>Selected image: </translation>
|
<translation>Selected image: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="194"/>
|
|
||||||
<source>This feature is under development. Wait it to appear in next updates.</source>
|
<source>This feature is under development. Wait it to appear in next updates.</source>
|
||||||
<translation>This feature is under development. Wait for it to appear in next updates.</translation>
|
<translation type="vanished">This feature is under development. Wait for it to appear in next updates.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="196"/>
|
|
||||||
<source>Under development</source>
|
<source>Under development</source>
|
||||||
<translation>Under development</translation>
|
<translation type="vanished">Under development</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="207"/>
|
<location filename="../mainwindow.cpp" line="168"/>
|
||||||
|
<source>Please, select an e-mail which contains QR code</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../mainwindow.cpp" line="170"/>
|
||||||
|
<source>E-Mail was not selected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../mainwindow.cpp" line="193"/>
|
||||||
<source>Please, add check(s) to parse</source>
|
<source>Please, add check(s) to parse</source>
|
||||||
<translation>Please, add check(s) to parse</translation>
|
<translation>Please, add check(s) to parse</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="209"/>
|
<location filename="../mainwindow.cpp" line="195"/>
|
||||||
<source>No checks to parse</source>
|
<source>No checks to parse</source>
|
||||||
<translation>No checks to parse</translation>
|
<translation>No checks to parse</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="275"/>
|
<location filename="../mainwindow.cpp" line="262"/>
|
||||||
<source>Captcha was not solved correctly!</source>
|
<source>Captcha was not solved correctly!</source>
|
||||||
<translation>Captcha was not solved correctly!</translation>
|
<translation>Captcha was not solved correctly!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="277"/>
|
<location filename="../mainwindow.cpp" line="264"/>
|
||||||
<source>Captcha is incorrect</source>
|
<source>Captcha is incorrect</source>
|
||||||
<translation>Captcha is incorrect</translation>
|
<translation>Captcha is incorrect</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="282"/>
|
<location filename="../mainwindow.cpp" line="268"/>
|
||||||
<source>Internal server error. Please, try again later.</source>
|
<source>Internal server error. Please, try again later.</source>
|
||||||
<translation>Internal server error. Please, try again later.</translation>
|
<translation>Internal server error. Please, try again later.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="284"/>
|
<location filename="../mainwindow.cpp" line="270"/>
|
||||||
<source>Internal server error</source>
|
<source>Internal server error</source>
|
||||||
<translation>Internal server error</translation>
|
<translation>Internal server error</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="289"/>
|
<location filename="../mainwindow.cpp" line="274"/>
|
||||||
<source>Check not found. Please, ensure correctness of entered data.</source>
|
<source>Check not found. Please, ensure correctness of entered data.</source>
|
||||||
<translation>Check not found. Please, ensure correctness of entered data.</translation>
|
<translation>Check not found. Please, ensure correctness of entered data.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="291"/>
|
<location filename="../mainwindow.cpp" line="276"/>
|
||||||
<source>Check was not found</source>
|
<source>Check was not found</source>
|
||||||
<translation>Check was not found</translation>
|
<translation>Check was not found</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -336,12 +344,12 @@
|
||||||
<translation type="vanished">Error in parsing</translation>
|
<translation type="vanished">Error in parsing</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="154"/>
|
<location filename="../mainwindow.cpp" line="142"/>
|
||||||
<source>Please, select a picture where QR code that contains info about check is present</source>
|
<source>Please, select a picture where QR code that contains info about check is present</source>
|
||||||
<translation>Please, select a picture where QR code that contains info about check is present</translation>
|
<translation>Please, select a picture where QR code that contains info about check is present</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="156"/>
|
<location filename="../mainwindow.cpp" line="144"/>
|
||||||
<source>Picture was not selected</source>
|
<source>Picture was not selected</source>
|
||||||
<translation>Picture was not selected</translation>
|
<translation>Picture was not selected</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -653,7 +661,7 @@
|
||||||
<context>
|
<context>
|
||||||
<name>QObject</name>
|
<name>QObject</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../main.cpp" line="64"/>
|
<location filename="../main.cpp" line="71"/>
|
||||||
<source>Using locale: </source>
|
<source>Using locale: </source>
|
||||||
<translation>Using locale: </translation>
|
<translation>Using locale: </translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -661,17 +669,17 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsDialog</name>
|
<name>SettingsDialog</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="26"/>
|
<location filename="../settingsdialog.cpp" line="24"/>
|
||||||
<source>Кто здесь?</source>
|
<source>Кто здесь?</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="91"/>
|
<location filename="../settingsdialog.cpp" line="89"/>
|
||||||
<source>You need to restart program to apply language changes</source>
|
<source>You need to restart program to apply language changes</source>
|
||||||
<translation>You need to restart program to apply language changes</translation>
|
<translation>You need to restart program to apply language changes</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="93"/>
|
<location filename="../settingsdialog.cpp" line="91"/>
|
||||||
<source>Restart required</source>
|
<source>Restart required</source>
|
||||||
<translation>Restart required</translation>
|
<translation>Restart required</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -261,57 +261,57 @@
|
||||||
<translation>Не получилось запустить HTTP сервер.</translation>
|
<translation>Не получилось запустить HTTP сервер.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="161"/>
|
<location filename="../mainwindow.cpp" line="149"/>
|
||||||
<source>Selected image: </source>
|
<source>Selected image: </source>
|
||||||
<translation>Выбранное изображение: </translation>
|
<translation>Выбранное изображение: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="194"/>
|
<location filename="../mainwindow.cpp" line="168"/>
|
||||||
<source>This feature is under development. Wait it to appear in next updates.</source>
|
<source>Please, select an e-mail which contains QR code</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="196"/>
|
<location filename="../mainwindow.cpp" line="170"/>
|
||||||
<source>Under development</source>
|
<source>E-Mail was not selected</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="207"/>
|
<location filename="../mainwindow.cpp" line="193"/>
|
||||||
<source>Please, add check(s) to parse</source>
|
<source>Please, add check(s) to parse</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="209"/>
|
<location filename="../mainwindow.cpp" line="195"/>
|
||||||
<source>No checks to parse</source>
|
<source>No checks to parse</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="275"/>
|
<location filename="../mainwindow.cpp" line="262"/>
|
||||||
<source>Captcha was not solved correctly!</source>
|
<source>Captcha was not solved correctly!</source>
|
||||||
<translation>Капча была решена неверно!</translation>
|
<translation>Капча была решена неверно!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="277"/>
|
<location filename="../mainwindow.cpp" line="264"/>
|
||||||
<source>Captcha is incorrect</source>
|
<source>Captcha is incorrect</source>
|
||||||
<translation>Капча введена неверно</translation>
|
<translation>Капча введена неверно</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="282"/>
|
<location filename="../mainwindow.cpp" line="268"/>
|
||||||
<source>Internal server error. Please, try again later.</source>
|
<source>Internal server error. Please, try again later.</source>
|
||||||
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
|
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="284"/>
|
<location filename="../mainwindow.cpp" line="270"/>
|
||||||
<source>Internal server error</source>
|
<source>Internal server error</source>
|
||||||
<translation>Внутренняя ошибка сервера</translation>
|
<translation>Внутренняя ошибка сервера</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="289"/>
|
<location filename="../mainwindow.cpp" line="274"/>
|
||||||
<source>Check not found. Please, ensure correctness of entered data.</source>
|
<source>Check not found. Please, ensure correctness of entered data.</source>
|
||||||
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
|
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="291"/>
|
<location filename="../mainwindow.cpp" line="276"/>
|
||||||
<source>Check was not found</source>
|
<source>Check was not found</source>
|
||||||
<translation>Чек не найден</translation>
|
<translation>Чек не найден</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -324,12 +324,12 @@
|
||||||
<translation type="vanished">Ошибка в парсинге</translation>
|
<translation type="vanished">Ошибка в парсинге</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="154"/>
|
<location filename="../mainwindow.cpp" line="142"/>
|
||||||
<source>Please, select a picture where QR code that contains info about check is present</source>
|
<source>Please, select a picture where QR code that contains info about check is present</source>
|
||||||
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
|
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../mainwindow.cpp" line="156"/>
|
<location filename="../mainwindow.cpp" line="144"/>
|
||||||
<source>Picture was not selected</source>
|
<source>Picture was not selected</source>
|
||||||
<translation>Изображение не было выбрано</translation>
|
<translation>Изображение не было выбрано</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -637,7 +637,7 @@
|
||||||
<context>
|
<context>
|
||||||
<name>QObject</name>
|
<name>QObject</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../main.cpp" line="64"/>
|
<location filename="../main.cpp" line="71"/>
|
||||||
<source>Using locale: </source>
|
<source>Using locale: </source>
|
||||||
<translation>Использую локаль: </translation>
|
<translation>Использую локаль: </translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -645,17 +645,17 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsDialog</name>
|
<name>SettingsDialog</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="26"/>
|
<location filename="../settingsdialog.cpp" line="24"/>
|
||||||
<source>Кто здесь?</source>
|
<source>Кто здесь?</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="91"/>
|
<location filename="../settingsdialog.cpp" line="89"/>
|
||||||
<source>You need to restart program to apply language changes</source>
|
<source>You need to restart program to apply language changes</source>
|
||||||
<translation>Требуется перезагрузить программу, чтобы применить изменения языка</translation>
|
<translation>Требуется перезагрузить программу, чтобы применить изменения языка</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../settingsdialog.cpp" line="93"/>
|
<location filename="../settingsdialog.cpp" line="91"/>
|
||||||
<source>Restart required</source>
|
<source>Restart required</source>
|
||||||
<translation>Требуется перезагрузка</translation>
|
<translation>Требуется перезагрузка</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -42,6 +42,7 @@ std::string get_local_ip_address() {
|
||||||
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
|
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
|
||||||
|
|
||||||
std::string value(addressBuffer);
|
std::string value(addressBuffer);
|
||||||
|
//TODO: better way to determine local IP address
|
||||||
if (!strncmp(value.c_str(), "192.168", 7)) {
|
if (!strncmp(value.c_str(), "192.168", 7)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +69,26 @@ std::string get_path_relative_to_home(std::string path) {
|
||||||
return std::string(std::getenv("HOME")) + "/" + path;
|
return std::string(std::getenv("HOME")) + "/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_application_home_path() {
|
||||||
|
return get_path_relative_to_home(".local/share/checks_parser");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> get_params_from_string(std::string parametersString) {
|
||||||
|
parametersString = boost::regex_replace(parametersString, boost::regex("%26"), "&");
|
||||||
|
parametersString = boost::regex_replace(parametersString, boost::regex("%3D"), "=");
|
||||||
|
|
||||||
|
std::vector<std::string> parameters = split(parametersString, "&");
|
||||||
|
|
||||||
|
std::map<std::string, std::string> paramsMap;
|
||||||
|
|
||||||
|
for (auto ¶meter : parameters) {
|
||||||
|
std::vector<std::string> values = split(parameter, "=");
|
||||||
|
paramsMap.insert(std::pair<std::string, std::string> (values[0], values[1]));
|
||||||
|
}
|
||||||
|
return paramsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool vector_contains_element(const std::vector<T>& vector, const T& to_find) {
|
bool vector_contains_element(const std::vector<T>& vector, const T& to_find) {
|
||||||
for (const T& element : vector) {
|
for (const T& element : vector) {
|
||||||
|
|
|
@ -11,6 +11,9 @@ std::string to_utf8(std::wstring wide_string);
|
||||||
std::wstring from_utf8(std::string string);
|
std::wstring from_utf8(std::string string);
|
||||||
|
|
||||||
std::string get_path_relative_to_home(std::string path);
|
std::string get_path_relative_to_home(std::string path);
|
||||||
|
std::string get_application_home_path();
|
||||||
|
|
||||||
|
std::map<std::string, std::string> get_params_from_string(std::string);
|
||||||
|
|
||||||
const std::map<std::string, ColumnType> column_names = {
|
const std::map<std::string, ColumnType> column_names = {
|
||||||
{"date", ColumnType::date},
|
{"date", ColumnType::date},
|
||||||
|
|
Loading…
Reference in New Issue