File indexing completed on 2024-04-21 05:45:48

0001 /*******************************************************************************
0002  * Copyright (C) 2008-2013 Konstantinos Smanis <konstantinos.smanis@gmail.com> *
0003  *                                                                             *
0004  * This program is free software: you can redistribute it and/or modify it     *
0005  * under the terms of the GNU General Public License as published by the Free  *
0006  * Software Foundation, either version 3 of the License, or (at your option)   *
0007  * any later version.                                                          *
0008  *                                                                             *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT *
0010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
0011  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
0012  * more details.                                                               *
0013  *                                                                             *
0014  * You should have received a copy of the GNU General Public License along     *
0015  * with this program. If not, see <http://www.gnu.org/licenses/>.              *
0016  *******************************************************************************/
0017 
0018 //Own
0019 #include "qPkBackend.h"
0020 
0021 //Qt
0022 #include <QEventLoop>
0023 
0024 //KDE
0025 #include <KLocalizedString>
0026 
0027 //PackageKit
0028 #include <PackageKit/Daemon>
0029 
0030 //Taken from KDE playground/sysadmin/apper "as is"
0031 static QString statusToString(PackageKit::Transaction::Status status)
0032 {
0033     switch (status) {
0034     case PackageKit::Transaction::StatusSetup:
0035         return i18nc("transaction state, the daemon is in the process of starting",
0036                      "Waiting for service to start");
0037     case PackageKit::Transaction::StatusWait:
0038         return i18nc("transaction state, the transaction is waiting for another to complete",
0039                      "Waiting for other tasks");
0040     case PackageKit::Transaction::StatusRunning:
0041         return i18nc("transaction state, just started",
0042                      "Running task");
0043     case PackageKit::Transaction::StatusQuery:
0044         return i18nc("transaction state, is querying data",
0045                      "Querying");
0046     case PackageKit::Transaction::StatusInfo:
0047         return i18nc("transaction state, getting data from a server",
0048                      "Getting information");
0049     case PackageKit::Transaction::StatusRemove:
0050         return i18nc("transaction state, removing packages",
0051                      "Removing packages");
0052     case PackageKit::Transaction::StatusDownload:
0053         return i18nc("transaction state, downloading package files",
0054                      "Downloading packages");
0055     case PackageKit::Transaction::StatusInstall:
0056         return i18nc("transaction state, installing packages",
0057                      "Installing packages");
0058     case PackageKit::Transaction::StatusRefreshCache:
0059         return i18nc("transaction state, refreshing internal lists",
0060                      "Refreshing software list");
0061     case PackageKit::Transaction::StatusUpdate:
0062         return i18nc("transaction state, installing updates",
0063                      "Updating packages");
0064     case PackageKit::Transaction::StatusCleanup:
0065         return i18nc("transaction state, removing old packages, and cleaning config files",
0066                      "Cleaning up packages");
0067     case PackageKit::Transaction::StatusObsolete:
0068         return i18nc("transaction state, obsoleting old packages",
0069                      "Obsoleting packages");
0070     case PackageKit::Transaction::StatusDepResolve:
0071         return i18nc("transaction state, checking the transaction before we do it",
0072                      "Resolving dependencies");
0073     case PackageKit::Transaction::StatusSigCheck:
0074         return i18nc("transaction state, checking if we have all the security keys for the operation",
0075                      "Checking signatures");
0076     case PackageKit::Transaction::StatusTestCommit:
0077         return i18nc("transaction state, when we're doing a test transaction",
0078                      "Testing changes");
0079     case PackageKit::Transaction::StatusCommit:
0080         return i18nc("transaction state, when we're writing to the system package database",
0081                      "Committing changes");
0082     case PackageKit::Transaction::StatusRequest:
0083         return i18nc("transaction state, requesting data from a server",
0084                      "Requesting data");
0085     case PackageKit::Transaction::StatusFinished:
0086         return i18nc("transaction state, all done!",
0087                      "Finished");
0088     case PackageKit::Transaction::StatusCancel:
0089         return i18nc("transaction state, in the process of cancelling",
0090                      "Cancelling");
0091     case PackageKit::Transaction::StatusDownloadRepository:
0092         return i18nc("transaction state, downloading metadata",
0093                      "Downloading repository information");
0094     case PackageKit::Transaction::StatusDownloadPackagelist:
0095         return i18nc("transaction state, downloading metadata",
0096                      "Downloading list of packages");
0097     case PackageKit::Transaction::StatusDownloadFilelist:
0098         return i18nc("transaction state, downloading metadata",
0099                      "Downloading file lists");
0100     case PackageKit::Transaction::StatusDownloadChangelog:
0101         return i18nc("transaction state, downloading metadata",
0102                      "Downloading lists of changes");
0103     case PackageKit::Transaction::StatusDownloadGroup:
0104         return i18nc("transaction state, downloading metadata",
0105                      "Downloading groups");
0106     case PackageKit::Transaction::StatusDownloadUpdateinfo:
0107         return i18nc("transaction state, downloading metadata",
0108                      "Downloading update information");
0109     case PackageKit::Transaction::StatusRepackaging:
0110         return i18nc("transaction state, repackaging delta files",
0111                      "Repackaging files");
0112     case PackageKit::Transaction::StatusLoadingCache:
0113         return i18nc("transaction state, loading databases",
0114                      "Loading cache");
0115     case PackageKit::Transaction::StatusScanApplications:
0116         return i18nc("transaction state, scanning for running processes",
0117                      "Scanning installed applications");
0118     case PackageKit::Transaction::StatusGeneratePackageList:
0119         return i18nc("transaction state, generating a list of packages installed on the system",
0120                      "Generating package lists");
0121     case PackageKit::Transaction::StatusWaitingForLock:
0122         return i18nc("transaction state, when we're waiting for the native tools to exit",
0123                      "Waiting for package manager lock");
0124     case PackageKit::Transaction::StatusWaitingForAuth:
0125         return i18nc("waiting for user to type in a password",
0126                      "Waiting for authentication");
0127     case PackageKit::Transaction::StatusScanProcessList:
0128         return i18nc("we are updating the list of processes",
0129                      "Updating the list of running applications");
0130     case PackageKit::Transaction::StatusCheckExecutableFiles:
0131         return i18nc("we are checking executable files in use",
0132                      "Checking for applications currently in use");
0133     case PackageKit::Transaction::StatusCheckLibraries:
0134         return i18nc("we are checking for libraries in use",
0135                      "Checking for libraries currently in use");
0136     case PackageKit::Transaction::StatusCopyFiles:
0137         return i18nc("we are copying package files to prepare to install",
0138                      "Copying files");
0139     case PackageKit::Transaction::StatusRunHook:
0140         return i18nc("we are running the install hooks", "Running install hooks");
0141     case PackageKit::Transaction::StatusUnknown:
0142         return i18nc("we received an unknown status", "Unknown status");
0143     }
0144     return QString();
0145 }
0146 
0147 QPkBackend::QPkBackend(QObject *parent) : QObject(parent)
0148 {
0149     m_t = nullptr;
0150 }
0151 QPkBackend::~QPkBackend()
0152 {
0153 }
0154 
0155 QStringList QPkBackend::ownerPackage(const QString &fileName)
0156 {
0157     auto *t = PackageKit::Daemon::searchFiles(fileName);
0158     m_packageId.clear();
0159     QEventLoop loop;
0160     connect(t, &PackageKit::Transaction::finished, &loop, &QEventLoop::quit);
0161     connect(t, &PackageKit::Transaction::finished, this, &QPkBackend::slotFinished);
0162     connect(t, &PackageKit::Transaction::package, this, &QPkBackend::slotPackage);
0163     loop.exec();
0164     return m_status == PackageKit::Transaction::ExitSuccess && !m_packageId.isNull() ?
0165                 QStringList() << PackageKit::Transaction::packageName(m_packageId) << PackageKit::Transaction::packageVersion(m_packageId) : QStringList();
0166 }
0167 void QPkBackend::markForRemoval(const QString &packageName)
0168 {
0169     if (!m_remove.contains(packageName) && packageExists(packageName)) {
0170         m_remove.append(PackageKit::Transaction::packageName(m_packageId));
0171         m_removeIds.append(m_packageId);
0172     }
0173 }
0174 QStringList QPkBackend::markedForRemoval() const
0175 {
0176     return m_remove;
0177 }
0178 void QPkBackend::removePackages()
0179 {
0180     m_t = PackageKit::Daemon::removePackages(m_removeIds, false, true);
0181     connect(m_t, &PackageKit::Transaction::percentageChanged, this, &QPkBackend::slotUpdateProgress);
0182     connect(m_t, &PackageKit::Transaction::statusChanged, this, &QPkBackend::slotUpdateProgress);
0183     connect(m_t, &PackageKit::Transaction::finished, this, &QPkBackend::slotFinished);
0184 }
0185 void QPkBackend::undoChanges()
0186 {
0187     m_remove.clear();
0188     m_removeIds.clear();
0189 }
0190 
0191 void QPkBackend::slotFinished(PackageKit::Transaction::Exit status, uint runtime)
0192 {
0193     Q_UNUSED(runtime)
0194     m_status = status;
0195     if (m_t && m_t->role() == PackageKit::Transaction::RoleRemovePackages) {
0196         Q_EMIT finished(m_status == PackageKit::Transaction::ExitSuccess);
0197     }
0198 }
0199 void QPkBackend::slotPackage(PackageKit::Transaction::Info, const QString &packageId, const QString &)
0200 {
0201     m_packageId = packageId;
0202 }
0203 void QPkBackend::slotUpdateProgress()
0204 {
0205     Q_EMIT progress(statusToString(m_t->status()), m_t->percentage());
0206 }
0207 
0208 bool QPkBackend::packageExists(const QString &packageName)
0209 {
0210     auto *t = PackageKit::Daemon::resolve(packageName);
0211     m_packageId.clear();
0212     QEventLoop loop;
0213     connect(t, &PackageKit::Transaction::finished, &loop, &QEventLoop::quit);
0214     connect(t, &PackageKit::Transaction::finished, this, &QPkBackend::slotFinished);
0215     connect(t, &PackageKit::Transaction::package, this, &QPkBackend::slotPackage);
0216     loop.exec();
0217     return m_status == PackageKit::Transaction::ExitSuccess && !m_packageId.isNull();
0218 }