Newer
Older
#include <QJsonValue>
#include <QJsonArray>
#include <QFileInfo>
#include <QDateTime>
#ifdef QTLIB_UNIX
#include <QProcess>
#endif
#include "qtlib_dir.h"
#include "qtlib_file.h"
#include "qtlib_networkresource.h"
#include "qtlib_package.h"
#include "handlers/confighandler.h"
ItemHandler::ItemHandler(ConfigHandler *configHandler, QObject *parent)
: QObject(parent), configHandler_(configHandler)
{}
QJsonObject ItemHandler::metadataSet() const
{
return metadataSet_;
}
void ItemHandler::getItem(const QString &command, const QString &url, const QString &installType, const QString &filename,
const QString &providerKey, const QString &contentId)
{
// Use URL as unique key for metadata, network resource, and installed item
metadata["url"] = url;
metadata["install_type"] = installType;
metadata["filename"] = filename;
if (filename.isEmpty()) {
metadata["filename"] = QUrl(url).fileName();
}
metadata["provider"] = providerKey;
metadata["content_id"] = contentId;
metadata["files"] = QJsonArray();
metadata["installed_at"] = qint64();
QJsonObject result;
result["metadata"] = metadata;
if (itemMetadataSet.contains(itemKey)) {
result["status"] = QString("error_downloadstart");
result["message"] = tr("The file already downloading");
emit downloadStarted(result);
return;
}
itemMetadataSet[itemKey] = metadata;
setMetadataSet(itemMetadataSet);
auto *resource = new qtlib::NetworkResource(itemKey, QUrl(url), true, this);
connect(resource, &qtlib::NetworkResource::downloadProgress, this, &ItemHandler::downloadProgress);
connect(resource, &qtlib::NetworkResource::finished, this, &ItemHandler::networkResourceFinished);
resource->get();
result["status"] = QString("success_downloadstart");
result["message"] = tr("Downloading");
emit downloadStarted(result);
}
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
void ItemHandler::getItemByOcsUrl(const QString &ocsUrl)
{
QUrl ocsUrlObj(ocsUrl);
QUrlQuery query(ocsUrlObj);
QString scheme = "ocs";
QString command = "download";
QString url = "";
QString type = "downloads";
QString filename = "";
if (!ocsUrlObj.scheme().isEmpty()) {
scheme = ocsUrlObj.scheme();
}
if (!ocsUrlObj.host().isEmpty()) {
command = ocsUrlObj.host();
}
if (query.hasQueryItem("url") && !query.queryItemValue("url").isEmpty()) {
url = query.queryItemValue("url", QUrl::FullyDecoded);
}
if (query.hasQueryItem("type") && !query.queryItemValue("type").isEmpty()) {
type = query.queryItemValue("type", QUrl::FullyDecoded);
}
if (query.hasQueryItem("filename") && !query.queryItemValue("filename").isEmpty()) {
filename = QUrl(query.queryItemValue("filename", QUrl::FullyDecoded)).fileName();
}
if (!url.isEmpty() && filename.isEmpty()) {
filename = QUrl(url).fileName();
}
// Still support xdg and xdgs schemes for backward compatibility
if ((scheme == "ocs" || scheme == "ocss" || scheme == "xdg" || scheme == "xdgs")
&& (command == "download" || command == "install")
&& QUrl(url).isValid()
&& configHandler_->getAppConfigInstallTypes().contains(type)
&& !filename.isEmpty()) {
getItem(command, url, type, filename);
}
else {
QJsonObject result;
result["status"] = QString("error_downloadstart");
result["message"] = tr("Invalid OCS-URL");
emit downloadStarted(result);
}
}
void ItemHandler::uninstall(const QString &itemKey)
{
QJsonObject result;
result["status"] = QString("success_uninstallstart");
result["message"] = tr("Uninstalling");
emit uninstallStarted(result);
auto installedItem = configHandler_->getUsrConfigInstalledItems()[itemKey].toObject();
auto installType = installedItem["install_type"].toString();
qtlib::Dir destDir;
#ifdef QTLIB_UNIX
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
for (const auto &filename : installedItem["files"].toArray()) {
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
QFileInfo fileInfo(destDir.path() + "/" + filename.toString());
// plasmapkg: Installation process has should be saved plasmapkg into destination directory
qtlib::Package package(fileInfo.filePath());
// Uninstall
if (installType == "bin") {
if (fileInfo.filePath().endsWith(".appimage", Qt::CaseInsensitive)) {
QProcess process;
process.start(fileInfo.filePath() + " --remove-appimage-desktop-integration");
process.waitForFinished();
}
}
else if (installType == "plasma_plasmoids" || installType == "plasma4_plasmoids" || installType == "plasma5_plasmoids") {
package.uninstallAsPlasmapkg("plasmoid");
}
else if (installType == "plasma_look_and_feel" || installType == "plasma5_look_and_feel") {
package.uninstallAsPlasmapkg("lookandfeel");
}
else if (installType == "plasma_desktopthemes" || installType == "plasma5_desktopthemes") {
package.uninstallAsPlasmapkg("theme");
}
else if (installType == "kwin_effects") {
package.uninstallAsPlasmapkg("kwineffect");
}
else if (installType == "kwin_scripts") {
package.uninstallAsPlasmapkg("kwinscript");
}
else if (installType == "kwin_tabbox") {
package.uninstallAsPlasmapkg("windowswitcher");
}
// Remove file
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).remove();
}
else {
qtlib::File(fileInfo.filePath()).remove();
}
}
#else
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString());
for (const auto &filename : installedItem["files"].toArray()) {
QFileInfo fileInfo(destDir.path() + "/" + filename.toString());
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).remove();
}
else {
qtlib::File(fileInfo.filePath()).remove();
}
}
#endif
configHandler_->removeUsrConfigInstalledItemsItem(itemKey);
result["status"] = QString("success_uninstall");
result["message"] = tr("Uninstalled");
emit uninstallFinished(result);
}
void ItemHandler::networkResourceFinished(qtlib::NetworkResource *resource)
{
auto itemMetadataSet = metadataSet();
auto metadata = itemMetadataSet[itemKey].toObject();
QJsonObject result;
result["metadata"] = metadata;
if (!resource->isFinishedWithNoError()) {
itemMetadataSet.remove(itemKey);
setMetadataSet(itemMetadataSet);
result["status"] = QString("error_download");
result["message"] = resource->reply()->errorString();
emit downloadFinished(result);
resource->deleteLater();
return;
}
result["status"] = QString("success_download");
result["message"] = tr("Downloaded");
emit downloadFinished(result);
if (metadata["command"].toString() == "download") {
saveDownloadedFile(resource);
}
else if (metadata["command"].toString() == "install") {
installDownloadedFile(resource);
}
}
void ItemHandler::setMetadataSet(const QJsonObject &metadataSet)
{
metadataSet_ = metadataSet;
emit metadataSetChanged();
}
void ItemHandler::saveDownloadedFile(qtlib::NetworkResource *resource)
{
auto itemMetadataSet = metadataSet();
auto metadata = itemMetadataSet[itemKey].toObject();
itemMetadataSet.remove(itemKey);
setMetadataSet(itemMetadataSet);
QJsonObject result;
result["metadata"] = metadata;
result["status"] = QString("success_savestart");
result["message"] = tr("Saving");
emit saveStarted(result);
auto filename = metadata["filename"].toString();
auto installType = metadata["install_type"].toString();
qtlib::Dir destDir(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
destDir.make();
qtlib::File destFile(destDir.path() + "/" + filename);
if (!resource->saveData(destFile.path())) {
result["status"] = QString("error_save");
result["message"] = tr("Failed to save data");
emit saveFinished(result);
resource->deleteLater();
return;
}
result["status"] = QString("success_save");
result["message"] = tr("Saved");
emit saveFinished(result);
resource->deleteLater();
}
void ItemHandler::installDownloadedFile(qtlib::NetworkResource *resource)
auto itemMetadataSet = metadataSet();
auto metadata = itemMetadataSet[itemKey].toObject();
itemMetadataSet.remove(itemKey);
setMetadataSet(itemMetadataSet);
QJsonObject result;
result["metadata"] = metadata;
result["status"] = QString("success_savestart");
result["message"] = tr("Saving");
emit saveStarted(result);
auto filename = metadata["filename"].toString();
auto installType = metadata["install_type"].toString();
auto prefix = configHandler_->getAppConfigApplication()["id"].toString() + "_" + filename;
qtlib::Dir tempDir(qtlib::Dir::tempPath() + "/" + prefix);
tempDir.make();
qtlib::Dir tempDestDir(tempDir.path() + "/dest");
tempDestDir.make();
qtlib::Package package(tempDir.path() + "/" + filename);
if (!resource->saveData(package.path())) {
tempDir.remove();
resource->deleteLater();
return;
}
result["status"] = QString("success_save");
result["message"] = tr("Saved");
emit saveFinished(result);
result["status"] = QString("success_installstart");
result["message"] = tr("Installing");
emit installStarted(result);
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
qtlib::Dir destDir;
#ifdef QTLIB_UNIX
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString());
// plasmapkg: Need to save package to remove installed files later
if (installType == "bin"
&& package.installAsProgram(tempDestDir.path() + "/" + filename)) {
result["message"] = tr("The file has been installed as program");
}
else if ((installType == "plasma_plasmoids" || installType == "plasma4_plasmoids" || installType == "plasma5_plasmoids")
&& package.installAsPlasmapkg("plasmoid")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The plasmoid has been installed");
}
else if ((installType == "plasma_look_and_feel" || installType == "plasma5_look_and_feel")
&& package.installAsPlasmapkg("lookandfeel")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The plasma look and feel has been installed");
}
else if ((installType == "plasma_desktopthemes" || installType == "plasma5_desktopthemes")
&& package.installAsPlasmapkg("theme")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The plasma desktop theme has been installed");
}
else if (installType == "kwin_effects"
&& package.installAsPlasmapkg("kwineffect")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The KWin effect has been installed");
}
else if (installType == "kwin_scripts"
&& package.installAsPlasmapkg("kwinscript")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The KWin script has been installed");
}
else if (installType == "kwin_tabbox"
&& package.installAsPlasmapkg("windowswitcher")) {
package.installAsFile(tempDestDir.path() + "/" + filename);
result["message"] = tr("The KWin window switcher has been installed");
}
else if (package.installAsArchive(tempDestDir.path())) {
result["message"] = tr("The archive file has been extracted");
}
else if (package.installAsFile(tempDestDir.path() + "/" + filename)) {
result["message"] = tr("The file has been installed");
}
else {
result["status"] = QString("error_install");
result["message"] = tr("Failed to installation");
emit installFinished(result);
tempDir.remove();
resource->deleteLater();
return;
}
#else
destDir.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString());
if (qtlib::File(package.path()).copy(tempDestDir.path() + "/" + filename)) {
result["message"] = tr("The file has been installed");
}
else {
result["status"] = QString("error_install");
result["message"] = tr("Failed to installation");
emit installFinished(result);
tempDir.remove();
resource->deleteLater();
return;
}
#endif
destDir.make();
QJsonArray installedFiles;
installedFiles.append(QJsonValue(fileInfo.fileName()));
if (fileInfo.isDir()) {
qtlib::Dir(fileInfo.filePath()).move(destDir.path() + "/" + fileInfo.fileName());
}
else {
qtlib::File(fileInfo.filePath()).move(destDir.path() + "/" + fileInfo.fileName());
}
}
// Installation post-process
metadata["files"] = installedFiles;
metadata["installed_at"] = QDateTime::currentMSecsSinceEpoch();
configHandler_->setUsrConfigInstalledItemsItem(itemKey, metadata);
result["metadata"] = metadata;
result["status"] = QString("success_install");
emit installFinished(result);
tempDir.remove();
resource->deleteLater();
}