File indexing completed on 2022-09-20 16:18:05

0001 /***************************************************************************
0002  *   Copyright (C) 2009-2018 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 "DistroUpgrade.h"
0022 
0023 #include <Daemon>
0024 
0025 #include <Enum.h>
0026 
0027 #include <KNotification>
0028 #include <KLocalizedString>
0029 #include <QIcon>
0030 
0031 #include <QLoggingCategory>
0032 
0033 Q_DECLARE_LOGGING_CATEGORY(APPER_DAEMON)
0034 
0035 DistroUpgrade::DistroUpgrade(QObject *parent) :
0036     QObject(parent),
0037     m_distroUpgradeProcess(nullptr),
0038     m_transaction(nullptr)
0039 {
0040 }
0041 
0042 DistroUpgrade::~DistroUpgrade()
0043 {
0044 }
0045 
0046 void DistroUpgrade::setConfig(const QVariantHash &configs)
0047 {
0048     m_configs = configs;
0049 }
0050 
0051 void DistroUpgrade::checkDistroUpgrades()
0052 {
0053     // Ignore check if the user disabled it
0054     if (m_configs[QLatin1String(CFG_DISTRO_UPGRADE)].toInt() == Enum::DistroNever) {
0055         return;
0056     }
0057 
0058     if (!m_transaction) {
0059         m_transaction = Daemon::getDistroUpgrades();
0060         connect(m_transaction, &Transaction::distroUpgrade, this, &DistroUpgrade::distroUpgrade);
0061         connect(m_transaction, &Transaction::finished, this, &DistroUpgrade::checkDistroFinished);
0062     }
0063 }
0064 
0065 void DistroUpgrade::distroUpgrade(PackageKit::Transaction::DistroUpgrade type, const QString &name, const QString &description)
0066 {
0067     // TODO make use of the type
0068     switch (m_configs[QLatin1String(CFG_DISTRO_UPGRADE)].toInt()) {
0069     case Enum::DistroNever:
0070         return;
0071     case Enum::DistroStable:
0072         if (type != Transaction::DistroUpgradeStable) {
0073             // The user only wants to know about stable releases
0074             return;
0075         }
0076     default:
0077         break;
0078     }
0079 
0080     qCDebug(APPER_DAEMON) << "Distro upgrade found!" << name << description;
0081     if (m_shownDistroUpgrades.contains(name)) {
0082         // ignore distro upgrade if the user already saw it
0083         return;
0084     }
0085 
0086     auto notify = new KNotification(QLatin1String("DistroUpgradeAvailable"), nullptr, KNotification::Persistent);
0087     notify->setComponentName(QLatin1String("apperd"));
0088     notify->setTitle(i18n("Distribution upgrade available"));
0089     notify->setText(description);
0090 
0091     QStringList actions;
0092     actions << i18n("Start upgrade now");
0093     notify->setActions(actions);
0094     connect(notify, SIGNAL(activated(uint)),
0095             this, SLOT(handleDistroUpgradeAction(uint)));
0096     notify->sendEvent();
0097     m_shownDistroUpgrades << name;
0098 }
0099 
0100 void DistroUpgrade::checkDistroFinished(Transaction::Exit status, uint enlapsed)
0101 {
0102     Q_UNUSED(status)
0103     Q_UNUSED(enlapsed)
0104     m_transaction = nullptr;
0105 }
0106 
0107 void DistroUpgrade::handleDistroUpgradeAction(uint action)
0108 {
0109     // get the sender cause there might be more than one
0110     auto notify = qobject_cast<KNotification*>(sender());
0111     switch(action) {
0112         case 1:
0113             // Check to see if there isn't another process running
0114             if (m_distroUpgradeProcess) {
0115                 // if so we BREAK otherwise our running count gets
0116                 // lost, and we leak as we don't close the caller.
0117                 break;
0118             }
0119             m_distroUpgradeProcess = new QProcess;
0120             connect (m_distroUpgradeProcess, &QProcess::errorOccurred, this, &DistroUpgrade::distroUpgradeError);
0121             connect (m_distroUpgradeProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &DistroUpgrade::distroUpgradeFinished);
0122             QStringList env = QProcess::systemEnvironment();
0123             env.append(QStringLiteral("DESKTOP=kde"));
0124             m_distroUpgradeProcess->setEnvironment(env);
0125             m_distroUpgradeProcess->start(QStringLiteral("/usr/share/PackageKit/pk-upgrade-distro.sh"));
0126             // TODO
0127 //             suppressSleep(true);
0128             break;
0129         // perhaps more actions needed in the future
0130     }
0131     // in persistent mode we need to manually close it
0132     notify->close();
0133 }
0134 
0135 void DistroUpgrade::distroUpgradeFinished(int exitCode, QProcess::ExitStatus exitStatus)
0136 {
0137     auto notify = new KNotification(QLatin1String("DistroUpgradeFinished"));
0138     notify->setComponentName(QLatin1String("apperd"));
0139     if (exitStatus == QProcess::NormalExit && exitCode == 0) {
0140         notify->setPixmap(QIcon::fromTheme(QLatin1String("security-high")).pixmap(64, 64));
0141         notify->setText(i18n("Distribution upgrade finished. "));
0142     } else if (exitStatus == QProcess::NormalExit) {
0143         notify->setPixmap(QIcon::fromTheme(QLatin1String("dialog-warning")).pixmap(64, 64));
0144         notify->setText(i18n("Distribution upgrade process exited with code %1.", exitCode));
0145     }/* else {
0146         notify->setText(i18n("Distribution upgrade didn't exit normally, the process probably crashed. "));
0147     }*/
0148     notify->sendEvent();
0149     m_distroUpgradeProcess->deleteLater();
0150     m_distroUpgradeProcess = nullptr;
0151 //     suppressSleep(false);
0152 }
0153 
0154 void DistroUpgrade::distroUpgradeError(QProcess::ProcessError error)
0155 {
0156     QString text;
0157 
0158     auto notify = new KNotification(QLatin1String("DistroUpgradeError"));
0159     notify->setComponentName(QLatin1String("apperd"));
0160     switch(error) {
0161         case QProcess::FailedToStart:
0162             text = i18n("The distribution upgrade process failed to start.");
0163             break;
0164         case QProcess::Crashed:
0165             text = i18n("The distribution upgrade process crashed some time after starting successfully.") ;
0166             break;
0167         default:
0168             text = i18n("The distribution upgrade process failed with an unknown error.");
0169             break;
0170     }
0171     notify->setPixmap(QIcon::fromTheme(QLatin1String("dialog-error")).pixmap(64,64));
0172     notify->setText(text);
0173     notify->sendEvent();
0174 }
0175 
0176 #include "moc_DistroUpgrade.cpp"