[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [discover] libdiscover/backends/FlatpakBackend: Install required runtime for flatpakref if it's spec
From:       Jan Grulich <null () kde ! org>
Date:       2017-08-09 5:15:48
Message-ID: E1dfJLQ-0004YU-64 () code ! kde ! org
[Download RAW message or body]

Git commit 224012fabcf2cf61ec2bc6422bf09f1c35bb1323 by Jan Grulich.
Committed on 09/08/2017 at 05:15.
Pushed by grulich into branch 'master'.

Install required runtime for flatpakref if it's specified

Summary:
If one wants to install using flatpakref which requires a runtime we should \
check if it's installed and provided by the flatpakref file to \
automatically install it as well, otherwise user ends up with just \
application installed but not working because of missing runtime.

Reviewers: apol

Reviewed By: apol

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7201

M  +94   -28   libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp

https://commits.kde.org/discover/224012fabcf2cf61ec2bc6422bf09f1c35bb1323

diff --git a/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp \
b/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp index \
                7ac2e486..46c9d5ff 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
+++ b/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
@@ -110,6 +110,55 @@ void FlatpakBackend::announceRatingsReady()
     }
 }
 
+class FlatpakFetchRemoteResourceJob : public QNetworkAccessManager
+{
+Q_OBJECT
+public:
+    FlatpakFetchRemoteResourceJob(const QUrl &url, FlatpakBackend \
*backend) +        : QNetworkAccessManager(backend)
+        , m_backend(backend)
+        , m_url(url)
+    {
+    }
+
+    void start()
+    {
+        auto replyGet = get(QNetworkRequest(m_url));
+
+        connect(replyGet, &QNetworkReply::finished, this, [this, replyGet] \
{ +            const QUrl originalUrl = replyGet->request().url();
+            if (replyGet->error() != QNetworkReply::NoError) {
+                qWarning() << "couldn't download" << originalUrl << \
replyGet->errorString(); +                Q_EMIT jobFinished(false, \
nullptr); +                return;
+            }
+
+            const QUrl fileUrl = \
QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) \
+ QLatin1Char('/') + originalUrl.fileName()); +            auto replyPut = \
put(QNetworkRequest(fileUrl), replyGet->readAll()); +            \
connect(replyPut, &QNetworkReply::finished, this, [this, originalUrl, \
fileUrl, replyPut]() { +                if (replyPut->error() == \
QNetworkReply::NoError) { +                    auto res = \
m_backend->resourceForFile(fileUrl); +                    if (res) {
+                        FlatpakResource *resource = \
qobject_cast<FlatpakResource*>(res); +                        \
resource->setResourceFile(originalUrl); +                        Q_EMIT \
jobFinished(true, resource); +                    } else {
+                        qWarning() << "couldn't download" << originalUrl \
<< "into" << fileUrl << replyPut->errorString(); +                        \
Q_EMIT jobFinished(false, nullptr); +                    }
+                }
+            });
+        });
+    }
+
+Q_SIGNALS:
+    void jobFinished(bool success, FlatpakResource *resource);
+
+private:
+    FlatpakBackend *m_backend;
+    QUrl m_url;
+};
+
 FlatpakRemote * FlatpakBackend::getFlatpakRemoteByUrl(const QString &url, \
FlatpakInstallation *installation) const  {
     auto remotes = flatpak_installation_list_remotes(installation, \
m_cancellable, nullptr); @@ -359,7 +408,41 @@ FlatpakResource * \
FlatpakBackend::addAppFromFlatpakRef(const QUrl &url)  \
resource->setFlatpakFileType(QStringLiteral("flatpakref"));  \
resource->setOrigin(QString::fromUtf8(remoteName));  \
                resource->updateFromRef(ref);
-    addResource(resource);
+
+    QUrl runtimeUrl = QUrl(settings.value(QStringLiteral("Flatpak \
Ref/RuntimeRepo")).toString()); +    if (!runtimeUrl.isEmpty()) {
+        // We need to fetch metadata to find information about required \
runtime +        FlatpakFetchDataJob *job = new \
FlatpakFetchDataJob(preferredInstallation(), resource, \
FlatpakFetchDataJob::FetchMetadata); +        connect(job, \
&FlatpakFetchDataJob::finished, job, &FlatpakFetchDataJob::deleteLater); +  \
connect(job, &FlatpakFetchDataJob::jobFetchMetadataFailed, this, [this, \
resource] { +            // Even when we failed to fetch information about \
runtime we still want to show the application +            \
addResource(resource); +        });
+        connect(job, &FlatpakFetchDataJob::jobFetchMetadataFinished, this, \
[this, runtimeUrl] (FlatpakInstallation *installation, FlatpakResource \
*resource, const QByteArray &metadata) { +            \
Q_UNUSED(installation); +
+            updateAppMetadata(resource, metadata);
+
+            auto runtime = getRuntimeForApp(resource);
+            if (!runtime || (runtime && !runtime->isInstalled())) {
+                FlatpakFetchRemoteResourceJob *fetchRemoteResource = new \
FlatpakFetchRemoteResourceJob(runtimeUrl, this); +                \
connect(fetchRemoteResource, &FlatpakFetchRemoteResourceJob::jobFinished, \
this, [this, resource] (bool success, FlatpakResource *repoResource) { +    \
if (success) { +                        installApplication(repoResource);
+                    }
+                    addResource(resource);
+                });
+                fetchRemoteResource->start();
+                return;
+            } else {
+                addResource(resource);
+            }
+        });
+        job->start();
+    } else {
+        addResource(resource);
+    }
+
     return resource;
 }
 
@@ -972,34 +1055,15 @@ ResultsStream * FlatpakBackend::search(const \
                AbstractResourcesBackend::Filters &
     if (filter.resourceUrl.fileName().endsWith(QLatin1String(".flatpakrepo")) \
                || filter.resourceUrl.fileName().endsWith(QLatin1String(".flatpakref"))) \
                {
         auto stream = new \
ResultsStream(QStringLiteral("FlatpakStream-http-")+filter.resourceUrl.fileName());
  
-        QNetworkAccessManager* manager = new QNetworkAccessManager;
-        auto replyGet = manager->get(QNetworkRequest(filter.resourceUrl));
-
-        connect(replyGet, &QNetworkReply::finished, this, [this, manager, \
                replyGet, stream] {
-            const QUrl originalUrl = replyGet->request().url();
-            if (replyGet->error() != QNetworkReply::NoError) {
-                qWarning() << "couldn't download" << originalUrl << \
                replyGet->errorString();
-                stream->finish();
-                return;
+        FlatpakFetchRemoteResourceJob *fetchResourceJob = new \
FlatpakFetchRemoteResourceJob(filter.resourceUrl, this); +        \
connect(fetchResourceJob, &FlatpakFetchRemoteResourceJob::jobFinished, \
this, [fetchResourceJob, stream] (bool success, FlatpakResource *resource) \
{ +            if (success) {
+                stream->resourcesFound({resource});
             }
-
-            const QUrl fileUrl = \
QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation) \
                + QLatin1Char('/') + originalUrl.fileName());
-            auto replyPut = manager->put(QNetworkRequest(fileUrl), \
                replyGet->readAll());
-            connect(replyPut, &QNetworkReply::finished, this, [this, \
                originalUrl, fileUrl, replyPut, stream, manager]() {
-                if (replyPut->error() == QNetworkReply::NoError) {
-                    auto res = resourceForFile(fileUrl);
-                    if (res) {
-                        FlatpakResource* fres = \
                qobject_cast<FlatpakResource*>(res);
-                        fres->setResourceFile(originalUrl);
-                        stream->resourcesFound({ res });
-                    } else {
-                        qWarning() << "couldn't download" << originalUrl \
                << "into" << fileUrl << replyPut->errorString();
-                    }
-                }
-                stream->finish();
-                manager->deleteLater();
-            });
+            stream->finish();
+            fetchResourceJob->deleteLater();
         });
+
         return stream;
     } else if (!filter.resourceUrl.isEmpty() && \
                filter.resourceUrl.scheme() != QLatin1String("appstream"))
         return new ResultsStream(QStringLiteral("FlatpakStream-void"), \
{}); @@ -1060,7 +1124,9 @@ Transaction* \
FlatpakBackend::installApplication(AbstractResource *app, const Add  \
FlatpakRemote *remote = m_sources->installSource(resource);  if (remote) {
             resource->setState(AbstractResource::Installed);
-            integrateRemote(preferredInstallation(), remote);
+            // Make sure we update appstream metadata first
+            // FIXME we have to let flatpak to return the remote as the \
one created by FlatpakSourcesBackend will not have appstream directory +    \
refreshAppstreamMetadata(preferredInstallation(), \
flatpak_installation_get_remote_by_name(preferredInstallation(), \
flatpak_remote_get_name(remote), nullptr, nullptr));  }
         return nullptr;
     }


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic