1
0
forked from BRT/arc
arc/android/toss/CommonTossScript.cpp
2025-07-31 11:32:52 +05:00

218 lines
7.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "CommonTossScript.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QRandomGenerator>
#include <QThread>
#include "adb/AdbUtils.h"
#include "net/NetworkService.h"
#include "time/DateUtils.h"
CommonTossScript::CommonTossScript(QObject *parent)
: QObject(parent) {
}
CommonTossScript::~CommonTossScript() = default;
void CommonTossScript::start() {
doStart();
emit finished();
}
Node CommonTossScript::swipeToButton(
const QString &deviceId,
const QString &text, int &counter, const int width, const int height
) {
for (int i = 0; i < 10; ++i) {
if (Node button = xmlScreenParser.findButtonNode(text, true); button.x() > 0 && button.y() > 0) {
return button;
}
const int x = width / 2;
const int offset = height / 4;
AdbUtils::makeSwipe(deviceId, x, height - offset, x, offset);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++counter));
}
return {};
}
bool CommonTossScript::runAppAndGoToHomeScreen(
const QString &deviceId,
const QString &packageName,
const QString &pinCode,
const int width,
const int height
) {
// Запустить устройство
if (const QString pid = AdbUtils::tryToGetRunningAppPid(deviceId, packageName); !pid.isEmpty()) {
qDebug() << "Process already running, pid: " << pid;
AdbUtils::getScreenDumpAsXml(deviceId, 1000);
AdbUtils::tryToKillApplication(deviceId, packageName);
}
if (!AdbUtils::tryToStartApplication(deviceId, packageName)) {
AdbUtils::takeScreenshot(deviceId, "run_app_error");
qWarning() << "Process has not started";
return false;
}
// Даем минимальное время на запуск
QThread::msleep(2500);
int counter = 0;
bool findAndInputPincode = false;
while (true) {
counter++;
// Если более 10 раз мы пытаемся перейти на домашнюю
if (counter > 10) {
AdbUtils::takeScreenshot(deviceId, "too_many_attempts");
return false;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
// Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
// if (!closeBannerNode.isEmpty()) {
// AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
// QThread::msleep(1000);
// continue;
// }
if (xmlScreenParser.isHomeScreen()) {
return true;
}
// Проверяем, что это экран ввода пин-кода
if (!findAndInputPincode) {
if (const QList<Node> pincode = xmlScreenParser.findPinCodeNodes(pinCode); pincode.size() == 6) {
for (const Node &node: pincode) {
AdbUtils::makeTap(deviceId, node.x(), node.y());
QThread::msleep(QRandomGenerator::global()->bounded(200, 901));
}
// После ввода пин-код нужно сделать задержку, пока подгрузка идет, чтобы снова не спарсить
findAndInputPincode = true;
QThread::msleep(3000);
continue;
}
}
QThread::msleep(1000);
}
}
bool CommonTossScript::goToAllProducts(
const QString &deviceId,
const int width,
const int height
) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
Node closeBannerNode = xmlScreenParser.findButtonNode("Maraqlı deyil", false);
if (!closeBannerNode.isEmpty()) {
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
QThread::msleep(500);
}
if (xmlScreenParser.isHomeScreen()) {
Node allMyAccountBtn = xmlScreenParser.findButtonNode("All My Accounts", false);
if (!allMyAccountBtn.isEmpty()) {
AdbUtils::makeTap(deviceId, allMyAccountBtn.x(), allMyAccountBtn.y());
QThread::msleep(500);
return true;
}
}
return false;
}
void CommonTossScript::postAccountsData(const QList<AccountInfo> &accounts) {
if (accounts.isEmpty()) {
return;
}
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonArray list;
for (const AccountInfo &account: accounts) {
QJsonObject obj;
obj["appName"] = account.appCode;
obj["lastNumbers"] = account.lastNumbers;
obj["amount"] = account.amount;
obj["currency"] = account.currency;
obj["description"] = account.description;
obj["status"] = accountStatusToString(account.status);
list.append(obj);
}
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(accounts.first().deviceId);
worker->setPayload(QJsonDocument(list).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::postAccountsData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::postNewTransactionData(const AccountInfo &account, const TransactionInfo &transaction) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transaction.id;
obj["amount"] = transaction.amount;
obj["name"] = transaction.name;
obj["fee"] = transaction.fee;
obj["status"] = transactionStatusToString(transaction.status);
obj["type"] = transactionTypeToString(transaction.type);
obj["phone"] = transaction.phone;
obj["description"] = transaction.description + " | " + transaction.bankTime;
obj["updatedDescription"] = transaction.updatedDescription;
obj["bankName"] = transaction.bankName;
obj["bankTime"] = DateUtils::toUtcString(transaction.completeTime);
obj["bankTransactionId"] = transaction.bankTrExternalId;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->addExtra("transactionId", transaction.id);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::insertTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::updateTransactionData(
const AccountInfo &account,
const int transactionId,
const TransactionStatus status,
const QString &oldDesc,
const QString &newDesc
) {
auto *thread = new QThread;
auto *worker = new NetworkService;
QJsonObject obj;
obj["id"] = transactionId;
obj["status"] = transactionStatusToString(status);
obj["description"] = newDesc;
obj["updatedDescription"] = oldDesc;
// FIXME доставить десктоп ид из настроеек
worker->setDeviceId(account.deviceId);
worker->addExtra("lastNumbers", account.lastNumbers);
worker->setPayload(QJsonDocument(obj).toJson());
worker->moveToThread(thread);
connect(thread, &QThread::started, worker, &NetworkService::updateTransactionData);
connect(worker, &NetworkService::finished, thread, &QThread::quit);
connect(worker, &NetworkService::finished, worker, &QObject::deleteLater);
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start();
}
void CommonTossScript::stop() {
m_running = false;
}