mirror of
https://gitee.com/spark-store-project/spark-store
synced 2025-09-03 01:42:20 +08:00
!17 多线程下载合并
* Update README.md * Improve Features * 修改获取线路的域名 * 修改默认源 * 修改多线程下载域名和图片服务器 * 修正取消下载的闪退问题 * 将图片下载由 curl 转为 QtNetworkService * 切换多域名下载,提高下载速度 * 完成并发请求下载
This commit is contained in:
parent
1a4b1176fb
commit
f7ced7739c
@ -21,9 +21,8 @@ web页面部分正在开发当中,详情请见[web仓库](https://gitee.com/de
|
|||||||
当前服务器线路列表(项目中包含):
|
当前服务器线路列表(项目中包含):
|
||||||
|
|
||||||
```
|
```
|
||||||
http://sucdn.jerrywang.top/
|
https://d.store.deepinos.org.cn/
|
||||||
http://store.jerrywang.top/
|
https://store.deepinos.org.cn/
|
||||||
http://dcstore.spark-app.store/
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 调用参数(spk规则)
|
#### 调用参数(spk规则)
|
||||||
|
@ -4,4 +4,4 @@ CONFIG += ordered
|
|||||||
SUBDIRS = third-party/QtNetworkService \
|
SUBDIRS = third-party/QtNetworkService \
|
||||||
src/spark-store.pro
|
src/spark-store.pro
|
||||||
|
|
||||||
spark-store.depends = third-party/QtNetworkService
|
spark-store.depends = third-party/QtNetworkService
|
||||||
|
259
src/downloadworker.cpp
Normal file
259
src/downloadworker.cpp
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
#include "downloadworker.h"
|
||||||
|
#include <QIODevice>
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
DownloadWorker::DownloadWorker(QObject *parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::setIdentifier(int identifier)
|
||||||
|
{
|
||||||
|
this->identifier = identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::setParamter(const QString &url, QPair<qint64, qint64> range, QFile *file)
|
||||||
|
{
|
||||||
|
this->url = url;
|
||||||
|
this->startPos = range.first;
|
||||||
|
this->endPos = range.second;
|
||||||
|
this->file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 DownloadWorker::getReceivedPos()
|
||||||
|
{
|
||||||
|
return receivedPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::doWork()
|
||||||
|
{
|
||||||
|
mgr = new QNetworkAccessManager(this);
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(url);
|
||||||
|
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
|
request.setRawHeader("Range", QString("bytes=%1-%2").arg(startPos)
|
||||||
|
.arg(endPos).toLocal8Bit());
|
||||||
|
reply = mgr->get(request);
|
||||||
|
qDebug() << "开始下载数据:" << QString(" %1~%2 -> writePos Start %3")
|
||||||
|
.arg(startPos).arg(endPos).arg(receivedPos);
|
||||||
|
connect(reply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
|
||||||
|
[this](QNetworkReply::NetworkError error){
|
||||||
|
if (error != QNetworkReply::NoError) {
|
||||||
|
qDebug() << "出错了:" << reply->errorString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(reply, &QNetworkReply::finished, mgr, &QNetworkAccessManager::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::readyRead, this, &DownloadWorker::dataReady);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &DownloadWorker::slotFinish);
|
||||||
|
connect(reply, &QNetworkReply::downloadProgress, this, &DownloadWorker::handleProcess);
|
||||||
|
// connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &DownloadWorker::doStop);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::doStop()
|
||||||
|
{
|
||||||
|
if (reply) {
|
||||||
|
reply->disconnect();
|
||||||
|
reply->aboutToClose();
|
||||||
|
reply->deleteLater();
|
||||||
|
reply = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::dataReady()
|
||||||
|
{
|
||||||
|
QByteArray data = reply->readAll();
|
||||||
|
file->seek(startPos + receivedPos);
|
||||||
|
file->write(data);
|
||||||
|
receivedPos += data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::slotFinish()
|
||||||
|
{
|
||||||
|
file->flush();
|
||||||
|
qDebug() << "数据块下载完毕:" << QString(" %1~%2 -> writePos Start %3")
|
||||||
|
.arg(startPos).arg(endPos).arg(receivedPos);
|
||||||
|
emit workFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadWorker::handleProcess(qint64, qint64)
|
||||||
|
{
|
||||||
|
emit this->downloadProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DownloadController::DownloadController(QObject *parent)
|
||||||
|
{
|
||||||
|
domains = {
|
||||||
|
"d1.store.deepinos.org.cn",
|
||||||
|
"d2.store.deepinos.org.cn",
|
||||||
|
"d3.store.deepinos.org.cn",
|
||||||
|
"d4.store.deepinos.org.cn",
|
||||||
|
"d5.store.deepinos.org.cn"
|
||||||
|
};
|
||||||
|
this->threadNum = domains.size() > 4 ? 4 : domains.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
DownloadController::~DownloadController()
|
||||||
|
{
|
||||||
|
if (workers.size() > 0) {
|
||||||
|
for(int i = 0; i < workers.size(); i++) {
|
||||||
|
workers.at(i)->doStop();
|
||||||
|
workers.at(i)->disconnect();
|
||||||
|
workers.at(i)->deleteLater();
|
||||||
|
}
|
||||||
|
workers.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadController::setFilename(QString filename)
|
||||||
|
{
|
||||||
|
this->filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadController::setThreadNum(int threadNum)
|
||||||
|
{
|
||||||
|
this->threadNum = threadNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 开始下载
|
||||||
|
*/
|
||||||
|
void DownloadController::startDownload(const QString &url)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
finish = 0;
|
||||||
|
|
||||||
|
// 下载任务等分,计算每个线程的下载数据
|
||||||
|
fileSize = getFileSize(url);
|
||||||
|
if (fileSize == 0) {
|
||||||
|
emit errorOccur("文件大小获取失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qint64 segmentSize = fileSize / threadNum;
|
||||||
|
ranges.resize(threadNum);
|
||||||
|
QVector<qint64> receivedBytes;
|
||||||
|
receivedBytes.resize(threadNum);
|
||||||
|
for (int i = 0; i < threadNum; i++) {
|
||||||
|
ranges[i].first = i * segmentSize;
|
||||||
|
ranges[i].second = i * segmentSize + segmentSize - 1;
|
||||||
|
receivedBytes[i] = 0;
|
||||||
|
}
|
||||||
|
ranges[threadNum-1].second = fileSize; // 余数部分加入最后一个
|
||||||
|
|
||||||
|
// 打开文件
|
||||||
|
QDir tmpdir("/tmp/spark-store");
|
||||||
|
file = new QFile;
|
||||||
|
file->setFileName(tmpdir.absoluteFilePath(filename));
|
||||||
|
|
||||||
|
if (file->exists())
|
||||||
|
file->remove();
|
||||||
|
if (!file->open(QIODevice::WriteOnly)) {
|
||||||
|
delete file;
|
||||||
|
file = nullptr;
|
||||||
|
emit errorOccur(file->errorString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file->resize(fileSize);
|
||||||
|
|
||||||
|
// 创建下载线程
|
||||||
|
workers.clear();
|
||||||
|
for(int i = 0; i < ranges.size(); i++) {
|
||||||
|
qDebug() << QString("第%1个下载请求:%2-%3").arg(i).arg(ranges.at(i).first).arg(ranges.at(i).second);
|
||||||
|
auto worker = new DownloadWorker(this);
|
||||||
|
auto range = ranges.at(i);
|
||||||
|
QString chunkUrl = replaceDomain(url, domains.at(i));
|
||||||
|
worker->setIdentifier(i);
|
||||||
|
worker->setParamter(chunkUrl, range, file);
|
||||||
|
workers.append(worker);
|
||||||
|
connect(worker, &DownloadWorker::downloadProcess, this, &DownloadController::handleProcess);
|
||||||
|
connect(worker, &DownloadWorker::workFinished, this, &DownloadController::chunkDownloadFinish);
|
||||||
|
worker->doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 停止下载
|
||||||
|
*/
|
||||||
|
void DownloadController::stopDownload()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < workers.size(); i++) {
|
||||||
|
workers.at(i)->doStop();
|
||||||
|
workers.at(i)->disconnect();
|
||||||
|
workers.at(i)->deleteLater();
|
||||||
|
}
|
||||||
|
workers.clear();
|
||||||
|
|
||||||
|
qDebug() << "文件下载路径:" << QFileInfo(file->fileName()).absoluteFilePath();
|
||||||
|
file->flush();
|
||||||
|
file->close();
|
||||||
|
delete file;
|
||||||
|
file = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DownloadController::handleProcess()
|
||||||
|
{
|
||||||
|
qint64 bytesReceived = 0;
|
||||||
|
for(int i = 0; i < workers.size(); i++) {
|
||||||
|
bytesReceived += workers.at(i)->getReceivedPos();
|
||||||
|
}
|
||||||
|
qDebug() << QString("下载进度 %1-%2").arg(bytesReceived).arg(fileSize);
|
||||||
|
emit downloadProcess(bytesReceived, fileSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DownloadController::chunkDownloadFinish()
|
||||||
|
{
|
||||||
|
finish++;
|
||||||
|
qDebug() << QString("已下载了%1块,共%2块!!!").arg(finish).arg(threadNum);
|
||||||
|
if (finish == threadNum) {
|
||||||
|
stopDownload();
|
||||||
|
emit downloadFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 DownloadController::getFileSize(const QString& url)
|
||||||
|
{
|
||||||
|
QEventLoop event;
|
||||||
|
QNetworkAccessManager requestManager;
|
||||||
|
QNetworkRequest request;
|
||||||
|
request.setUrl(QUrl(url));
|
||||||
|
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
|
QNetworkReply *reply = requestManager.head(request);
|
||||||
|
connect(reply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
|
||||||
|
[this, reply](QNetworkReply::NetworkError error){
|
||||||
|
if (error != QNetworkReply::NoError) {
|
||||||
|
emit errorOccur(reply->errorString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(reply, &QNetworkReply::finished, &event, &QEventLoop::quit);
|
||||||
|
event.exec();
|
||||||
|
qint64 fileSize = 0;
|
||||||
|
if (reply->rawHeader("Accept-Ranges") == QByteArrayLiteral("bytes")
|
||||||
|
&& reply->hasRawHeader(QString("Content-Length").toLocal8Bit())) {
|
||||||
|
fileSize = reply->header(QNetworkRequest::ContentLengthHeader).toUInt();
|
||||||
|
}
|
||||||
|
qDebug() << "文件大小为:" << fileSize;
|
||||||
|
reply->deleteLater();
|
||||||
|
return fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DownloadController::replaceDomain(const QString& url, const QString domain)
|
||||||
|
{
|
||||||
|
QRegularExpression regex(R"((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9])");
|
||||||
|
if (regex.match(url).hasMatch()) {
|
||||||
|
return QString(url).replace(regex.match(url).captured(), domain);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
75
src/downloadworker.h
Normal file
75
src/downloadworker.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef DOWNLOADWORKER_H
|
||||||
|
#define DOWNLOADWORKER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
class DownloadWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DownloadWorker(QObject *parent = nullptr);
|
||||||
|
void setIdentifier(int identifier);
|
||||||
|
void setParamter(const QString &url, QPair<qint64, qint64> range, QFile *flle);
|
||||||
|
qint64 getReceivedPos();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void doWork();
|
||||||
|
void doStop();
|
||||||
|
void dataReady();
|
||||||
|
void slotFinish();
|
||||||
|
void handleProcess(qint64, qint64);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void resultReady(int identifier, QByteArray data);
|
||||||
|
void testSignals();
|
||||||
|
void workFinished();
|
||||||
|
void downloadProcess();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int identifier;
|
||||||
|
QString url;
|
||||||
|
qint64 startPos;
|
||||||
|
qint64 endPos;
|
||||||
|
qint64 receivedPos = 0;
|
||||||
|
QNetworkReply *reply;
|
||||||
|
QNetworkAccessManager *mgr;
|
||||||
|
QFile *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DownloadController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DownloadController(QObject *parent = nullptr);
|
||||||
|
~DownloadController();
|
||||||
|
void setFilename(QString filename);
|
||||||
|
void setThreadNum(int threadNum);
|
||||||
|
void startDownload(const QString &url);
|
||||||
|
void stopDownload();
|
||||||
|
qint64 getFileSize(const QString& url);
|
||||||
|
QString replaceDomain(const QString& url, const QString domain);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void handleProcess();
|
||||||
|
void chunkDownloadFinish();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void errorOccur(const QString& msg);
|
||||||
|
void downloadProcess(qint64, qint64);
|
||||||
|
void downloadFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int threadNum;
|
||||||
|
QString filename;
|
||||||
|
qint64 fileSize;
|
||||||
|
QVector<QPair<qint64, qint64>> ranges;
|
||||||
|
QFile *file;
|
||||||
|
QList<DownloadWorker*> workers;
|
||||||
|
int finish = 0;
|
||||||
|
QVector<QString> domains;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILEDOWNLOADWORKER_H
|
@ -25,8 +25,12 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
# 禁止输出 qWarning / qDebug 信息
|
||||||
|
CONFIG(release, debug|release): DEFINES += QT_NO_WARNING_OUTPUT QT_NO_DEBUG_OUTPUT
|
||||||
|
|
||||||
SOURCES += main.cpp\
|
SOURCES += main.cpp\
|
||||||
appitem.cpp \
|
appitem.cpp \
|
||||||
|
downloadworker.cpp \
|
||||||
widget.cpp \
|
widget.cpp \
|
||||||
downloadlist.cpp \
|
downloadlist.cpp \
|
||||||
image_show.cpp \
|
image_show.cpp \
|
||||||
@ -37,6 +41,7 @@ SOURCES += main.cpp\
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
appitem.h \
|
appitem.h \
|
||||||
|
downloadworker.h \
|
||||||
widget.h \
|
widget.h \
|
||||||
downloadlist.h \
|
downloadlist.h \
|
||||||
image_show.h \
|
image_show.h \
|
||||||
|
248
src/widget.cpp
248
src/widget.cpp
@ -33,6 +33,7 @@
|
|||||||
#include "HttpClient.h"
|
#include "HttpClient.h"
|
||||||
#include "appitem.h"
|
#include "appitem.h"
|
||||||
#include "flowlayout.h"
|
#include "flowlayout.h"
|
||||||
|
#include "downloadworker.h"
|
||||||
|
|
||||||
DWIDGET_USE_NAMESPACE
|
DWIDGET_USE_NAMESPACE
|
||||||
|
|
||||||
@ -48,6 +49,8 @@ Widget::Widget(DBlurEffectWidget *parent) :
|
|||||||
m_loadweb->show();
|
m_loadweb->show();
|
||||||
|
|
||||||
httpClient = new AeaQt::HttpClient;
|
httpClient = new AeaQt::HttpClient;
|
||||||
|
// 并发下载
|
||||||
|
downloadController = new DownloadController(this);
|
||||||
|
|
||||||
connect(ui->menu_main,&QPushButton::clicked,[=](){Widget::chooseLeftMenu(0);});
|
connect(ui->menu_main,&QPushButton::clicked,[=](){Widget::chooseLeftMenu(0);});
|
||||||
connect(ui->menu_network,&QPushButton::clicked,[=](){Widget::chooseLeftMenu(1);});
|
connect(ui->menu_network,&QPushButton::clicked,[=](){Widget::chooseLeftMenu(1);});
|
||||||
@ -72,6 +75,7 @@ Widget::Widget(DBlurEffectWidget *parent) :
|
|||||||
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishedScreenshotLoad, this, &Widget::sltAppinfoScreenshot, Qt::ConnectionType::BlockingQueuedConnection);
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishedScreenshotLoad, this, &Widget::sltAppinfoScreenshot, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishAllLoading, this, &Widget::sltAppinfoFinish, Qt::ConnectionType::BlockingQueuedConnection);
|
connect(&appinfoLoadThread, &SpkAppInfoLoaderThread::finishAllLoading, this, &Widget::sltAppinfoFinish, Qt::ConnectionType::BlockingQueuedConnection);
|
||||||
|
|
||||||
|
|
||||||
// 搜索事件
|
// 搜索事件
|
||||||
connect(searchEdit, &DSearchEdit::returnPressed, this, [=]()
|
connect(searchEdit, &DSearchEdit::returnPressed, this, [=]()
|
||||||
{
|
{
|
||||||
@ -127,6 +131,7 @@ Widget::~Widget()
|
|||||||
{
|
{
|
||||||
notify_uninit();
|
notify_uninit();
|
||||||
|
|
||||||
|
// delete httpFinished;
|
||||||
delete ui;
|
delete ui;
|
||||||
qDebug()<<"exit";
|
qDebug()<<"exit";
|
||||||
DApplication::quit();
|
DApplication::quit();
|
||||||
@ -231,8 +236,15 @@ void Widget::initConfig()
|
|||||||
while (getline(serverList,lineTmp)) {
|
while (getline(serverList,lineTmp)) {
|
||||||
ui->comboBox_server->addItem(QString::fromStdString(lineTmp));
|
ui->comboBox_server->addItem(QString::fromStdString(lineTmp));
|
||||||
}
|
}
|
||||||
|
for(int i = 0; i < ui->comboBox_server->count(); i++)
|
||||||
|
{
|
||||||
|
if(ui->comboBox_server->itemText(i) == "开发者模式 Dev only")
|
||||||
|
{
|
||||||
|
ui->comboBox_server->model()->setData(ui->comboBox_server->model()->index(i, 0), QVariant(0), Qt::UserRole - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
ui->comboBox_server->addItem("http://sucdn.jerrywang.top/");
|
ui->comboBox_server->addItem("https://d.store.deepinos.org.cn/");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取服务器URL并初始化菜单项的链接
|
// 读取服务器URL并初始化菜单项的链接
|
||||||
@ -241,7 +253,7 @@ void Widget::initConfig()
|
|||||||
ui->comboBox_server->setCurrentText(readConfig.value("server/choose").toString());
|
ui->comboBox_server->setCurrentText(readConfig.value("server/choose").toString());
|
||||||
appinfoLoadThread.setServer(serverUrl=readConfig.value("server/choose").toString());
|
appinfoLoadThread.setServer(serverUrl=readConfig.value("server/choose").toString());
|
||||||
}else {
|
}else {
|
||||||
appinfoLoadThread.setServer(serverUrl="http://sucdn.jerrywang.top/"); // 默认URL
|
appinfoLoadThread.setServer(serverUrl="https://d.store.deenos.org.cn/"); // 默认URL
|
||||||
}
|
}
|
||||||
configCanSave=true; // 防止触发保存配置信号
|
configCanSave=true; // 防止触发保存配置信号
|
||||||
menuUrl[0]=serverUrl + "store/#/";
|
menuUrl[0]=serverUrl + "store/#/";
|
||||||
@ -266,8 +278,8 @@ void Widget::initConfig()
|
|||||||
ui->webfoot->hide();
|
ui->webfoot->hide();
|
||||||
|
|
||||||
//初始化首页
|
//初始化首页
|
||||||
ui->webEngineView->setUrl(menuUrl[0]);
|
chooseLeftMenu(0);
|
||||||
// ui->webEngineView->setUrl(menuUrl[1]);
|
// ui->webEngineView->setUrl(menuUrl[0]);
|
||||||
|
|
||||||
//给下载列表赋值到数组,方便调用
|
//给下载列表赋值到数组,方便调用
|
||||||
for (int i =0; i<LIST_MAX;i++){
|
for (int i =0; i<LIST_MAX;i++){
|
||||||
@ -512,174 +524,6 @@ void Widget::updatefoot()
|
|||||||
ui->webfoot->setFixedHeight(allh-foot);
|
ui->webfoot->setFixedHeight(allh-foot);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Widget::loadappinfo(QUrl arg1)
|
|
||||||
{
|
|
||||||
if(arg1.isEmpty()){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 先隐藏详情页负责显示截图的label
|
|
||||||
ui->screen_0->hide();
|
|
||||||
ui->screen_1->hide();
|
|
||||||
ui->screen_2->hide();
|
|
||||||
ui->screen_3->hide();
|
|
||||||
ui->screen_4->hide();
|
|
||||||
ui->label_appicon->clear();
|
|
||||||
ui->tag_community->hide();
|
|
||||||
ui->tag_ubuntu->hide();
|
|
||||||
ui->tag_deepin->hide();
|
|
||||||
ui->tag_uos->hide();
|
|
||||||
ui->tag_dtk5->hide();
|
|
||||||
ui->tag_dwine2->hide();
|
|
||||||
ui->tag_dwine5->hide();
|
|
||||||
ui->tag_a2d->hide();
|
|
||||||
|
|
||||||
// 重置UI状态
|
|
||||||
ui->pushButton_uninstall->hide();
|
|
||||||
ui->pushButton_website->setEnabled(false);
|
|
||||||
ui->pushButton->setEnabled(false);
|
|
||||||
ui->pushButton_translate->setEnabled(false);
|
|
||||||
ui->label_show->setText("Loading...");
|
|
||||||
ui->label_show->show();
|
|
||||||
|
|
||||||
QProcess get_json;
|
|
||||||
QDir dir("/tmp");
|
|
||||||
dir.mkdir("spark-store");
|
|
||||||
QDir::setCurrent("/tmp/spark-store");
|
|
||||||
|
|
||||||
get_json.start("curl -o app.json "+arg1.toString());
|
|
||||||
get_json.waitForFinished();
|
|
||||||
if(get_json.exitCode())
|
|
||||||
{
|
|
||||||
sendNotification(tr("Failed to download app info. Please check internet connection."));
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile app_json("app.json");
|
|
||||||
if(app_json.open(QIODevice::ReadOnly)){
|
|
||||||
// 成功得到json文件
|
|
||||||
QByteArray json_array=app_json.readAll();
|
|
||||||
// 将路径转化为相应源的下载路径
|
|
||||||
urladdress=arg1.toString().left(arg1.toString().length()-8);
|
|
||||||
QStringList downloadurl=urladdress.split("/");
|
|
||||||
urladdress=ui->comboBox_server->currentText();
|
|
||||||
QString deburl=urladdress;
|
|
||||||
deburl=deburl.left(urladdress.length()-1);
|
|
||||||
urladdress="https://cdn.jsdelivr.net/gh/Jerrywang959/jsonpng@master/"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
|
|
||||||
urladdress=urladdress.left(urladdress.length()-1);
|
|
||||||
|
|
||||||
for (int i=3;i<downloadurl.size();i++) {
|
|
||||||
urladdress+="/"+downloadurl[i];
|
|
||||||
deburl+="/"+downloadurl[i];
|
|
||||||
}
|
|
||||||
// 路径转化完成
|
|
||||||
QJsonObject json= QJsonDocument::fromJson(json_array).object();
|
|
||||||
appName = json["Name"].toString();
|
|
||||||
url=deburl + json["Filename"].toString();
|
|
||||||
qDebug()<<url;
|
|
||||||
ui->label_appname->setText(appName);
|
|
||||||
system("rm -r *.png");
|
|
||||||
ui->label_show->show();
|
|
||||||
// 软件信息加载
|
|
||||||
QString info;
|
|
||||||
info= tr("PkgName: ")+json["Pkgname"].toString()+"\n";
|
|
||||||
info+=tr("Version: ")+json["Version"].toString()+"\n";
|
|
||||||
if(json["Author"].toString()!="" && json["Author"].toString()!=" "){
|
|
||||||
info+=tr("Author: ")+json["Author"].toString()+"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(json["Website"].toString()!="" && json["Website"].toString()!=" "){
|
|
||||||
info+=tr("Official Site: ")+json["Website"].toString()+"\n";
|
|
||||||
ui->pushButton_website->show();
|
|
||||||
appweb=json["Website"].toString();
|
|
||||||
}
|
|
||||||
info+=tr("Contributor: ")+json["Contributor"].toString()+"\n";
|
|
||||||
info+=tr("Update Time: ")+json["Update"].toString()+"\n";
|
|
||||||
info+=tr("Installed Size: ")+json["Size"].toString()+"\n";
|
|
||||||
ui->label_info->setText(info);
|
|
||||||
ui->label_more->setText(json["More"].toString());
|
|
||||||
QProcess isInstall;
|
|
||||||
pkgName=json["Pkgname"].toString();
|
|
||||||
isInstall.start("dpkg -s "+json["Pkgname"].toString());
|
|
||||||
isInstall.waitForFinished();
|
|
||||||
int error=QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
|
||||||
if(error==0){
|
|
||||||
ui->pushButton_download->setText(tr("Reinstall"));
|
|
||||||
ui->pushButton_uninstall->show();
|
|
||||||
|
|
||||||
}else {
|
|
||||||
ui->pushButton_download->setText(tr("Install"));
|
|
||||||
}
|
|
||||||
//tag加载
|
|
||||||
QString tags=json["Tags"].toString();
|
|
||||||
QStringList tagList=tags.split(";");
|
|
||||||
for (int i=0;i<tagList.size();i++) {
|
|
||||||
if(tagList[i]=="community")
|
|
||||||
ui->tag_community->show();
|
|
||||||
if(tagList[i]=="ubuntu")
|
|
||||||
ui->tag_ubuntu->show();
|
|
||||||
if(tagList[i]=="deepin")
|
|
||||||
ui->tag_deepin->show();
|
|
||||||
if(tagList[i]=="uos")
|
|
||||||
ui->tag_uos->show();
|
|
||||||
if(tagList[i]=="dtk5")
|
|
||||||
ui->tag_dtk5->show();
|
|
||||||
if(tagList[i]=="dwine2")
|
|
||||||
ui->tag_dwine2->show();
|
|
||||||
if(tagList[i]=="dwine5")
|
|
||||||
ui->tag_dwine5->show();
|
|
||||||
if(tagList[i]=="a2d")
|
|
||||||
ui->tag_a2d->show();
|
|
||||||
}
|
|
||||||
// 图标加载
|
|
||||||
get_json.start("curl -o icon.png "+urladdress+"icon.png");
|
|
||||||
get_json.waitForFinished();
|
|
||||||
if(!get_json.exitCode()) {
|
|
||||||
QPixmap appicon(QString::fromUtf8(TMP_PATH)+"/icon.png");
|
|
||||||
ui->label_appicon->setPixmap(appicon);
|
|
||||||
ui->pushButton_download->setEnabled(true);
|
|
||||||
ui->pushButton->setEnabled(true);
|
|
||||||
ui->pushButton_translate->setEnabled(true);
|
|
||||||
ui->pushButton_website->setEnabled(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sendNotification(tr("Failed to load application icon."));
|
|
||||||
|
|
||||||
|
|
||||||
// 截图展示加载
|
|
||||||
QList<image_show*> label_screen;
|
|
||||||
label_screen << ui->screen_0 << ui->screen_1 << ui->screen_2 << ui->screen_3 << ui->screen_4;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
QString cmd = "curl -o screen_"+QString::number(i+1)+".png "+urladdress+"screen_"+QString::number(i+1)+".png";
|
|
||||||
get_json.terminate();
|
|
||||||
get_json.start(cmd);
|
|
||||||
get_json.waitForFinished();
|
|
||||||
bool s = screen[i].load("screen_"+QString::number(i+1)+".png");
|
|
||||||
if(s){
|
|
||||||
label_screen[i]->setImage(screen[i]);
|
|
||||||
label_screen[i]->show();
|
|
||||||
/*
|
|
||||||
switch(i){ // 故意为之,为了清除多余截图
|
|
||||||
case 0:
|
|
||||||
label_screen[1]->hide();
|
|
||||||
case 1:
|
|
||||||
label_screen[2]->hide();
|
|
||||||
case 2:
|
|
||||||
label_screen[3]->hide();
|
|
||||||
case 3:
|
|
||||||
label_screen[4]->hide();
|
|
||||||
|
|
||||||
}*/
|
|
||||||
}else{
|
|
||||||
QFile::remove("screen_"+QString::number(i+1)+".png");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ui->label_show->setText("");
|
|
||||||
ui->label_show->hide();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::on_pushButton_download_clicked()
|
void Widget::on_pushButton_download_clicked()
|
||||||
{
|
{
|
||||||
chooseLeftMenu(13);
|
chooseLeftMenu(13);
|
||||||
@ -705,31 +549,37 @@ void Widget::on_pushButton_download_clicked()
|
|||||||
system("cp icon.png icon_"+QString::number(allDownload-1).toUtf8()+".png");
|
system("cp icon.png icon_"+QString::number(allDownload-1).toUtf8()+".png");
|
||||||
download_list[allDownload-1].seticon(icon);
|
download_list[allDownload-1].seticon(icon);
|
||||||
if(!isBusy){
|
if(!isBusy){
|
||||||
file = new QFile(fileName);
|
// file = new QFile(fileName);
|
||||||
if(!file->open(QIODevice::WriteOnly)){
|
// if(!file->open(QIODevice::WriteOnly)){
|
||||||
delete file;
|
// delete file;
|
||||||
file = nullptr;
|
// file = nullptr;
|
||||||
return ;
|
// return ;
|
||||||
}
|
// }
|
||||||
|
|
||||||
nowDownload+=1;
|
nowDownload+=1;
|
||||||
startRequest(urList.at(nowDownload-1)); // 进行链接请求
|
|
||||||
|
startRequest(urList.at(nowDownload-1), fileName); // 进行链接请求
|
||||||
}
|
}
|
||||||
if(ui->pushButton_download->text()==tr("Reinstall")){
|
if(ui->pushButton_download->text()==tr("Reinstall")){
|
||||||
download_list[allDownload-1].reinstall=true;
|
download_list[allDownload-1].reinstall=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::startRequest(QUrl url)
|
void Widget::startRequest(QUrl url, QString fileName)
|
||||||
{
|
{
|
||||||
ui->listWidget->show();
|
ui->listWidget->show();
|
||||||
ui->label->hide();
|
ui->label->hide();
|
||||||
isBusy=true;
|
isBusy=true;
|
||||||
isdownload=true;
|
isdownload=true;
|
||||||
download_list[allDownload-1].free=false;
|
download_list[allDownload-1].free=false;
|
||||||
reply = manager->get(QNetworkRequest(url));
|
|
||||||
connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
|
connect(downloadController, &DownloadController::downloadProcess, this, &Widget::updateDataReadProgress);
|
||||||
connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
|
connect(downloadController, &DownloadController::downloadFinished, this, &Widget::httpFinished);
|
||||||
connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(updateDataReadProgress(qint64,qint64)));
|
connect(downloadController, &DownloadController::errorOccur, [this](QString msg){
|
||||||
|
this->sendNotification(msg);
|
||||||
|
});
|
||||||
|
downloadController->setFilename(fileName);
|
||||||
|
downloadController->startDownload(url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::searchApp(QString text)
|
void Widget::searchApp(QString text)
|
||||||
@ -846,6 +696,8 @@ void Widget::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
|
|||||||
download_list[nowDownload-1].setValue((bytesRead*10000)/totalBytes); // 当前值
|
download_list[nowDownload-1].setValue((bytesRead*10000)/totalBytes); // 当前值
|
||||||
download_size=bytesRead;
|
download_size=bytesRead;
|
||||||
if(download_list[nowDownload-1].close){ // 随时检测下载是否被取消
|
if(download_list[nowDownload-1].close){ // 随时检测下载是否被取消
|
||||||
|
downloadController->disconnect();
|
||||||
|
downloadController->stopDownload();
|
||||||
download_list[nowDownload-1].closeDownload();
|
download_list[nowDownload-1].closeDownload();
|
||||||
httpFinished();
|
httpFinished();
|
||||||
}
|
}
|
||||||
@ -958,12 +810,6 @@ void Widget::sltAppinfoFinish()
|
|||||||
|
|
||||||
void Widget::httpFinished() // 完成下载
|
void Widget::httpFinished() // 完成下载
|
||||||
{
|
{
|
||||||
file->flush();
|
|
||||||
file->close();
|
|
||||||
reply->deleteLater();
|
|
||||||
reply = nullptr;
|
|
||||||
delete file;
|
|
||||||
file = nullptr;
|
|
||||||
isdownload=false;
|
isdownload=false;
|
||||||
isBusy=false;
|
isBusy=false;
|
||||||
download_list[nowDownload-1].readyInstall();
|
download_list[nowDownload-1].readyInstall();
|
||||||
@ -974,14 +820,7 @@ void Widget::httpFinished() // 完成下载
|
|||||||
nowDownload+=1;
|
nowDownload+=1;
|
||||||
}
|
}
|
||||||
QString fileName=download_list[nowDownload-1].getName();
|
QString fileName=download_list[nowDownload-1].getName();
|
||||||
file = new QFile(fileName);
|
startRequest(urList.at(nowDownload-1), fileName);
|
||||||
if(!file->open(QIODevice::WriteOnly))
|
|
||||||
{
|
|
||||||
delete file;
|
|
||||||
file = nullptr;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
startRequest(urList.at(nowDownload-1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1049,7 +888,7 @@ void Widget::on_pushButton_updateServer_clicked()
|
|||||||
ui->pushButton_updateServer->setEnabled(false);
|
ui->pushButton_updateServer->setEnabled(false);
|
||||||
ui->comboBox_server->clear();
|
ui->comboBox_server->clear();
|
||||||
QFile::remove(QDir::homePath().toUtf8()+"/.config/spark-store/server.list");
|
QFile::remove(QDir::homePath().toUtf8()+"/.config/spark-store/server.list");
|
||||||
system("curl -o "+QDir::homePath().toUtf8()+"/.config/spark-store/server.list http://dcstore.shenmo.tech/store/server.list");
|
system("curl -o "+QDir::homePath().toUtf8()+"/.config/spark-store/server.list https://d.store.deepinos.org.cn/store/server.list");
|
||||||
std::fstream server;
|
std::fstream server;
|
||||||
server.open(QDir::homePath().toUtf8()+"/.config/spark-store/server.list",std::ios::in);
|
server.open(QDir::homePath().toUtf8()+"/.config/spark-store/server.list",std::ios::in);
|
||||||
std::string lineTmp;
|
std::string lineTmp;
|
||||||
@ -1058,10 +897,18 @@ void Widget::on_pushButton_updateServer_clicked()
|
|||||||
ui->comboBox_server->addItem(QString::fromStdString(lineTmp));
|
ui->comboBox_server->addItem(QString::fromStdString(lineTmp));
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
ui->comboBox_server->addItem("http://sucdn.jerrywang.top/");
|
ui->comboBox_server->addItem("https://d.store.deepinos.org.cn/");
|
||||||
}
|
}
|
||||||
ui->pushButton_updateServer->setEnabled(true);
|
ui->pushButton_updateServer->setEnabled(true);
|
||||||
ui->comboBox_server->setCurrentIndex(0);
|
ui->comboBox_server->setCurrentIndex(0);
|
||||||
|
|
||||||
|
for(int i = 0; i < ui->comboBox_server->count(); i++)
|
||||||
|
{
|
||||||
|
if(ui->comboBox_server->itemText(i) == "开发者模式 Dev only")
|
||||||
|
{
|
||||||
|
ui->comboBox_server->model()->setData(ui->comboBox_server->model()->index(i, 0), QVariant(0), Qt::UserRole - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1269,6 +1116,7 @@ void Widget::on_webEngineView_urlChanged(const QUrl &arg1)
|
|||||||
ui->pushButton_download->setEnabled(false);
|
ui->pushButton_download->setEnabled(false);
|
||||||
ui->stackedWidget->setCurrentIndex(2);
|
ui->stackedWidget->setCurrentIndex(2);
|
||||||
qDebug()<<"https://demo-one-vert.vercel.app/"+type_name+"/"+pname;
|
qDebug()<<"https://demo-one-vert.vercel.app/"+type_name+"/"+pname;
|
||||||
|
qDebug()<< "链接地址:" << arg1;
|
||||||
/*
|
/*
|
||||||
load.cancel();//打开并发加载线程前关闭正在执行的线程
|
load.cancel();//打开并发加载线程前关闭正在执行的线程
|
||||||
load = QtConcurrent::run([=](){
|
load = QtConcurrent::run([=](){
|
||||||
|
@ -39,6 +39,7 @@ class Widget;
|
|||||||
|
|
||||||
|
|
||||||
class FlowLayout;
|
class FlowLayout;
|
||||||
|
class DownloadController;
|
||||||
|
|
||||||
namespace AeaQt {
|
namespace AeaQt {
|
||||||
class HttpClient;
|
class HttpClient;
|
||||||
@ -51,7 +52,7 @@ class Widget : public DBlurEffectWidget
|
|||||||
public:
|
public:
|
||||||
explicit Widget(DBlurEffectWidget *parent = nullptr);
|
explicit Widget(DBlurEffectWidget *parent = nullptr);
|
||||||
~Widget();
|
~Widget();
|
||||||
void startRequest(QUrl url);
|
void startRequest(QUrl url, QString fileName);
|
||||||
void searchApp(QString);
|
void searchApp(QString);
|
||||||
int nowDownload=0;
|
int nowDownload=0;
|
||||||
int allDownload=0;
|
int allDownload=0;
|
||||||
@ -122,7 +123,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
void initUI();
|
void initUI();
|
||||||
void initConfig();
|
void initConfig();
|
||||||
int loadappinfo(QUrl);
|
|
||||||
void chooseLeftMenu(int index);
|
void chooseLeftMenu(int index);
|
||||||
void setfoot(int);
|
void setfoot(int);
|
||||||
void updatefoot();
|
void updatefoot();
|
||||||
@ -163,6 +163,7 @@ private:
|
|||||||
AeaQt::HttpClient *httpClient;
|
AeaQt::HttpClient *httpClient;
|
||||||
FlowLayout *applist_grid;
|
FlowLayout *applist_grid;
|
||||||
QHBoxLayout *main;
|
QHBoxLayout *main;
|
||||||
|
DownloadController *downloadController;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIDGET_H
|
#endif // WIDGET_H
|
||||||
|
@ -5,117 +5,124 @@
|
|||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include "workerthreads.h"
|
#include "workerthreads.h"
|
||||||
#include "widget.h"
|
#include "widget.h"
|
||||||
|
#include "HttpClient.h"
|
||||||
|
|
||||||
void SpkAppInfoLoaderThread::run()
|
void SpkAppInfoLoaderThread::run()
|
||||||
{
|
{
|
||||||
emit requestResetUi();
|
emit requestResetUi();
|
||||||
|
|
||||||
QProcess get_json;
|
httpClient = new AeaQt::HttpClient;
|
||||||
QString urladdress, deatils, more, packagename, appweb;
|
|
||||||
QDir dir("/tmp");
|
|
||||||
bool isInstalled;
|
|
||||||
dir.mkdir("spark-store");
|
|
||||||
QDir::setCurrent("/tmp/spark-store");
|
|
||||||
|
|
||||||
get_json.start("curl -o app.json " + targetUrl.toString());
|
httpClient->get(targetUrl.toString())
|
||||||
if(waitDownload(get_json) == -1)
|
.header("content-type", "application/json")
|
||||||
return;
|
.onResponse([this](QByteArray json_array) {
|
||||||
if(get_json.exitCode())
|
qDebug() << "请求应用信息 " << json_array;
|
||||||
{
|
QString urladdress, deatils, more, packagename, appweb;
|
||||||
Widget::sendNotification(tr("Failed to download app info. Please check internet connection."));
|
bool isInstalled;
|
||||||
}
|
|
||||||
|
|
||||||
QFile app_json("app.json");
|
// 将路径转化为相应源的下载路径
|
||||||
if(app_json.open(QIODevice::ReadOnly)){
|
urladdress = targetUrl.toString().left(targetUrl.toString().length()-8);
|
||||||
// 成功得到json文件
|
QStringList downloadurl=urladdress.split("/");
|
||||||
QByteArray json_array = app_json.readAll();
|
|
||||||
// 将路径转化为相应源的下载路径
|
|
||||||
urladdress = targetUrl.toString().left(targetUrl.toString().length()-8);
|
|
||||||
QStringList downloadurl=urladdress.split("/");
|
|
||||||
|
|
||||||
QString deburl = serverUrl;
|
QString deburl = serverUrl;
|
||||||
deburl = deburl.left(urladdress.length()-1);
|
deburl = deburl.left(urladdress.length()-1);
|
||||||
urladdress = "https://cdn.jsdelivr.net/gh/Jerrywang959/jsonpng@master/"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
|
urladdress = "https://img.jerrywang.top/"; // 使用图片专用服务器请保留这行,删除后将使用源服务器
|
||||||
urladdress = urladdress.left(urladdress.length()-1);
|
urladdress = urladdress.left(urladdress.length()-1);
|
||||||
|
|
||||||
for (int i=3;i<downloadurl.size();i++) {
|
for (int i=3;i<downloadurl.size();i++) {
|
||||||
urladdress+="/"+downloadurl[i];
|
urladdress+="/"+downloadurl[i];
|
||||||
deburl+="/"+downloadurl[i];
|
deburl+="/"+downloadurl[i];
|
||||||
}
|
|
||||||
|
|
||||||
// 路径转化完成
|
|
||||||
QJsonObject json= QJsonDocument::fromJson(json_array).object();
|
|
||||||
QString appName = json["Name"].toString();
|
|
||||||
QUrl fileUrl = deburl + json["Filename"].toString();
|
|
||||||
|
|
||||||
// 软件信息加载
|
|
||||||
QString details;
|
|
||||||
details = tr("PkgName: ") + json["Pkgname"].toString()+"\n";
|
|
||||||
details += tr("Version: ") + json["Version"].toString()+"\n";
|
|
||||||
if(json["Author"].toString() != "" && json["Author"].toString() != " "){
|
|
||||||
details += tr("Author: ") + json["Author"].toString() + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(json["Website"].toString() != "" && json["Website"].toString() != " "){
|
|
||||||
details += tr("Official Site: ") + json["Website"].toString() + "\n";
|
|
||||||
//ui->pushButton_website->show(); move to setinfo slot
|
|
||||||
appweb=json["Website"].toString();
|
|
||||||
}
|
|
||||||
details+=tr("Contributor: ")+json["Contributor"].toString()+"\n";
|
|
||||||
details+=tr("Update Time: ")+json["Update"].toString()+"\n";
|
|
||||||
details+=tr("Installed Size: ")+json["Size"].toString()+"\n";
|
|
||||||
more = json["More"].toString();
|
|
||||||
|
|
||||||
QProcess isInstall;
|
|
||||||
packagename = json["Pkgname"].toString();
|
|
||||||
isInstall.start("dpkg -s "+json["Pkgname"].toString());
|
|
||||||
isInstall.waitForFinished();
|
|
||||||
int error=QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
|
||||||
if(error==0)
|
|
||||||
isInstalled = true;
|
|
||||||
else
|
|
||||||
isInstalled = false;
|
|
||||||
|
|
||||||
emit requestSetAppInformation(&appName, &details, &more, &appweb, &packagename, &fileUrl, isInstalled);
|
|
||||||
|
|
||||||
//tag加载
|
|
||||||
QString tags=json["Tags"].toString();
|
|
||||||
QStringList tagList=tags.split(";");
|
|
||||||
emit requestSetTags(&tagList);
|
|
||||||
|
|
||||||
// 图标加载
|
|
||||||
get_json.start("curl -o icon.png "+urladdress+"icon.png");
|
|
||||||
if(waitDownload(get_json) == -1)
|
|
||||||
return;
|
|
||||||
if(!get_json.exitCode()) {
|
|
||||||
QPixmap appicon("icon.png");
|
|
||||||
emit finishedIconLoad(&appicon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Widget::sendNotification(tr("Failed to load application icon."));
|
|
||||||
|
|
||||||
|
|
||||||
// 截图展示加载
|
|
||||||
QPixmap screenshotCache[5];
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
QString cmd = "curl -o screen_"+QString::number(i+1)+".png "+urladdress+"screen_"+QString::number(i+1)+".png";
|
|
||||||
get_json.start(cmd);
|
|
||||||
if(waitDownload(get_json) == -1)
|
|
||||||
return;
|
|
||||||
bool s = screenshotCache[i].load(QString(TMP_PATH) + "/screen_"+QString::number(i+1)+".png");
|
|
||||||
if(s){
|
|
||||||
emit finishedScreenshotLoad(&screenshotCache[i], i);
|
|
||||||
}else{
|
|
||||||
emit finishedScreenshotLoad(nullptr, i);
|
|
||||||
QFile::remove("screen_"+QString::number(i+1)+".png");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
emit finishAllLoading();
|
// 路径转化完成
|
||||||
}
|
QJsonObject json= QJsonDocument::fromJson(json_array).object();
|
||||||
|
QString appName = json["Name"].toString();
|
||||||
|
QUrl fileUrl = deburl + json["Filename"].toString();
|
||||||
|
|
||||||
|
// 软件信息加载
|
||||||
|
QString details;
|
||||||
|
details = tr("PkgName: ") + json["Pkgname"].toString()+"\n";
|
||||||
|
details += tr("Version: ") + json["Version"].toString()+"\n";
|
||||||
|
if(json["Author"].toString() != "" && json["Author"].toString() != " "){
|
||||||
|
details += tr("Author: ") + json["Author"].toString() + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["Website"].toString() != "" && json["Website"].toString() != " "){
|
||||||
|
details += tr("Official Site: ") + json["Website"].toString() + "\n";
|
||||||
|
//ui->pushButton_website->show(); move to setinfo slot
|
||||||
|
appweb=json["Website"].toString();
|
||||||
|
}
|
||||||
|
details+=tr("Contributor: ")+json["Contributor"].toString()+"\n";
|
||||||
|
details+=tr("Update Time: ")+json["Update"].toString()+"\n";
|
||||||
|
details+=tr("Installed Size: ")+json["Size"].toString()+"\n";
|
||||||
|
more = json["More"].toString();
|
||||||
|
|
||||||
|
QProcess isInstall;
|
||||||
|
packagename = json["Pkgname"].toString();
|
||||||
|
isInstall.start("dpkg -s "+json["Pkgname"].toString());
|
||||||
|
isInstall.waitForFinished();
|
||||||
|
int error=QString::fromStdString(isInstall.readAllStandardError().toStdString()).length();
|
||||||
|
if(error==0)
|
||||||
|
isInstalled = true;
|
||||||
|
else
|
||||||
|
isInstalled = false;
|
||||||
|
|
||||||
|
emit requestSetAppInformation(&appName, &details, &more, &appweb, &packagename, &fileUrl, isInstalled);
|
||||||
|
|
||||||
|
//tag加载
|
||||||
|
QString tags=json["Tags"].toString();
|
||||||
|
QStringList tagList=tags.split(";");
|
||||||
|
emit requestSetTags(&tagList);
|
||||||
|
|
||||||
|
// 图标加载
|
||||||
|
httpClient->get(urladdress+"icon.png")
|
||||||
|
.onResponse([this](QByteArray imgData){
|
||||||
|
QPixmap appicon;
|
||||||
|
appicon.loadFromData(imgData);
|
||||||
|
emit finishedIconLoad(&appicon);
|
||||||
|
})
|
||||||
|
.onError([this](QString errorStr) {
|
||||||
|
Widget::sendNotification(tr("Failed to load application icon."));
|
||||||
|
})
|
||||||
|
.block()
|
||||||
|
.timeout(5 * 100)
|
||||||
|
.exec();
|
||||||
|
|
||||||
|
|
||||||
|
// 截图展示加载
|
||||||
|
QPixmap screenshotCache[5];
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
httpClient->get(urladdress+"screen_"+QString::number(i+1)+".png")
|
||||||
|
.onResponse([this, i, &screenshotCache](QByteArray imgData){
|
||||||
|
bool s = screenshotCache[i].loadFromData(imgData);
|
||||||
|
if(s){
|
||||||
|
emit finishedScreenshotLoad(&screenshotCache[i], i);
|
||||||
|
}else{
|
||||||
|
emit finishedScreenshotLoad(nullptr, i);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onError([this](QString errorStr) {
|
||||||
|
qDebug() << "截图下载失败";
|
||||||
|
// Widget::sendNotification(tr("Failed to load application screenshot."));
|
||||||
|
})
|
||||||
|
.block()
|
||||||
|
.timeout(4 * 100)
|
||||||
|
.exec();
|
||||||
|
}
|
||||||
|
emit finishAllLoading();
|
||||||
|
|
||||||
|
httpClient->deleteLater();
|
||||||
|
})
|
||||||
|
.onError([](QString errorStr) {
|
||||||
|
Widget::sendNotification(tr("Failed to download app info. Please check internet connection."));
|
||||||
|
})
|
||||||
|
.timeout(5 * 100)
|
||||||
|
.block()
|
||||||
|
.exec();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpkAppInfoLoaderThread::setUrl(const QUrl &url)
|
void SpkAppInfoLoaderThread::setUrl(const QUrl &url)
|
||||||
{
|
{
|
||||||
targetUrl = url;
|
targetUrl = url;
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
|
|
||||||
|
namespace AeaQt {
|
||||||
|
class HttpClient;
|
||||||
|
}
|
||||||
|
|
||||||
class SpkAppInfoLoaderThread Q_DECL_FINAL : public QThread
|
class SpkAppInfoLoaderThread Q_DECL_FINAL : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -31,6 +36,8 @@ private:
|
|||||||
QString serverUrl;
|
QString serverUrl;
|
||||||
bool finishedDownload = false;
|
bool finishedDownload = false;
|
||||||
int downloaderRetval = 0;
|
int downloaderRetval = 0;
|
||||||
|
|
||||||
|
AeaQt::HttpClient *httpClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WORKERTHREADS_H
|
#endif // WORKERTHREADS_H
|
||||||
|
BIN
translations/spark-store_en.qm
Normal file
BIN
translations/spark-store_en.qm
Normal file
Binary file not shown.
@ -28,47 +28,47 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>SpkAppInfoLoaderThread</name>
|
<name>SpkAppInfoLoaderThread</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="25"/>
|
<location filename="../src/workerthreads.cpp" line="117"/>
|
||||||
<source>Failed to download app info. Please check internet connection.</source>
|
<source>Failed to download app info. Please check internet connection.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="53"/>
|
<location filename="../src/workerthreads.cpp" line="44"/>
|
||||||
<source>PkgName: </source>
|
<source>PkgName: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="54"/>
|
<location filename="../src/workerthreads.cpp" line="45"/>
|
||||||
<source>Version: </source>
|
<source>Version: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="56"/>
|
<location filename="../src/workerthreads.cpp" line="47"/>
|
||||||
<source>Author: </source>
|
<source>Author: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="60"/>
|
<location filename="../src/workerthreads.cpp" line="51"/>
|
||||||
<source>Official Site: </source>
|
<source>Official Site: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="64"/>
|
<location filename="../src/workerthreads.cpp" line="55"/>
|
||||||
<source>Contributor: </source>
|
<source>Contributor: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="65"/>
|
<location filename="../src/workerthreads.cpp" line="56"/>
|
||||||
<source>Update Time: </source>
|
<source>Update Time: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="66"/>
|
<location filename="../src/workerthreads.cpp" line="57"/>
|
||||||
<source>Installed Size: </source>
|
<source>Installed Size: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="95"/>
|
<location filename="../src/workerthreads.cpp" line="85"/>
|
||||||
<source>Failed to load application icon.</source>
|
<source>Failed to load application icon.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
@ -127,8 +127,7 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.ui" line="547"/>
|
<location filename="../src/widget.ui" line="547"/>
|
||||||
<location filename="../src/widget.cpp" line="602"/>
|
<location filename="../src/widget.cpp" line="772"/>
|
||||||
<location filename="../src/widget.cpp" line="901"/>
|
|
||||||
<source>Install</source>
|
<source>Install</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
@ -411,128 +410,82 @@
|
|||||||
<translation type="unfinished">0B</translation>
|
<translation type="unfinished">0B</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="165"/>
|
<location filename="../src/widget.cpp" line="172"/>
|
||||||
<source>Spark Store</source>
|
<source>Spark Store</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="166"/>
|
<location filename="../src/widget.cpp" line="173"/>
|
||||||
<source>Search or enter spk://</source>
|
<source>Search or enter spk://</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="172"/>
|
<location filename="../src/widget.cpp" line="179"/>
|
||||||
<source>Submit App</source>
|
<source>Submit App</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="173"/>
|
<location filename="../src/widget.cpp" line="180"/>
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="275"/>
|
<location filename="../src/widget.cpp" line="295"/>
|
||||||
<source>Not Exist</source>
|
<source>Not Exist</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="121"/>
|
<location filename="../src/widget.cpp" line="127"/>
|
||||||
<location filename="../src/widget.cpp" line="329"/>
|
<location filename="../src/widget.cpp" line="349"/>
|
||||||
<location filename="../src/widget.cpp" line="333"/>
|
<location filename="../src/widget.cpp" line="353"/>
|
||||||
<location filename="../src/widget.cpp" line="342"/>
|
<location filename="../src/widget.cpp" line="362"/>
|
||||||
<location filename="../src/widget.cpp" line="346"/>
|
<location filename="../src/widget.cpp" line="366"/>
|
||||||
<source>Spark\ Store</source>
|
<source>Spark\ Store</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="546"/>
|
<location filename="../src/widget.cpp" line="563"/>
|
||||||
<source>Failed to download app info. Please check internet connection.</source>
|
<location filename="../src/widget.cpp" line="769"/>
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="576"/>
|
|
||||||
<source>PkgName: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="577"/>
|
|
||||||
<source>Version: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="579"/>
|
|
||||||
<source>Author: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="583"/>
|
|
||||||
<source>Official Site: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="587"/>
|
|
||||||
<source>Contributor: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="588"/>
|
|
||||||
<source>Update Time: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="589"/>
|
|
||||||
<source>Installed Size: </source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="598"/>
|
|
||||||
<location filename="../src/widget.cpp" line="709"/>
|
|
||||||
<location filename="../src/widget.cpp" line="898"/>
|
|
||||||
<source>Reinstall</source>
|
<source>Reinstall</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="637"/>
|
<location filename="../src/widget.cpp" line="536"/>
|
||||||
<source>Failed to load application icon.</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../src/widget.cpp" line="684"/>
|
|
||||||
<source>Failed to get the name to the file to be downloaded.</source>
|
<source>Failed to get the name to the file to be downloaded.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1047"/>
|
<location filename="../src/widget.cpp" line="919"/>
|
||||||
<source>Updating, please wait...</source>
|
<source>Updating, please wait...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1100"/>
|
<location filename="../src/widget.cpp" line="972"/>
|
||||||
<source>Apt has reported an error. Please use apt update in terminal to locate the problem.</source>
|
<source>Apt has reported an error. Please use apt update in terminal to locate the problem.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1106"/>
|
<location filename="../src/widget.cpp" line="978"/>
|
||||||
<source>Unknown error!</source>
|
<source>Unknown error!</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1289"/>
|
<location filename="../src/widget.cpp" line="1164"/>
|
||||||
<source>Yes</source>
|
<source>Yes</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1289"/>
|
<location filename="../src/widget.cpp" line="1164"/>
|
||||||
<source>No</source>
|
<source>No</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1290"/>
|
<location filename="../src/widget.cpp" line="1165"/>
|
||||||
<source>Information for Contributors</source>
|
<source>Information for Contributors</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1291"/>
|
<location filename="../src/widget.cpp" line="1166"/>
|
||||||
<source>Currently the translation contribution is limited to English,
|
<source>Currently the translation contribution is limited to English,
|
||||||
and you will be redirected to our Gitee repository at which you are
|
and you will be redirected to our Gitee repository at which you are
|
||||||
supposed to be creating pull requests to contribute app info
|
supposed to be creating pull requests to contribute app info
|
||||||
@ -543,27 +496,27 @@ Click yes to continue.</source>
|
|||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1126"/>
|
<location filename="../src/widget.cpp" line="998"/>
|
||||||
<source>Uninstall succeeded</source>
|
<source>Uninstall succeeded</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="749"/>
|
<location filename="../src/widget.cpp" line="607"/>
|
||||||
<source>Relative apps Not Found!</source>
|
<source>Relative apps Not Found!</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="757"/>
|
<location filename="../src/widget.cpp" line="615"/>
|
||||||
<source>Request Error: %1</source>
|
<source>Request Error: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1140"/>
|
<location filename="../src/widget.cpp" line="1012"/>
|
||||||
<source>Temporary cache was cleaned</source>
|
<source>Temporary cache was cleaned</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1208"/>
|
<location filename="../src/widget.cpp" line="1081"/>
|
||||||
<source>The URL has been copied to the clipboard</source>
|
<source>The URL has been copied to the clipboard</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
BIN
translations/spark-store_zh_CN.qm
Normal file
BIN
translations/spark-store_zh_CN.qm
Normal file
Binary file not shown.
@ -48,47 +48,47 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>SpkAppInfoLoaderThread</name>
|
<name>SpkAppInfoLoaderThread</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="25"/>
|
<location filename="../src/workerthreads.cpp" line="117"/>
|
||||||
<source>Failed to download app info. Please check internet connection.</source>
|
<source>Failed to download app info. Please check internet connection.</source>
|
||||||
<translation>下载应用程序详细信息失败,请检查网络连接。</translation>
|
<translation>下载应用程序详细信息失败,请检查网络连接。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="53"/>
|
<location filename="../src/workerthreads.cpp" line="44"/>
|
||||||
<source>PkgName: </source>
|
<source>PkgName: </source>
|
||||||
<translation>包名: </translation>
|
<translation>包名: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="54"/>
|
<location filename="../src/workerthreads.cpp" line="45"/>
|
||||||
<source>Version: </source>
|
<source>Version: </source>
|
||||||
<translation>版本: </translation>
|
<translation>版本: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="56"/>
|
<location filename="../src/workerthreads.cpp" line="47"/>
|
||||||
<source>Author: </source>
|
<source>Author: </source>
|
||||||
<translation>作者: </translation>
|
<translation>作者: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="60"/>
|
<location filename="../src/workerthreads.cpp" line="51"/>
|
||||||
<source>Official Site: </source>
|
<source>Official Site: </source>
|
||||||
<translation>官网: </translation>
|
<translation>官网: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="64"/>
|
<location filename="../src/workerthreads.cpp" line="55"/>
|
||||||
<source>Contributor: </source>
|
<source>Contributor: </source>
|
||||||
<translation>投稿者: </translation>
|
<translation>投稿者: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="65"/>
|
<location filename="../src/workerthreads.cpp" line="56"/>
|
||||||
<source>Update Time: </source>
|
<source>Update Time: </source>
|
||||||
<translation>更新时间: </translation>
|
<translation>更新时间: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="66"/>
|
<location filename="../src/workerthreads.cpp" line="57"/>
|
||||||
<source>Installed Size: </source>
|
<source>Installed Size: </source>
|
||||||
<translation>大小: </translation>
|
<translation>大小: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/workerthreads.cpp" line="95"/>
|
<location filename="../src/workerthreads.cpp" line="85"/>
|
||||||
<source>Failed to load application icon.</source>
|
<source>Failed to load application icon.</source>
|
||||||
<translation>加载应用程序图标失败。</translation>
|
<translation>加载应用程序图标失败。</translation>
|
||||||
</message>
|
</message>
|
||||||
@ -190,8 +190,7 @@
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.ui" line="547"/>
|
<location filename="../src/widget.ui" line="547"/>
|
||||||
<location filename="../src/widget.cpp" line="602"/>
|
<location filename="../src/widget.cpp" line="772"/>
|
||||||
<location filename="../src/widget.cpp" line="901"/>
|
|
||||||
<source>Install</source>
|
<source>Install</source>
|
||||||
<translation>安装</translation>
|
<translation>安装</translation>
|
||||||
</message>
|
</message>
|
||||||
@ -471,103 +470,93 @@
|
|||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="165"/>
|
<location filename="../src/widget.cpp" line="172"/>
|
||||||
<source>Spark Store</source>
|
<source>Spark Store</source>
|
||||||
<translation>Spark 应用商店</translation>
|
<translation>Spark 应用商店</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="166"/>
|
<location filename="../src/widget.cpp" line="173"/>
|
||||||
<source>Search or enter spk://</source>
|
<source>Search or enter spk://</source>
|
||||||
<translation>搜索或打开链接</translation>
|
<translation>搜索或打开链接</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="172"/>
|
<location filename="../src/widget.cpp" line="179"/>
|
||||||
<source>Submit App</source>
|
<source>Submit App</source>
|
||||||
<translation>投递应用</translation>
|
<translation>投递应用</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="173"/>
|
<location filename="../src/widget.cpp" line="180"/>
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation>设置</translation>
|
<translation>设置</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="275"/>
|
<location filename="../src/widget.cpp" line="295"/>
|
||||||
<source>Not Exist</source>
|
<source>Not Exist</source>
|
||||||
<translation>不存在</translation>
|
<translation>不存在</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="121"/>
|
<location filename="../src/widget.cpp" line="127"/>
|
||||||
<location filename="../src/widget.cpp" line="329"/>
|
<location filename="../src/widget.cpp" line="349"/>
|
||||||
<location filename="../src/widget.cpp" line="333"/>
|
<location filename="../src/widget.cpp" line="353"/>
|
||||||
<location filename="../src/widget.cpp" line="342"/>
|
<location filename="../src/widget.cpp" line="362"/>
|
||||||
<location filename="../src/widget.cpp" line="346"/>
|
<location filename="../src/widget.cpp" line="366"/>
|
||||||
<source>Spark\ Store</source>
|
<source>Spark\ Store</source>
|
||||||
<translation>星火应用商店</translation>
|
<translation>星火应用商店</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="546"/>
|
|
||||||
<source>Failed to download app info. Please check internet connection.</source>
|
<source>Failed to download app info. Please check internet connection.</source>
|
||||||
<translation>下载应用程序详细信息失败,请检查网络连接。</translation>
|
<translation type="vanished">下载应用程序详细信息失败,请检查网络连接。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="576"/>
|
|
||||||
<source>PkgName: </source>
|
<source>PkgName: </source>
|
||||||
<translation>包名: </translation>
|
<translation type="vanished">包名: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="577"/>
|
|
||||||
<source>Version: </source>
|
<source>Version: </source>
|
||||||
<translation>版本: </translation>
|
<translation type="vanished">版本: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="579"/>
|
|
||||||
<source>Author: </source>
|
<source>Author: </source>
|
||||||
<translation>作者: </translation>
|
<translation type="vanished">作者: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="583"/>
|
|
||||||
<source>Official Site: </source>
|
<source>Official Site: </source>
|
||||||
<translation>官网: </translation>
|
<translation type="vanished">官网: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="587"/>
|
|
||||||
<source>Contributor: </source>
|
<source>Contributor: </source>
|
||||||
<translation>投稿者: </translation>
|
<translation type="vanished">投稿者: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="588"/>
|
|
||||||
<source>Update Time: </source>
|
<source>Update Time: </source>
|
||||||
<translation>更新时间: </translation>
|
<translation type="vanished">更新时间: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="589"/>
|
|
||||||
<source>Installed Size: </source>
|
<source>Installed Size: </source>
|
||||||
<translation>大小: </translation>
|
<translation type="vanished">大小: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="598"/>
|
<location filename="../src/widget.cpp" line="563"/>
|
||||||
<location filename="../src/widget.cpp" line="709"/>
|
<location filename="../src/widget.cpp" line="769"/>
|
||||||
<location filename="../src/widget.cpp" line="898"/>
|
|
||||||
<source>Reinstall</source>
|
<source>Reinstall</source>
|
||||||
<translation>重新安装</translation>
|
<translation>重新安装</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="637"/>
|
|
||||||
<source>Failed to load application icon.</source>
|
<source>Failed to load application icon.</source>
|
||||||
<translation>加载应用程序图标失败。</translation>
|
<translation type="vanished">加载应用程序图标失败。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="684"/>
|
<location filename="../src/widget.cpp" line="536"/>
|
||||||
<source>Failed to get the name to the file to be downloaded.</source>
|
<source>Failed to get the name to the file to be downloaded.</source>
|
||||||
<translation>获取安装包文件名失败。</translation>
|
<translation>获取安装包文件名失败。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="749"/>
|
<location filename="../src/widget.cpp" line="607"/>
|
||||||
<source>Relative apps Not Found!</source>
|
<source>Relative apps Not Found!</source>
|
||||||
<translation>相关应用未找到!</translation>
|
<translation>相关应用未找到!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="757"/>
|
<location filename="../src/widget.cpp" line="615"/>
|
||||||
<source>Request Error: %1</source>
|
<source>Request Error: %1</source>
|
||||||
<translation>请求错误:%1</translation>
|
<translation>请求错误:%1</translation>
|
||||||
</message>
|
</message>
|
||||||
@ -576,37 +565,37 @@
|
|||||||
<translation type="vanished">目前仅支持商店专用链接的打开,搜索功能正在开发,请期待以后的版本!</translation>
|
<translation type="vanished">目前仅支持商店专用链接的打开,搜索功能正在开发,请期待以后的版本!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1047"/>
|
<location filename="../src/widget.cpp" line="919"/>
|
||||||
<source>Updating, please wait...</source>
|
<source>Updating, please wait...</source>
|
||||||
<translation>正在更新,请稍候……</translation>
|
<translation>正在更新,请稍候……</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1100"/>
|
<location filename="../src/widget.cpp" line="972"/>
|
||||||
<source>Apt has reported an error. Please use apt update in terminal to locate the problem.</source>
|
<source>Apt has reported an error. Please use apt update in terminal to locate the problem.</source>
|
||||||
<translation>更新中发生错误,请在终端使用apt update来查看错误原因。</translation>
|
<translation>更新中发生错误,请在终端使用apt update来查看错误原因。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1106"/>
|
<location filename="../src/widget.cpp" line="978"/>
|
||||||
<source>Unknown error!</source>
|
<source>Unknown error!</source>
|
||||||
<translation>未知错误!</translation>
|
<translation>未知错误!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1289"/>
|
<location filename="../src/widget.cpp" line="1164"/>
|
||||||
<source>Yes</source>
|
<source>Yes</source>
|
||||||
<translation>是</translation>
|
<translation>是</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1289"/>
|
<location filename="../src/widget.cpp" line="1164"/>
|
||||||
<source>No</source>
|
<source>No</source>
|
||||||
<translation>否</translation>
|
<translation>否</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1290"/>
|
<location filename="../src/widget.cpp" line="1165"/>
|
||||||
<source>Information for Contributors</source>
|
<source>Information for Contributors</source>
|
||||||
<translation>贡献者须知</translation>
|
<translation>贡献者须知</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1291"/>
|
<location filename="../src/widget.cpp" line="1166"/>
|
||||||
<source>Currently the translation contribution is limited to English,
|
<source>Currently the translation contribution is limited to English,
|
||||||
and you will be redirected to our Gitee repository at which you are
|
and you will be redirected to our Gitee repository at which you are
|
||||||
supposed to be creating pull requests to contribute app info
|
supposed to be creating pull requests to contribute app info
|
||||||
@ -642,17 +631,17 @@ Click yes to continue.</source>
|
|||||||
<translation type="vanished">服务器未知错误</translation>
|
<translation type="vanished">服务器未知错误</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1126"/>
|
<location filename="../src/widget.cpp" line="998"/>
|
||||||
<source>Uninstall succeeded</source>
|
<source>Uninstall succeeded</source>
|
||||||
<translation>卸载成功</translation>
|
<translation>卸载成功</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1140"/>
|
<location filename="../src/widget.cpp" line="1012"/>
|
||||||
<source>Temporary cache was cleaned</source>
|
<source>Temporary cache was cleaned</source>
|
||||||
<translation>缓存目录已清空</translation>
|
<translation>缓存目录已清空</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/widget.cpp" line="1208"/>
|
<location filename="../src/widget.cpp" line="1081"/>
|
||||||
<source>The URL has been copied to the clipboard</source>
|
<source>The URL has been copied to the clipboard</source>
|
||||||
<translation>链接已复制到剪贴板</translation>
|
<translation>链接已复制到剪贴板</translation>
|
||||||
</message>
|
</message>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user