Fix for windows
This commit is contained in:
parent
0ab71db506
commit
dfbe1cbf72
@ -222,6 +222,42 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
<< "date(local)=" << searchDate.toString("dd.MM.yyyy");
|
<< "date(local)=" << searchDate.toString("dd.MM.yyyy");
|
||||||
|
|
||||||
// ── Шаг 1: скроллим до нужной даты ──────────────────────────────
|
// ── Шаг 1: скроллим до нужной даты ──────────────────────────────
|
||||||
|
static const QMap<QString, int> monthMap = {
|
||||||
|
{"января", 1}, {"февраля", 2}, {"марта", 3}, {"апреля", 4},
|
||||||
|
{"мая", 5}, {"июня", 6}, {"июля", 7}, {"августа", 8},
|
||||||
|
{"сентября", 9}, {"октября", 10}, {"ноября", 11}, {"декабря", 12}
|
||||||
|
};
|
||||||
|
static const QRegularExpression dateRx(R"((\d{1,2})\s+(\S+),\s+\S+)");
|
||||||
|
|
||||||
|
auto parseDateHeader = [&](const QString &t) -> QDate {
|
||||||
|
const QDate today = QDateTime::currentDateTimeUtc().toTimeZone(deviceTz).date();
|
||||||
|
if (t.compare("Сегодня", Qt::CaseInsensitive) == 0) return today;
|
||||||
|
if (t.compare("Вчера", Qt::CaseInsensitive) == 0) return today.addDays(-1);
|
||||||
|
const auto match = dateRx.match(t);
|
||||||
|
if (!match.hasMatch()) return {};
|
||||||
|
const int day = match.captured(1).toInt();
|
||||||
|
const int month = monthMap.value(match.captured(2), 0);
|
||||||
|
if (month == 0) return {};
|
||||||
|
return QDate(searchDate.year(), month, day);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto hasDateOnScreen = [&]() -> bool {
|
||||||
|
for (const Node &node : xmlScreenParser.getNodes()) {
|
||||||
|
if (node.className != "android.widget.TextView") continue;
|
||||||
|
if (parseDateHeader(node.text.trimmed()) == searchDate) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto hasOlderDateOnScreen = [&]() -> bool {
|
||||||
|
for (const Node &node : xmlScreenParser.getNodes()) {
|
||||||
|
if (node.className != "android.widget.TextView") continue;
|
||||||
|
const QDate d = parseDateHeader(node.text.trimmed());
|
||||||
|
if (d.isValid() && d < searchDate) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
bool dateFound = false;
|
bool dateFound = false;
|
||||||
for (int scroll = 0; scroll < maxScrolls; ++scroll) {
|
for (int scroll = 0; scroll < maxScrolls; ++scroll) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) {
|
if (QThread::currentThread()->isInterruptionRequested()) {
|
||||||
@ -229,57 +265,15 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
|
if (hasDateOnScreen()) {
|
||||||
// Ищем заголовки дат на экране (формат: "4 января, вс")
|
|
||||||
static const QMap<QString, int> monthMap = {
|
|
||||||
{"января", 1}, {"февраля", 2}, {"марта", 3}, {"апреля", 4},
|
|
||||||
{"мая", 5}, {"июня", 6}, {"июля", 7}, {"августа", 8},
|
|
||||||
{"сентября", 9}, {"октября", 10}, {"ноября", 11}, {"декабря", 12}
|
|
||||||
};
|
|
||||||
|
|
||||||
const QDate today = QDateTime::currentDateTimeUtc().toTimeZone(deviceTz).date();
|
|
||||||
bool hasOlderDate = false;
|
|
||||||
for (const Node &node : xmlScreenParser.getNodes()) {
|
|
||||||
if (node.className != "android.widget.TextView") continue;
|
|
||||||
const QString t = node.text.trimmed();
|
|
||||||
QDate headerDate;
|
|
||||||
|
|
||||||
// Относительные заголовки "Сегодня" / "Вчера"
|
|
||||||
if (t.compare("Сегодня", Qt::CaseInsensitive) == 0) {
|
|
||||||
headerDate = today;
|
|
||||||
} else if (t.compare("Вчера", Qt::CaseInsensitive) == 0) {
|
|
||||||
headerDate = today.addDays(-1);
|
|
||||||
} else {
|
|
||||||
// Абсолютный формат "4 января, вс"
|
|
||||||
static const QRegularExpression dateRx(R"((\d{1,2})\s+(\S+),\s+\S+)");
|
|
||||||
const auto match = dateRx.match(t);
|
|
||||||
if (!match.hasMatch()) continue;
|
|
||||||
const int day = match.captured(1).toInt();
|
|
||||||
const int month = monthMap.value(match.captured(2), 0);
|
|
||||||
if (month == 0) continue;
|
|
||||||
headerDate = QDate(searchDate.year(), month, day);
|
|
||||||
}
|
|
||||||
if (!headerDate.isValid()) continue;
|
|
||||||
|
|
||||||
if (headerDate == searchDate) {
|
|
||||||
dateFound = true;
|
dateFound = true;
|
||||||
qDebug() << "[FetchTransactions] Found target date header:" << t;
|
qDebug() << "[FetchTransactions] Found target date on screen";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (headerDate < searchDate) {
|
if (hasOlderDateOnScreen()) {
|
||||||
hasOlderDate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dateFound) break;
|
|
||||||
|
|
||||||
if (hasOlderDate) {
|
|
||||||
// Проскочили мимо нужной даты — её нет в списке
|
|
||||||
qDebug() << "[FetchTransactions] Passed target date, not found in list";
|
qDebug() << "[FetchTransactions] Passed target date, not found in list";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Скроллим вниз
|
|
||||||
AdbUtils::makeSwipe(m_deviceId, device.screenWidth / 2,
|
AdbUtils::makeSwipe(m_deviceId, device.screenWidth / 2,
|
||||||
device.screenHeight - 300, device.screenWidth / 2, 300, 300);
|
device.screenHeight - 300, device.screenWidth / 2, 300, 300);
|
||||||
QThread::msleep(1500);
|
QThread::msleep(1500);
|
||||||
@ -293,8 +287,11 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Шаг 2: на экране с нужной датой ищем транзакцию по сумме ────
|
// ── Шаг 2: тапаем по кнопкам с нужной суммой, проверяем дату/время в деталях ─
|
||||||
for (int attempt = 0; attempt < 10; ++attempt) {
|
// Запоминаем уже проверенные (date+time из деталей) чтобы не застревать
|
||||||
|
QSet<QString> checkedDetails;
|
||||||
|
|
||||||
|
for (int attempt = 0; attempt < 15; ++attempt) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) {
|
if (QThread::currentThread()->isInterruptionRequested()) {
|
||||||
m_error = "Interrupted";
|
m_error = "Interrupted";
|
||||||
return;
|
return;
|
||||||
@ -302,6 +299,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
||||||
QList<Node> txButtons = xmlScreenParser.findTransactionButtons(20);
|
QList<Node> txButtons = xmlScreenParser.findTransactionButtons(20);
|
||||||
|
|
||||||
|
bool tapped = false;
|
||||||
for (int bi = 0; bi < txButtons.size(); ++bi) {
|
for (int bi = 0; bi < txButtons.size(); ++bi) {
|
||||||
if (QThread::currentThread()->isInterruptionRequested()) {
|
if (QThread::currentThread()->isInterruptionRequested()) {
|
||||||
m_error = "Interrupted";
|
m_error = "Interrupted";
|
||||||
@ -311,28 +309,9 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
const TransactionInfo parsed = xmlScreenParser.parseTransactionButtonText(txButtons[bi].text);
|
const TransactionInfo parsed = xmlScreenParser.parseTransactionButtonText(txButtons[bi].text);
|
||||||
if (qAbs(parsed.amount - m_searchAmount) > 0.01) continue;
|
if (qAbs(parsed.amount - m_searchAmount) > 0.01) continue;
|
||||||
|
|
||||||
// Если кнопка за экраном — скроллим до неё, рассчитывая дистанцию
|
// Пропускаем кнопки за экраном
|
||||||
if (txButtons[bi].y() <= 0 || txButtons[bi].y() >= navBarTop) {
|
|
||||||
bool scrolledIntoView = false;
|
|
||||||
for (int s = 0; s < 5; ++s) {
|
|
||||||
const int btnY = txButtons[bi].y();
|
const int btnY = txButtons[bi].y();
|
||||||
const int x = device.screenWidth / 2;
|
if (btnY <= 0 || btnY >= navBarTop) continue;
|
||||||
const int visibleCenter = navBarTop / 2;
|
|
||||||
// Расстояние от кнопки до центра видимой области + небольшой запас
|
|
||||||
const int delta = btnY - visibleCenter;
|
|
||||||
const int fromY = qBound(100, visibleCenter + delta / 2, device.screenHeight - 100);
|
|
||||||
const int toY = qBound(100, visibleCenter - delta / 2, device.screenHeight - 100);
|
|
||||||
AdbUtils::makeSwipe(m_deviceId, x, fromY, x, toY, 300);
|
|
||||||
QThread::msleep(1000);
|
|
||||||
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
|
|
||||||
txButtons = xmlScreenParser.findTransactionButtons(20);
|
|
||||||
if (bi < txButtons.size() && txButtons[bi].y() > 0 && txButtons[bi].y() < navBarTop) {
|
|
||||||
scrolledIntoView = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!scrolledIntoView) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Node &visibleBtn = txButtons[bi];
|
const Node &visibleBtn = txButtons[bi];
|
||||||
qDebug() << "[FetchTransactions] Amount match:" << parsed.amount
|
qDebug() << "[FetchTransactions] Amount match:" << parsed.amount
|
||||||
@ -341,6 +320,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
// Тапаем и ждём деталей
|
// Тапаем и ждём деталей
|
||||||
AdbUtils::makeTap(m_deviceId, visibleBtn.x(), visibleBtn.y());
|
AdbUtils::makeTap(m_deviceId, visibleBtn.x(), visibleBtn.y());
|
||||||
QThread::msleep(2000);
|
QThread::msleep(2000);
|
||||||
|
tapped = true;
|
||||||
|
|
||||||
TransactionInfo detail;
|
TransactionInfo detail;
|
||||||
for (int da = 0; da < 10; ++da) {
|
for (int da = 0; da < 10; ++da) {
|
||||||
@ -374,15 +354,25 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
if (!txTime.isValid()) txTime = QDateTime::fromString(dtStr, "dd.MM.yyyy,HH:mm");
|
if (!txTime.isValid()) txTime = QDateTime::fromString(dtStr, "dd.MM.yyyy,HH:mm");
|
||||||
if (txTime.isValid()) txTime.setTimeZone(deviceTz);
|
if (txTime.isValid()) txTime.setTimeZone(deviceTz);
|
||||||
|
|
||||||
// Проверяем что дата и время совпадают (±1 час от m_searchTime)
|
// Пропускаем если уже проверяли эту транзакцию
|
||||||
if (txTime.isValid()) {
|
if (checkedDetails.contains(dtStr)) {
|
||||||
if (txTime.date() != searchDate) {
|
qDebug() << "[FetchTransactions] Already checked:" << dtStr << "- skipping";
|
||||||
|
AdbUtils::goBack(m_deviceId);
|
||||||
|
QThread::msleep(500);
|
||||||
|
continue; // пробуем следующую кнопку
|
||||||
|
}
|
||||||
|
checkedDetails.insert(dtStr);
|
||||||
|
|
||||||
|
// Проверяем дату
|
||||||
|
if (txTime.isValid() && txTime.date() != searchDate) {
|
||||||
qDebug() << "[FetchTransactions] Wrong date:" << dtStr << "expected" << searchDate;
|
qDebug() << "[FetchTransactions] Wrong date:" << dtStr << "expected" << searchDate;
|
||||||
AdbUtils::goBack(m_deviceId);
|
AdbUtils::goBack(m_deviceId);
|
||||||
QThread::msleep(1000);
|
QThread::msleep(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (m_searchTime.isValid()) {
|
|
||||||
|
// Проверяем время (±1 час)
|
||||||
|
if (txTime.isValid() && m_searchTime.isValid()) {
|
||||||
const qint64 diffSecs = qAbs(txTime.toUTC().secsTo(m_searchTime.toUTC()));
|
const qint64 diffSecs = qAbs(txTime.toUTC().secsTo(m_searchTime.toUTC()));
|
||||||
if (diffSecs > 3600) {
|
if (diffSecs > 3600) {
|
||||||
qDebug() << "[FetchTransactions] Time mismatch:" << dtStr
|
qDebug() << "[FetchTransactions] Time mismatch:" << dtStr
|
||||||
@ -393,7 +383,6 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Нашли!
|
// Нашли!
|
||||||
qDebug() << "[FetchTransactions] FOUND transaction:"
|
qDebug() << "[FetchTransactions] FOUND transaction:"
|
||||||
@ -504,11 +493,15 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
|
|||||||
return; // успех
|
return; // успех
|
||||||
}
|
}
|
||||||
|
|
||||||
// Скроллим чуть вниз чтобы увидеть больше транзакций за этот день
|
// Скроллим вниз если ни одна кнопка не была нажата или все проверенные не подошли
|
||||||
|
if (!tapped) {
|
||||||
AdbUtils::makeSwipe(m_deviceId, device.screenWidth / 2,
|
AdbUtils::makeSwipe(m_deviceId, device.screenWidth / 2,
|
||||||
device.screenHeight - 300, device.screenWidth / 2, 300, 300);
|
device.screenHeight * 3 / 4,
|
||||||
|
device.screenWidth / 2,
|
||||||
|
device.screenHeight / 4, 300);
|
||||||
QThread::msleep(1000);
|
QThread::msleep(1000);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_error = "Transaction not found: amount=" + QString::number(m_searchAmount, 'f', 2)
|
m_error = "Transaction not found: amount=" + QString::number(m_searchAmount, 'f', 2)
|
||||||
+ " date=" + searchDate.toString("dd.MM.yyyy");
|
+ " date=" + searchDate.toString("dd.MM.yyyy");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user