summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Grulich <[email protected]>2017-02-14 10:54:32 +0100
committerJan Grulich <[email protected]>2017-02-14 10:54:32 +0100
commit36148ca07414bcce3d05536ee372f0a6002a4cdf (patch)
treee3707d36a720b60632567f6954706243f919430c
parent72f63ea03dcccd83a4c5d0f31f8506de790106b1 (diff)
Add support for flatpak bundles
-rw-r--r--libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp277
-rw-r--r--libdiscover/backends/FlatpakBackend/FlatpakBackend.h7
-rw-r--r--libdiscover/backends/FlatpakBackend/FlatpakResource.cpp39
-rw-r--r--libdiscover/backends/FlatpakBackend/FlatpakResource.h10
-rw-r--r--libdiscover/backends/FlatpakBackend/FlatpakTransactionJob.cpp26
-rw-r--r--libdiscover/backends/FlatpakBackend/org.kde.discover-flatpak.desktop2
6 files changed, 267 insertions, 94 deletions
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp b/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
index 40ba892..41d3442 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
+++ b/libdiscover/backends/FlatpakBackend/FlatpakBackend.cpp
@@ -32,6 +32,7 @@
#include <AppStreamQt/bundle.h>
#include <AppStreamQt/component.h>
+#include <AppStreamQt/icon.h>
#include <AppStream/appstream.h>
#include <KAboutData>
@@ -108,6 +109,24 @@ FlatpakRef * FlatpakBackend::createFakeRef(FlatpakResource *resource)
return ref;
}
+FlatpakRemote * FlatpakBackend::getFlatpakRemoteByUrl(const QString &url, FlatpakInstallation *installation) const
+{
+ auto remotes = flatpak_installation_list_remotes(installation, m_cancellable, nullptr);
+ if (!remotes) {
+ return nullptr;
+ }
+
+ const QByteArray comparableUrl = url.toUtf8();
+ for (uint i = 0; i < remotes->len; i++) {
+ FlatpakRemote *remote = FLATPAK_REMOTE(g_ptr_array_index(remotes, i));
+
+ if (comparableUrl == flatpak_remote_get_url(remote)) {
+ return remote;
+ }
+ }
+ return nullptr;
+}
+
FlatpakInstalledRef * FlatpakBackend::getInstalledRefForApp(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource)
{
AppStream::Component *component = resource->appstreamComponent();
@@ -186,6 +205,167 @@ FlatpakResource * FlatpakBackend::getRuntimeForApp(FlatpakResource *resource)
return runtime;
}
+FlatpakResource * FlatpakBackend::addAppFromFlatpakBundle(const QUrl &url)
+{
+ g_autoptr(GBytes) appstreamGz = nullptr;
+ g_autoptr(GError) localError = nullptr;
+ g_autoptr(GFile) file = nullptr;
+ g_autoptr(FlatpakBundleRef) bundleRef = nullptr;
+ AppStream::Component *asComponent = nullptr;
+
+
+ file = g_file_new_for_path(url.toLocalFile().toStdString().c_str());
+ bundleRef = flatpak_bundle_ref_new(file, &localError);
+
+ if (!bundleRef) {
+ qWarning() << "Failed to load bundle: " << localError->message;
+ return nullptr;
+ }
+
+ appstreamGz = flatpak_bundle_ref_get_appstream(bundleRef);
+ if (appstreamGz) {
+ g_autoptr(GZlibDecompressor) decompressor = nullptr;
+ g_autoptr(GInputStream) streamGz = nullptr;
+ g_autoptr(GInputStream) streamData = nullptr;
+ g_autoptr(GBytes) appstream = nullptr;
+
+ /* decompress data */
+ decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
+ streamGz = g_memory_input_stream_new_from_bytes (appstreamGz);
+ if (!streamGz) {
+ return nullptr;
+ }
+
+ streamData = g_converter_input_stream_new (streamGz, G_CONVERTER (decompressor));
+
+ appstream = g_input_stream_read_bytes (streamData, 0x100000, m_cancellable, &localError);
+ if (!appstream) {
+ qWarning() << "Failed to extract appstream metadata from bundle: " << localError->message;
+ return nullptr;
+ }
+
+ g_autoptr(AsMetadata) metadata = as_metadata_new();
+ as_metadata_set_format_style(metadata, AS_FORMAT_STYLE_COLLECTION);
+ as_metadata_parse(metadata, (char *)g_bytes_get_data(appstream, nullptr), AS_FORMAT_KIND_XML, &localError);
+ if (localError) {
+ qWarning() << "Failed to parse appstream metadata: " << localError->message;
+ return nullptr;
+ }
+
+ g_autoptr(GPtrArray) components = as_metadata_get_components(metadata);
+ if (g_ptr_array_index(components, 0)) {
+ asComponent = new AppStream::Component(AS_COMPONENT(g_ptr_array_index(components, 0)));
+ } else {
+ qWarning() << "Failed to parse appstream metadata";
+ return nullptr;
+ }
+ } else {
+ AsComponent *component = as_component_new();
+ asComponent = new AppStream::Component(component);
+ qWarning() << "No appstream metadata in bundle";
+ }
+
+ gsize len = 0;
+ g_autoptr(GBytes) iconData = nullptr;
+ g_autoptr(GBytes) metadata = nullptr;
+ FlatpakResource *resource = new FlatpakResource(asComponent, this);
+
+ metadata = flatpak_bundle_ref_get_metadata(bundleRef);
+ QByteArray metadataContent = QByteArray((char *)g_bytes_get_data(metadata, &len));
+ if (!updateAppMetadata(resource, metadataContent)) {
+ qWarning() << "Failed to update metadata from app bundle";
+ return nullptr;
+ }
+
+ iconData = flatpak_bundle_ref_get_icon(bundleRef, 128);
+ if (!iconData) {
+ iconData = flatpak_bundle_ref_get_icon(bundleRef, 64);
+ }
+
+ if (iconData) {
+ gsize len = 0;
+ QPixmap pixmap;
+ char * data = (char *)g_bytes_get_data(iconData, &len);
+ QByteArray icon = QByteArray(data, len);
+ pixmap.loadFromData(icon, "PNG");
+ resource->setBundledIcon(pixmap);
+ }
+
+ resource->setInstalledSize(flatpak_bundle_ref_get_installed_size(bundleRef));
+ resource->setFlatpakFileType(QStringLiteral("flatpak"));
+ resource->setOrigin(QString::fromUtf8(flatpak_bundle_ref_get_origin(bundleRef)));
+ resource->setResourceFile(url);
+ resource->setState(FlatpakResource::None);
+ resource->setType(FlatpakResource::DesktopApp);
+
+ addResource(resource);
+ return resource;
+}
+
+FlatpakResource * FlatpakBackend::addAppFromFlatpakRef(const QUrl &url)
+{
+ auto installation = m_flatpakInstallationSystem;
+ QSettings settings(url.toLocalFile(), QSettings::NativeFormat);
+ const QString refurl = settings.value(QStringLiteral("Flatpak Ref/Url")).toString();
+ FlatpakRemote* remote = getFlatpakRemoteByUrl(refurl, installation);
+
+ if (!remote) {
+ const auto res = QMessageBox::question(nullptr, i18n("Add Remote"),
+ i18n("Would you like to add remote '%1'?\n\nFrom: %2\nWith GPG key=%3...",
+ settings.value(QStringLiteral("Flatpak Ref/Title")).toString(),
+ refurl,
+ settings.value(QStringLiteral("Flatpak Ref/GPGKey")).toString().left(23)),
+ QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No));
+ if (res != QMessageBox::Yes) {
+ return nullptr;
+ }
+ }
+
+ g_autoptr(GError) error = NULL;
+ g_autoptr(FlatpakRemoteRef) remoteRef = nullptr;
+ {
+ QFile f(url.toLocalFile());
+ if (!f.open(QFile::ReadOnly | QFile::Text)) {
+ return nullptr;
+ }
+
+ QByteArray contents = f.readAll();
+
+ g_autoptr(GBytes) bytes = g_bytes_new (contents.data(), contents.size());
+
+ remoteRef = flatpak_installation_install_ref_file (installation, bytes, m_cancellable, &error);
+ if (!remoteRef) {
+ return nullptr;
+ }
+ }
+
+ const auto remoteName = flatpak_remote_ref_get_remote_name(remoteRef);
+ remote = flatpak_installation_get_remote_by_name(installation, remoteName, m_cancellable, &error);
+
+ auto ref = FLATPAK_REF(remoteRef);
+
+ AsComponent *component = as_component_new();
+ as_component_add_url(component, AS_URL_KIND_HOMEPAGE, settings.value(QStringLiteral("Flatpak Ref/Homepage")).toString().toStdString().c_str());
+ as_component_set_description(component, settings.value(QStringLiteral("Flatpak Ref/Description")).toString().toStdString().c_str(), nullptr);
+ as_component_set_name(component, settings.value(QStringLiteral("Flatpak Ref/Title")).toString().toStdString().c_str(), nullptr);
+ as_component_set_summary(component, settings.value(QStringLiteral("Flatpak Ref/Comment")).toString().toStdString().c_str(), nullptr);
+ const QString iconUrl = settings.value(QStringLiteral("Flatpak Ref/Icon")).toString();
+ if (!iconUrl.isEmpty()) {
+ AsIcon *icon = as_icon_new();
+ as_icon_set_kind(icon, AS_ICON_KIND_REMOTE);
+ as_icon_set_url(icon, iconUrl.toStdString().c_str());
+ as_component_add_icon(component, icon);
+ }
+
+ AppStream::Component *asComponent = new AppStream::Component(component);
+ auto resource = new FlatpakResource(asComponent, this);
+ resource->setFlatpakFileType(QStringLiteral("flatpakref"));
+ resource->setOrigin(QString::fromUtf8(remoteName));
+ resource->updateFromRef(ref);
+ addResource(resource);
+ return resource;
+}
+
void FlatpakBackend::addResource(FlatpakResource *resource)
{
// Update app with all possible information we have
@@ -572,6 +752,11 @@ bool FlatpakBackend::updateAppMetadata(FlatpakInstallation* flatpakInstallation,
return false;
}
+ return updateAppMetadata(resource, metadataContent);
+}
+
+bool FlatpakBackend::updateAppMetadata(FlatpakResource *resource, const QByteArray &data)
+{
// Save the content to temporary file
QTemporaryFile tempFile;
tempFile.setAutoRemove(false);
@@ -580,7 +765,7 @@ bool FlatpakBackend::updateAppMetadata(FlatpakInstallation* flatpakInstallation,
return false;
}
- tempFile.write(metadataContent);
+ tempFile.write(data);
tempFile.close();
// Parse the temporary file
@@ -636,6 +821,9 @@ bool FlatpakBackend::updateAppSize(FlatpakInstallation *flatpakInstallation, Fla
qWarning() << "Failed to get runtime size needed for total size of " << resource->name();
return false;
}
+ // Set required download size to include runtime size even now, in case we fail to
+ // get the app size (e.g. when installing bundles where download size is 0)
+ resource->setDownloadSize(runtime->downloadSize());
}
}
}
@@ -654,6 +842,7 @@ bool FlatpakBackend::updateAppSize(FlatpakInstallation *flatpakInstallation, Fla
if (resource->origin().isEmpty()) {
qWarning() << "Failed to get size of " << resource->name() << " because of missing origin";
+ return false;
}
ref = createFakeRef(resource);
@@ -670,7 +859,7 @@ bool FlatpakBackend::updateAppSize(FlatpakInstallation *flatpakInstallation, Fla
// TODO: What size do we want to show (installed vs download)? Do we want to show app size + runtime size if runtime is not installed?
if (runtime && !runtime->isInstalled()) {
resource->setDownloadSize(runtime->downloadSize() + downloadSize);
- resource->setInstalledSize(runtime->installedSize() + installedSize);
+ resource->setInstalledSize(installedSize);
} else {
resource->setDownloadSize(downloadSize);
resource->setInstalledSize(installedSize);
@@ -806,89 +995,23 @@ void FlatpakBackend::checkForUpdates()
loadRemoteUpdates(m_flatpakInstallationUser);
}
-FlatpakRemote * FlatpakBackend::flatpakRemoteByUrl(const QString& url, FlatpakInstallation* installation) const
-{
- auto remotes = flatpak_installation_list_remotes(installation, m_cancellable, nullptr);
- if (!remotes) {
- return nullptr;
- }
-
- const QByteArray comparableUrl = url.toUtf8();
- for (uint i = 0; i < remotes->len; i++) {
- FlatpakRemote *remote = FLATPAK_REMOTE(g_ptr_array_index(remotes, i));
-
- if (comparableUrl == flatpak_remote_get_url(remote)) {
- return remote;
- }
- }
- return nullptr;
-}
-
AbstractResource * FlatpakBackend::resourceForFile(const QUrl &url)
{
- if (!url.path().endsWith(QLatin1String(".flatpakref")) || !url.isLocalFile()) {
+ if ((!url.path().endsWith(QLatin1String(".flatpakref")) && !url.path().endsWith(QLatin1String(".flatpak"))) || !url.isLocalFile()) {
return nullptr;
}
- auto installation = m_flatpakInstallationSystem;
- QSettings settings(url.toLocalFile(), QSettings::NativeFormat);
- const QString refurl = settings.value(QStringLiteral("Flatpak Ref/Url")).toString();
- FlatpakRemote* remote = flatpakRemoteByUrl(refurl, installation);
-
- if (!remote) {
- const auto res = QMessageBox::question(nullptr, i18n("Add Remote"),
- i18n("Would you like to add remote '%1'?\n\nFrom: %2\nWith GPG key=%3...",
- settings.value(QStringLiteral("Flatpak Ref/Title")).toString(),
- refurl,
- settings.value(QStringLiteral("Flatpak Ref/GPGKey")).toString().left(23)),
- QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No));
- if (res != QMessageBox::Yes) {
- return nullptr;
- }
- }
-
- g_autoptr(GError) error = NULL;
- g_autoptr(FlatpakRemoteRef) remoteRef = nullptr;
- {
- QFile f(url.toLocalFile());
- if (!f.open(QFile::ReadOnly | QFile::Text)) {
- return nullptr;
- }
-
- QByteArray contents = f.readAll();
-
- g_autoptr(GBytes) bytes = g_bytes_new (contents.data(), contents.size());
-
- remoteRef = flatpak_installation_install_ref_file (installation, bytes, m_cancellable, &error);
- if (!remoteRef) {
- return nullptr;
- }
- }
-
- const auto remoteName = flatpak_remote_ref_get_remote_name(remoteRef);
- remote = flatpak_installation_get_remote_by_name(installation, remoteName, m_cancellable, &error);
-
- auto ref = FLATPAK_REF(remoteRef);
-
- AsComponent *component = as_component_new();
- as_component_add_url(component, AS_URL_KIND_HOMEPAGE, settings.value(QStringLiteral("Flatpak Ref/Homepage")).toString().toStdString().c_str());
- as_component_set_description(component, settings.value(QStringLiteral("Flatpak Ref/Description")).toString().toStdString().c_str(), nullptr);
- as_component_set_name(component, settings.value(QStringLiteral("Flatpak Ref/Title")).toString().toStdString().c_str(), nullptr);
- as_component_set_summary(component, settings.value(QStringLiteral("Flatpak Ref/Comment")).toString().toStdString().c_str(), nullptr);
- const QString iconUrl = settings.value(QStringLiteral("Flatpak Ref/Icon")).toString();
- if (!iconUrl.isEmpty()) {
- AsIcon *icon = as_icon_new();
- as_icon_set_kind(icon, AS_ICON_KIND_REMOTE);
- as_icon_set_url(icon, iconUrl.toStdString().c_str());
- as_component_add_icon(component, icon);
+ FlatpakResource *resource = nullptr;
+ if (url.path().endsWith(QLatin1String(".flatpak"))) {
+ resource = addAppFromFlatpakBundle(url);
+ } else if (url.path().endsWith(QLatin1String(".flatpakref"))) {
+ resource = addAppFromFlatpakRef(url);
+ } else {
+ // TODO .flatpakrepo
}
- AppStream::Component *asComponent = new AppStream::Component(component);
- auto resource = new FlatpakResource(asComponent, this);
- resource->updateFromRef(ref);
- resource->setOrigin(QString::fromUtf8(remoteName));
- addResource(resource);
return resource;
+
}
#include "FlatpakBackend.moc"
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakBackend.h b/libdiscover/backends/FlatpakBackend/FlatpakBackend.h
index b66be4d..8982ccc 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakBackend.h
+++ b/libdiscover/backends/FlatpakBackend/FlatpakBackend.h
@@ -65,9 +65,13 @@ public Q_SLOTS:
private:
void integrateRemote(FlatpakInstallation *flatpakInstallation, FlatpakRemote *remote);
FlatpakRef * createFakeRef(FlatpakResource *resource);
+ FlatpakRemote * getFlatpakRemoteByUrl(const QString &url, FlatpakInstallation *installation) const;
FlatpakInstalledRef * getInstalledRefForApp(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource);
FlatpakResource * getAppForInstalledRef(FlatpakInstallation *flatpakInstallation, FlatpakInstalledRef *ref);
FlatpakResource * getRuntimeForApp(FlatpakResource *resource);
+
+ FlatpakResource * addAppFromFlatpakBundle(const QUrl &url);
+ FlatpakResource * addAppFromFlatpakRef(const QUrl &url);
void addResource(FlatpakResource *resource);
bool compareAppFlatpakRef(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource, FlatpakInstalledRef *ref);
bool loadAppsFromAppstreamData(FlatpakInstallation *flatpakInstallation);
@@ -79,11 +83,10 @@ private:
bool setupFlatpakInstallations(GError **error);
void updateAppInstalledMetadata(FlatpakInstalledRef *installedRef, FlatpakResource *resource);
bool updateAppMetadata(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource);
+ bool updateAppMetadata(FlatpakResource *resource, const QByteArray &data);
bool updateAppSize(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource);
void updateAppState(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource);
- FlatpakRemote* flatpakRemoteByUrl(const QString &url, FlatpakInstallation *installation) const;
-
void setFetching(bool fetching);
QHash<QString, FlatpakResource*> m_resources;
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
index ad32e21..f9da894 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
+++ b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
@@ -33,6 +33,7 @@
#include <QDebug>
#include <QDesktopServices>
#include <QIcon>
+#include <QFileInfo>
#include <QStringList>
#include <QTimer>
@@ -136,7 +137,9 @@ QVariant FlatpakResource::icon() const
QIcon ret;
const auto icons = m_appdata->icons();
- if (icons.isEmpty()) {
+ if (!m_bundledIcon.isNull()) {
+ ret = QIcon(m_bundledIcon);
+ } else if (icons.isEmpty()) {
ret = QIcon::fromTheme(QStringLiteral("package-x-generic"));
} else foreach(const AppStream::Icon &icon, icons) {
QStringList stock;
@@ -144,12 +147,13 @@ QVariant FlatpakResource::icon() const
switch (icon.kind()) {
case AppStream::Icon::KindLocal:
- url += icon.url().toLocalFile();
- ret.addFile(url);
- break;
case AppStream::Icon::KindCached:
url += icon.url().toLocalFile();
- ret.addFile(url);
+ if (QFileInfo::exists(url)) {
+ ret.addFile(url);
+ } else {
+ ret = QIcon::fromTheme(QStringLiteral("package-x-generic"));
+ }
break;
case AppStream::Icon::KindStock:
stock += icon.name();
@@ -193,6 +197,11 @@ QUrl FlatpakResource::homepage()
return m_appdata->url(AppStream::Component::UrlKindHomepage);
}
+QString FlatpakResource::flatpakFileType() const
+{
+ return m_flatpakFileType;
+}
+
QString FlatpakResource::flatpakName() const
{
// If the flatpak name is not known (known only for installed apps), then use
@@ -234,6 +243,11 @@ QString FlatpakResource::packageName() const
return m_appdata->name();
}
+QUrl FlatpakResource::resourceFile() const
+{
+ return m_resourceFile;
+}
+
QString FlatpakResource::runtime() const
{
return m_runtime;
@@ -385,6 +399,11 @@ void FlatpakResource::setBranch(const QString &branch)
m_branch = branch;
}
+void FlatpakResource::setBundledIcon(const QPixmap &pixmap)
+{
+ m_bundledIcon = pixmap;
+}
+
void FlatpakResource::setCommit(const QString &commit)
{
m_commit = commit;
@@ -395,6 +414,11 @@ void FlatpakResource::setDownloadSize(int size)
m_downloadSize = size;
}
+void FlatpakResource::setFlatpakFileType(const QString &fileType)
+{
+ m_flatpakFileType = fileType;
+}
+
void FlatpakResource::setFlatpakName(const QString &name)
{
m_flatpakName = name;
@@ -415,6 +439,11 @@ void FlatpakResource::setOrigin(const QString &origin)
m_origin = origin;
}
+void FlatpakResource::setResourceFile(const QUrl &url)
+{
+ m_resourceFile = url;
+}
+
void FlatpakResource::setRuntime(const QString &runtime)
{
m_runtime = runtime;
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakResource.h b/libdiscover/backends/FlatpakBackend/FlatpakResource.h
index fa2a92f..171b1e8 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakResource.h
+++ b/libdiscover/backends/FlatpakBackend/FlatpakResource.h
@@ -30,6 +30,8 @@ extern "C" {
#include <AppStreamQt/component.h>
+#include <QPixmap>
+
class AddonList;
class FlatpakBackend;
class FlatpakResource : public AbstractResource
@@ -81,12 +83,14 @@ public:
int installedSize() const;
bool isTechnical() const override;
QUrl homepage() override;
+ QString flatpakFileType() const;
QString flatpakName() const;
QString license() override;
QString longDescription() override;
QString name() override;
QString origin() const override;
QString packageName() const override;
+ QUrl resourceFile() const;
QString runtime() const;
QUrl screenshotUrl() override;
Scope scope() const;
@@ -105,12 +109,15 @@ public:
void setArch(const QString &arch);
void setBranch(const QString &branch);
+ void setBundledIcon(const QPixmap &pixmap);
void setCommit(const QString &commit);
void setDownloadSize(int size);
void setIconPath(const QString &path);
void setInstalledSize(int size);
+ void setFlatpakFileType(const QString &fileType);
void setFlatpakName(const QString &name);
void setOrigin(const QString &origin);
+ void setResourceFile(const QUrl &url);
void setRuntime(const QString &runtime);
void setScope(Scope scope);
void setState(State state);
@@ -126,12 +133,15 @@ public:
FlatpakRefKind m_flatpakRefKind;
QString m_arch;
QString m_branch;
+ QPixmap m_bundledIcon;
QString m_commit;
int m_downloadSize;
+ QString m_flatpakFileType;
QString m_flatpakName;
QString m_iconPath;
int m_installedSize;
QString m_origin;
+ QUrl m_resourceFile;
QString m_runtime;
Scope m_scope;
AbstractResource::State m_state;
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakTransactionJob.cpp b/libdiscover/backends/FlatpakBackend/FlatpakTransactionJob.cpp
index 5694164..2abf9a8 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakTransactionJob.cpp
+++ b/libdiscover/backends/FlatpakBackend/FlatpakTransactionJob.cpp
@@ -73,15 +73,23 @@ void FlatpakTransactionJob::run()
this,
cancellable, &localError);
} else {
- ref = flatpak_installation_install(m_installation,
- m_app->origin().toStdString().c_str(),
- m_app->type() == FlatpakResource::DesktopApp ? FLATPAK_REF_KIND_APP : FLATPAK_REF_KIND_RUNTIME,
- m_app->flatpakName().toStdString().c_str(),
- m_app->arch().toStdString().c_str(),
- m_app->branch().toStdString().c_str(),
- flatpakInstallationProgressCallback,
- this,
- cancellable, &localError);
+ if (m_app->flatpakFileType() == QStringLiteral("flatpak")) {
+ g_autoptr(GFile) file = g_file_new_for_path(m_app->resourceFile().toLocalFile().toStdString().c_str());
+ if (!file) {
+ qWarning() << "Failed to install bundled application " << m_app->name();
+ }
+ ref = flatpak_installation_install_bundle(m_installation, file, flatpakInstallationProgressCallback, this, m_cancellable, &localError);
+ } else {
+ ref = flatpak_installation_install(m_installation,
+ m_app->origin().toStdString().c_str(),
+ m_app->type() == FlatpakResource::DesktopApp ? FLATPAK_REF_KIND_APP : FLATPAK_REF_KIND_RUNTIME,
+ m_app->flatpakName().toStdString().c_str(),
+ m_app->arch().toStdString().c_str(),
+ m_app->branch().toStdString().c_str(),
+ flatpakInstallationProgressCallback,
+ this,
+ cancellable, &localError);
+ }
}
if (!ref) {
diff --git a/libdiscover/backends/FlatpakBackend/org.kde.discover-flatpak.desktop b/libdiscover/backends/FlatpakBackend/org.kde.discover-flatpak.desktop
index 9af7f6e..570d715 100644
--- a/libdiscover/backends/FlatpakBackend/org.kde.discover-flatpak.desktop
+++ b/libdiscover/backends/FlatpakBackend/org.kde.discover-flatpak.desktop
@@ -43,4 +43,4 @@ Type=Application
X-DocPath=plasma-discover/index.html
Categories=Qt;KDE;System;
-MimeType=application/vnd.flatpak.ref
+MimeType=application/vnd.flatpak.ref;application/vnd.flatpak