File indexing completed on 2024-04-14 05:38:07

0001 /***************************************************************************
0002  *   Copyright (C) 2008-2011 by Daniel Nicoletti                           *
0003  *   dantti12@gmail.com                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; see the file COPYING. If not, write to       *
0017  *   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,  *
0018  *   Boston, MA 02110-1301, USA.                                           *
0019  ***************************************************************************/
0020 
0021 #include "TransactionJob.h"
0022 
0023 #include <PkStrings.h>
0024 #include <PkIcons.h>
0025 
0026 #include <KLocalizedString>
0027 //#include <KGlobal>
0028 #include <KNotification>
0029 
0030 #include <QLoggingCategory>
0031 
0032 Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON)
0033 
0034 TransactionJob::TransactionJob(Transaction *transaction, QObject *parent) :
0035     KJob(parent),
0036     m_transaction(transaction),
0037     m_status(transaction->status()),
0038     m_role(transaction->role()),
0039     m_flags(transaction->transactionFlags()),
0040     m_percentage(0),
0041     m_speed(0),
0042     m_downloadSizeRemainingTotal(0),
0043     m_finished(false)
0044 {
0045     setCapabilities(Killable);
0046 
0047     connect(transaction, &Transaction::roleChanged, this, &TransactionJob::updateJob);
0048     connect(transaction, &Transaction::statusChanged, this, &TransactionJob::updateJob);
0049     connect(transaction, &Transaction::downloadSizeRemainingChanged, this, &TransactionJob::updateJob);
0050     connect(transaction, &Transaction::transactionFlagsChanged, this, &TransactionJob::updateJob);
0051     connect(transaction, &Transaction::percentageChanged, this, &TransactionJob::updateJob);
0052     connect(transaction, &Transaction::speedChanged, this, &TransactionJob::updateJob);
0053     connect(transaction, &Transaction::finished, this, &TransactionJob::finished);
0054     connect(transaction, &Transaction::package, this, &TransactionJob::package);
0055     connect(transaction, &Transaction::repoDetail, this, &TransactionJob::repoDetail);
0056 }
0057 
0058 TransactionJob::~TransactionJob()
0059 {
0060 }
0061 
0062 void TransactionJob::finished(PackageKit::Transaction::Exit exit)
0063 {
0064     if (m_finished) {
0065         return;
0066     }
0067 
0068     // emit the description so the Speed: xxx KiB/s
0069     // don't get confused to a destination URL
0070     emit description(this, PkStrings::action(m_role, m_flags));
0071     if (exit == Transaction::ExitCancelled || exit == Transaction::ExitFailed) {
0072         setError(KilledJobError);
0073     }
0074     m_finished = true;
0075     emitResult();
0076 }
0077 
0078 void TransactionJob::package(Transaction::Info info, const QString &packageID, const QString &summary)
0079 {
0080     Q_UNUSED(summary)
0081     if (!packageID.isEmpty()) {
0082         bool changed = false;
0083         if (info == Transaction::InfoFinished) {
0084             changed = m_packages.removeOne(Transaction::packageName(packageID));
0085         } else if (!m_packages.contains(Transaction::packageName(packageID))) {
0086             m_packages << Transaction::packageName(packageID);
0087             changed = true;
0088         }
0089 
0090         if (changed) {
0091             m_details = m_packages.join(QLatin1String(", "));
0092             emitDescription();
0093         }
0094     }
0095 }
0096 
0097 void TransactionJob::repoDetail(const QString &repoId, const QString &repoDescription)
0098 {
0099     Q_UNUSED(repoId)
0100     QString first = PkStrings::status(m_status);
0101     emit description(this, PkStrings::action(m_role, m_flags), qMakePair(first, repoDescription));
0102 }
0103 
0104 void TransactionJob::emitDescription()
0105 {
0106     QString details = m_details;
0107     if (details.isEmpty()) {
0108         details = QLatin1String("...");
0109     }
0110 
0111     QString first = PkStrings::status(m_status);
0112     emit description(this, PkStrings::action(m_role, m_flags), qMakePair(first, details));
0113 }
0114 
0115 void TransactionJob::updateJob()
0116 {
0117     Transaction::Role role = m_transaction->role();
0118     Transaction::TransactionFlags flags = m_transaction->transactionFlags();
0119     if (m_role != role || m_flags != flags) {
0120         m_role = role;
0121         m_flags = flags;
0122         emitDescription();
0123     }
0124 
0125     // Status & Speed
0126     Transaction::Status status = m_transaction->status();
0127     if (m_status != status) {
0128         m_status = status;
0129         emitDescription();
0130     }
0131 
0132     uint percentage = m_transaction->percentage();
0133     if (percentage <= 100) {
0134         emitPercent(percentage, 100);
0135     } else if (m_percentage != 0) {
0136         percentage = 0;
0137         emitPercent(0, 0);
0138     }
0139     m_percentage = percentage;
0140 
0141     uint speed = m_transaction->speed();
0142     if (m_speed != speed) {
0143         m_speed = speed;
0144         emitSpeed(m_speed);
0145     }
0146 
0147     if (m_downloadSizeRemainingTotal == 0) {
0148         m_downloadSizeRemainingTotal = m_transaction->downloadSizeRemaining();
0149     }
0150 
0151     if (m_downloadSizeRemainingTotal) {
0152         qulonglong processed;
0153         processed = m_downloadSizeRemainingTotal - m_transaction->downloadSizeRemaining();
0154         emitPercent(processed, m_downloadSizeRemainingTotal);
0155     }
0156 }
0157 
0158 void TransactionJob::start()
0159 {
0160     m_role = Transaction::RoleUnknown;
0161     m_speed = 0;
0162     m_downloadSizeRemainingTotal = 0;
0163     m_details = Transaction::packageName(m_transaction->lastPackage());
0164     updateJob();
0165 }
0166 
0167 bool TransactionJob::isFinished() const
0168 {
0169     return m_finished;
0170 }
0171 
0172 Transaction *TransactionJob::transaction() const
0173 {
0174     return m_transaction;
0175 }
0176 
0177 bool TransactionJob::doKill()
0178 {
0179     // emit the description so the Speed: xxx KiB/s
0180     // don't get confused to a destination URL
0181     emit description(this, PkStrings::action(m_role, m_flags));
0182     QDBusPendingReply<> reply = m_transaction->cancel();
0183     reply.waitForFinished();
0184     qCDebug(APPER_DAEMON) << "Transaction cancel operation result" << m_transaction->tid().path() << reply.error();
0185     emit canceled();
0186 
0187     return !reply.isError() && m_transaction->role() == Transaction::RoleCancel;
0188 }
0189 
0190 #include "moc_TransactionJob.cpp"