1 /*
2     loader.cpp
3     SPDX-FileCopyrightText: 2001, 2002, 2003 Frerich Raabe <raabe@kde.org>
4 
5     SPDX-License-Identifier: BSD-2-Clause
6 */
7 
8 #include "loader.h"
9 #include "dataretriever.h"
10 #include "documentsource.h"
11 #include "feed.h"
12 #include "global.h"
13 #include "loaderutil_p.h"
14 #include "parsercollection.h"
15 
16 #include <QUrl>
17 
18 
19 #include <syndication_debug.h>
20 
21 namespace Syndication
22 {
23 struct Loader::LoaderPrivate {
LoaderPrivateSyndication::Loader::LoaderPrivate24     LoaderPrivate()
25     {
26     }
27 
~LoaderPrivateSyndication::Loader::LoaderPrivate28     ~LoaderPrivate()
29     {
30         delete retriever;
31     }
32 
33     DataRetriever *retriever = nullptr;
34     Syndication::ErrorCode lastError = Success;
35     int retrieverError = 0;
36     QUrl discoveredFeedURL;
37     QUrl url;
38 };
39 
create()40 Loader *Loader::create()
41 {
42     return new Loader;
43 }
44 
create(QObject * object,const char * slot)45 Loader *Loader::create(QObject *object, const char *slot)
46 {
47     Loader *loader = create();
48     connect(loader, SIGNAL(loadingComplete(Syndication::Loader *, Syndication::FeedPtr, Syndication::ErrorCode)), object, slot);
49     return loader;
50 }
51 
Loader()52 Loader::Loader()
53     : d(new LoaderPrivate)
54 {
55 }
56 
~Loader()57 Loader::~Loader()
58 {
59     delete d;
60 }
61 
loadFrom(const QUrl & url,DataRetriever * retriever)62 void Loader::loadFrom(const QUrl &url, DataRetriever *retriever)
63 {
64     if (d->retriever != nullptr) {
65         return;
66     }
67 
68     d->url = url;
69     d->retriever = retriever;
70 
71     connect(d->retriever, &DataRetriever::dataRetrieved, this, &Loader::slotRetrieverDone);
72 
73     d->retriever->retrieveData(url);
74 }
75 
retrieverError() const76 int Loader::retrieverError() const
77 {
78     return d->retrieverError;
79 }
80 
errorCode() const81 Syndication::ErrorCode Loader::errorCode() const
82 {
83     return d->lastError;
84 }
85 
abort()86 void Loader::abort()
87 {
88     if (d && d->retriever) {
89         d->retriever->abort();
90         delete d->retriever;
91         d->retriever = nullptr;
92     }
93 
94     Q_EMIT loadingComplete(this, FeedPtr(), Aborted);
95     delete this;
96 }
97 
discoveredFeedURL() const98 QUrl Loader::discoveredFeedURL() const
99 {
100     return d->discoveredFeedURL;
101 }
102 
slotRetrieverDone(const QByteArray & data,bool success)103 void Loader::slotRetrieverDone(const QByteArray &data, bool success)
104 {
105     d->retrieverError = d->retriever->errorCode();
106     ErrorCode status = Success;
107     FeedPtr feed;
108     delete d->retriever;
109     d->retriever = nullptr;
110 
111     if (success) {
112         DocumentSource src(data, d->url.url());
113         feed = parserCollection()->parse(src);
114 
115         if (parserCollection()->lastError() != Syndication::Success) {
116             status = parserCollection()->lastError();
117             discoverFeeds(data);
118         }
119     } else {
120         qCDebug(SYNDICATION_LOG) << "Retriever error:" << d->retrieverError;
121         // retriever is a custom impl, so we set OtherRetrieverError
122         status = OtherRetrieverError;
123     }
124 
125     Q_EMIT loadingComplete(this, feed, status);
126 
127     delete this;
128 }
129 
discoverFeeds(const QByteArray & data)130 void Loader::discoverFeeds(const QByteArray &data)
131 {
132     const QUrl url = LoaderUtil::parseFeed(data, d->url);
133     if (!url.isEmpty()) {
134         d->discoveredFeedURL = url;
135     }
136 }
137 
138 } // namespace Syndication
139