From 6706cbec4553266eb5463282bcfa0c53ac16a1e2 Mon Sep 17 00:00:00 2001 From: leca Date: Tue, 15 Apr 2025 22:02:33 +0300 Subject: [PATCH] plans and sketches --- CMakeLists.txt | 5 +++ check/check.h | 29 +++++++++++++ email_parser/emailparser.cpp | 70 ++++++++++++++++++++++++++++++++ email_parser/emailparser.h | 15 +++++++ main.cpp | 6 +++ translations/en_US.ts | 2 +- translations/ru_RU.ts | 2 +- utils/base64.cpp | 79 ++++++++++++++++++++++++++++++++++++ utils/base64.h | 29 +++++++++++++ 9 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 email_parser/emailparser.cpp create mode 100644 email_parser/emailparser.h create mode 100644 utils/base64.cpp create mode 100644 utils/base64.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3218158..3b20c4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,11 @@ if (BUILD_OFD_BINARYEYE_SCAN) list(APPEND PROJECT_SOURCES http_server/http_server.h http_server/http_server.cpp) endif() +if (BUILD_EMAIL_MODE) + list(APPEND PROJECT_SOURCES email_parser/emailparser.h email_parser/emailparser.cpp) + list(APPEND PROJECT_SOURCES utils/base64.h utils/base64.cpp) +endif() + if (BUILD_TRANSLATIONS) set(TS_FILES diff --git a/check/check.h b/check/check.h index 01af62b..1fc64d8 100644 --- a/check/check.h +++ b/check/check.h @@ -3,7 +3,22 @@ #include "../goods/goods.h" #include +typedef enum OperationTypes { + funds_income, // Приход средств + funds_return, // Возврат прихода + funds_spend, // Расход средств + spends_return // Возврат расхода +} OperationType; + class Check { + std::string fn; // Fiscal Number = Фискальный номер + std::string fd; // Fiscal Document = Фискальный документ + std::string fi; // Fiscal Identifier = Фискальный признак + + std::string date; + OperationType operation_type; + double total; + std::vector goods; public: @@ -14,6 +29,20 @@ public: double calculae_total_price(); std::vector &get_goods(); + + void set_fn(std::string); + void set_fd(std::string); + void set_fi(std::string); + void set_date(std::string); + void set_operation_type(OperationType); + void set_total(double); + + std::string get_fn(); + std::string get_fd(); + std::string get_fi(); + std::string get_date(); + OperationType get_operationType(); + double get_total(); }; #endif // CHECK_H diff --git a/email_parser/emailparser.cpp b/email_parser/emailparser.cpp new file mode 100644 index 0000000..020b612 --- /dev/null +++ b/email_parser/emailparser.cpp @@ -0,0 +1,70 @@ +#include + +#include +#include +#include +#include +#include +#if __GNUC__ < 8 && __clang_major__ < 17 +# include + using namespace std::experimental::filesystem; +#else +# include + using namespace std::filesystem; +#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::vector 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() { + +} + +Check EmailParser::parse(std::string &email_content) { + //1. Search "Content-Type: image/.*" in the .eml file. + // 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.3 Loop through every found entry. If not found in any, go to [2] + //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.1 If not found, notify the user that we could not parse the .eml file + + + // 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::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); +} diff --git a/email_parser/emailparser.h b/email_parser/emailparser.h new file mode 100644 index 0000000..b52f383 --- /dev/null +++ b/email_parser/emailparser.h @@ -0,0 +1,15 @@ +#ifndef CHECKS_PARSER_EMAIL_PARSER +#define CHECKS_PARSER_EMAIL_PARSER + +#include + +class EmailParser { + std::string get_payload_in_email(std::string &email_content); + // std::vector find_base64_blocks_in_email(std::string &email_content); +public: + EmailParser(); + Check parse(std::string &email_content); + Check parse_file(std::string path); +}; + +#endif // CHECKS_PARSER_EMAIL_PARSER diff --git a/main.cpp b/main.cpp index e7d1ec2..59f8d0a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,4 @@ +#include "email_parser/emailparser.h" #include #include #include @@ -27,7 +28,12 @@ #endif #include +#include + int main(int argc, char *argv[]) { +// EmailParser ep; +// ep.parse_file("/home/leca/example_email_receipts/rzd.eml"); +// return 0; curl_global_init(CURL_GLOBAL_ALL); std::string program_data_path = get_path_relative_to_home(".local/share/checks_parser"); diff --git a/translations/en_US.ts b/translations/en_US.ts index faa1153..ed4649e 100644 --- a/translations/en_US.ts +++ b/translations/en_US.ts @@ -597,7 +597,7 @@ QObject - + Using locale: Using locale: diff --git a/translations/ru_RU.ts b/translations/ru_RU.ts index 2827ecb..21c8dab 100644 --- a/translations/ru_RU.ts +++ b/translations/ru_RU.ts @@ -593,7 +593,7 @@ QObject - + Using locale: Использую локаль: diff --git a/utils/base64.cpp b/utils/base64.cpp new file mode 100644 index 0000000..a8b6175 --- /dev/null +++ b/utils/base64.cpp @@ -0,0 +1,79 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +#include +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static inline bool is_base64(unsigned char c) { + return (std::isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/utils/base64.h b/utils/base64.h new file mode 100644 index 0000000..65e36c4 --- /dev/null +++ b/utils/base64.h @@ -0,0 +1,29 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ +#include + +std::string base64_decode(std::string const& encoded_string);