This update introduces support for Ziraat Bank, including scripts for retrieving transaction history, parsing account information, and performing IBAN payments. Enhancements include improved screen parsing logic, additional transaction types, and better handling of amounts and IBAN-specific operations.
223 lines
7.8 KiB
C++
223 lines
7.8 KiB
C++
#include "CommonZiraatScript.h"
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QRandomGenerator>
|
|
#include <QThread>
|
|
|
|
#include "adb/AdbUtils.h"
|
|
#include "net/NetworkService.h"
|
|
|
|
CommonZiraatScript::CommonZiraatScript(QObject *parent)
|
|
: QObject(parent) {
|
|
}
|
|
|
|
CommonZiraatScript::~CommonZiraatScript() = default;
|
|
|
|
void CommonZiraatScript::start() {
|
|
doStart();
|
|
emit finished();
|
|
}
|
|
|
|
Node CommonZiraatScript::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 CommonZiraatScript::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(4500);
|
|
int counter = 0;
|
|
bool findAndInputPassword = 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("HAYIR", false);
|
|
if (!closeBannerNode.isEmpty()) {
|
|
AdbUtils::makeTap(deviceId, closeBannerNode.x(), closeBannerNode.y());
|
|
QThread::msleep(1000);
|
|
continue;
|
|
}
|
|
|
|
if (xmlScreenParser.isHomeScreen()) {
|
|
return true;
|
|
}
|
|
|
|
// Проверяем, что это экран ввода пин-кода
|
|
if (!findAndInputPassword) {
|
|
Node loginNode = xmlScreenParser.findButtonNode("Login", false);
|
|
if (!loginNode.isEmpty()) {
|
|
AdbUtils::makeTap(deviceId, loginNode.x(), loginNode.y());
|
|
QThread::msleep(500);
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, ++m_counter));
|
|
|
|
Node passwordEditText = xmlScreenParser.findEditText("Password");
|
|
if (!passwordEditText.isEmpty()) {
|
|
AdbUtils::makeTap(deviceId, passwordEditText.x(), passwordEditText.y());
|
|
QThread::msleep(500);
|
|
AdbUtils::inputText(deviceId, pinCode);
|
|
|
|
findAndInputPassword = true;
|
|
QThread::msleep(3000);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
QThread::msleep(1000);
|
|
}
|
|
}
|
|
|
|
bool CommonZiraatScript::goToAllProducts(
|
|
const QString &deviceId,
|
|
const int width,
|
|
const int height
|
|
) {
|
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(deviceId, m_counter));
|
|
Node closeBannerNode = xmlScreenParser.findButtonNode("HAYIR", 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 CommonZiraatScript::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["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 CommonZiraatScript::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;
|
|
obj["updatedDescription"] = transaction.updatedDescription;
|
|
obj["bankName"] = transaction.bankName;
|
|
obj["bankTime"] = transaction.bankTime;
|
|
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 CommonZiraatScript::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 CommonZiraatScript::stop() {
|
|
m_running = false;
|
|
}
|