1
0
forked from BRT/arc
arc/android/black/GetProfileInfoScript.cpp

189 lines
7.0 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 "GetProfileInfoScript.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QThread>
#include "adb/AdbUtils.h"
#include "dao/MaterialDAO.h"
#include "dao/BankProfileDAO.h"
#include "dao/DeviceDAO.h"
#include "dump/TaskDumpRecorder.h"
#include "net/NetworkService.h"
namespace Black {
GetProfileInfoScript::GetProfileInfoScript(
QString deviceId,
QString appCode,
QObject *parent
) : CommonScript(parent),
m_deviceId(std::move(deviceId)),
m_appCode(std::move(appCode)) {
}
GetProfileInfoScript::~GetProfileInfoScript() = default;
void GetProfileInfoScript::doStart() {
DeviceInfo device = DeviceDAO::getDeviceById(m_deviceId); if (device.id.isEmpty()) device = DeviceDAO::findByAdbSerial(m_deviceId); if (!device.adbSerial.isEmpty()) m_deviceId = device.adbSerial;
const BankProfileInfo app = BankProfileDAO::getApplication(device.id, m_appCode);
if (device.id.isEmpty() || app.id == -1) {
m_error = "Device or app not found: " + m_deviceId + " " + m_appCode;
qCritical() << m_error;
emit finishedWithResult(m_error);
return;
}
const TaskDumpMeta dumpMeta{};
TaskDumpRecorder::Scope dumpScope("black", "FETCH_PROFILE_INFO", m_deviceId, dumpMeta, &m_error);
// Читаем текущий экран
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
// Если не на домашнем экране — перезапускаем
if (!xmlScreenParser.isHomeScreen()) {
qDebug() << "[Black::GetProfileInfo] Not on home screen, restarting app...";
if (!runAppAndGoToHomeScreen(m_deviceId, app.package, app.pinCode,
device.screenWidth, device.screenHeight)) {
m_error = "Cannot reach home screen: " + device.name + " (" + m_deviceId + ") " + m_appCode;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
}
// 1. Тапаем по кнопке "¡Hola!" (аватар с именем) на домашнем экране
Node holaNode = xmlScreenParser.findHolaButton();
if (holaNode.isEmpty()) {
m_error = "Cannot find Hola button on home screen: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
// Парсим имя и баланс с домашнего экрана
const QString fullName = xmlScreenParser.parseUserNameFromHomeScreen();
const double balance = xmlScreenParser.parseBalanceFromHomeScreen();
qDebug() << "[Black::GetProfileInfo] fullName from home:" << fullName << "balance:" << balance;
// Сохраняем баланс
BankProfileDAO::updateAmount(app.id, balance);
AdbUtils::makeTap(m_deviceId, holaNode.x(), holaNode.y());
QThread::msleep(2000);
// 2. Ждём боковое меню
bool sideMenuFound = false;
for (int attempt = 0; attempt < 5; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (xmlScreenParser.isSideMenu()) {
sideMenuFound = true;
break;
}
QThread::msleep(1000);
}
if (!sideMenuFound) {
m_error = "Side menu not detected: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
// 3. Тапаем "Tu Información"
Node tuInfoNode = xmlScreenParser.findNodeByContentDesc(QString::fromUtf8("Tu Información"));
if (tuInfoNode.isEmpty()) {
m_error = "Cannot find Tu Información button: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
AdbUtils::makeTap(m_deviceId, tuInfoNode.x(), tuInfoNode.y());
QThread::msleep(2500);
// 4. Ждём страницу профиля "Tu información"
bool profileFound = false;
for (int attempt = 0; attempt < 5; ++attempt) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (xmlScreenParser.isProfilePage()) {
profileFound = true;
break;
}
QThread::msleep(1000);
}
if (!profileFound) {
m_error = "Profile page not detected: " + m_deviceId;
qWarning() << m_error;
AdbUtils::tryToKillApplication(m_deviceId, app.package);
emit finishedWithResult(m_error);
return;
}
// 5. Парсим данные профиля (первый экран: nombre, apellido, email)
const QString nombre = xmlScreenParser.parseProfileNombre();
const QString apellido = xmlScreenParser.parseProfileApellido();
const QString email = xmlScreenParser.parseProfileEmail();
// 6. Скроллим вниз чтобы увидеть телефон
const int x = device.screenWidth / 2;
const int fromY = device.screenHeight * 3 / 4;
const int toY = device.screenHeight / 4;
AdbUtils::makeSwipe(m_deviceId, x, fromY, x, toY);
QThread::msleep(1500);
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
const QString phone = xmlScreenParser.parseProfilePhone();
// Собираем полное имя: "имя фамилия"
QString parsedFullName;
if (!nombre.isEmpty() && !apellido.isEmpty()) {
parsedFullName = nombre + " " + apellido;
} else if (!nombre.isEmpty()) {
parsedFullName = nombre;
} else {
parsedFullName = fullName; // fallback с домашнего экрана
}
qDebug() << "[Black::GetProfileInfo] nombre:" << nombre
<< "apellido:" << apellido
<< "email:" << email
<< "phone:" << phone
<< "fullName:" << parsedFullName;
// 7. Сохраняем в БД
if (!BankProfileDAO::updateProfileInfo(app.id, parsedFullName, phone, email)) {
qWarning() << "[Black::GetProfileInfo] Failed to save profile info to DB";
}
// 7. Создаём bank profile если нет
if (const QString err = createBankProfileIfNeeded(m_deviceId, m_appCode); !err.isEmpty()) {
m_error = err;
emit finishedWithResult(m_error);
return;
}
// 8. Отправляем данные аккаунтов на сервер если нет material_id
const QList<MaterialInfo> allAccounts = MaterialDAO::getAccounts(device.id, m_appCode);
QList<QPair<MaterialInfo, Node>> accountsToPost;
for (const auto &acc : allAccounts) {
if (acc.materialId.isEmpty()) {
accountsToPost.append({acc, Node()});
}
}
if (!accountsToPost.isEmpty()) {
postAccountsData(accountsToPost);
}
emit finishedWithResult(m_error);
}
} // namespace Black