From d06219002e7d0b77d3a685018e08c0857f88237d Mon Sep 17 00:00:00 2001
From: Akira Ohgaki <akiraohgaki@gmail.com>
Date: Tue, 19 Dec 2017 08:52:42 +0900
Subject: [PATCH] Use AppImageUpdater class

---
 app/src/handlers/updatehandler.cpp | 142 +++++++++++++----------------
 app/src/handlers/updatehandler.h   |  23 +++--
 2 files changed, 79 insertions(+), 86 deletions(-)

diff --git a/app/src/handlers/updatehandler.cpp b/app/src/handlers/updatehandler.cpp
index 8728458..d1e11c2 100644
--- a/app/src/handlers/updatehandler.cpp
+++ b/app/src/handlers/updatehandler.cpp
@@ -3,27 +3,22 @@
 #include <QStringList>
 #include <QJsonValue>
 #include <QJsonArray>
-#include <QJsonObject>
 #include <QDateTime>
-#include <QThread>
-#include <QDebug>
-
-#ifdef QTLIB_UNIX
-#include "appimage/update.h"
-#endif
 
 #include "qtlib_file.h"
 
 #include "handlers/confighandler.h"
 
+#ifdef QTLIB_UNIX
+#include "updaters/appimageupdater.h"
+#endif
+
 UpdateHandler::UpdateHandler(ConfigHandler *configHandler, QObject *parent)
     : QObject(parent), configHandler_(configHandler)
 {}
 
 void UpdateHandler::checkAll()
 {
-    emit checkAllStarted();
-
     // Resets data
     QJsonObject updateAvailableItems;
     configHandler_->setUsrConfigUpdateAvailableItems(updateAvailableItems);
@@ -31,32 +26,34 @@ void UpdateHandler::checkAll()
     auto installedItems = configHandler_->getUsrConfigInstalledItems();
 
     if (installedItems.isEmpty()) {
-        emit checkAllFinished();
+        emit checkAllStarted(false);
         return;
     }
 
+    emit checkAllStarted(true);
+
     for (const auto &itemKey : installedItems.keys()) {
         auto installedItem = installedItems[itemKey].toObject();
         auto filename = installedItem["filename"].toString();
         auto installType = installedItem["install_type"].toString();
 
-        qtlib::File file;
+        QString filePath = "";
 #ifdef QTLIB_UNIX
-        file.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename);
+        filePath = configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename;
 #else
-        file.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString() + "/" + filename);
+        filePath = configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString() + "/" + filename;
 #endif
 
         QString updateMethod = "";
 
         if (installType == "bin") {
 #ifdef QTLIB_UNIX
-            if (file.path().endsWith(".appimage", Qt::CaseInsensitive)) {
-                if (checkAppImage(file.path())) {
+            if (filePath.endsWith(".appimage", Qt::CaseInsensitive)) {
+                if (AppImageUpdater(itemKey, filePath).checkAppImage()) {
                     updateMethod = "appimageupdate";
                 }
-                //else if (checkAppImageWithOcsApi(itemKey)) {
-                //    updateMethod = "appimageupdatewithocsapi";
+                //else if (OcsFileUpdater(url).checkFile()) {
+                //    updateMethod = "appimageupdate_ocs";
                 //}
             }
 #endif
@@ -75,7 +72,7 @@ void UpdateHandler::checkAll()
     application["update_checked_at"] = QDateTime::currentMSecsSinceEpoch();
     configHandler_->setUsrConfigApplication(application);
 
-    emit checkAllFinished();
+    emit checkAllFinished(true);
 }
 
 void UpdateHandler::update(const QString &itemKey)
@@ -83,6 +80,7 @@ void UpdateHandler::update(const QString &itemKey)
     auto updateAvailableItems = configHandler_->getUsrConfigUpdateAvailableItems();
 
     if (!updateAvailableItems.contains(itemKey)) {
+        emit updateStarted(itemKey, false);
         return;
     }
 
@@ -92,34 +90,49 @@ void UpdateHandler::update(const QString &itemKey)
     if (updateMethod == "appimageupdate") {
         updateAppImage(itemKey);
     }
-    //else if (updateMethod == "appimageupdatewithocsapi") {
-    //    updateAppImageWithOcsApi(itemKey);
+    //else if (updateMethod == "appimageupdate_ocs") {
+    //    updateAppImageOcs(itemKey);
     //}
 #endif
 }
 
 #ifdef QTLIB_UNIX
-QString UpdateHandler::describeAppImage(const QString &path) const
+void UpdateHandler::appImageUpdaterFinished(AppImageUpdater *updater)
 {
-    appimage::update::Updater appImageUpdater(path.toStdString());
-    QString updateInformation;
-    std::string description;
-    if (appImageUpdater.describeAppImage(description)) {
-        updateInformation = QString::fromStdString(description);
+    auto itemKey = updater->id();
+
+    auto metadata = metadataSet_[itemKey].toObject();
+    metadataSet_.remove(itemKey);
+
+    if (!updater->isFinishedWithNoError()) {
+        emit updateFinished(itemKey, false);
+        return;
     }
-    return updateInformation;
-}
 
-bool UpdateHandler::checkAppImage(const QString &path) const
-{
-    appimage::update::Updater appImageUpdater(path.toStdString());
-    bool updateAvailable;
-    if (appImageUpdater.checkForChanges(updateAvailable)) {
-        return updateAvailable;
+    auto installedItemKey = metadata["installed_item_key"].toString();
+    auto installedItem = metadata["installed_item_obj"].toObject();
+    auto newFilename = metadata["new_filename"].toString();
+    auto filename = installedItem["filename"].toString();
+
+    installedItem["filename"] = newFilename;
+    QJsonArray files;
+    files.append(QJsonValue(newFilename));
+    installedItem["files"] = files;
+    installedItem["installed_at"] = QDateTime::currentMSecsSinceEpoch();
+
+    configHandler_->setUsrConfigInstalledItemsItem(installedItemKey, installedItem);
+
+    if (newFilename != filename) {
+        qtlib::File(updater->path()).remove();
     }
-    return false;
+
+    configHandler_->removeUsrConfigUpdateAvailableItemsItem(itemKey);
+
+    emit updateFinished(itemKey, true);
 }
+#endif
 
+#ifdef QTLIB_UNIX
 void UpdateHandler::updateAppImage(const QString &itemKey)
 {
     auto updateAvailableItem = configHandler_->getUsrConfigUpdateAvailableItems()[itemKey].toObject();
@@ -127,6 +140,7 @@ void UpdateHandler::updateAppImage(const QString &itemKey)
     auto installedItems = configHandler_->getUsrConfigInstalledItems();
 
     if (!installedItems.contains(installedItemKey)) {
+        emit updateStarted(itemKey, false);
         return;
     }
 
@@ -134,57 +148,27 @@ void UpdateHandler::updateAppImage(const QString &itemKey)
     auto filename = installedItem["filename"].toString();
     auto installType = installedItem["install_type"].toString();
 
-    qtlib::File file(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename);
+    auto filePath = configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename;
+    auto *updater = new AppImageUpdater(itemKey, filePath, this);
+    connect(updater, &AppImageUpdater::updateProgress, this, &UpdateHandler::updateProgress);
+    connect(updater, &AppImageUpdater::finished, this, &UpdateHandler::appImageUpdaterFinished);
+
+    QJsonObject metadata;
+    metadata["installed_item_key"] = installedItemKey;
+    metadata["installed_item_obj"] = installedItem;
+    metadata["new_filename"] = filename;
 
-    auto newFilename = filename;
-    auto updateInformation = describeAppImage(file.path());
+    auto updateInformation = updater->describeAppImage();
     for (const auto &info : updateInformation.split("\n")) {
         if (info.endsWith(".zsync", Qt::CaseInsensitive)) {
-            newFilename = info.split("|").last().split("/").last().replace(".zsync", "", Qt::CaseInsensitive);
+            metadata["new_filename"] = info.split("|").last().split("/").last().replace(".zsync", "", Qt::CaseInsensitive);
             break;
         }
     }
 
-    appimage::update::Updater appImageUpdater(file.path().toStdString(), false);
-
-    if (!appImageUpdater.start()) {
-        return;
-    }
-
-    emit updateStarted(itemKey);
-
-    while (!appImageUpdater.isDone()) {
-        QThread::msleep(100);
-        double progress;
-        if (appImageUpdater.progress(progress)) {
-            emit updateProgress(itemKey, progress * 100);
-        }
-    }
-
-    if (appImageUpdater.hasError()) {
-        std::string nextMessage;
-        while (appImageUpdater.nextStatusMessage(nextMessage)) {
-            qWarning() << QString::fromStdString(nextMessage);
-        }
-
-        emit updateFinished(itemKey);
-        return;
-    }
-
-    installedItem["filename"] = newFilename;
-    QJsonArray files;
-    files.append(QJsonValue(newFilename));
-    installedItem["files"] = files;
-    installedItem["installed_at"] = QDateTime::currentMSecsSinceEpoch();
-
-    configHandler_->setUsrConfigInstalledItemsItem(installedItemKey, installedItem);
-
-    if (newFilename != filename) {
-        file.remove();
-    }
-
-    configHandler_->removeUsrConfigUpdateAvailableItemsItem(itemKey);
+    metadataSet_[itemKey] = metadata;
 
-    emit updateFinished(itemKey);
+    emit updateStarted(itemKey, true);
+    updater->updateAppImage();
 }
 #endif
diff --git a/app/src/handlers/updatehandler.h b/app/src/handlers/updatehandler.h
index 7c6e851..813608f 100644
--- a/app/src/handlers/updatehandler.h
+++ b/app/src/handlers/updatehandler.h
@@ -1,9 +1,14 @@
 #pragma once
 
 #include <QObject>
+#include <QJsonObject>
 
 class ConfigHandler;
 
+#ifdef QTLIB_UNIX
+class AppImageUpdater;
+#endif
+
 class UpdateHandler : public QObject
 {
     Q_OBJECT
@@ -12,22 +17,26 @@ public:
     explicit UpdateHandler(ConfigHandler *configHandler, QObject *parent = nullptr);
 
 signals:
-    void checkAllStarted();
-    void checkAllFinished();
-    void updateStarted(QString itemKey);
-    void updateFinished(QString itemKey);
-    void updateProgress(QString itemKey, int progress);
+    void checkAllStarted(bool status);
+    void checkAllFinished(bool status);
+    void updateStarted(QString itemKey, bool status);
+    void updateFinished(QString itemKey, bool status);
+    void updateProgress(QString itemKey, double progress);
 
 public slots:
     void checkAll();
     void update(const QString &itemKey);
 
+private slots:
+#ifdef QTLIB_UNIX
+    void appImageUpdaterFinished(AppImageUpdater *updater);
+#endif
+
 private:
 #ifdef QTLIB_UNIX
-    QString describeAppImage(const QString &path) const;
-    bool checkAppImage(const QString &path) const;
     void updateAppImage(const QString &itemKey);
 #endif
 
     ConfigHandler *configHandler_;
+    QJsonObject metadataSet_;
 };
-- 
GitLab