diff --git a/dist/arch/plasma-appimage-integration-git.install b/dist/arch/plasma-appimage-integration-git.install index 9a9a0747af63fc4dd3752dde11b577dc6523588a..d1a876523953e5d8764bc492bcf2ec71213d8bdd 100755 --- a/dist/arch/plasma-appimage-integration-git.install +++ b/dist/arch/plasma-appimage-integration-git.install @@ -6,16 +6,11 @@ post_install() { APPIMAGE_SERVICES_BIN_PATH=/usr/bin/appimage-services APPIMAGE_SERVICES_URL="https://www.opencode.net/azubieta/AppImageService/-/jobs/artifacts/master/raw/appimage-services-x86_64.AppImage?job=build:AppImage" - if [ -f "$APPIMAGE_SERVICES_BIN_PATH" ] - then - echo "Using appimamge-services bin from $APPIMAGE_SERVICES_BIN_PATH" - else - echo "Installing appimage-services to $APPIMAGE_SERVICES_BIN_PATH" - wget "$APPIMAGE_SERVICES_URL" -O "$APPIMAGE_SERVICES_BIN_PATH" + echo "Installing appimage-services to $APPIMAGE_SERVICES_BIN_PATH" + wget -N "$APPIMAGE_SERVICES_URL" -O "$APPIMAGE_SERVICES_BIN_PATH" - chmod +x "$APPIMAGE_SERVICES_BIN_PATH" - "$APPIMAGE_SERVICES_BIN_PATH" self-install - fi + chmod +x "$APPIMAGE_SERVICES_BIN_PATH" + "$APPIMAGE_SERVICES_BIN_PATH" self-install } ## arg 1: the old package version diff --git a/dist/deb/postinst b/dist/deb/postinst index 676310e55ac644b2b828405adbbbd4dd5b5e25dc..de626ecd6a59e1aeb1862d038f9a744c266220f0 100755 --- a/dist/deb/postinst +++ b/dist/deb/postinst @@ -4,13 +4,8 @@ set -e APPIMAGE_SERVICES_BIN_PATH=/usr/bin/appimage-services APPIMAGE_SERVICES_URL="https://www.opencode.net/azubieta/AppImageService/-/jobs/artifacts/master/raw/appimage-services-x86_64.AppImage?job=build:AppImage" -if [ -f "$APPIMAGE_SERVICES_BIN_PATH" ] -then - echo "Using appimamge-services bin from $APPIMAGE_SERVICES_BIN_PATH" -else - echo "Installing appimage-services to $APPIMAGE_SERVICES_BIN_PATH" - wget "$APPIMAGE_SERVICES_URL" -O "$APPIMAGE_SERVICES_BIN_PATH" +echo "Installing appimage-services to $APPIMAGE_SERVICES_BIN_PATH" +wget -N "$APPIMAGE_SERVICES_URL" -O "$APPIMAGE_SERVICES_BIN_PATH" - chmod +x "$APPIMAGE_SERVICES_BIN_PATH" - "$APPIMAGE_SERVICES_BIN_PATH" self-install -fi +chmod +x "$APPIMAGE_SERVICES_BIN_PATH" +"$APPIMAGE_SERVICES_BIN_PATH" self-install \ No newline at end of file diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 2db6cfc26a37336997e79eade6bda1c3e1c4fad4..ede1a1408906fa5d367eaeefd4553ae52af4a541 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -1 +1 @@ -install(FILES "AppImage Services.conf" DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/The AppImage Project") +install(FILES "org.appimage.services.conf" DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xdg") diff --git a/res/AppImage Services.conf b/res/org.appimage.services.conf similarity index 65% rename from res/AppImage Services.conf rename to res/org.appimage.services.conf index 6d9f8151510407898fafaf0f3d3a95d1d02ccb4a..7efdc87d5dd1cdfa9a3f5055e7a0bc8d8dff50e0 100644 --- a/res/AppImage Services.conf +++ b/res/org.appimage.services.conf @@ -4,3 +4,6 @@ RemoveCommandArgs=remove %1 UpdateCommand=plasma-appimage-integration UpdateCommandArgs=update %1 + +UninstallCommand=plasma-appimage-integration +UninstallCommandArgs=uninstall %1 diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt index 3e1d9ba01f7f82813ea81b244d250fffe05719ef..e2680510be15ff152af27abe7aee8daca5e3d47a 100644 --- a/src/bin/CMakeLists.txt +++ b/src/bin/CMakeLists.txt @@ -3,6 +3,8 @@ add_executable( main.cpp UpdateJob.cpp RemoveJob.cpp + InstallJob.cpp + UninstallJob.cpp ) target_link_libraries(plasma-appimage-integration appimageservices-interfaces KF5::KIOWidgets KF5::I18n KF5::Notifications) diff --git a/src/bin/InstallJob.cpp b/src/bin/InstallJob.cpp new file mode 100644 index 0000000000000000000000000000000000000000..171c73c6ca4bfb5656d148cf5c2bb516c061e5d3 --- /dev/null +++ b/src/bin/InstallJob.cpp @@ -0,0 +1,34 @@ +// libraries +#include +#include +#include +#include + +// local +#include "InstallJob.h" + +InstallJob::InstallJob(QString target, QObject* parent) : KJob(parent), target(std::move(target)) {} + +void InstallJob::start() { + process.setProgram("pkexec"); + process.setArguments({"appimage-services", "install", target}); + qDebug() << "calling pkexec appimage-services install " << target; + + connect(&process, SIGNAL(finished(int)), this, SLOT(onProcessFinished(int))); + description(this, i18n("Installing Application"), + qMakePair(i18nc("The AppImage being installed", "Source"), target)); + + process.start(); +} + +void InstallJob::onProcessFinished(int exitCode) { + qDebug() << exitCode; + qDebug() << process.errorString(); + if (exitCode != 0) { + setError(exitCode); + setErrorText(process.readAllStandardError()); + } + + // notify result delayed + QTimer::singleShot(1000, this, &InstallJob::emitResult); +} diff --git a/src/bin/InstallJob.h b/src/bin/InstallJob.h new file mode 100644 index 0000000000000000000000000000000000000000..a33cb5f0181a02ca8eb48f99e7e16e548fbbbc90 --- /dev/null +++ b/src/bin/InstallJob.h @@ -0,0 +1,21 @@ +#pragma once + +// libraries +#include +#include + +class InstallJob : public KJob { +Q_OBJECT +public: + explicit InstallJob(QString target, QObject* parent = nullptr); + + void start() override; + +protected slots: + + void onProcessFinished(int exitCode); + +private: + QString target; + QProcess process; +}; diff --git a/src/bin/UninstallJob.cpp b/src/bin/UninstallJob.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b9ffd6d8273cc3023b7729622282578ff666f72 --- /dev/null +++ b/src/bin/UninstallJob.cpp @@ -0,0 +1,34 @@ +// libraries +#include +#include +#include +#include + +// local +#include "UninstallJob.h" + +UninstallJob::UninstallJob(QString target, QObject* parent) : KJob(parent), target(std::move(target)) {} + +void UninstallJob::start() { + process.setProgram("pkexec"); + process.setArguments({"appimage-services", "uninstall", target}); + qDebug() << "calling pkexec appimage-services install " << target; + + connect(&process, SIGNAL(finished(int)), this, SLOT(onProcessFinished(int))); + description(this, i18n("Uninstalling Application"), + qMakePair(i18nc("The AppImage being uninstalled", "Source"), target)); + + process.start(); +} + +void UninstallJob::onProcessFinished(int exitCode) { + qDebug() << exitCode; + qDebug() << process.errorString(); + if (exitCode != 0) { + setError(exitCode); + setErrorText(process.readAllStandardError()); + } + + // notify result delayed + QTimer::singleShot(1000, this, &UninstallJob::emitResult); +} diff --git a/src/bin/UninstallJob.h b/src/bin/UninstallJob.h new file mode 100644 index 0000000000000000000000000000000000000000..d72bf8af8ee7b25b6fd3b17f7256ad9133a93c45 --- /dev/null +++ b/src/bin/UninstallJob.h @@ -0,0 +1,21 @@ +#pragma once + +// libraries +#include +#include + +class UninstallJob : public KJob { +Q_OBJECT +public: + explicit UninstallJob(QString target, QObject* parent = nullptr); + + void start() override; + +protected slots: + + void onProcessFinished(int exitCode); + +private: + QString target; + QProcess process; +}; diff --git a/src/bin/main.cpp b/src/bin/main.cpp index 800efef33eb61d2c943e0b760b00db1ff9e4e03f..22b809c0be0370ed84a768463c13b97841064b57 100644 --- a/src/bin/main.cpp +++ b/src/bin/main.cpp @@ -11,6 +11,8 @@ // local #include "UpdateJob.h" #include "RemoveJob.h" +#include "InstallJob.h" +#include "UninstallJob.h" QString parseTarget(QCommandLineParser& parser) { @@ -51,6 +53,20 @@ void executeRemoveCommand(const QString& target) { } +void executeInstallCommand(const QString& target) { + KJob* job = new InstallJob(target); + + KIO::getJobTracker()->registerJob(job); + job->start(); +} + +void executeUninstallCommand(const QString& target) { + KJob* job = new UninstallJob(target); + + KIO::getJobTracker()->registerJob(job); + job->start(); +} + int main(int argc, char** argv) { QApplication app(argc, argv); QApplication::setApplicationName("plasma-appimage-integration"); @@ -82,6 +98,15 @@ int main(int argc, char** argv) { executeRemoveCommand(target); } + if (command == "install") { + QString target = parseTarget(parser); + executeInstallCommand(target); + } + + if (command == "uninstall") { + QString target = parseTarget(parser); + executeUninstallCommand(target); + } return QApplication::exec(); } diff --git a/src/fileitem-actions/AppImageFileItemActions.cpp b/src/fileitem-actions/AppImageFileItemActions.cpp index 492a47664035a0a2b6d9dab016f68e2394bfdc82..8552cffc442e0fab712685968713261b9d4b8c38 100644 --- a/src/fileitem-actions/AppImageFileItemActions.cpp +++ b/src/fileitem-actions/AppImageFileItemActions.cpp @@ -27,33 +27,38 @@ AppImageFileItemActions::AppImageFileItemActions(QObject* parent, const QVariant "/org/appimage/Services1/Updater", QDBusConnection::sessionBus(), this)) { - if (!launcherInterface->isValid()) - qWarning() << "Unable to connect to the AppImage Launcher Service"; - if (!updaterInterface->isValid()) - qWarning() << "Unable to connect to the AppImage Updater Service"; } QList AppImageFileItemActions::actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) { QList actions; - - const QList urlList = fileItemInfos.urlList(); - if (urlList.size() == 1) { - if (launcherInterface->isRegistered(urlList.first().toString())) - actions += createRemoveFromMenuAction(fileItemInfos, parentWidget); - else + if (launcherInterface->isValid()) { + const QList urlList = fileItemInfos.urlList(); + if (urlList.size() == 1) { + if (launcherInterface->isRegistered(urlList.first().toString())) + actions += createRemoveFromMenuAction(fileItemInfos, parentWidget); + else + actions += createAddToMenuAction(fileItemInfos, parentWidget); + } else { actions += createAddToMenuAction(fileItemInfos, parentWidget); + actions += createRemoveFromMenuAction(fileItemInfos, parentWidget); + } + } else { + qWarning() << "Discarding AppImage Add/Remove to Menu actions. Unable to connect to the AppImage Launcher Service"; + } + + if (launcherInterface->isValid()) { + QAction* updateAction = new QAction(QIcon::fromTheme("update-none"), "Update", parentWidget); + updateAction->setProperty("urls", QVariant::fromValue(fileItemInfos.urlList())); + updateAction->setProperty("parentWidget", QVariant::fromValue(parentWidget)); + connect(updateAction, &QAction::triggered, this, &AppImageFileItemActions::update); + actions += updateAction; } else { - actions += createAddToMenuAction(fileItemInfos, parentWidget); - actions += createRemoveFromMenuAction(fileItemInfos, parentWidget); + qWarning() << "Discarding AppImage Update action. Unable to connect to the AppImage Launcher Updater"; } - QAction* updateAction = new QAction(QIcon::fromTheme("update-none"), "Update", parentWidget); - updateAction->setProperty("urls", QVariant::fromValue(fileItemInfos.urlList())); - updateAction->setProperty("parentWidget", QVariant::fromValue(parentWidget)); - connect(updateAction, &QAction::triggered, this, &AppImageFileItemActions::update); - actions += updateAction; + actions += createInstallAction(fileItemInfos, parentWidget); return actions; } @@ -78,6 +83,15 @@ QAction* AppImageFileItemActions::createAddToMenuAction(const KFileItemListPrope return addToMenuAction; } +QAction *AppImageFileItemActions::createInstallAction(const KFileItemListProperties &fileItemInfos, + QWidget *parentWidget) const { + QAction* installAction = new QAction(QIcon::fromTheme("install"), "Install", parentWidget); + installAction->setProperty("urls", QVariant::fromValue(fileItemInfos.urlList())); + installAction->setProperty("parentWidget", QVariant::fromValue(parentWidget)); + connect(installAction, &QAction::triggered, this, &AppImageFileItemActions::install); + return installAction; +} + void AppImageFileItemActions::addToMenu() { const QList urls = sender()->property("urls").value>(); QWidget* parentWidget = sender()->property("parentWidget").value(); @@ -120,6 +134,18 @@ void AppImageFileItemActions::update() { } } +void AppImageFileItemActions::install() { + const QList urls = sender()->property("urls").value>(); + QString program = "plasma-appimage-integration"; + + for (const QUrl& url : urls) { + QStringList arguments; + arguments << "install" << url.toLocalFile(); + + QProcess::startDetached(program, arguments); + } +} + void AppImageFileItemActions::showErrorMessage(const QString& title, const QString& message, QWidget* parentWidget) { KNotification* notify = new KNotification(QStringLiteral("notification"), parentWidget, KNotification::CloseOnTimeout | KNotification::DefaultEvent); diff --git a/src/fileitem-actions/AppImageFileItemActions.h b/src/fileitem-actions/AppImageFileItemActions.h index 505858ff68bd4de9f79e9aac09f6099d0aecf670..6d49ae6f1e4a05f87d34e298a74ac806b96110c4 100644 --- a/src/fileitem-actions/AppImageFileItemActions.h +++ b/src/fileitem-actions/AppImageFileItemActions.h @@ -33,6 +33,8 @@ private Q_SLOTS: void update(); + void install(); + private: OrgAppimageServices1LauncherInterface* launcherInterface; OrgAppimageServices1UpdaterInterface* updaterInterface; @@ -42,4 +44,6 @@ private: QAction* createAddToMenuAction(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) const; QAction* createRemoveFromMenuAction(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) const; + + QAction* createInstallAction(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) const; };