mirror of
https://invent.kde.org/system/dolphin
synced 2024-07-04 17:30:55 +00:00
Dolphin: Implement package kit for deb/rpm/pacman service packages
Summary: The deb/rpm/pacman packages are now installed/uninstalled using packagekit. Test Plan: Try to install deb package from kde store (search for `jetbrains`). Then uninstall it. Reviewers: #dolphin, ngraham, elvisangelaccio, meven Reviewed By: #dolphin, ngraham, elvisangelaccio, meven Subscribers: cblack, anthonyfieroni, asturmlechner, meven, kfm-devel Tags: #dolphin Differential Revision: https://phabricator.kde.org/D29119
This commit is contained in:
parent
ecede34048
commit
3e1cb2c7fb
|
@ -77,6 +77,16 @@ set_package_properties(KF5Activities PROPERTIES DESCRIPTION "KActivities librari
|
||||||
|
|
||||||
find_package(Phonon4Qt5 CONFIG REQUIRED)
|
find_package(Phonon4Qt5 CONFIG REQUIRED)
|
||||||
|
|
||||||
|
find_package(PackageKitQt5)
|
||||||
|
set_package_properties(PackageKitQt5
|
||||||
|
PROPERTIES DESCRIPTION "Software Manager integration"
|
||||||
|
TYPE OPTIONAL
|
||||||
|
PURPOSE "Used in the service menu installer"
|
||||||
|
)
|
||||||
|
if(PackageKitQt5_FOUND)
|
||||||
|
set(HAVE_PACKAGEKIT TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(KF5Baloo ${KF5_MIN_VERSION})
|
find_package(KF5Baloo ${KF5_MIN_VERSION})
|
||||||
set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries"
|
set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries"
|
||||||
URL "https://www.kde.org"
|
URL "https://www.kde.org"
|
||||||
|
|
|
@ -4,6 +4,8 @@ configure_file(config-baloo.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-baloo.h)
|
||||||
|
|
||||||
configure_file(config-kactivities.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kactivities.h)
|
configure_file(config-kactivities.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kactivities.h)
|
||||||
|
|
||||||
|
configure_file(config-packagekit.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-packagekit.h)
|
||||||
|
|
||||||
configure_file(config-terminal.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-terminal.h)
|
configure_file(config-terminal.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-terminal.h)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
|
|
1
src/config-packagekit.h.cmake
Normal file
1
src/config-packagekit.h.cmake
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#cmakedefine HAVE_PACKAGEKIT
|
|
@ -8,4 +8,8 @@ target_link_libraries(servicemenuinstaller PRIVATE
|
||||||
KF5::I18n
|
KF5::I18n
|
||||||
KF5::CoreAddons
|
KF5::CoreAddons
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(HAVE_PACKAGEKIT)
|
||||||
|
target_link_libraries(servicemenuinstaller PRIVATE PK::packagekitqt5)
|
||||||
|
endif()
|
||||||
install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
|
@ -20,29 +20,42 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QTimer>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
#include <KShell>
|
#include <KShell>
|
||||||
|
|
||||||
|
#include "../../../config-packagekit.h"
|
||||||
|
|
||||||
|
const static QStringList binaryPackages = {QStringLiteral("application/vnd.debian.binary-package"),
|
||||||
|
QStringLiteral("application/x-rpm"),
|
||||||
|
QStringLiteral("application/x-xz"),
|
||||||
|
QStringLiteral("application/zstd")};
|
||||||
|
enum PackageOperation {
|
||||||
|
Install,
|
||||||
|
Uninstall
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_PACKAGEKIT
|
||||||
|
#include <PackageKit/Daemon>
|
||||||
|
#include <PackageKit/Details>
|
||||||
|
#include <PackageKit/Transaction>
|
||||||
|
#else
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#endif
|
||||||
|
|
||||||
// @param msg Error that gets logged to CLI
|
// @param msg Error that gets logged to CLI
|
||||||
Q_NORETURN void fail(const QString &str)
|
Q_NORETURN void fail(const QString &str)
|
||||||
{
|
{
|
||||||
qCritical() << str;
|
qCritical() << str;
|
||||||
|
const QStringList args = {"--detailederror" ,i18n("Dolphin service menu installation failed"), str};
|
||||||
QProcess process;
|
QProcess::startDetached("kdialog", args);
|
||||||
const QStringList args = {"--passivepopup", i18n("Dolphin service menu installation failed"), "15"};
|
|
||||||
process.start("kdialog", args, QIODevice::ReadOnly);
|
|
||||||
if (!process.waitForStarted()) {
|
|
||||||
qFatal("Failed to run kdialog");
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -53,6 +66,84 @@ QString getServiceMenusDir()
|
||||||
return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus");
|
return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PACKAGEKIT
|
||||||
|
void packageKitInstall(const QString &fileName)
|
||||||
|
{
|
||||||
|
PackageKit::Transaction *transaction = PackageKit::Daemon::installFile(fileName);
|
||||||
|
|
||||||
|
const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) {
|
||||||
|
fail(details);
|
||||||
|
};
|
||||||
|
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::finished,
|
||||||
|
[=](PackageKit::Transaction::Exit status, uint) {
|
||||||
|
if (status == PackageKit::Transaction::ExitSuccess) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
// Fallback error handling
|
||||||
|
QTimer::singleShot(500, [=](){
|
||||||
|
fail(i18n("Failed to install \"%1\", exited with status \"%2\"",
|
||||||
|
fileName, QVariant::fromValue(status).toString()));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void packageKitUninstall(const QString &fileName)
|
||||||
|
{
|
||||||
|
const auto exitWithError = [=](PackageKit::Transaction::Error, const QString &details) {
|
||||||
|
fail(details);
|
||||||
|
};
|
||||||
|
const auto uninstallLambda = [=](PackageKit::Transaction::Exit status, uint) {
|
||||||
|
if (status == PackageKit::Transaction::ExitSuccess) {
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PackageKit::Transaction *transaction = PackageKit::Daemon::getDetailsLocal(fileName);
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::details,
|
||||||
|
[=](const PackageKit::Details &details) {
|
||||||
|
PackageKit::Transaction *transaction = PackageKit::Daemon::removePackage(details.packageId());
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::finished, uninstallLambda);
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::errorCode, exitWithError);
|
||||||
|
// Fallback error handling
|
||||||
|
QObject::connect(transaction, &PackageKit::Transaction::finished,
|
||||||
|
[=](PackageKit::Transaction::Exit status, uint) {
|
||||||
|
if (status != PackageKit::Transaction::ExitSuccess) {
|
||||||
|
QTimer::singleShot(500, [=]() {
|
||||||
|
fail(i18n("Failed to uninstall \"%1\", exited with status \"%2\"",
|
||||||
|
fileName, QVariant::fromValue(status).toString()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Q_NORETURN void packageKit(PackageOperation operation, const QString &fileName)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PACKAGEKIT
|
||||||
|
QFileInfo fileInfo(fileName);
|
||||||
|
if (!fileInfo.exists()) {
|
||||||
|
fail(i18n("The file does not exist!"));
|
||||||
|
}
|
||||||
|
const QString absPath = fileInfo.absoluteFilePath();
|
||||||
|
if (operation == PackageOperation::Install) {
|
||||||
|
packageKitInstall(absPath);
|
||||||
|
} else {
|
||||||
|
packageKitUninstall(absPath);
|
||||||
|
}
|
||||||
|
QGuiApplication::exec(); // For event handling, no return after signals finish
|
||||||
|
fail(i18n("Unknown error when installing package"));
|
||||||
|
#else
|
||||||
|
Q_UNUSED(operation)
|
||||||
|
QDesktopServices::openUrl(QUrl(fileName));
|
||||||
|
exit(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
struct UncompressCommand
|
struct UncompressCommand
|
||||||
{
|
{
|
||||||
QString command;
|
QString command;
|
||||||
|
@ -220,9 +311,8 @@ bool cmdInstall(const QString &archive, QString &errorText)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const QStringList binaryPackages = {"application/vnd.debian.binary-package", "application/x-rpm"};
|
|
||||||
if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) {
|
if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) {
|
||||||
return QDesktopServices::openUrl(QUrl(archive));
|
packageKit(PackageOperation::Install, archive);
|
||||||
}
|
}
|
||||||
const QString dir = generateDirPath(archive);
|
const QString dir = generateDirPath(archive);
|
||||||
if (QFile::exists(dir)) {
|
if (QFile::exists(dir)) {
|
||||||
|
@ -290,6 +380,9 @@ bool cmdUninstall(const QString &archive, QString &errorText)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) {
|
||||||
|
packageKit(PackageOperation::Uninstall, archive);
|
||||||
|
}
|
||||||
const QString dir = generateDirPath(archive);
|
const QString dir = generateDirPath(archive);
|
||||||
|
|
||||||
// Try "deinstall" first
|
// Try "deinstall" first
|
||||||
|
|
Loading…
Reference in New Issue
Block a user