mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-12-14 04:42:03 +08:00
git-subtree-dir: spark-update-tool git-subtree-mainline:286f34f3f8git-subtree-split:e5217b3829
118 lines
3.9 KiB
C++
118 lines
3.9 KiB
C++
#include "downloadmanager.h"
|
|
#include <QFileInfo>
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QRegularExpression>
|
|
#include <QDebug>
|
|
|
|
DownloadManager::DownloadManager(QObject *parent) : QObject(parent)
|
|
{
|
|
cleanupTempFiles();
|
|
}
|
|
|
|
void DownloadManager::startDownload(const QString &packageName, const QString &url, const QString &outputPath)
|
|
{
|
|
if (m_processes.contains(packageName)) {
|
|
qWarning() << packageName << " is already downloading.";
|
|
return;
|
|
}
|
|
|
|
QString metalinkUrl = url + ".metalink";
|
|
QFileInfo fileInfo(outputPath);
|
|
|
|
QStringList arguments = {
|
|
"--enable-rpc=false",
|
|
"--console-log-level=warn",
|
|
"--summary-interval=1",
|
|
"--allow-overwrite=true",
|
|
"--dir=" + fileInfo.absolutePath(),
|
|
"--out=" + fileInfo.fileName(),
|
|
metalinkUrl
|
|
};
|
|
|
|
QProcess *process = new QProcess(this);
|
|
m_processes.insert(packageName, process);
|
|
|
|
// 新增:准备日志文件
|
|
QString logPath = QString("/tmp/%1_download.log").arg(packageName);
|
|
QFile *logFile = new QFile(logPath, process);
|
|
if (logFile->open(QIODevice::Append | QIODevice::Text)) {
|
|
// 设置权限为777
|
|
QFile::setPermissions(logPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
|
|
QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup |
|
|
QFile::ReadOther | QFile::WriteOther | QFile::ExeOther);
|
|
connect(process, &QProcess::readyReadStandardOutput, this, [this, packageName, process, logFile]() {
|
|
while (process->canReadLine()) {
|
|
QString line = QString::fromUtf8(process->readLine()).trimmed();
|
|
// 写入日志
|
|
logFile->write(line.toUtf8() + '\n');
|
|
logFile->flush();
|
|
QRegularExpression regex(R"(\((\d+)%\))");
|
|
QRegularExpressionMatch match = regex.match(line);
|
|
if (match.hasMatch()) {
|
|
int progress = match.captured(1).toInt();
|
|
emit downloadProgress(packageName, progress);
|
|
}
|
|
}
|
|
});
|
|
connect(process, &QProcess::readyReadStandardError, this, [process, logFile]() {
|
|
QByteArray err = process->readAllStandardError();
|
|
logFile->write(err);
|
|
logFile->flush();
|
|
});
|
|
}
|
|
|
|
connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, [this, packageName, outputPath, logFile](int exitCode, QProcess::ExitStatus status) {
|
|
bool success = (exitCode == 0 && status == QProcess::NormalExit);
|
|
if (!success) {
|
|
qWarning() << "Download failed for" << packageName << "exit code:" << exitCode;
|
|
}
|
|
|
|
removeAria2Files(outputPath); // 清理残留 .aria2
|
|
emit downloadFinished(packageName, success);
|
|
|
|
if (logFile) logFile->close();
|
|
|
|
QProcess *proc = m_processes.take(packageName);
|
|
if (proc) proc->deleteLater();
|
|
});
|
|
|
|
process->start("aria2c", arguments);
|
|
}
|
|
|
|
void DownloadManager::cancelDownload(const QString &packageName)
|
|
{
|
|
if (!m_processes.contains(packageName)) return;
|
|
|
|
QProcess *process = m_processes.take(packageName);
|
|
if (process) {
|
|
process->kill(); // 立即终止
|
|
process->waitForFinished(3000); // 最多等待3秒
|
|
process->deleteLater();
|
|
}
|
|
|
|
emit downloadFinished(packageName, false); // 显式通知取消
|
|
|
|
}
|
|
|
|
void DownloadManager::removeAria2Files(const QString &filePath)
|
|
{
|
|
QString ariaFile = filePath + ".aria2";
|
|
QFile::remove(ariaFile);
|
|
}
|
|
|
|
bool DownloadManager::isDownloading(const QString &packageName) const
|
|
{
|
|
return m_processes.contains(packageName);
|
|
}
|
|
|
|
void DownloadManager::cleanupTempFiles()
|
|
{
|
|
QDir tempDir(QDir::tempPath());
|
|
QStringList leftovers = tempDir.entryList(QStringList() << "*.aria2", QDir::Files);
|
|
for (const QString &f : leftovers) {
|
|
tempDir.remove(f);
|
|
}
|
|
}
|