File indexing completed on 2024-11-17 04:55:41
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "LocalFilePKResource.h" 0008 #include "libdiscover_backend_debug.h" 0009 #include <PackageKit/Daemon> 0010 #include <PackageKit/Details> 0011 #include <QDebug> 0012 #include <QFileInfo> 0013 #include <QProcess> 0014 #include <utils.h> 0015 0016 LocalFilePKResource::LocalFilePKResource(QUrl path, PackageKitBackend *parent) 0017 : PackageKitResource(path.toString(), path.toString(), parent) 0018 , m_path(std::move(path)) 0019 { 0020 } 0021 0022 quint64 LocalFilePKResource::size() 0023 { 0024 const QFileInfo info(m_path.toLocalFile()); 0025 return info.size(); 0026 } 0027 0028 QString LocalFilePKResource::name() const 0029 { 0030 const QFileInfo info(m_path.toLocalFile()); 0031 return info.baseName(); 0032 } 0033 0034 QString LocalFilePKResource::comment() 0035 { 0036 return m_path.toLocalFile(); 0037 } 0038 0039 QString LocalFilePKResource::origin() const 0040 { 0041 return m_path.toLocalFile(); 0042 } 0043 0044 void LocalFilePKResource::fetchDetails() 0045 { 0046 if (!m_details.isEmpty()) { 0047 return; 0048 } 0049 m_details.insert(QStringLiteral("fetching"), true); // we add an entry so it's not re-fetched. 0050 0051 if (PackageKit::Daemon::roles() & PackageKit::Transaction::RoleGetDetailsLocal) { 0052 PackageKit::Transaction *transaction = PackageKit::Daemon::getDetailsLocal(m_path.toLocalFile()); 0053 connect(transaction, &PackageKit::Transaction::details, this, &LocalFilePKResource::resolve); 0054 connect(transaction, &PackageKit::Transaction::errorCode, this, &PackageKitResource::failedFetchingDetails); 0055 } 0056 0057 if (PackageKit::Daemon::roles() & PackageKit::Transaction::RoleGetFilesLocal) { 0058 PackageKit::Transaction *transaction2 = PackageKit::Daemon::getFilesLocal(m_path.toLocalFile()); 0059 connect(transaction2, &PackageKit::Transaction::errorCode, this, &PackageKitResource::failedFetchingDetails); 0060 connect(transaction2, &PackageKit::Transaction::files, this, [this](const QString & /*pkgid*/, const QStringList &files) { 0061 const auto execIdx = kIndexOf(files, [](const QString &file) { 0062 return file.endsWith(QLatin1String(".desktop")) && file.contains(QLatin1String("usr/share/applications")); 0063 }); 0064 if (execIdx >= 0) { 0065 m_exec = files[execIdx]; 0066 0067 // sometimes aptcc provides paths like usr/share/applications/steam.desktop 0068 if (!m_exec.startsWith(QLatin1Char('/'))) { 0069 m_exec.prepend(QLatin1Char('/')); 0070 } 0071 } else { 0072 qWarning() << "could not find an executable desktop file for" << m_path << "among" << files; 0073 } 0074 }); 0075 } 0076 } 0077 0078 void LocalFilePKResource::resolve(const PackageKit::Details &inDetails) 0079 { 0080 clearPackageIds(); 0081 const PackageKit::Details details = inDetails.isEmpty() ? m_details : inDetails; 0082 const auto detailsPackageId = details.packageId(); 0083 auto resolve = PackageKit::Daemon::resolve(PackageKit::Daemon::packageName(detailsPackageId), PackageKit::Transaction::FilterNone); 0084 0085 connect(resolve, &PackageKit::Transaction::package, this, [this, detailsPackageId](PackageKit::Transaction::Info info, const QString &packageId) { 0086 if (PackageKit::Daemon::packageName(packageId) == PackageKit::Daemon::packageName(detailsPackageId) 0087 && PackageKit::Daemon::packageVersion(packageId) == PackageKit::Daemon::packageVersion(detailsPackageId) 0088 && PackageKit::Daemon::packageArch(packageId) == PackageKit::Daemon::packageArch(detailsPackageId) 0089 && info == PackageKit::Transaction::InfoInstalled) { 0090 addPackageId(info, packageId, true); 0091 } 0092 }); 0093 connect(resolve, &PackageKit::Transaction::finished, this, [this, details, detailsPackageId] { 0094 addPackageId(PackageKit::Transaction::InfoAvailable, detailsPackageId, true); 0095 PackageKitResource::setDetails(details); 0096 }); 0097 } 0098 0099 void LocalFilePKResource::invokeApplication() const 0100 { 0101 KService::Ptr service = KService::Ptr(new KService(m_exec)); 0102 0103 if (!service) { 0104 return; 0105 } 0106 0107 runService(service); 0108 }