Skip to content
Snippets Groups Projects
ocsurlhandler.cpp 7.22 KiB
Newer Older
akiraohgaki's avatar
akiraohgaki committed
#include "ocsurlhandler.h"
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
#include <QUrlQuery>
akiraohgaki's avatar
akiraohgaki committed
#include <QDesktopServices>
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
#include "qtil_file.h"
#include "qtil_dir.h"
#include "qtil_networkresource.h"
#include "qtil_package.h"
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
#include "handlers/confighandler.h"

OcsUrlHandler::OcsUrlHandler(const QString &ocsUrl, ConfigHandler *configHandler, QObject *parent)
    : QObject(parent), ocsUrl_(ocsUrl), configHandler_(configHandler)
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    parse();
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
QString OcsUrlHandler::ocsUrl() const
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    return ocsUrl_;
akiraohgaki's avatar
akiraohgaki committed
}
akiraohgaki's avatar
akiraohgaki committed
QJsonObject OcsUrlHandler::metadata() const
akiraohgaki's avatar
akiraohgaki committed
{
    return metadata_;
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
void OcsUrlHandler::process()
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    // ocss scheme is a reserved name, so the process of ocss
    // is the same process of the ocs scheme currently.
akiraohgaki's avatar
akiraohgaki committed

    if (!isValid()) {
        QJsonObject result;
        result["status"] = QString("error_validation");
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("Invalid OCS-URL");
akiraohgaki's avatar
akiraohgaki committed
        emit finishedWithError(result);
akiraohgaki's avatar
akiraohgaki committed
        return;
    }

    auto url = metadata_["url"].toString();
akiraohgaki's avatar
akiraohgaki committed
    auto *resource = new Qtil::NetworkResource(url, QUrl(url), true, this);
    connect(resource, &Qtil::NetworkResource::downloadProgress, this, &OcsUrlHandler::downloadProgress);
    connect(resource, &Qtil::NetworkResource::finished, this, &OcsUrlHandler::networkResourceFinished);
akiraohgaki's avatar
akiraohgaki committed
    resource->get();
akiraohgaki's avatar
akiraohgaki committed
    emit started();
}

bool OcsUrlHandler::isValid() const
akiraohgaki's avatar
akiraohgaki committed
{
    QString scheme = metadata_["scheme"].toString();
    QString command = metadata_["command"].toString();
    QString url = metadata_["url"].toString();
    QString type = metadata_["type"].toString();
    QString filename = metadata_["filename"].toString();

akiraohgaki's avatar
akiraohgaki committed
    if ((scheme == "ocs" || scheme == "ocss")
akiraohgaki's avatar
akiraohgaki committed
            && (command == "download" || command == "install")
            && QUrl(url).isValid()
akiraohgaki's avatar
akiraohgaki committed
            && configHandler_->getAppConfigInstallTypes().contains(type)
akiraohgaki's avatar
akiraohgaki committed
            && !filename.isEmpty()) {
        return true;
    }
    return false;
}

void OcsUrlHandler::openDestination() const
akiraohgaki's avatar
akiraohgaki committed
{
    auto type = metadata_["type"].toString();
akiraohgaki's avatar
akiraohgaki committed
    QDesktopServices::openUrl(QUrl("file://" + configHandler_->getAppConfigInstallTypes()[type].toObject()["destination"].toString()));
akiraohgaki's avatar
akiraohgaki committed
}

akiraohgaki's avatar
akiraohgaki committed
void OcsUrlHandler::networkResourceFinished(Qtil::NetworkResource *resource)
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    if (!resource->isFinishedWithNoError()) {
akiraohgaki's avatar
akiraohgaki committed
        QJsonObject result;
        result["status"] = QString("error_network");
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = resource->reply()->errorString();
akiraohgaki's avatar
akiraohgaki committed
        emit finishedWithError(result);
akiraohgaki's avatar
akiraohgaki committed
        resource->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
        return;
    }

    if (metadata_["command"].toString() == "download") {
akiraohgaki's avatar
akiraohgaki committed
        saveDownloadedFile(resource);
akiraohgaki's avatar
akiraohgaki committed
    }
    else if (metadata_["command"].toString() == "install") {
akiraohgaki's avatar
akiraohgaki committed
        installDownloadedFile(resource);
akiraohgaki's avatar
akiraohgaki committed
    }
}

akiraohgaki's avatar
akiraohgaki committed
void OcsUrlHandler::parse()
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    QUrl url(ocsUrl_);
akiraohgaki's avatar
akiraohgaki committed
    QUrlQuery query(url);

akiraohgaki's avatar
akiraohgaki committed
    metadata_["scheme"] = QString("ocs");
akiraohgaki's avatar
akiraohgaki committed
    metadata_["command"] = QString("download");
    metadata_["url"] = QString("");
    metadata_["type"] = QString("downloads");
    metadata_["filename"] = QString("");
akiraohgaki's avatar
akiraohgaki committed

    if (!url.scheme().isEmpty()) {
akiraohgaki's avatar
akiraohgaki committed
        metadata_["scheme"] = url.scheme();
akiraohgaki's avatar
akiraohgaki committed
    }

    if (!url.host().isEmpty()) {
akiraohgaki's avatar
akiraohgaki committed
        metadata_["command"] = url.host();
akiraohgaki's avatar
akiraohgaki committed
    }

    if (query.hasQueryItem("url") && !query.queryItemValue("url").isEmpty()) {
akiraohgaki's avatar
akiraohgaki committed
        metadata_["url"] = query.queryItemValue("url", QUrl::FullyDecoded);
akiraohgaki's avatar
akiraohgaki committed
    }

    if (query.hasQueryItem("type") && !query.queryItemValue("type").isEmpty()) {
akiraohgaki's avatar
akiraohgaki committed
        metadata_["type"] = query.queryItemValue("type", QUrl::FullyDecoded);
akiraohgaki's avatar
akiraohgaki committed
    }

    if (query.hasQueryItem("filename") && !query.queryItemValue("filename").isEmpty()) {
akiraohgaki's avatar
akiraohgaki committed
        metadata_["filename"] = QUrl(query.queryItemValue("filename", QUrl::FullyDecoded)).fileName();
akiraohgaki's avatar
akiraohgaki committed
    }

akiraohgaki's avatar
akiraohgaki committed
    if (!metadata_["url"].toString().isEmpty() && metadata_["filename"].toString().isEmpty()) {
        metadata_["filename"] = QUrl(metadata_["url"].toString()).fileName();
akiraohgaki's avatar
akiraohgaki committed
    }
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
void OcsUrlHandler::saveDownloadedFile(Qtil::NetworkResource *resource)
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    QJsonObject result;

    auto type = metadata_["type"].toString();
akiraohgaki's avatar
akiraohgaki committed
    Qtil::Dir destDir(configHandler_->getAppConfigInstallTypes()[type].toObject()["destination"].toString());
akiraohgaki's avatar
akiraohgaki committed
    destDir.make();
akiraohgaki's avatar
akiraohgaki committed
    Qtil::File destFile(destDir.path() + "/" + metadata_["filename"].toString());
akiraohgaki's avatar
akiraohgaki committed
    if (!resource->saveData(destFile.path())) {
akiraohgaki's avatar
akiraohgaki committed
        result["status"] = QString("error_save");
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("Failed to save data");
akiraohgaki's avatar
akiraohgaki committed
        emit finishedWithError(result);
akiraohgaki's avatar
akiraohgaki committed
        resource->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
        return;
    }

akiraohgaki's avatar
akiraohgaki committed
    result["status"] = QString("success_download");
akiraohgaki's avatar
akiraohgaki committed
    result["message"] = tr("The file has been downloaded");
akiraohgaki's avatar
akiraohgaki committed
    emit finishedWithSuccess(result);
akiraohgaki's avatar
akiraohgaki committed

    resource->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
void OcsUrlHandler::installDownloadedFile(Qtil::NetworkResource *resource)
akiraohgaki's avatar
akiraohgaki committed
{
akiraohgaki's avatar
akiraohgaki committed
    QJsonObject result;

akiraohgaki's avatar
akiraohgaki committed
    Qtil::File tempFile(Qtil::Dir::tempPath() + "/" + metadata_["filename"].toString());
akiraohgaki's avatar
akiraohgaki committed

akiraohgaki's avatar
akiraohgaki committed
    if (!resource->saveData(tempFile.path())) {
akiraohgaki's avatar
akiraohgaki committed
        result["status"] = QString("error_save");
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("Failed to save data");
akiraohgaki's avatar
akiraohgaki committed
        emit finishedWithError(result);
akiraohgaki's avatar
akiraohgaki committed
        resource->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
    Qtil::Package package(tempFile.path());
    auto type = metadata_["type"].toString();
akiraohgaki's avatar
akiraohgaki committed
    Qtil::Dir destDir(configHandler_->getAppConfigInstallTypes()[type].toObject()["destination"].toString());
akiraohgaki's avatar
akiraohgaki committed
    destDir.make();
akiraohgaki's avatar
akiraohgaki committed
    Qtil::File destFile(destDir.path() + "/" + metadata_["filename"].toString());
akiraohgaki's avatar
akiraohgaki committed
    if (type == "bin"
akiraohgaki's avatar
akiraohgaki committed
            && package.installAsProgram(destFile.path())) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The file has been installed as program");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if ((type == "plasma_plasmoids" || type == "plasma4_plasmoids" || type == "plasma5_plasmoids")
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("plasmoid")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The plasmoid has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if ((type == "plasma_look_and_feel" || type == "plasma5_look_and_feel")
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("lookandfeel")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The plasma look and feel has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if ((type == "plasma_desktopthemes" || type == "plasma5_desktopthemes")
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("theme")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The plasma desktop theme has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if (type == "kwin_effects"
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("kwineffect")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The KWin effect has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if (type == "kwin_scripts"
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("kwinscript")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The KWin script has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else if (type == "kwin_tabbox"
akiraohgaki's avatar
akiraohgaki committed
             && package.installAsPlasmapkg("windowswitcher")) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The KWin window switcher has been installed");
akiraohgaki's avatar
akiraohgaki committed
    else if (package.installAsArchive(destDir.path())) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The archive file has been extracted");
akiraohgaki's avatar
akiraohgaki committed
    else if (package.installAsFile(destFile.path())) {
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("The file has been installed");
akiraohgaki's avatar
akiraohgaki committed
    }
    else {
akiraohgaki's avatar
akiraohgaki committed
        result["status"] = QString("error_install");
akiraohgaki's avatar
akiraohgaki committed
        result["message"] = tr("Failed to installation");
akiraohgaki's avatar
akiraohgaki committed
        emit finishedWithError(result);
akiraohgaki's avatar
akiraohgaki committed
        tempFile.remove();
akiraohgaki's avatar
akiraohgaki committed
    result["status"] = QString("success_install");
akiraohgaki's avatar
akiraohgaki committed
    emit finishedWithSuccess(result);
akiraohgaki's avatar
akiraohgaki committed

    tempFile.remove();
    resource->deleteLater();
akiraohgaki's avatar
akiraohgaki committed
}