File indexing completed on 2024-05-12 05:29:03

0001 /*
0002  *   SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "AbstractResourcesBackend.h"
0008 #include "Category/Category.h"
0009 #include "libdiscover_debug.h"
0010 #include "utils.h"
0011 #include <KLocalizedString>
0012 #include <QHash>
0013 #include <QMetaObject>
0014 #include <QMetaProperty>
0015 #include <QTimer>
0016 
0017 QDebug operator<<(QDebug debug, const AbstractResourcesBackend::Filters &filters)
0018 {
0019     QDebugStateSaver saver(debug);
0020     debug.nospace() << "Filters(";
0021     if (filters.category)
0022         debug.nospace() << "category: " << filters.category << ',';
0023     if (filters.state)
0024         debug.nospace() << "state: " << filters.state << ',';
0025     if (!filters.mimetype.isEmpty())
0026         debug.nospace() << "mimetype: " << filters.mimetype << ',';
0027     if (!filters.search.isEmpty())
0028         debug.nospace() << "search: " << filters.search << ',';
0029     if (!filters.extends.isEmpty())
0030         debug.nospace() << "extends:" << filters.extends << ',';
0031     if (!filters.origin.isEmpty())
0032         debug.nospace() << "origin:" << filters.origin << ',';
0033     if (!filters.resourceUrl.isEmpty())
0034         debug.nospace() << "resourceUrl:" << filters.resourceUrl << ',';
0035     debug.nospace() << ')';
0036 
0037     return debug;
0038 }
0039 
0040 ResultsStream::ResultsStream(const QString &objectName, const QVector<StreamResult> &resources)
0041     : ResultsStream(objectName)
0042 {
0043     Q_ASSERT(!kContains(resources, [](const StreamResult &res) {
0044         return res.resource == nullptr;
0045     }));
0046     QTimer::singleShot(0, this, [resources, this]() {
0047         if (!resources.isEmpty())
0048             Q_EMIT resourcesFound(resources);
0049         finish();
0050     });
0051 }
0052 
0053 ResultsStream::ResultsStream(const QString &objectName)
0054 {
0055     setObjectName(objectName);
0056     QTimer::singleShot(5000, this, [objectName]() {
0057         qCDebug(LIBDISCOVER_LOG) << "stream took really long" << objectName;
0058     });
0059 }
0060 
0061 ResultsStream::~ResultsStream()
0062 {
0063 }
0064 
0065 void ResultsStream::finish()
0066 {
0067     deleteLater();
0068 }
0069 
0070 AbstractResourcesBackend::AbstractResourcesBackend(QObject *parent)
0071     : QObject(parent)
0072 {
0073     QTimer *fetchingChangedTimer = new QTimer(this);
0074     fetchingChangedTimer->setInterval(3000);
0075     fetchingChangedTimer->setSingleShot(true);
0076     connect(fetchingChangedTimer, &QTimer::timeout, this, [this] {
0077         qCDebug(LIBDISCOVER_LOG) << "took really long to fetch" << this;
0078     });
0079 
0080     connect(this, &AbstractResourcesBackend::fetchingChanged, this, [this, fetchingChangedTimer] {
0081         // Q_ASSERT(isFetching() != fetchingChangedTimer->isActive());
0082         if (isFetching())
0083             fetchingChangedTimer->start();
0084         else
0085             fetchingChangedTimer->stop();
0086 
0087         Q_EMIT fetchingUpdatesProgressChanged();
0088     });
0089 }
0090 
0091 Transaction *AbstractResourcesBackend::installApplication(AbstractResource *app)
0092 {
0093     return installApplication(app, AddonList());
0094 }
0095 
0096 void AbstractResourcesBackend::setName(const QString &name)
0097 {
0098     m_name = name;
0099 }
0100 
0101 QString AbstractResourcesBackend::name() const
0102 {
0103     return m_name;
0104 }
0105 
0106 void AbstractResourcesBackend::emitRatingsReady()
0107 {
0108     Q_EMIT allDataChanged({"rating", "ratingPoints", "ratingCount", "sortableRating"});
0109 }
0110 
0111 bool AbstractResourcesBackend::Filters::shouldFilter(AbstractResource *res) const
0112 {
0113     Q_ASSERT(res);
0114 
0115     if (!extends.isEmpty() && !res->extends().contains(extends)) {
0116         return false;
0117     }
0118 
0119     if (!origin.isEmpty() && res->origin() != origin) {
0120         return false;
0121     }
0122 
0123     if (filterMinimumState ? (res->state() < state) : (res->state() != state)) {
0124         return false;
0125     }
0126 
0127     if (!mimetype.isEmpty() && !res->mimetypes().contains(mimetype)) {
0128         return false;
0129     }
0130 
0131     return !category || res->categoryMatches(category);
0132 }
0133 
0134 void AbstractResourcesBackend::Filters::filterJustInCase(QVector<AbstractResource *> &input) const
0135 {
0136     for (auto it = input.begin(); it != input.end();) {
0137         if (shouldFilter(*it))
0138             ++it;
0139         else
0140             it = input.erase(it);
0141     }
0142 }
0143 
0144 void AbstractResourcesBackend::Filters::filterJustInCase(QVector<StreamResult> &input) const
0145 {
0146     for (auto it = input.begin(); it != input.end();) {
0147         if (shouldFilter(it->resource))
0148             ++it;
0149         else
0150             it = input.erase(it);
0151     }
0152 }
0153 
0154 bool AbstractResourcesBackend::extends(const QString & /*id*/) const
0155 {
0156     return false;
0157 }
0158 
0159 int AbstractResourcesBackend::fetchingUpdatesProgress() const
0160 {
0161     return isFetching() ? 42 : 100;
0162 }
0163 
0164 uint AbstractResourcesBackend::fetchingUpdatesProgressWeight() const
0165 {
0166     return 1;
0167 }
0168 
0169 InlineMessage *AbstractResourcesBackend::explainDysfunction() const
0170 {
0171     return new InlineMessage(InlineMessage::Error, QStringLiteral("network-disconnect"), i18n("Please verify Internet connectivity"));
0172 }