a lot of fixes

This commit is contained in:
leca 2024-10-05 13:52:44 +03:00
parent 640337d420
commit d2afa8c9dd
32 changed files with 909 additions and 104 deletions

3
.gitignore vendored
View File

@ -75,3 +75,6 @@ CMakeLists.txt.user*
#Build
build
build/
*.AppImage
*.appimage

View File

@ -43,13 +43,17 @@ else()
check/check.h check/check.cpp
parser/parser.h parser/parser.cpp
parser/module.h parser/module.cpp
settings.h
outputdialog.h outputdialog.cpp outputdialog.ui
output/output_options.h output/output_options.cpp
ofd/ofd.h ofd/ofd.cpp
ofd/module.h ofd/module.cpp
utils/utils.h utils/utils.cpp
image/checkimage.h image/checkimage.cpp
net/net.h net/net.cpp
settings/settings.h settings/settings.cpp
settingsdialog.h settingsdialog.cpp settingsdialog.ui
)
endif()
endif()

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 14.0.0, 2024-08-30T01:20:43. -->
<!-- Written by QtCreator 14.0.1, 2024-10-02T12:10:46. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -102,14 +102,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
@ -159,14 +159,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
@ -213,14 +213,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
@ -267,14 +267,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
@ -322,14 +322,14 @@
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=MinSizeRel
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}</value>
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_BUILD_TYPE:STRING=MinSizeRel
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/leca/projects/qt/checks-parser/build/Desktop-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
@ -402,7 +402,7 @@
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/leca/projects/qt/checks-parser/build/Desktop-Debug</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/leca/projects/qt/checks-parser/build/Desktop-Debug/bin</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>

2
TODO
View File

@ -7,5 +7,7 @@ Complete module "image-to-text":
Add features:
autodetect store type
auto download of stores modules
auto download of ofd modules
settings, a window for editing settings.
Refactor:
Get rid of CPR, use libcurl instead

View File

@ -0,0 +1 @@
checks-parser.png

View File

@ -0,0 +1 @@
usr/bin/checks-parser

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Name=Checks parser
Type=Application
Terminal=false
NoDisplay=false
Exec=checks-parser
Categories=Utility;
Icon=checks-parser

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 KiB

Binary file not shown.

View File

@ -1,7 +1,47 @@
#include "mainwindow.h"
#include "net/net.h"
#include "ofd/ofd.h"
#include "settings/settings.h"
#include "utils/utils.h"
#include <QApplication>
#include <curl/curl.h>
#include <iostream>
int main(int argc, char *argv[]) {
curl_global_init(CURL_GLOBAL_ALL);
std::string settings_file_path =
get_path_relative_to_home(".local/share/checks_parser/settings.json");
Settings s(settings_file_path);
OFD ofd;
Net n;
std::vector<std::string> ofd_updates = ofd.check_updates();
for (const std::string &update : ofd_updates) {
std::cout << "Downloading "
<< s.get_setting("ofds_modules_url") + update << " to "
<< get_path_relative_to_home(s.get_setting("ofds_modules_dir") +
"/" + update)
<< std::endl;
n.get_file(s.get_setting("ofds_modules_url") + "/" + update,
get_path_relative_to_home(s.get_setting("ofds_modules_dir") +
"/" + update));
}
Parser p;
std::vector<std::string> stores_updates = p.check_updates();\
for (const std::string &update : stores_updates) {
std::cout << "Downloading "
<< s.get_setting("stores_modules_url") + update << " to "
<< get_path_relative_to_home(s.get_setting("stores_modules_dir") +
"/" + update)
<< std::endl;
n.get_file(s.get_setting("stores_modules_url") + "/" + update,
get_path_relative_to_home(s.get_setting("stores_modules_dir") +
"/" + update));
}
QApplication a(argc, argv);
MainWindow w;

View File

@ -3,7 +3,7 @@
#include "check/check.h"
#include "goods/goods.h"
#include "outputdialog.h"
#include "settings.h"
#include "settingsdialog.h"
#include <iostream>
#include <QFileDialog>
#include "image/checkimage.h"
@ -67,9 +67,9 @@ void MainWindow::on_parseButton_clicked() {
check.add_goods(g);
}
OutputDialog *d = new OutputDialog(this, check);
d->show();
d->exec();
OutputDialog d = OutputDialog(this, check);
d.show();
d.exec();
}
void MainWindow::on_storeType_currentIndexChanged(int index) {
@ -91,3 +91,10 @@ void MainWindow::on_chooseImageButton_clicked() {
ui->checkContentFromImage->setPlainText(QString::fromStdString(parsed));
}
void MainWindow::on_preferencesButton_clicked() {
SettingsDialog s = SettingsDialog();
s.show();
s.exec();
}

View File

@ -33,6 +33,8 @@ private slots:
void on_chooseImageButton_clicked();
void on_preferencesButton_clicked();
private:
Ui::MainWindow *ui;
};

View File

@ -172,6 +172,19 @@
<string>Parse</string>
</property>
</widget>
<widget class="QPushButton" name="preferencesButton">
<property name="geometry">
<rect>
<x>730</x>
<y>0</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Preferences</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">

63
net/net.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "net.h"
#include <curl/curl.h>
#include <iostream>
#include <vector>
#include <regex>
struct data {};
size_t write_data(void *buffer, size_t size, size_t nmemb, void *filename) {
FILE *f = fopen(((std::string *)filename)->c_str(), "w");
size_t written = fwrite(buffer, size, nmemb, f);
fclose(f);
return written;
}
Net::Net() {}
void write_modules(void *buffer, size_t size, size_t nmemb, void *modules) {
std::vector<std::string> *modules_vector =
(std::vector<std::string> *)modules;
std::string to_parse = std::string((char*)buffer);
std::regex r("(?!\\\")\\w+\\.json(?!\\\")", std::regex::collate);
std::smatch res;
std::string::const_iterator search(to_parse.cbegin());
while (std::regex_search(search, to_parse.cend(), res, r)) {
modules_vector->push_back(res[0]);
search = res.suffix().first;
}
}
std::vector<std::string> Net::get_all_modules(std::string url) {
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_modules);
std::vector<std::string> modules {};
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &modules);
curl_easy_perform(handle);
return modules;
}
std::string Net::get_file(std::string url, std::string filename) {
CURL *handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &filename);
auto success = curl_easy_perform(handle);
curl_easy_cleanup(handle);
return "";
}

17
net/net.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef NET_H
#define NET_H
#include <string>
#include <vector>
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
class Net
{
public:
Net();
std::vector<std::string> get_all_modules(std::string url);
std::string get_file(std::string url, std::string filename);
};
#endif // NET_H

View File

@ -1,19 +1,21 @@
#include "ofd.h"
#include "../settings.h"
#include "../utils/utils.h"
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
#include "../net/net.h"
#include "../settings/settings.h"
OFD::OFD() {}
OFD::OFD(std::string path) { this->module = OFDModule(path); };
std::vector<std::string> OFD::search_ofds() {
Settings s(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
std::vector<std::string> result{};
std::string path = std::string(std::getenv("HOME")) + "/" + OFDS_MODULES_DIR;
std::string path = get_path_relative_to_home(s.get_setting("ods_modules_dir"));
std::filesystem::directory_entry modules_dir(path);
if (!modules_dir.exists()) {
@ -35,45 +37,31 @@ void OFD::set_module(std::string path) { this->module = OFDModule(path); }
std::string OFD::get_check_data(std::string fn, std::string fd,
std::string fp) {
//curl 'https://ofd.beeline.ru/api/ofdcheck/checkf?fn=7281440701327430&fp=2518183888&fd=25955&format=4' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-US,en;q=0.9,eo;q=0.8,ru;q=0.7' \
-H 'Authorization: bearer null' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'DNT: 1' \
-H 'Referer: https://ofd.beeline.ru/check-order?fn=7281440701327430&fp=2518183888&fd=25955' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Chromium";v="127", "Not)A;Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Linux"'
// curl 'https://ofd.beeline.ru/api/ofdcheck/checkf?fn=7281440701327430&fp=2807139546&fd=25051&format=4' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: en-US,en;q=0.9,eo;q=0.8,ru;q=0.7' \
-H 'Authorization: bearer null' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'DNT: 1' \
-H 'Referer: https://ofd.beeline.ru/check-order?fn=7281440701327430&fp=2807139546&fd=25051' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Chromium";v="127", "Not)A;Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Linux"'
// // cpr::Response r = cpr::Get(cpr::Url{"https://httpbin.org/get"});
// std::cout << fn << " " << fd << " " << fp << std::endl;
// cpr::Response r =
// //to_utf8(module.get_url())
// cpr::Get(cpr::Url{"https://ofd.beeline.ru/api/ofdcheck/checkf"},
// cpr::Parameters{{"fn", fn}, {"fd", fd}, {"fp", fp}, {"format", "4"}});
// return r.text;
//TODO
return "";
}
std::vector<std::string> OFD::check_updates() {
Settings s(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
std::string path = get_path_relative_to_home(s.get_setting("ofds_modules_dir"));
std::vector<std::string> to_download;
std::vector<std::string> stored_modules;
for (const auto& file : std::filesystem::directory_iterator(path)) {
if (!file.is_regular_file()) continue;
stored_modules.push_back(file.path().filename());
std::cout << "Detected OFD module" << file.path().filename() << std::endl;
}
Net n;
std::vector<std::string> remote_modules = n.get_all_modules(s.get_setting("ofds_modules_url"));
for (const std::string& module : remote_modules) {
if (!vector_contains_element(stored_modules, module)) {
to_download.push_back(module);
std::cout << "I need to download OFD module " << module << std::endl;
}
}
return to_download;
}

View File

@ -18,5 +18,6 @@ public:
void set_module(std::string);
std::string get_check_data(std::string fn, std::string fd, std::string fp);
std::vector<std::string> check_updates();
};
#endif // OFD_H

View File

@ -10,7 +10,7 @@ void OutputOptions::add_or_update_column(Column &column) {
}
}
void OutputOptions::update_column(Column& column, unsigned short index) {
void OutputOptions::update_column(Column &column, unsigned short index) {
this->order[index] = column;
}
@ -38,13 +38,11 @@ bool OutputOptions::column_exist(ColumnType t) {
return false;
}
Column& OutputOptions::get_column (ColumnType t){
Column &OutputOptions::get_column(ColumnType t) {
return this->order[find_column(t)];
}
std::vector<Column>& OutputOptions::get_columns() {
return this->order;
}
std::vector<Column> &OutputOptions::get_columns() { return this->order; }
void OutputOptions::set_print_header(bool value) { this->print_header = value; }
bool OutputOptions::get_print_header() { return this->print_header; }

View File

@ -6,11 +6,35 @@
#include <QMainWindow>
#include <fstream>
#include <iostream>
#include "settings/settings.h"
#include "utils/utils.h"
OutputDialog::OutputDialog(QWidget *parent, Check &check)
: QDialog(parent), ui(new Ui::OutputDialog), check(check),
options(*(new OutputOptions())) {
options(OutputOptions()) {
Settings settings(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
ui->setupUi(this);
ui->tableWidget->item(0, 0)->setText(QString::fromStdString(settings.get_all_settings()["output_order"]["goods_name"]["name"]));
ui->tableWidget->item(0, 1)->setText(QString::number((int)settings.get_all_settings()["output_order"]["goods_name"]["position"]));
ui->tableWidget->item(1, 0)->setText(QString::fromStdString(settings.get_all_settings()["output_order"]["goods_price_per_unit"]["name"]));
ui->tableWidget->item(1, 1)->setText(QString::number((int)settings.get_all_settings()["output_order"]["goods_price_per_unit"]["position"]));
ui->tableWidget->item(2, 0)->setText(QString::fromStdString(settings.get_all_settings()["output_order"]["goods_quantity"]["name"]));
ui->tableWidget->item(2, 1)->setText(QString::number((int)settings.get_all_settings()["output_order"]["goods_quantity"]["position"]));
ui->tableWidget->item(3, 0)->setText(QString::fromStdString(settings.get_all_settings()["output_order"]["goods_net_weight"]["name"]));
ui->tableWidget->item(3, 1)->setText(QString::number((int)settings.get_all_settings()["output_order"]["goods_net_weight"]["position"]));
ui->tableWidget->item(4, 0)->setText(QString::fromStdString(settings.get_all_settings()["output_order"]["goods_total"]["name"]));
ui->tableWidget->item(4, 1)->setText(QString::number((int)settings.get_all_settings()["output_order"]["goods_total"]["position"]));
ui->printHeaderCheckBox->setChecked(settings.get_all_settings()["print_header"]);
ui->printTotalCheckBox->setChecked(settings.get_all_settings()["print_total"]);
}
OutputDialog::~OutputDialog() { delete ui; }

View File

@ -3,8 +3,8 @@
#include "check/check.h"
#include "output/output_options.h"
#include <QDialog>
#include <QComboBox>
#include <QDialog>
namespace Ui {
class OutputDialog;
@ -16,7 +16,6 @@ class OutputDialog : public QDialog {
OutputOptions options;
Check &check;
public:
explicit OutputDialog(QWidget *parent = nullptr, Check & = *(new Check()));
~OutputDialog();

View File

@ -1,13 +1,16 @@
#include "parser.h"
#include "../settings.h"
#include "../goods/goods.h"
#include "../net/net.h"
#include "../settings/settings.h"
#include "../utils/utils.h"
#include <filesystem>
#include <iostream>
#include "../goods/goods.h"
Parser::Parser() {}
std::vector<std::string> Parser::search_modules() {
std::string path = std::string(std::getenv("HOME")) + "/" + STORES_MODULES_DIR;
Settings s(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
std::string path = get_path_relative_to_home(s.get_setting("stores_modules_dir"));//std::string(std::getenv("HOME")) + "/" + STORES_MODULES_DIR;
std::filesystem::directory_entry modules_dir(path);
if (!modules_dir.exists()) {
@ -38,9 +41,7 @@ std::vector<Goods> Parser::parse(std::wstring check_plaintext) {
std::vector<std::string> goods_prices = module.parse_price(check_plaintext);
std::vector<std::string> goods_quantities =
module.parse_quantity(check_plaintext);
#ifdef DEBUG
std::cout << goods_names.size() << " " << goods_prices.size() << " " << goods_quantities.size() << std::endl;
#endif
if (goods_names.size() != goods_prices.size() ||
goods_names.size() != goods_quantities.size() ||
goods_prices.size() != goods_quantities.size()) {
@ -57,3 +58,38 @@ std::vector<Goods> Parser::parse(std::wstring check_plaintext) {
return result;
}
std::vector<std::string> Parser::check_updates() {
std::cout << "Checking updates for stores modules" << std::endl;
Settings s(get_path_relative_to_home(".local/share/checks_parser/settings.json"));
std::string path = get_path_relative_to_home(s.get_setting("stores_modules_dir"));
std::vector<std::string> to_download;
std::vector<std::string> stored_modules;
std::filesystem::directory_entry modules_dir(path);
if (!modules_dir.exists()) {
std::filesystem::create_directories(path);
}
for (const auto& file : std::filesystem::directory_iterator(path)) {
if (!file.is_regular_file()) continue;
stored_modules.push_back(file.path().filename());
std::cout << file.path().filename() << " detected store module" << std::endl;
}
Net n;
std::cerr << "Downloading modules list from: " << s.get_setting("stores_modules_url");
std::vector<std::string> remote_modules = n.get_all_modules(s.get_setting("stores_modules_url"));
if (stored_modules.empty()) {
std::cout << "I need to download everything" << std::endl;
to_download = remote_modules;
} else {
for (const std::string& module : remote_modules) {
if (!vector_contains_element(stored_modules, module)) {
std::cout << "I need to download store module " << module << std::endl;
to_download.push_back(module);
}
}
}
return to_download;
}

View File

@ -1,22 +1,25 @@
#ifndef PARSER_H
#define PARSER_H
#include "../goods/goods.h"
#include "module.h"
#include <string>
#include <vector>
#include "../goods/goods.h"
class Parser {
StoreModule module;
public:
Parser();
std::vector<std::string> search_modules();
std::vector<std::string> check_updates();
void set_module(std::string);
std::vector<Goods> parse (std::wstring);
std::vector<Goods> parse(std::wstring);
};
#endif // PARSER_H

View File

@ -1,8 +0,0 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#define OFDS_MODULES_DIR ".local/share/checks_parser/modules/ofd"
#define STORES_MODULES_DIR ".local/share/checks_parser/modules/stores"
// #define DEBUG
#endif // SETTINGS_H

85
settings/settings.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "settings.h"
#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <string>
Settings::Settings(std::string path) {
this->settings_file_path = path;
if (!std::filesystem::exists(path)) {
std::ofstream output(path);
nlohmann::json settings = R"({
"ofds_modules_dir":".local/share/checks_parser/modules/ofd",
"stores_modules_dir":".local/share/checks_parser/modules/stores",
"ofds_modules_url":"https://foxarmy.org/checks-parser/modules/ofd/",
"stores_modules_url":"https://foxarmy.org/checks-parser/modules/modules/",
"print_header": true,
"print_total": true,
"output_order": {
"goods_name": {
"position":1,
"name":"Goods name"
},
"goods_price_per_unit": {
"position":2,
"name":"Goods price per unit"
},
"goods_quantity": {
"position":3,
"name":"Goods quantity"
},
"goods_net_weight": {
"position":4,
"name":"Goods net weight"
},
"goods_total": {
"position":5,
"name":"Goods total"
}
}
})"_json;
output << settings;
output.flush();
output.close();
this->settings = settings;
} else {
std::ifstream input(path);
nlohmann::json settings = nlohmann::json::parse(input);
this->settings = settings;
}
}
void Settings::write_setting(std::string setting, std::string value) {
std::ofstream output(this->settings_file_path, std::fstream::trunc);
this->settings[setting] = value;
output << this->settings;
}
std::string Settings::get_setting(std::string setting) {
return this->settings[setting];
}
void Settings::set_settings_file_path(std::string path) {
this->settings_file_path = path;
}
std::string Settings::get_settings_file_path() {
return this->settings_file_path;
}
nlohmann::json& Settings::get_all_settings() { return this->settings; }
void Settings::alter_setting(std::string setting, std::string value) {
this->settings[setting] = value;
}
void Settings::flush() {
std::ofstream output(this->settings_file_path, std::fstream::trunc);
output << this->settings;
}

28
settings/settings.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <nlohmann/json.hpp>
#include <string>
class Settings {
std::string settings_file_path;
nlohmann::json settings;
public:
Settings(std::string path);
//Immediately saves to a file
void write_setting(std::string setting, std::string value);
//Waits for a flush
void alter_setting(std::string setting, std::string value);
std::string get_setting(std::string setting);
void set_settings_file_path(std::string path);
std::string get_settings_file_path();
nlohmann::json& get_all_settings();
void flush();
};
#endif // SETTINGS_H

125
settingsdialog.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "settingsdialog.h"
#include "settings/settings.h"
#include "ui_settingsdialog.h"
#include "utils/utils.h"
#include <iostream>
SettingsDialog::SettingsDialog(QWidget *parent)
: QDialog(parent), ui(new Ui::settingsdialog),
settings(Settings(get_path_relative_to_home(
".local/share/checks_parser/settings.json"))) {
ui->setupUi(this);
ui->OFDModulesDirEdit->setText(QString::fromStdString(settings.get_all_settings()["ofds_modules_dir"]));
ui->OFDModulesURLEdit->setText(QString::fromStdString(settings.get_all_settings()["ofds_modules_url"]));
ui->storesModulesDirEdit->setText(QString::fromStdString(settings.get_all_settings()["stores_modules_dir"]));
ui->storesModulesURLEdit->setText(QString::fromStdString(settings.get_all_settings()["stores_modules_url"]));
ui->goodsNamePositionSpin->setValue(this->settings.get_all_settings()["output_order"]["goods_name"]["position"]);
ui->goodsNameAliasEdit->setText(QString::fromStdString(this->settings.get_all_settings()["output_order"]["goods_name"]["name"]));
ui->goodsPricePerUnitPositionSpin->setValue(this->settings.get_all_settings()["output_order"]["goods_price_per_unit"]["position"]);
ui->goodsPricePerUnitAliasEdit->setText(QString::fromStdString(this->settings.get_all_settings()["output_order"]["goods_price_per_unit"]["name"]));
ui->goodsQuantityPositionSpin->setValue(this->settings.get_all_settings()["output_order"]["goods_quantity"]["position"]);
ui->goodsQuantityAliasEdit->setText(QString::fromStdString(this->settings.get_all_settings()["output_order"]["goods_quantity"]["name"]));
ui->goodsNetWeightPositionSpin->setValue(this->settings.get_all_settings()["output_order"]["goods_net_weight"]["position"]);
ui->goodsNetWeightAliasEdit->setText(QString::fromStdString(this->settings.get_all_settings()["output_order"]["goods_net_weight"]["name"]));
ui->goodsTotalPositionSpin->setValue(this->settings.get_all_settings()["output_order"]["goods_total"]["position"]);
ui->goodsTotalAliasEdit->setText(QString::fromStdString(this->settings.get_all_settings()["output_order"]["goods_total"]["name"]));
ui->printHeaderCheckBox->setChecked(this->settings.get_all_settings()["print_header"]);
ui->printTotalCheckBox->setChecked(this->settings.get_all_settings()["print_total"]);
}
SettingsDialog::~SettingsDialog() { delete ui; }
void SettingsDialog::on_OFDModulesDirEdit_editingFinished() {
this->settings.alter_setting("ofds_modules_dir",
ui->OFDModulesDirEdit->text().toStdString());
}
void SettingsDialog::on_storesModulesDirEdit_editingFinished() {
this->settings.alter_setting("stores_modules_dir",
ui->storesModulesDirEdit->text().toStdString());
}
void SettingsDialog::on_OFDModulesURLEdit_editingFinished() {
this->settings.alter_setting("ofds_modules_url",
ui->OFDModulesURLEdit->text().toStdString());
}
void SettingsDialog::on_storesModulesURLEdit_editingFinished() {
this->settings.alter_setting("stores_modules_url",
ui->storesModulesURLEdit->text().toStdString());
}
void SettingsDialog::on_goodsNamePositionSpin_valueChanged(int value) {
this->settings.get_all_settings()["output_order"]["goods_name"]["position"] =
value;
}
void SettingsDialog::on_goodsNameAliasEdit_editingFinished() {
this->settings.get_all_settings()["output_order"]["goods_name"]["name"] =
ui->goodsNameAliasEdit->text().toStdString();
}
void SettingsDialog::on_goodsPricePerUnitPositionSpin_valueChanged(int value) {
this->settings
.get_all_settings()["output_order"]["goods_price_per_unit"]["position"] =
value;
}
void SettingsDialog::on_goodsPricePerUnitAliasEdit_editingFinished() {
this->settings.get_all_settings()["output_order"]["goods_price_per_unit"]["name"] =
ui->goodsPricePerUnitAliasEdit->text().toStdString();
}
void SettingsDialog::on_goodsQuantityPositionSpin_valueChanged(int value) {
this->settings
.get_all_settings()["output_order"]["goods_quantity"]["position"] = value;
}
void SettingsDialog::on_goodsQuantityAliasEdit_editingFinished() {
this->settings.get_all_settings()["output_order"]["goods_quantity"]["name"] =
ui->goodsQuantityAliasEdit->text().toStdString();
}
void SettingsDialog::on_goodsNetWeightPositionSpin_valueChanged(int value) {
this->settings
.get_all_settings()["output_order"]["goods_net_weight"]["position"] =
value;
}
void SettingsDialog::on_goodsNetWeightAliasEdit_editingFinished() {
this->settings.get_all_settings()["output_order"]["goods_net_weight"]["name"] =
ui->goodsNetWeightAliasEdit->text().toStdString();
}
void SettingsDialog::on_goodsTotalPositionSpin_valueChanged(int value) {
this->settings
.get_all_settings()["output_order"]["goods_total"]["position"] =
value;
}
void SettingsDialog::on_goodsTotalAliasEdit_editingFinished() {
this->settings.get_all_settings()["output_order"]["goods_total"]["name"] =
ui->goodsTotalAliasEdit->text().toStdString();
}
void SettingsDialog::on_printHeaderCheckBox_stateChanged(int value) {
this->settings.get_all_settings()["print_header"] = (value? true : false);
}
void SettingsDialog::on_printTotalCheckBox_stateChanged(int value) {
this->settings.get_all_settings()["print_total"] = (value? true : false);
}
void SettingsDialog::on_buttonBox_accepted() { this->settings.flush(); }
void SettingsDialog::on_buttonBox_rejected() { this->close(); }

59
settingsdialog.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QDialog>
#include "settings/settings.h"
namespace Ui {
class settingsdialog;
}
class SettingsDialog : public QDialog {
Q_OBJECT
Settings settings;
public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
private slots:
void on_OFDModulesDirEdit_editingFinished();
void on_buttonBox_accepted();
void on_storesModulesDirEdit_editingFinished();
void on_OFDModulesURLEdit_editingFinished();
void on_storesModulesURLEdit_editingFinished();
void on_goodsNamePositionSpin_valueChanged(int arg1);
void on_goodsNameAliasEdit_editingFinished();
void on_goodsPricePerUnitPositionSpin_valueChanged(int arg1);
void on_goodsPricePerUnitAliasEdit_editingFinished();
void on_goodsQuantityPositionSpin_valueChanged(int arg1);
void on_goodsQuantityAliasEdit_editingFinished();
void on_goodsNetWeightPositionSpin_valueChanged(int arg1);
void on_goodsNetWeightAliasEdit_editingFinished();
void on_goodsTotalPositionSpin_valueChanged(int arg1);
void on_goodsTotalAliasEdit_editingFinished();
void on_printHeaderCheckBox_stateChanged(int arg1);
void on_printTotalCheckBox_stateChanged(int arg1);
void on_buttonBox_rejected();
private:
Ui::settingsdialog *ui;
};
#endif // SETTINGSDIALOG_H

285
settingsdialog.ui Normal file
View File

@ -0,0 +1,285 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>settingsdialog</class>
<widget class="QDialog" name="settingsdialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>599</width>
<height>727</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>310</x>
<y>690</y>
<width>251</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Save</set>
</property>
</widget>
<widget class="QScrollArea" name="scrollArea">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>541</width>
<height>661</height>
</rect>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>539</width>
<height>659</height>
</rect>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>531</width>
<height>651</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="11" column="1">
<widget class="QLineEdit" name="goodsNetWeightAliasEdit"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="storesModulesDirEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Goods name position</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Goods price per unit alias</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="storedModulesDirChooseButton">
<property name="text">
<string>Choose</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLineEdit" name="goodsTotalAliasEdit"/>
</item>
<item row="14" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Print header</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Goods net weight alias</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Stores modules url</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="storesModulesURLEdit"/>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Goods total alias</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Goods name alias</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QSpinBox" name="goodsTotalPositionSpin"/>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Goods quantity alias</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Stores modules directory</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="goodsNameAliasEdit"/>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="goodsNetWeightPositionSpin"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>OFD modules directory</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="goodsNamePositionSpin"/>
</item>
<item row="9" column="1">
<widget class="QLineEdit" name="goodsQuantityAliasEdit"/>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="goodsPricePerUnitAliasEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Goods price per unit position</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Goods net weight position</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>OFD modules url</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="OFDModulesDirEdit"/>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Goods total position</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Goods quantity position</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="OFDModulesURLEdit"/>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="goodsQuantityPositionSpin"/>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="OFDModulesDirChooseButton">
<property name="text">
<string>Choose</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="goodsPricePerUnitPositionSpin"/>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Print total</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QCheckBox" name="printHeaderCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QCheckBox" name="printTotalCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>settingsdialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>settingsdialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,8 +1,8 @@
#include "utils.h"
#include <codecvt>
#include <string>
#include <locale>
#include <string>
std::string to_utf8(std::wstring wide_string) {
static std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
@ -13,3 +13,18 @@ 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);

View File

@ -2,8 +2,14 @@
#define UTILS_H
#include <string>
#include <vector>
std::string to_utf8(std::wstring wide_string);
std::wstring from_utf8(std::string string);
std::string get_path_relative_to_home(std::string path);
template <typename T>
bool vector_contains_element(const std::vector<T> &vector, const T &to_find);
#endif // UTILS_H