able to receive file

This commit is contained in:
2026-04-27 15:06:59 +08:00
parent 5442e32abc
commit 71ea3dbd01
11 changed files with 605 additions and 32 deletions

View File

@@ -1,5 +1,11 @@
#include "AppController.h"
#include <QJsonArray>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#include <QStandardPaths>
#include <QUrl>
#include <QDebug>
AppController::AppController(QObject* parent)
: QObject(parent)
@@ -33,8 +39,20 @@ void AppController::initialize()
this, &AppController::onDeviceDiscovered);
connect(m_discovery, &LocalSend::DiscoveryManager::deviceLost,
this, &AppController::onDeviceLost);
connect(m_server, &LocalSend::HttpServer::registerRequest,
this, &AppController::onRegisterRequest);
connect(m_server, &LocalSend::HttpServer::prepareUploadRequest,
this, &AppController::onPrepareUploadRequest);
connect(m_server, &LocalSend::HttpServer::uploadRequest,
this, &AppController::onUploadRequest);
connect(m_sessions, &LocalSend::SessionManager::receiveSessionAccepted,
this, &AppController::onSessionAccepted);
connect(m_sessions, &LocalSend::SessionManager::receiveSessionDeclined,
this, &AppController::onSessionDeclined);
connect(m_sessions, &LocalSend::SessionManager::receiveProgress,
this, &AppController::onReceiveProgress);
connect(m_sessions, &LocalSend::SessionManager::receiveSessionCompleted,
this, &AppController::onReceiveCompleted);
startDiscovery();
}
@@ -76,6 +94,32 @@ void AppController::setPort(quint16 port)
}
}
QString AppController::downloadPath() const
{
return m_settings->downloadDir();
}
void AppController::setDownloadPath(const QString& path)
{
if (m_settings->downloadDir() != path) {
m_settings->setDownloadDir(path);
emit downloadPathChanged();
}
}
bool AppController::quickSave() const
{
return m_settings->quickSave();
}
void AppController::setQuickSave(bool enabled)
{
if (m_settings->quickSave() != enabled) {
m_settings->setQuickSave(enabled);
emit quickSaveChanged();
}
}
QVariantList AppController::devices() const
{
QVariantList result;
@@ -112,6 +156,64 @@ void AppController::refreshDevices()
m_discovery->startScan();
}
void AppController::acceptReceive(const QString& sessionId)
{
qDebug() << "[AppController] acceptReceive called with sessionId:" << sessionId;
LocalSend::ReceiveSession session = m_sessions->receiveSession(sessionId);
if (session.sessionId.isEmpty()) {
qWarning() << "[AppController] Session not found for sessionId:" << sessionId;
return;
}
QString baseDir = downloadPath();
QDir dir(baseDir);
if (!dir.exists()) {
dir.mkpath(QStringLiteral("."));
}
QMap<QString, QString> destinationPaths;
for (auto it = session.files.constBegin(); it != session.files.constEnd(); ++it) {
QString filePath = generateUniqueFilePath(baseDir, it->file.fileName);
destinationPaths.insert(it.key(), filePath);
qDebug() << "[AppController] File" << it.key() << "->" << filePath;
}
m_sessions->acceptReceiveSession(sessionId, destinationPaths);
}
void AppController::declineReceive(const QString& sessionId)
{
qDebug() << "[AppController] declineReceive called with sessionId:" << sessionId;
m_sessions->declineReceiveSession(sessionId);
}
QString AppController::generateUniqueFilePath(const QString& baseDir, const QString& fileName) const
{
QString filePath = baseDir + QDir::separator() + fileName;
QFileInfo info(filePath);
if (!info.exists()) {
return filePath;
}
QString baseName = info.completeBaseName();
QString suffix = info.suffix();
int counter = 1;
while (info.exists()) {
QString newName = QString(QStringLiteral("%1 (%2)")).arg(baseName).arg(counter);
if (!suffix.isEmpty()) {
newName += QStringLiteral(".") + suffix;
}
filePath = baseDir + QDir::separator() + newName;
info.setFile(filePath);
counter++;
}
return filePath;
}
void AppController::onDeviceDiscovered(const LocalSend::Device& device)
{
m_devices.insert(device.fingerprint, device);
@@ -124,9 +226,33 @@ void AppController::onDeviceLost(const QString& fingerprint)
emit devicesChanged();
}
void AppController::onPrepareUploadRequest(const LocalSend::PrepareUploadRequestDto& dto,
void AppController::onRegisterRequest(const LocalSend::RegisterDto& dto, const QHostAddress& sender)
{
qDebug() << "[AppController] onRegisterRequest from:" << sender.toString()
<< "alias:" << dto.alias << "fingerprint:" << dto.fingerprint;
LocalSend::Device device;
device.ip = sender.toString();
device.port = dto.port;
device.protocol = dto.protocol;
device.alias = dto.alias;
device.fingerprint = dto.fingerprint;
device.deviceModel = dto.deviceModel;
device.deviceType = dto.deviceType;
device.version = dto.version;
device.download = dto.download;
device.lastSeen = QDateTime::currentDateTime();
m_devices.insert(device.fingerprint, device);
emit devicesChanged();
}
void AppController::onPrepareUploadRequest(const QString& httpSessionId,
const LocalSend::PrepareUploadRequestDto& dto,
const QHostAddress& sender)
{
qDebug() << "[AppController] onPrepareUploadRequest received, httpSessionId:" << httpSessionId;
LocalSend::Device device;
device.ip = sender.toString();
device.alias = dto.info.alias;
@@ -135,7 +261,8 @@ void AppController::onPrepareUploadRequest(const LocalSend::PrepareUploadRequest
device.deviceType = dto.info.deviceType;
device.version = dto.info.version;
QString sessionId = m_sessions->createReceiveSession(device, dto.files);
QString sessionId = m_sessions->createReceiveSession(device, dto.files, httpSessionId);
qDebug() << "[AppController] Created receive session, sessionId:" << sessionId;
QVariantList filesList;
for (auto it = dto.files.constBegin(); it != dto.files.constEnd(); ++it) {
@@ -147,5 +274,74 @@ void AppController::onPrepareUploadRequest(const LocalSend::PrepareUploadRequest
filesList.append(file);
}
emit receiveRequest(sessionId, dto.info.alias, filesList);
emit receiveRequest(sessionId, dto.info.alias, sender.toString(), filesList);
}
void AppController::onUploadRequest(const QString& sessionId, const QString& fileId,
const QString& token, const QByteArray& data)
{
LocalSend::ReceiveSession session = m_sessions->receiveSession(sessionId);
if (session.sessionId.isEmpty()) {
return;
}
if (!session.files.contains(fileId)) {
return;
}
const LocalSend::FileTransfer& transfer = session.files[fileId];
if (transfer.token != token) {
emit receiveError(sessionId, QStringLiteral("Invalid token"));
return;
}
QString filePath = transfer.destinationPath;
if (filePath.isEmpty()) {
emit receiveError(sessionId, QStringLiteral("No destination path"));
return;
}
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
emit receiveError(sessionId, QStringLiteral("Cannot open file: ") + file.errorString());
return;
}
qint64 written = file.write(data);
file.close();
if (written != data.size()) {
m_sessions->failReceiveFile(sessionId, fileId);
emit receiveError(sessionId, QStringLiteral("Write error"));
return;
}
m_sessions->updateReceiveProgress(sessionId, fileId, written);
if (written >= transfer.file.size) {
m_sessions->completeReceiveFile(sessionId, fileId);
}
}
void AppController::onSessionAccepted(const QString& sessionId, const QMap<QString, QString>& tokens)
{
qDebug() << "[AppController] onSessionAccepted, sessionId:" << sessionId;
qDebug() << "[AppController] Tokens:" << tokens;
m_server->respondToPrepareUpload(sessionId, true, tokens);
}
void AppController::onSessionDeclined(const QString& sessionId)
{
qDebug() << "[AppController] onSessionDeclined, sessionId:" << sessionId;
m_server->respondToPrepareUpload(sessionId, false);
}
void AppController::onReceiveProgress(const QString& sessionId, const QString& fileId, double progress)
{
emit receiveProgress(sessionId, fileId, progress);
}
void AppController::onReceiveCompleted(const QString& sessionId)
{
emit receiveCompleted(sessionId);
}