File indexing completed on 2024-07-21 04:35:15

0001 /*
0002     SPDX-FileCopyrightText: 2024 Ralf Habacker ralf.habacker @freenet.de
0003 
0004     This file is part of libalkimia.
0005 
0006     SPDX-License-Identifier: LGPL-2.1-or-later
0007 */
0008 
0009 #include "alknewstuffengine.h"
0010 
0011 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0012     #include <knscore/engine.h>
0013     #include <knewstuff_version.h>
0014 #else
0015     #include <knewstuff3/downloadmanager.h>
0016     #define KNEWSTUFF_VERSION 0
0017 #endif
0018 
0019 #include <QEventLoop>
0020 #include <QtDebug>
0021 #include <QPointer>
0022 #include <QWidget>
0023 
0024 class AlkNewStuffEngine::Private : public QObject
0025 {
0026     Q_OBJECT
0027 public:
0028     AlkNewStuffEngine *q;
0029 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0030     QPointer<KNSCore::Engine> m_engine;
0031     bool m_providersLoaded{false};
0032     bool m_wantUpdates{false};
0033 #else
0034     QPointer<KNS3::DownloadManager> m_engine;
0035 #endif
0036     QEventLoop m_loop;
0037     AlkNewStuffEntryList m_availableEntries;
0038 
0039     explicit Private(AlkNewStuffEngine *parent);
0040     ~Private();
0041 
0042     bool init(const QString &configFile);
0043     void checkForUpdates();
0044 
0045     const AlkNewStuffEntryList installedEntries();
0046 
0047 public Q_SLOTS:
0048     void slotUpdatesAvailable(const KNS3::Entry::List &entries);
0049     void slotEntriesAvailable(const KNS3::Entry::List &entries);
0050 };
0051 
0052 AlkNewStuffEngine::Private::Private(AlkNewStuffEngine *parent)
0053     : q(parent), m_engine(nullptr) {}
0054 
0055 AlkNewStuffEngine::Private::~Private() { delete m_engine; }
0056 
0057 bool AlkNewStuffEngine::Private::init(const QString &configFile)
0058 {
0059     bool state = false;
0060 #if KNEWSTUFF_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0061     m_engine = new KNSCore::Engine(this);
0062     state = m_engine->init(configFile);
0063     if (!state)
0064         return false;
0065 
0066     connect(m_engine, &KNSCore::Engine::signalProvidersLoaded, this, [this]()
0067     {
0068         qDebug() << Q_FUNC_INFO << "providers loaded";
0069         m_providersLoaded = true;
0070         if (m_wantUpdates)
0071             m_engine->checkForUpdates();
0072     });
0073 
0074     connect(m_engine, &KNSCore::Engine::signalUpdateableEntriesLoaded, this, [this](const KNSCore::EntryInternal::List &entries)
0075     {
0076         qDebug() << Q_FUNC_INFO << "updates loaded";
0077         AlkNewStuffEntryList updateEntries;
0078         for (const KNSCore::EntryInternal &entry : entries) {
0079             AlkNewStuffEntry e;
0080             e.category = entry.category();
0081             e.id = entry.uniqueId();
0082             e.installedFiles = entry.installedFiles();
0083             e.name = entry.name();
0084             e.providerId = entry.providerId();
0085             e.status =
0086                 static_cast<AlkNewStuffEntry::Status>(entry.status());
0087             e.version = entry.version();
0088             updateEntries.append(e);
0089             qDebug() << Q_FUNC_INFO << e.name << toString(e.status);
0090         }
0091         Q_EMIT q->updatesAvailable(updateEntries);
0092     });
0093 #else
0094     m_engine = new KNS3::DownloadManager(configFile, this);
0095     // no chance get the state
0096     state = true;
0097 
0098     connect(m_engine, SIGNAL(searchResult(KNS3::Entry::List)), this,
0099             SLOT(slotUpdatesAvailable(KNS3::Entry::List)));
0100 #endif
0101     return state;
0102 }
0103 
0104 void AlkNewStuffEngine::Private::checkForUpdates()
0105 {
0106 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0107     if (m_providersLoaded && !m_wantUpdates) {
0108         m_engine->checkForUpdates();
0109     } else
0110         m_wantUpdates = true;
0111 #else
0112     m_engine->checkForUpdates();
0113 #endif
0114 }
0115 
0116 const AlkNewStuffEntryList AlkNewStuffEngine::Private::installedEntries()
0117 {
0118     if (m_availableEntries.empty()) {
0119         m_engine->setSearchTerm("*");
0120 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0121         QMetaObject::Connection conn;
0122         conn = QObject::connect(m_engine, &KNSCore::Engine::signalEntriesLoaded, this, [this, &conn](const KNSCore::EntryInternal::List &entries)
0123         {
0124             for (const KNSCore::EntryInternal &entry : entries) {
0125                 AlkNewStuffEntry e;
0126                 e.category = entry.category();
0127                 e.id = entry.uniqueId();
0128                 e.installedFiles = entry.installedFiles();
0129                 e.name = entry.name();
0130                 e.providerId = entry.providerId();
0131                 e.status =
0132                     static_cast<AlkNewStuffEntry::Status>(entry.status());
0133                 e.version = entry.version();
0134                 this->m_availableEntries.append(e);
0135                 qDebug() << Q_FUNC_INFO << e.name << toString(e.status);
0136             }
0137             QObject::disconnect(conn);
0138             m_loop.exit();
0139         });
0140         m_engine->requestData(0, 1000);
0141 #else
0142         QEventLoop loop;
0143         disconnect(m_engine, SIGNAL(searchResult(KNS3::Entry::List)), this,
0144                 SLOT(slotUpdatesAvailable(KNS3::Entry::List)));
0145         connect(m_engine, SIGNAL(searchResult(KNS3::Entry::List)), this,
0146                 SLOT(slotEntriesAvailable(KNS3::Entry::List)));
0147         m_engine->search(0, 1000);
0148 #endif
0149         m_loop.exec();
0150     }
0151 
0152     AlkNewStuffEntryList result;
0153     for (const AlkNewStuffEntry &entry : m_availableEntries) {
0154         if (entry.status == AlkNewStuffEntry::Installed || entry.status == AlkNewStuffEntry::Updateable)
0155             result.append(entry);
0156     }
0157     return result;
0158 }
0159 
0160 void AlkNewStuffEngine::Private::slotUpdatesAvailable(const KNS3::Entry::List &entries)
0161 {
0162 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0163     Q_UNUSED(entries);
0164 #else
0165     qDebug() << Q_FUNC_INFO << "updates loaded";
0166     AlkNewStuffEntryList updateEntries;
0167     for (const KNS3::Entry &entry : entries) {
0168         AlkNewStuffEntry e;
0169         e.category = entry.category();
0170         e.id = entry.id();
0171         e.installedFiles = entry.installedFiles();
0172         e.name = entry.name();
0173         e.providerId = entry.providerId();
0174         e.status = static_cast<AlkNewStuffEntry::Status>(entry.status());
0175         e.version = entry.version();
0176         updateEntries.append(e);
0177 
0178         qDebug() << Q_FUNC_INFO << e.name << toString(e.status);
0179     }
0180 
0181     Q_EMIT q->updatesAvailable(updateEntries);
0182 #endif
0183 }
0184 
0185 void AlkNewStuffEngine::Private::slotEntriesAvailable(const KNS3::Entry::List &entries)
0186 {
0187 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
0188     Q_UNUSED(entries);
0189 #else
0190     qDebug() << Q_FUNC_INFO << "entries loaded";
0191     for (const KNS3::Entry &entry : entries) {
0192         AlkNewStuffEntry e;
0193         e.category = entry.category();
0194         e.id = entry.id();
0195         e.installedFiles = entry.installedFiles();
0196         e.name = entry.name();
0197         e.providerId = entry.providerId();
0198         e.status = static_cast<AlkNewStuffEntry::Status>(entry.status());
0199         e.version = entry.version();
0200         m_availableEntries.append(e);
0201 
0202         qDebug() << Q_FUNC_INFO << e.name << toString(e.status);
0203     }
0204     disconnect(m_engine, SIGNAL(searchResult(KNS3::Entry::List)), this,
0205             SLOT(slotEntriesAvailable(KNS3::Entry::List)));
0206     connect(m_engine, SIGNAL(searchResult(KNS3::Entry::List)), this,
0207             SLOT(slotUpdatesAvailable(KNS3::Entry::List)));
0208     m_loop.exit();
0209 #endif
0210 }
0211 
0212 AlkNewStuffEngine::AlkNewStuffEngine(QObject *parent)
0213     : QObject{parent}
0214     , d(new Private(this))
0215 {
0216 }
0217 
0218 bool AlkNewStuffEngine::init(const QString &configFile)
0219 {
0220     bool result = d->init(configFile);
0221     return result;
0222 }
0223 
0224 void AlkNewStuffEngine::checkForUpdates()
0225 {
0226     d->checkForUpdates();
0227 }
0228 
0229 AlkNewStuffEntryList AlkNewStuffEngine::installedEntries() const
0230 {
0231     return d->installedEntries();
0232 }
0233 
0234 const char *toString(AlkNewStuffEntry::Status status)
0235 {
0236     switch(status) {
0237         case AlkNewStuffEntry::Invalid: return "Invalid";
0238         case AlkNewStuffEntry::Downloadable: return "Downloadable";
0239         case AlkNewStuffEntry::Installed: return "Installed";
0240         case AlkNewStuffEntry::Updateable: return "Updateable";
0241         case AlkNewStuffEntry::Deleted: return "Deleted";
0242         case AlkNewStuffEntry::Installing: return "Installing";
0243         case AlkNewStuffEntry::Updating: return "Updating";
0244     }
0245     return "";
0246 }
0247 
0248 #include "alknewstuffengine.moc"