1/*
2 SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleixpol@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include "resultsstream.h"
8#include "enginebase_p.h"
9#include "knewstuffcore_debug.h"
10
11#include <QTimer>
12
13using namespace KNSCore;
14
15class KNSCore::ResultsStreamPrivate
16{
17public:
18 QList<QSharedPointer<KNSCore::Provider>> providers;
19 EngineBase const *engine;
20 Provider::SearchRequest request;
21};
22
23ResultsStream::ResultsStream(const Provider::SearchRequest &request, EngineBase *base)
24 : d(new ResultsStreamPrivate{
25 .providers = base->d->providers.values(),
26 .engine = base,
27 .request = request,
28 })
29{
30 auto finished = [this](const KNSCore::Provider::SearchRequest &request, const KNSCore::Entry::List &entries) {
31 if (request != d->request) {
32 return;
33 }
34
35 if (d->providers.removeAll(t: qobject_cast<Provider *>(object: sender())) <= 0) {
36 qCDebug(KNEWSTUFFCORE) << "Request finished twice, check your provider" << sender() << d->engine << entries.size();
37 return;
38 }
39
40 if (entries.isEmpty() && d->providers.isEmpty()) {
41 finish();
42 }
43 if (!entries.isEmpty()) {
44 Q_EMIT entriesFound(entries);
45 }
46 };
47 auto failed = [this](const KNSCore::Provider::SearchRequest &request) {
48 if (request == d->request) {
49 finish();
50 }
51 };
52 for (const auto &provider : d->providers) {
53 connect(sender: provider.data(), signal: &Provider::loadingFinished, context: this, slot&: finished);
54 connect(sender: provider.data(), signal: &Provider::entryDetailsLoaded, context: this, slot: [this](const KNSCore::Entry &entry) {
55 if (d->request.filter == KNSCore::Provider::ExactEntryId && d->request.searchTerm == entry.uniqueId()) {
56 if (entry.isValid()) {
57 Q_EMIT entriesFound(entries: {entry});
58 }
59 finish();
60 }
61 });
62 connect(sender: provider.data(), signal: &Provider::loadingFailed, context: this, slot&: failed);
63 }
64}
65
66ResultsStream::~ResultsStream() = default;
67
68void ResultsStream::fetch()
69{
70 if (d->request.filter != Provider::Installed) {
71 // when asking for installed entries, never use the cache
72 Entry::List cacheEntries = d->engine->cache()->requestFromCache(d->request);
73 if (!cacheEntries.isEmpty()) {
74 Q_EMIT entriesFound(entries: cacheEntries);
75 return;
76 }
77 }
78
79 for (const QSharedPointer<KNSCore::Provider> &p : std::as_const(t&: d->providers)) {
80 if (p->isInitialized()) {
81 QTimer::singleShot(interval: 0, receiver: this, slot: [this, p] {
82 p->loadEntries(request: d->request);
83 });
84 } else {
85 connect(sender: p.get(), signal: &KNSCore::Provider::providerInitialized, context: this, slot: [this, p] {
86 disconnect(sender: p.get(), signal: &KNSCore::Provider::providerInitialized, receiver: this, zero: nullptr);
87 p->loadEntries(request: d->request);
88 });
89 }
90 }
91}
92
93void ResultsStream::fetchMore()
94{
95 d->request.page++;
96 fetch();
97}
98
99void ResultsStream::finish()
100{
101 Q_EMIT finished();
102 deleteLater();
103}
104
105#include "moc_resultsstream.cpp"
106

source code of knewstuff/src/core/resultsstream.cpp