deployment and fixed punycode crashing program

This commit is contained in:
leca 2025-05-31 01:40:35 +03:00
parent 896b81c999
commit 259b8543a4
9 changed files with 146 additions and 82 deletions

View File

@ -1,28 +1,36 @@
# Checks parser
-->[Русская версия](https://git.foxarmy.org/leca/checks-parser/src/branch/master/README.ru.md)<--
# Checks parser
checks parser is a program that help parsing different checks to csv.
!!!CURRENTLY SUPPORTED ONLY RUSSIAN CHECKS!!!
To know why, see [this section](https://git.foxarmy.org/leca/checks-parser#checks-from-different-countries)
# Usage
## Usage
For more detailed description, please, refer to [the wiki](https://git.foxarmy.org/leca/checks-parser/wiki/Description-%5BEN%5D)
### Input
## Input
Ways you can input a check to this programm:
* Via image (it uses OCR(Optical Character Recognition) to parse check content. The picture of a check must be contrast and well-lined (text must be perpendicular to right and left borders of an image) enough in order to be parsed well.) OCR is not a magic wand :(
* Via plaintext, copied from an E-Mail. Just copy&paste text from your email, pick a correct store type (autodetect is in my plans!) and parse.
* Via QRCode on check (this method queries check content from OFD (ОФД, Оператор Фискальных Данных in Russian) (My program makes requests to ofd.ru)).
### Output
At the start of writing this program, I considered 3 or more output formats: csv, xlsx and ods. But throught the development I understood that most of modern table processor (i.e. electronic tables) can import csv much better than I'd be writing a shitty export module, adding more dependencies and shitty code to the codebase. So I decided that there's no need to use anything other than csv format.
At the start of writing this program, I considered 3 or more output formats: csv, xlsx and ods. But throught the development I understood that most of modern table processor (i.e. electronic tables) can import csv much better than I'd be writing a shitty export module, adding more dependencies and shitty code to the codebase. So I decided that there's no need to use anything other than csv format.
To export, you need to specify an output file path and, if you wish, you can change order and/or rename columns, choose to print or not to print header (column names) and total.
# Installing
## Building
## Installing
### Building
In general, you need to install following dependencies in order to build that app(I suppose you have installed all the build necessaries such as cmake, make, gcc, git, etc...):
* boost
* tesseract (you also have to install appropriate for your needs language data)
* opencv
@ -33,8 +41,11 @@ In general, you need to install following dependencies in order to build that ap
* qrencode
Please, do not hesitate to open an issue if you cannot build that. I will help and if you are building on a distro that is not listed there, we can append that list as soon as we will solve your problem!
### Linux
#### Linux
##### Arch Linux-based
I recommend using aur helper (I use yay) to install dependencies. Or, if you're masochist, you can build all by yourself ¯\\\_(ツ)\_/¯
```
#Install dependencies
@ -49,17 +60,24 @@ make -j{nproc}
#If you wish to install that program system-wide, run
sudo make install
```
##### Debian-based
In debian-based distributions most, but not every, package names are the same.
Installation of dependencies for different debian-based distros:
###### Ubuntu 18.04
```apt install -y qtbase5-dev openssl libmbedtls-dev tesseract-ocr tesseract-ocr-rus libopencv-dev libzbar-dev qttools5-dev nlohmann-json-dev libcurl4-openssl-dev libtesseract-dev libqrencode-dev libboost-regex-dev```
###### Ubuntu 20.04, LMDE (tested only 6), Debian (tested only 12)
```apt install -y qtbase5-dev openssl libmbedtls-dev tesseract-ocr tesseract-ocr-rus libopencv-dev libzbar-dev qttools5-dev nlohmann-json3-dev libcurl4-openssl-dev libtesseract-dev libqrencode-dev libboost-regex-dev```
```apt install -y qt6-base-dev openssl libmbedtls-dev tesseract-ocr tesseract-ocr-rus libopencv-dev qt6-tools-dev nlohmann-json3-dev libcurl4-openssl-dev libqrencode-dev libboost-regex-dev```
Next steps are identical for every debian-based distro
```
```sh
#Clone and compile an app
git clone https://git.foxarmy.org/leca/checks-parser
cd checks-parser
@ -69,36 +87,42 @@ make -j{nproc}
sudo make install
```
### Windows
#### Windows
See [Precompiled binaries](https://git.foxarmy.org/leca/checks-parser#precompiled-binaries)
### Mac OS
#### Mac OS
Probably not, I do not have nor desire or time. But if you can maintain that program on Mac, I'd be grateful! Please, contact me, if you can!
## Precompiled binaries
### Precompiled binaries
Currently I have published the program to the [AUR](https://aur.archlinux.org/packages/checks-parser-git).
Every new release will certainly contain AppImage and tarball. I am working towards binaries for Windows and deb packets. Expect them to appear in next releases!
# Special thanks
## Special thanks
HyperFlint (@hyperflint:foxarmy.org) - for the great idea to use OFD and a huge help in release preparations!
https://check.ofd.ru - for providing a way to request data from FNS.
[ofd.ru](https://check.ofd.ru) - for providing a way to request data from FNS.
# Contribution
## Contribution
If you want to contribute to the project, you can do it by some of the following:
## Checks from different countries
### Checks from different countries
I live in Russia and only know how Russian state checks system works. If you live in another country and want to help me with adding support to checks from your country - feel free to contact me!
## Issues and PRs
### Issues and PRs
If you have found a bug, or want to suggest a feature - don't hesitate to open an issue / a PR!
## Tell friends
### Tell friends
You can help me by distributing that program. If you know people that are in search of such program, please let them know about its existance!
## Donate
### Donate
```XMR 45ZjyH5YWdRfKxLoKEBYaiHUTcP5Z8Gv64QQxmabbooPAa7KPBxZLmqft5ohKXn5VpHiVj1x9JKCcAcAjdu9jA8b5N8XqR7```

View File

@ -8,10 +8,10 @@ arch=('x86_64')
url="https://git.foxarmy.org/leca/checks-parser"
license=('GPL-3.0-or-later')
groups=()
depends=('qt5-base' 'opencv' 'zbar' 'nlohmann-json' 'tesseract' 'qrencode' 'boost')
makedepends=('cmake' 'make' 'gcc' 'git' 'qt5-tools')
depends=('qt6-base' 'opencv' 'nlohmann-json' 'qrencode' 'boost')
makedepends=('cmake' 'make' 'gcc' 'git' 'qt6-tools')
checkdepends=()
optdepends=('tesseract-data-rus: scan russian checks with OCR')
optdepends=()
provides=()
conflicts=("checks-parser-git")
replaces=()

View File

@ -8,10 +8,10 @@ arch=('x86_64')
url="https://git.foxarmy.org/leca/checks-parser"
license=('GPL-3.0-or-later')
groups=()
depends=('qt5-base' 'opencv' 'zbar' 'nlohmann-json' 'tesseract' 'qrencode' 'boost')
makedepends=('cmake' 'make' 'gcc' 'git' 'qt5-tools')
depends=('qt6-base' 'opencv' 'nlohmann-json' 'qrencode' 'boost')
makedepends=('cmake' 'make' 'gcc' 'git' 'qt6-tools')
checkdepends=()
optdepends=('tesseract-data-rus: scan russian checks with OCR')
optdepends=()
provides=()
conflicts=("checks-parser-bin")
replaces=()
@ -25,12 +25,15 @@ sha256sums=('SKIP')
build() {
cd "$pkgname"
cmake -DBUILD_TRANSLATIONS=on .
mkdir build && cd build
cmake -DBUILD_TRANSLATIONS=on ..
make -j ${nproc}
}
package() {
cd "$pkgname"
cd "$pkgname"
cd build
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
##install -Dm755
make DESTDIR="$pkgdir/" PREFIX="/usr" install
}

View File

@ -0,0 +1,30 @@
FROM archlinux:latest
ARG pkgname=$name
ARG pkgver=$version
ARG revision
RUN mkdir -p /output
RUN pacman --noconfirm -Syu base base-devel sudo
RUN chmod +x /deploy.sh
# RUN useradd -m builder
# RUN usermod -a -G wheel builder
# RUN chown -R builder:builder /output
# RUN echo "%wheel ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers
# USER builder
# WORKDIR /home/builder/checks-parser
COPY deploy/archlinux/bin/PKGBUILD PKGBUILD
RUN sed -i "s|\$pkgname|${pkgname}-bin|g" PKGBUILD
RUN sed -i "s|\$pkgver|${pkgver}|g" PKGBUILD
RUN sed -i "s|\$pkgrel|$revision|g" PKGBUILD
RUN makepkg -s --noconfirm
RUN echo "sudo cp ${pkgname}-bin-${pkgver}-$revision-x86_64.pkg.tar.zst /output" > /deploy.sh
ENTRYPOINT ["bash", "/deploy.sh"]

View File

@ -3,7 +3,7 @@ FROM ubuntu:24.04
# Installing dependencies
RUN apt update
RUN DEBIAN_FRONTEND=noninteractive apt install -y qt6-base-dev qt6-tools-dev openssl libmbedtls-dev libopencv-dev libzbar-dev nlohmann-json3-dev libcurl4-openssl-dev libqrencode-dev
RUN DEBIAN_FRONTEND=noninteractive apt install -y qt6-base-dev qt6-tools-dev openssl libmbedtls-dev libopencv-dev nlohmann-json3-dev libcurl4-openssl-dev libqrencode-dev
RUN DEBIAN_FRONTEND=noninteractive apt install -y wget git cmake make gcc g++ fuse libboost-regex-dev
WORKDIR /app

View File

@ -1,31 +1,33 @@
#ifndef GOODS_H
#define GOODS_H
#include <string>
#include <QDataStream>
#include <string>
#include <vector>
class Goods {
std::string name;
double quantity; // by weight or by the piece
std::string net_weight; // will contain values like "5мл" or "10г"
double price_per_unit;
class Goods
{
std::string name;
double quantity; // by weight or by the piece
std::string net_weight; // will contain values like "5мл" or "10г"
double price_per_unit;
public:
Goods();
Goods(std::string name, double quantity, std::string net_weight, double price_per_unit);
double calculate_total_price();
Goods();
Goods(std::string name, double quantity, std::string net_weight,
double price_per_unit);
double calculate_total_price();
std::string get_name();
double get_quantity();
std::string get_net_weight();
double get_price_per_unit();
std::string get_name();
double get_quantity();
std::string get_net_weight();
double get_price_per_unit();
void set_name(std::string);
void set_name(QString);
void set_quantity(double);
void set_net_weight(std::string);
void set_net_weight(QString);
void set_price_per_unit(double);
void set_name(std::string);
void set_name(QString);
void set_quantity(double);
void set_net_weight(std::string);
void set_net_weight(QString);
void set_price_per_unit(double);
};
QDataStream &operator<<(QDataStream &, Goods &);

View File

@ -5,6 +5,8 @@
#include <QMessageBox>
#include <QPixmap>
#include <settingsdialog.h>
#include <string>
#include <boost/regex.hpp>
#ifdef BUILD_OFD_LOCAL_QR_SCAN
# include <adjustpicturedialog.h>
@ -125,6 +127,9 @@ void MainWindow::httpNewMessageHandler(QString message) {
//erase /?result= from the string
parametersString.erase(0, parametersString.find("=") + 1);
//TODO: punycode %26 %3D
parametersString = boost::regex_replace(parametersString, boost::regex("%26"), "&");
parametersString = boost::regex_replace(parametersString, boost::regex("%3D"), "=");
std::vector<std::string> parameters = split(parametersString, "&");

View File

@ -253,77 +253,77 @@
<translation type="vanished">checks parser</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="104"/>
<location filename="../mainwindow.cpp" line="106"/>
<source>QR code for binaryeye to connect</source>
<translation>QR code for binaryeye to connect</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="105"/>
<location filename="../mainwindow.cpp" line="107"/>
<source>I&apos;ve scanned</source>
<translation>I&apos;ve scanned</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="111"/>
<location filename="../mainwindow.cpp" line="113"/>
<source>Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn&apos;t lucky, please, contact the developer.</source>
<translation>Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn&apos;t lucky, please, contact the developer.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="113"/>
<location filename="../mainwindow.cpp" line="115"/>
<source>Could not start http server.</source>
<translation>Could not start http server.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="156"/>
<location filename="../mainwindow.cpp" line="161"/>
<source>Selected image: </source>
<translation>Selected image: </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="189"/>
<location filename="../mainwindow.cpp" line="194"/>
<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>
</message>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="196"/>
<source>Under development</source>
<translation>Under development</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="202"/>
<location filename="../mainwindow.cpp" line="207"/>
<source>Please, add check(s) to parse</source>
<translation>Please, add check(s) to parse</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="204"/>
<location filename="../mainwindow.cpp" line="209"/>
<source>No checks to parse</source>
<translation>No checks to parse</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="270"/>
<location filename="../mainwindow.cpp" line="275"/>
<source>Captcha was not solved correctly!</source>
<translation>Captcha was not solved correctly!</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="272"/>
<location filename="../mainwindow.cpp" line="277"/>
<source>Captcha is incorrect</source>
<translation>Captcha is incorrect</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="277"/>
<location filename="../mainwindow.cpp" line="282"/>
<source>Internal server error. Please, try again later.</source>
<translation>Internal server error. Please, try again later.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="279"/>
<location filename="../mainwindow.cpp" line="284"/>
<source>Internal server error</source>
<translation>Internal server error</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="284"/>
<location filename="../mainwindow.cpp" line="289"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Check not found. Please, ensure correctness of entered data.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="286"/>
<location filename="../mainwindow.cpp" line="291"/>
<source>Check was not found</source>
<translation>Check was not found</translation>
</message>
@ -336,12 +336,12 @@
<translation type="vanished">Error in parsing</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="149"/>
<location filename="../mainwindow.cpp" line="154"/>
<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>
</message>
<message>
<location filename="../mainwindow.cpp" line="151"/>
<location filename="../mainwindow.cpp" line="156"/>
<source>Picture was not selected</source>
<translation>Picture was not selected</translation>
</message>

View File

@ -241,77 +241,77 @@
<translation type="vanished">Парсер чеков</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="104"/>
<location filename="../mainwindow.cpp" line="106"/>
<source>QR code for binaryeye to connect</source>
<translation>QR код для подключения BinaryEye</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="105"/>
<location filename="../mainwindow.cpp" line="107"/>
<source>I&apos;ve scanned</source>
<translation>Просканировал</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="111"/>
<location filename="../mainwindow.cpp" line="113"/>
<source>Could not start http server. 10 times in a row random port was occupied. Either you should run for a lottery ticket, or the problem is in the program. If the lottery ticket wasn&apos;t lucky, please, contact the developer.</source>
<translation>Не смог поднять HTTP сервер. 10 раз подряд случайно выбранный порт был занят. Либо Вам следует бежать за лоттерейным билетом, или в программе баг. Если лотерейный билет не был выигрышным, пожалуйста, сообщите разработчику.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="113"/>
<location filename="../mainwindow.cpp" line="115"/>
<source>Could not start http server.</source>
<translation>Не получилось запустить HTTP сервер.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="156"/>
<location filename="../mainwindow.cpp" line="161"/>
<source>Selected image: </source>
<translation>Выбранное изображение: </translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="189"/>
<location filename="../mainwindow.cpp" line="194"/>
<source>This feature is under development. Wait it to appear in next updates.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="191"/>
<location filename="../mainwindow.cpp" line="196"/>
<source>Under development</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="202"/>
<location filename="../mainwindow.cpp" line="207"/>
<source>Please, add check(s) to parse</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="204"/>
<location filename="../mainwindow.cpp" line="209"/>
<source>No checks to parse</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="270"/>
<location filename="../mainwindow.cpp" line="275"/>
<source>Captcha was not solved correctly!</source>
<translation>Капча была решена неверно!</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="272"/>
<location filename="../mainwindow.cpp" line="277"/>
<source>Captcha is incorrect</source>
<translation>Капча введена неверно</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="277"/>
<location filename="../mainwindow.cpp" line="282"/>
<source>Internal server error. Please, try again later.</source>
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="279"/>
<location filename="../mainwindow.cpp" line="284"/>
<source>Internal server error</source>
<translation>Внутренняя ошибка сервера</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="284"/>
<location filename="../mainwindow.cpp" line="289"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="286"/>
<location filename="../mainwindow.cpp" line="291"/>
<source>Check was not found</source>
<translation>Чек не найден</translation>
</message>
@ -324,12 +324,12 @@
<translation type="vanished">Ошибка в парсинге</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="149"/>
<location filename="../mainwindow.cpp" line="154"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
</message>
<message>
<location filename="../mainwindow.cpp" line="151"/>
<location filename="../mainwindow.cpp" line="156"/>
<source>Picture was not selected</source>
<translation>Изображение не было выбрано</translation>
</message>