Skip to content
Snippets Groups Projects
updatehandler.cpp 5.75 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "updatehandler.h"
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include <QStringList>
    #include <QJsonValue>
    #include <QJsonArray>
    #include <QJsonObject>
    #include <QDateTime>
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include <QThread>
    #include <QDebug>
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    #ifdef QTLIB_UNIX
    #include "appimage/update.h"
    #endif
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include "qtlib_file.h"
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    #include "handlers/confighandler.h"
    
    
    UpdateHandler::UpdateHandler(ConfigHandler *configHandler, QObject *parent)
    
    akiraohgaki's avatar
    akiraohgaki committed
        : QObject(parent), configHandler_(configHandler)
    {}
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    void UpdateHandler::checkAll()
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        emit checkAllStarted();
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        // Resets data
    
    akiraohgaki's avatar
    akiraohgaki committed
        QJsonObject updateAvailableItems;
    
    akiraohgaki's avatar
    akiraohgaki committed
        configHandler_->setUsrConfigUpdateAvailableItems(updateAvailableItems);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto installedItems = configHandler_->getUsrConfigInstalledItems();
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (installedItems.isEmpty()) {
            emit checkAllFinished();
            return;
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
        for (const auto &itemKey : installedItems.keys()) {
            auto installedItem = installedItems[itemKey].toObject();
    
    akiraohgaki's avatar
    akiraohgaki committed
            auto filename = installedItem["filename"].toString();
    
    akiraohgaki's avatar
    akiraohgaki committed
            auto installType = installedItem["install_type"].toString();
    
    
    akiraohgaki's avatar
    akiraohgaki committed
            qtlib::File file;
    
    akiraohgaki's avatar
    akiraohgaki committed
    #ifdef QTLIB_UNIX
    
    akiraohgaki's avatar
    akiraohgaki committed
            file.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename);
    
    akiraohgaki's avatar
    akiraohgaki committed
    #else
    
    akiraohgaki's avatar
    akiraohgaki committed
            file.setPath(configHandler_->getAppConfigInstallTypes()[installType].toObject()["generic_destination"].toString() + "/" + filename);
    
    akiraohgaki's avatar
    akiraohgaki committed
    #endif
    
    
    akiraohgaki's avatar
    akiraohgaki committed
            QString updateMethod = "";
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
            if (installType == "bin") {
    
    akiraohgaki's avatar
    akiraohgaki committed
    #ifdef QTLIB_UNIX
    
    akiraohgaki's avatar
    akiraohgaki committed
                if (file.path().endsWith(".appimage", Qt::CaseInsensitive)) {
                    if (checkAppImage(file.path())) {
    
    akiraohgaki's avatar
    akiraohgaki committed
                        updateMethod = "appimageupdate";
    
    akiraohgaki's avatar
    akiraohgaki committed
                    }
    
    akiraohgaki's avatar
    akiraohgaki committed
                    //else if (checkAppImageWithOcsApi(itemKey)) {
                    //    updateMethod = "appimageupdatewithocsapi";
                    //}
    
    akiraohgaki's avatar
    akiraohgaki committed
                }
    
    akiraohgaki's avatar
    akiraohgaki committed
    #endif
    
    akiraohgaki's avatar
    akiraohgaki committed
            }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
            if (!updateMethod.isEmpty()) {
                QJsonObject updateAvailableItem;
                updateAvailableItem["installed_item"] = itemKey;
                updateAvailableItem["update_method"] = updateMethod;
                // Use installed item's key as unique key to the update available item
                configHandler_->setUsrConfigUpdateAvailableItemsItem(itemKey, updateAvailableItem);
            }
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto application = configHandler_->getUsrConfigApplication();
    
    akiraohgaki's avatar
    akiraohgaki committed
        application["update_checked_at"] = QDateTime::currentMSecsSinceEpoch();
        configHandler_->setUsrConfigApplication(application);
    
        emit checkAllFinished();
    
    akiraohgaki's avatar
    akiraohgaki committed
    void UpdateHandler::update(const QString &itemKey)
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto updateAvailableItems = configHandler_->getUsrConfigUpdateAvailableItems();
    
        if (!updateAvailableItems.contains(itemKey)) {
            return;
        }
    
        auto updateMethod = updateAvailableItems[itemKey].toObject()["update_method"].toString();
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    #ifdef QTLIB_UNIX
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (updateMethod == "appimageupdate") {
            updateAppImage(itemKey);
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        //else if (updateMethod == "appimageupdatewithocsapi") {
        //    updateAppImageWithOcsApi(itemKey);
        //}
    
    akiraohgaki's avatar
    akiraohgaki committed
    #endif
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    #ifdef QTLIB_UNIX
    
    QString UpdateHandler::describeAppImage(const QString &path) const
    {
    
    akiraohgaki's avatar
    akiraohgaki committed
        appimage::update::Updater appImageUpdater(path.toStdString());
    
        QString updateInformation;
    
    akiraohgaki's avatar
    akiraohgaki committed
        std::string description;
        if (appImageUpdater.describeAppImage(description)) {
            updateInformation = QString::fromStdString(description);
        }
        return updateInformation;
    }
    
    
    bool UpdateHandler::checkAppImage(const QString &path) const
    
    akiraohgaki's avatar
    akiraohgaki committed
    {
        appimage::update::Updater appImageUpdater(path.toStdString());
        bool updateAvailable;
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (appImageUpdater.checkForChanges(updateAvailable)) {
            return updateAvailable;
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
        return false;
    }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
    void UpdateHandler::updateAppImage(const QString &itemKey)
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto updateAvailableItem = configHandler_->getUsrConfigUpdateAvailableItems()[itemKey].toObject();
        auto installedItemKey = updateAvailableItem["installed_item"].toString();
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto installedItems = configHandler_->getUsrConfigInstalledItems();
    
    akiraohgaki's avatar
    akiraohgaki committed
    
        if (!installedItems.contains(installedItemKey)) {
            return;
        }
    
        auto installedItem = installedItems[installedItemKey].toObject();
        auto filename = installedItem["filename"].toString();
        auto installType = installedItem["install_type"].toString();
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        qtlib::File file(configHandler_->getAppConfigInstallTypes()[installType].toObject()["destination"].toString() + "/" + filename);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
        auto newFilename = filename;
    
    akiraohgaki's avatar
    akiraohgaki committed
        auto updateInformation = describeAppImage(file.path());
    
    akiraohgaki's avatar
    akiraohgaki committed
        for (const auto &info : updateInformation.split("\n")) {
            if (info.endsWith(".zsync", Qt::CaseInsensitive)) {
    
    akiraohgaki's avatar
    akiraohgaki committed
                newFilename = info.split("|").last().split("/").last().replace(".zsync", "", Qt::CaseInsensitive);
    
    akiraohgaki's avatar
    akiraohgaki committed
                break;
            }
        }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        appimage::update::Updater appImageUpdater(file.path().toStdString(), false);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (!appImageUpdater.start()) {
            return;
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        emit updateStarted(itemKey);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        while (!appImageUpdater.isDone()) {
            QThread::msleep(100);
            double progress;
            if (appImageUpdater.progress(progress)) {
                emit updateProgress(itemKey, progress * 100);
            }
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (appImageUpdater.hasError()) {
            std::string nextMessage;
            while (appImageUpdater.nextStatusMessage(nextMessage)) {
                qWarning() << QString::fromStdString(nextMessage);
    
    akiraohgaki's avatar
    akiraohgaki committed
            }
    
    
    akiraohgaki's avatar
    akiraohgaki committed
            emit updateFinished(itemKey);
            return;
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        installedItem["filename"] = newFilename;
        QJsonArray files;
        files.append(QJsonValue(newFilename));
        installedItem["files"] = files;
        installedItem["installed_at"] = QDateTime::currentMSecsSinceEpoch();
    
        configHandler_->setUsrConfigInstalledItemsItem(installedItemKey, installedItem);
    
    akiraohgaki's avatar
    akiraohgaki committed
    
    
    akiraohgaki's avatar
    akiraohgaki committed
        if (newFilename != filename) {
            file.remove();
    
    akiraohgaki's avatar
    akiraohgaki committed
        }
    
    akiraohgaki's avatar
    akiraohgaki committed
    
        configHandler_->removeUsrConfigUpdateAvailableItemsItem(itemKey);
    
        emit updateFinished(itemKey);
    
    akiraohgaki's avatar
    akiraohgaki committed
    }
    #endif