From kde-commits Wed Aug 09 05:15:48 2017 From: Jan Grulich Date: Wed, 09 Aug 2017 05:15:48 +0000 To: kde-commits Subject: [discover] libdiscover/backends/FlatpakBackend: Install required runtime for flatpakref if it's spec Message-Id: X-MARC-Message: https://marc.info/?l=kde-commits&m=150225575923973 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 inst= all it as well, otherwise user ends up with just application installed but not workin= g 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/libdi= scover/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 =3D get(QNetworkRequest(m_url)); + + connect(replyGet, &QNetworkReply::finished, this, [this, replyGet]= { + const QUrl originalUrl =3D replyGet->request().url(); + if (replyGet->error() !=3D QNetworkReply::NoError) { + qWarning() << "couldn't download" << originalUrl << replyG= et->errorString(); + Q_EMIT jobFinished(false, nullptr); + return; + } + + const QUrl fileUrl =3D QUrl::fromLocalFile(QStandardPaths::wri= tableLocation(QStandardPaths::TempLocation) + QLatin1Char('/') + originalUr= l.fileName()); + auto replyPut =3D put(QNetworkRequest(fileUrl), replyGet->read= All()); + connect(replyPut, &QNetworkReply::finished, this, [this, origi= nalUrl, fileUrl, replyPut]() { + if (replyPut->error() =3D=3D QNetworkReply::NoError) { + auto res =3D m_backend->resourceForFile(fileUrl); + if (res) { + FlatpakResource *resource =3D qobject_cast(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 =3D flatpak_installation_list_remotes(installation, m_can= cellable, 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 =3D QUrl(settings.value(QStringLiteral("Flatpak Ref/Ru= ntimeRepo")).toString()); + if (!runtimeUrl.isEmpty()) { + // We need to fetch metadata to find information about required ru= ntime + FlatpakFetchDataJob *job =3D new FlatpakFetchDataJob(preferredInst= allation(), resource, FlatpakFetchDataJob::FetchMetadata); + connect(job, &FlatpakFetchDataJob::finished, job, &FlatpakFetchDat= aJob::deleteLater); + connect(job, &FlatpakFetchDataJob::jobFetchMetadataFailed, this, [= this, resource] { + // Even when we failed to fetch information about runtime we s= till want to show the application + addResource(resource); + }); + connect(job, &FlatpakFetchDataJob::jobFetchMetadataFinished, this,= [this, runtimeUrl] (FlatpakInstallation *installation, FlatpakResource *re= source, const QByteArray &metadata) { + Q_UNUSED(installation); + + updateAppMetadata(resource, metadata); + + auto runtime =3D getRuntimeForApp(resource); + if (!runtime || (runtime && !runtime->isInstalled())) { + FlatpakFetchRemoteResourceJob *fetchRemoteResource =3D new= FlatpakFetchRemoteResourceJob(runtimeUrl, this); + connect(fetchRemoteResource, &FlatpakFetchRemoteResourceJo= b::jobFinished, this, [this, resource] (bool success, FlatpakResource *repo= Resource) { + 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 Abstrac= tResourcesBackend::Filters & if (filter.resourceUrl.fileName().endsWith(QLatin1String(".flatpakrepo= ")) || filter.resourceUrl.fileName().endsWith(QLatin1String(".flatpakref"))= ) { auto stream =3D new ResultsStream(QStringLiteral("FlatpakStream-ht= tp-")+filter.resourceUrl.fileName()); = - QNetworkAccessManager* manager =3D new QNetworkAccessManager; - auto replyGet =3D manager->get(QNetworkRequest(filter.resourceUrl)= ); - - connect(replyGet, &QNetworkReply::finished, this, [this, manager, = replyGet, stream] { - const QUrl originalUrl =3D replyGet->request().url(); - if (replyGet->error() !=3D QNetworkReply::NoError) { - qWarning() << "couldn't download" << originalUrl << replyG= et->errorString(); - stream->finish(); - return; + FlatpakFetchRemoteResourceJob *fetchResourceJob =3D new FlatpakFet= chRemoteResourceJob(filter.resourceUrl, this); + connect(fetchResourceJob, &FlatpakFetchRemoteResourceJob::jobFinis= hed, this, [fetchResourceJob, stream] (bool success, FlatpakResource *resou= rce) { + if (success) { + stream->resourcesFound({resource}); } - - const QUrl fileUrl =3D QUrl::fromLocalFile(QStandardPaths::wri= tableLocation(QStandardPaths::TempLocation) + QLatin1Char('/') + originalUr= l.fileName()); - auto replyPut =3D manager->put(QNetworkRequest(fileUrl), reply= Get->readAll()); - connect(replyPut, &QNetworkReply::finished, this, [this, origi= nalUrl, fileUrl, replyPut, stream, manager]() { - if (replyPut->error() =3D=3D QNetworkReply::NoError) { - auto res =3D resourceForFile(fileUrl); - if (res) { - FlatpakResource* fres =3D qobject_cast(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(= ) !=3D QLatin1String("appstream")) return new ResultsStream(QStringLiteral("FlatpakStream-void"), {}); @@ -1060,7 +1124,9 @@ Transaction* FlatpakBackend::installApplication(Abstr= actResource *app, const Add FlatpakRemote *remote =3D 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 on= e created by FlatpakSourcesBackend will not have appstream directory + refreshAppstreamMetadata(preferredInstallation(), flatpak_inst= allation_get_remote_by_name(preferredInstallation(), flatpak_remote_get_nam= e(remote), nullptr, nullptr)); } return nullptr; }