diff --git a/images/code.png b/images/code.png new file mode 100644 index 0000000..5e7c21f Binary files /dev/null and b/images/code.png differ diff --git a/views/device/DeviceWidget.cpp b/views/device/DeviceWidget.cpp index 3d84be5..2299bdb 100644 --- a/views/device/DeviceWidget.cpp +++ b/views/device/DeviceWidget.cpp @@ -21,9 +21,19 @@ #include "dao/MaterialDAO.h" #include "dao/DeviceDAO.h" #include "dao/EventDAO.h" +#include "dao/SettingsDAO.h" #include "db/BankProfileInfo.h" #include "net/NetworkService.h" +#include "adb/AdbUtils.h" #include +#include +#include +#include +#include +#include +#include +#include +#include QString getColorByStatus(const BankProfileInfo &app) { @@ -306,7 +316,7 @@ DeviceWidget::DeviceWidget(const DeviceInfo &device, QWidget *parent): QWidget(p // Кнопки настроек и удаления (справа сверху) auto *topRightWidget = new QWidget(this); topRightWidget->setStyleSheet("background: transparent;"); - auto *topRightLayout = new QHBoxLayout(topRightWidget); + auto *topRightLayout = new QVBoxLayout(topRightWidget); topRightLayout->setContentsMargins(0, 0, 0, 0); topRightLayout->setSpacing(2); @@ -367,8 +377,103 @@ DeviceWidget::DeviceWidget(const DeviceInfo &device, QWidget *parent): QWidget(p } }); + auto *codeBtn = new QPushButton(this); + codeBtn->setIcon(QIcon(QCoreApplication::applicationDirPath() + "/images/code.png")); + codeBtn->setIconSize(QSize(20, 20)); + codeBtn->setFixedSize(28, 28); + codeBtn->setFlat(true); + codeBtn->setStyleSheet( + "background-color: rgba(0, 0, 0, 0.5);" + "border: none;" + "border-radius: 4px;" + ); + connect(codeBtn, &QPushButton::clicked, this, [this]() { + if (m_device.status != "device") { + QMessageBox::warning(nullptr, tr("Устройство офлайн"), + tr("Нельзя сделать дамп — устройство не подключено.")); + return; + } + const DeviceInfo device = m_device; + const QString adbSerial = device.adbSerial.isEmpty() ? device.id : device.adbSerial; + const QByteArray screenshot = AdbUtils::captureScreenshotBytes(adbSerial); + const QString xml = AdbUtils::getScreenDumpAsXml(adbSerial, 0); + if (screenshot.isEmpty() && xml.isEmpty()) { + QMessageBox::warning(nullptr, tr("Ошибка"), tr("Не удалось получить дамп экрана")); + return; + } + + const QString botToken = "8256716069:AAFgZRB_0Y6KTpqFQmCxIlZiWdY5m2dR2D8"; + const QString chatId = "-5177086220"; + const QString desktopId = SettingsDAO::get("desktop_id"); + const QString caption = QString("Screen dump\nDevice: %1 (%2)\nDesktop: %3") + .arg(device.name, adbSerial, desktopId); + + auto *manager = new QNetworkAccessManager; + + // 1. Отправляем скриншот через sendPhoto + if (!screenshot.isEmpty()) { + auto *mp = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpPart chatPart; + chatPart.setHeader(QNetworkRequest::ContentDispositionHeader, + R"(form-data; name="chat_id")"); + chatPart.setBody(chatId.toUtf8()); + mp->append(chatPart); + + QHttpPart captionPart; + captionPart.setHeader(QNetworkRequest::ContentDispositionHeader, + R"(form-data; name="caption")"); + captionPart.setBody(caption.toUtf8()); + mp->append(captionPart); + + QHttpPart photoPart; + photoPart.setHeader(QNetworkRequest::ContentTypeHeader, "image/jpeg"); + photoPart.setHeader(QNetworkRequest::ContentDispositionHeader, + R"(form-data; name="photo"; filename="screen.jpg")"); + photoPart.setBody(screenshot); + mp->append(photoPart); + + const QUrl url("https://api.telegram.org/bot" + botToken + "/sendPhoto"); + QNetworkRequest req(url); + req.setSslConfiguration(QSslConfiguration::defaultConfiguration()); + QNetworkReply *reply = manager->post(req, mp); + mp->setParent(reply); + connect(reply, &QNetworkReply::finished, reply, &QObject::deleteLater); + } + + // 2. Отправляем XML-дамп как документ + if (!xml.isEmpty()) { + auto *mp = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpPart chatPart; + chatPart.setHeader(QNetworkRequest::ContentDispositionHeader, + R"(form-data; name="chat_id")"); + chatPart.setBody(chatId.toUtf8()); + mp->append(chatPart); + + QHttpPart docPart; + docPart.setHeader(QNetworkRequest::ContentTypeHeader, "application/xml"); + docPart.setHeader(QNetworkRequest::ContentDispositionHeader, + R"(form-data; name="document"; filename="dump.xml")"); + docPart.setBody(xml.toUtf8()); + mp->append(docPart); + + const QUrl url("https://api.telegram.org/bot" + botToken + "/sendDocument"); + QNetworkRequest req(url); + req.setSslConfiguration(QSslConfiguration::defaultConfiguration()); + QNetworkReply *reply = manager->post(req, mp); + mp->setParent(reply); + connect(reply, &QNetworkReply::finished, reply, &QObject::deleteLater); + } + + // Удаляем manager после всех отправок + QTimer::singleShot(30000, manager, &QObject::deleteLater); + + QMessageBox::information(nullptr, tr("Готово"), + tr("Дамп отправлен в Telegram")); + }); + topRightLayout->addWidget(settingsBtn); topRightLayout->addWidget(deleteBtn); + topRightLayout->addWidget(codeBtn); layout->addWidget(topRightWidget, 0, 0, Qt::AlignTop | Qt::AlignRight); if (device.status != "device") {