generate and show qr code

This commit is contained in:
leca 2025-03-15 00:48:46 +03:00
parent 2b2127e3b5
commit 3dbc85f929
9 changed files with 129 additions and 41 deletions

View File

@ -135,12 +135,18 @@ endif()
FetchContent_Declare(httplib SYSTEM
GIT_REPOSITORY https://github.com/yhirose/cpp-httplib
GIT_TAG 2eaa2ea64f9fb12773306534d461d9ed63cb76b6 # v0.14.1
GIT_TAG 0bda3a7d1a797f2b67953504fefa7391a817a0bd
GIT_SHALLOW TRUE)
FetchContent_MakeAvailable(httplib)
find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs)
find_package(PkgConfig)
pkg_check_modules(QRENCODE REQUIRED libqrencode)
include_directories(${QRENCODE_INCLUDE_DIRS})
link_directories(${QRENCODE_LIBRARY_DIRS})
target_link_libraries(checks-parser PRIVATE ${QRENCODE_LIBRARIES})
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_include_directories(checks-parser PUBLIC ${OpenCV_INCLUDE_DIRS})

View File

@ -29,6 +29,7 @@ In general, you need to install following dependencies in order to build that ap
* curl
* nlohmann-json
* qt5
* 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
@ -36,7 +37,7 @@ Please, do not hesitate to open an issue if you cannot build that. I will help a
I recommend using aur helper (I use yay) to install dependencies. Or, if you're masochist, you can build all by yourself ¯\\\_(ツ)\_/¯
```
#Install dependencies
yay -S base-devel qt5-base opencv zbar nlohmann-json tesseract
yay -S base-devel qt5-base opencv zbar nlohmann-json tesseract qrencode
#Install a language package for OCR. Replace ``LANG` to your language. For example, ``tesseract-data-rus`` for russian language
yay -S tesseract-data-LANG
#Clone and compile an app

View File

@ -37,7 +37,7 @@
Я рекомендую использовать помощник для АУРа (я использую yay) чтобы установить зависимости. Или, если вы мазохист, можете собрать все зависимости ручками ¯\\\_(ツ)\_/¯
```
#Установка зависимостей
yay -S base-devel qt5-base opencv zbar nlohmann-json tesseract
yay -S base-devel qt5-base opencv zbar nlohmann-json tesseract qrencode
#Установка языкового пакета для OCR. Замените ``LANG` на желаемый язык. Например, ``tesseract-data-rus`` для русского языка
yay -S tesseract-data-LANG
#Загрузка исходгого кода и сборка приложения

View File

@ -7,11 +7,13 @@
#include <adjustpicturedialog.h>
#include <httplib.h>
#include <outputdialog.h>
#include <qpixmap.h>
#include <solvecaptchadialog.h>
#include <net/net.h>
#include <exceptions/ofdrequestexception.h>
#include <bits/basic_string.h>
#include <qrencode.h>
#include <bits/basic_string.h>
@ -46,27 +48,29 @@ void OFDScene::startHttpServer() {
}
this->port = rand() % (65535 - 1024) + 1024;
httplib::Server svr;
std::string connectionString = "binaryeye://scan/?ret=http://"+ localIp +":"+ std::to_string(port) +"/?result={RESULT}";
svr.Get("/", [&](const httplib::Request &req, httplib::Response &res){
if (req.params.size() < 6) {
res.set_redirect("binaryeye://scan/?ret=http://"+ localIp +":"+ std::to_string(port) +"/", 301);
server.Get("/", [&](const httplib::Request &req, httplib::Response &res){
std::map<std::string, std::string> paramsMap;
if (req.params.size() < 1) {
res.set_redirect(connectionString, 301);
std::cerr << "Too few params: " << req.params.size() << std::endl;
return;
}
std::map<std::string, std::string> paramsMap;
for (auto &param : req.params) {
paramsMap.insert(std::pair<std::string, std::string>(param.first, param.second));
std::string result = req.params.find("result")->second;
std::vector<std::string> dataSplit = split(result, "&");
for (std::string &pair : dataSplit) {
std::vector<std::string> values = split(pair, "=");
paramsMap.insert(std::pair<std::string, std::string>(values[0], values[1]));
}
emit onDataDecode(paramsMap);
res.set_redirect("binaryeye://scan/?ret=http://"+ localIp +":"+ std::to_string(port) +"/", 301);
res.set_redirect(connectionString, 301);
});
number_of_retries ++;
std::cerr << "Listening on port: " << this->port << std::endl;
if (!svr.listen("0.0.0.0", this->port)) {
if (!server.listen("0.0.0.0", this->port)) {
std::cerr << "Random port seems to be occupied. Trying to generate another one" << std::endl;
number_of_retries ++;
continue;
@ -94,9 +98,6 @@ void OFDScene::on_choose_image_button_clicked() {
}
void OFDScene::onDataDecode(std::map<std::string, std::string> data) {
// std::vector<std::string> dataSplit = split(data, "&");
ui->fn_line_edit->setText(QString::fromStdString(data["fn"]));
ui->fd_line_edit->setText(QString::fromStdString(data["i"]));
ui->fi_line_edit->setText(QString::fromStdString(data["fp"]));
@ -117,7 +118,6 @@ void OFDScene::onDataDecode(std::map<std::string, std::string> data) {
ui->total_spin_box->setValue(std::stod(total));
}
void OFDScene::on_parse_button_clicked() {
Net net;
net.get_captcha_from_ofdru();
@ -178,9 +178,28 @@ void OFDScene::on_parse_button_clicked() {
}
}
void OFDScene::on_binary_eye_button_clicked() {
http_thread = new std::thread(&OFDScene::startHttpServer, this);
ui->binary_eye_button->setEnabled(false);
while (!server.is_running());
std::string localIp;
try {
localIp = get_local_ip_address();
} catch(std::exception e) {
std::cerr << e.what() << std::endl;
return;
}
std::string connectionString = "binaryeye://scan?ret=http://" + localIp + ":" + std::to_string(port) + "/?result={RESULT}";
generate_qr_code(connectionString);
QMessageBox infoDialog = QMessageBox();
infoDialog.setText(QString::fromStdString(connectionString));
infoDialog.setIconPixmap(QPixmap(QString::fromStdString(get_path_relative_to_home(".local/share/checks_parser/binaryeye_connection.png"))).scaled(400, 400, Qt::KeepAspectRatio));
infoDialog.setWindowTitle(tr("QR code for binaryeye to connect"));
infoDialog.setButtonText(1, tr("I've scanned"));
infoDialog.exec();
}
void OFDScene::notifyHttpServerFailure() {

View File

@ -2,6 +2,7 @@
#define OFDSCENE_H
#include <QWidget>
#include <httplib.h>
#include <thread>
namespace Ui {
@ -36,6 +37,7 @@ private:
std::thread *http_thread;
unsigned int port;
httplib::Server server;
};
#endif // OFDSCENE_H

View File

@ -367,60 +367,74 @@
<translation>Parse</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="188"/>
<location filename="../ofdscene.cpp" line="205"/>
<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 type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="190"/>
<location filename="../ofdscene.cpp" line="207"/>
<source>Could not start http server.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="82"/>
<location filename="../ofdscene.cpp" line="84"/>
<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="../ofdscene.cpp" line="84"/>
<location filename="../ofdscene.cpp" line="86"/>
<source>Picture was not selected</source>
<translation>Picture was not selected</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="89"/>
<location filename="../ofdscene.cpp" line="91"/>
<source>Selected image: </source>
<translation>Selected image: </translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="152"/>
<location filename="../ofdscene.cpp" line="150"/>
<source>Captcha was not solved correctly!</source>
<translation>Captcha was not solved correctly!</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="154"/>
<location filename="../ofdscene.cpp" line="152"/>
<source>Captcha is incorrect</source>
<translation>Captcha is incorrect</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="159"/>
<location filename="../ofdscene.cpp" line="157"/>
<source>Internal server error. Please, try again later.</source>
<translation>Internal server error. Please, try again later.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="161"/>
<location filename="../ofdscene.cpp" line="159"/>
<source>Internal server error</source>
<translation>Internal server error</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="166"/>
<location filename="../ofdscene.cpp" line="164"/>
<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="../ofdscene.cpp" line="168"/>
<location filename="../ofdscene.cpp" line="166"/>
<source>Check was not found</source>
<translation>Check was not found</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="198"/>
<source>QR code for binaryeye to connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="199"/>
<source>I&apos;ve scanned</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>123 123</source>
<translation type="obsolete">123 123</translation>
</message>
</context>
<context>
<name>OutputDialog</name>

View File

@ -367,60 +367,74 @@
<translation>Парсить</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="188"/>
<location filename="../ofdscene.cpp" line="205"/>
<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 type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="190"/>
<location filename="../ofdscene.cpp" line="207"/>
<source>Could not start http server.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="82"/>
<location filename="../ofdscene.cpp" line="84"/>
<source>Please, select a picture where QR code that contains info about check is present</source>
<translation>Пожалуйста, выберете изображение, содержащее QR код с информацией о чеке</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="84"/>
<location filename="../ofdscene.cpp" line="86"/>
<source>Picture was not selected</source>
<translation>Изображение не было выбрано</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="89"/>
<location filename="../ofdscene.cpp" line="91"/>
<source>Selected image: </source>
<translation>Выбранное изображение: </translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="152"/>
<location filename="../ofdscene.cpp" line="150"/>
<source>Captcha was not solved correctly!</source>
<translation>Капча была решена неверно!</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="154"/>
<location filename="../ofdscene.cpp" line="152"/>
<source>Captcha is incorrect</source>
<translation>Капча введена неверно</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="159"/>
<location filename="../ofdscene.cpp" line="157"/>
<source>Internal server error. Please, try again later.</source>
<translation>Внутренняя ошибка сервера. Пожалуйста, попробуйте снова позже.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="161"/>
<location filename="../ofdscene.cpp" line="159"/>
<source>Internal server error</source>
<translation>Внутренняя ошибка сервера</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="166"/>
<location filename="../ofdscene.cpp" line="164"/>
<source>Check not found. Please, ensure correctness of entered data.</source>
<translation>Чек не найден. Пожалуйста, убедитесь в правильности введённых данных.</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="168"/>
<location filename="../ofdscene.cpp" line="166"/>
<source>Check was not found</source>
<translation>Чек не найден</translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="198"/>
<source>QR code for binaryeye to connect</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ofdscene.cpp" line="199"/>
<source>I&apos;ve scanned</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>123 123</source>
<translation type="obsolete">123 123</translation>
</message>
</context>
<context>
<name>OutputDialog</name>

View File

@ -5,6 +5,10 @@
#include <cstring>
#include <iostream>
#include <locale>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>
#include <qrencode.h>
#include <regex>
#include <string>
#include "../exceptions/ofdrequestexception.h"
@ -13,6 +17,7 @@
#include <fstream>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <opencv2/opencv.hpp>
std::string get_local_ip_address() {
struct ifaddrs * ifAddrStruct=NULL;
@ -214,3 +219,28 @@ Check parseOfdRuAnswer(std::string html) {
return c;
}
void generate_qr_code(std::string data) {
QRcode *qrCode = QRcode_encodeString(data.c_str(), 2, QR_ECLEVEL_L, QR_MODE_8, 1);
if (qrCode == NULL) {
std::cerr << "Error on generating qr code" << std::endl;
}
cv::Mat qrCodeImage = cv::Mat::zeros(qrCode->width, qrCode->width, CV_8UC3);
for (int y = 0; y < qrCode->width; y++) {
for (int x = 0; x < qrCode->width; x++) {
cv::rectangle(
qrCodeImage,
cv::Point(x, y),
cv::Point(x + 1, y + 1),
((qrCode->data[y * qrCode->width + x] & 1) ?
cv::Scalar(255., 255., 255.) : cv::Scalar(0., 0., 0.)
),
-1
);
}
}
cv::imwrite(get_path_relative_to_home(".local/share/checks_parser/binaryeye_connection.png"), qrCodeImage);
QRcode_free(qrCode);
}

View File

@ -20,4 +20,6 @@ Check parseOfdRuAnswer(std::string);
std::wstring trim_html_response(std::wstring& check);
void generate_qr_code(std::string data);
#endif // UTILS_H