File indexing completed on 2024-06-16 05:08:59

0001 /*
0002     SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.lohnau@gmx.de>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 
0006 #include <KLocalizedString>
0007 #include <KMessageBox>
0008 #include <KOSRelease>
0009 #include <QApplication>
0010 #include <QCommandLineParser>
0011 #include <QDebug>
0012 #include <QDir>
0013 #include <QFileInfo>
0014 #include <QMimeDatabase>
0015 #include <QStandardPaths>
0016 #include <QUrl>
0017 
0018 #include "KRunnerPlugininstallerRcJob.h"
0019 #include "config-workspace.h"
0020 #if HAVE_PACKAGEKIT
0021 #include "PackageKitJob.h"
0022 #endif
0023 #include "ScriptJob.h"
0024 #include "ZypperRPMJob.h"
0025 
0026 void fail(const QString &str)
0027 {
0028     if (str.isEmpty()) {
0029         // 130 means Ctrl+C as an exit code this is interpreted by KNewStuff as cancel operation
0030         // and no error will be displayed to the user, BUG: 436355
0031         qApp->exit(130);
0032     } else {
0033         KMessageBox::error(nullptr, str, i18nc("@info", "KRunner plugin installation failed"));
0034         qApp->exit(1);
0035     }
0036 }
0037 
0038 int main(int argc, char *argv[])
0039 {
0040     QApplication app(argc, argv);
0041     app.setQuitOnLastWindowClosed(false);
0042 
0043     if (qEnvironmentVariableIsSet("PLUGININSTALLER_TEST_MODE")) {
0044         QStandardPaths::setTestModeEnabled(true);
0045     }
0046 
0047     QCommandLineParser parser;
0048     parser.addPositionalArgument(QStringLiteral("command"), i18nc("@info:shell", "Command to execute: install or uninstall."));
0049     parser.addPositionalArgument(QStringLiteral("path"), i18nc("@info:shell", "Path to archive."));
0050     QCommandLineOption noConfirm(QStringLiteral("no-confirm"), i18nc("@info:shell", "Do not show a visual confirmation dialog"));
0051     parser.addOption(noConfirm);
0052     parser.process(app);
0053 
0054     const QStringList args = parser.positionalArguments();
0055     if (args.isEmpty()) {
0056         qWarning() << "Command is required";
0057         return 1;
0058     }
0059     if (args.size() == 1) {
0060         qWarning() << "Path to archive is required";
0061         return 1;
0062     }
0063 
0064     const QString cmd = args.at(0);
0065     const QString file = args.at(1);
0066     const QStringList binaryPackages = {
0067         QStringLiteral("application/vnd.debian.binary-package"),
0068         QStringLiteral("application/x-rpm"),
0069         QStringLiteral("application/x-xz"),
0070         QStringLiteral("application/zstd"),
0071     };
0072     bool install;
0073     if (cmd == QLatin1String("install")) {
0074         install = true;
0075     } else if (cmd == QLatin1String("uninstall")) {
0076         install = false;
0077     } else {
0078         qWarning() << "Unsupported command" << cmd;
0079         return 1;
0080     }
0081 
0082     std::unique_ptr<AbstractJob> job;
0083     QFileInfo fileInfo(file);
0084     const QString mimeType = QMimeDatabase().mimeTypeForFile(fileInfo).name();
0085     if (mimeType == QLatin1String("application/x-rpm") && KOSRelease().idLike().contains(u"suse")) {
0086         job.reset(new ZypperRPMJob());
0087     } else if (binaryPackages.contains(mimeType)) {
0088 #if HAVE_PACKAGEKIT
0089         job.reset(new PackageKitJob());
0090 #else
0091         fail(i18nc("@info", "No PackageKit support"));
0092 #endif
0093     } else if (const QString rcPath = QDir(file).filePath("krunner-plugininstallerrc"); fileInfo.isDir() && QFileInfo::exists(rcPath)) {
0094         fileInfo = QFileInfo(rcPath);
0095         job.reset(new KRunnerPluginInstallerRcJob(parser.isSet(noConfirm)));
0096     } else {
0097         job.reset(new ScriptJob());
0098     }
0099 
0100     QObject::connect(
0101         job.get(),
0102         &AbstractJob::finished,
0103         qApp,
0104         []() {
0105             qApp->exit();
0106         },
0107         Qt::QueuedConnection);
0108     QObject::connect(
0109         job.get(),
0110         &AbstractJob::error,
0111         qApp,
0112         [](const QString &error) {
0113             fail(error);
0114         },
0115         Qt::QueuedConnection);
0116 
0117     job->executeOperation(fileInfo, mimeType, install);
0118 
0119     return app.exec();
0120 }