1/*
2 loader.h
3 SPDX-FileCopyrightText: 2001, 2002, 2003 Frerich Raabe <raabe@kde.org>
4
5 SPDX-License-Identifier: BSD-2-Clause
6*/
7
8#ifndef SYNDICATION_LOADER_H
9#define SYNDICATION_LOADER_H
10
11#include "global.h"
12
13#include "syndication_export.h"
14
15#include <QObject>
16
17#include <memory>
18
19class QUrl;
20
21namespace Syndication
22{
23class DataRetriever;
24class Feed;
25typedef QSharedPointer<Feed> FeedPtr;
26
27/*!
28 * \class Syndication::Loader
29 * \inmodule Syndication
30 * \inheaderfile Syndication/Loader
31 *
32 * \brief This class is the preferred way of loading feed sources.
33 *
34 * Usage is very straightforward:
35 *
36 * \code
37 * Loader *loader = Loader::create();
38 * connect(loader, SIGNAL(loadingComplete(Loader*, FeedPtr, ErrorCode)),
39 * this, SLOT(slotLoadingComplete(Loader*, FeedPtr, ErrorCode)));
40 * loader->loadFrom("http://www.blah.org/foobar.rdf");
41 * \endcode
42 *
43 * This creates a Loader object, connects it's loadingComplete() signal to
44 * your custom slot and then makes it load the file
45 * 'http://www.blah.org/foobar.rdf'. You could've
46 * done something like this as well:
47 *
48 * \code
49 * // create the Loader, connect it's signal...
50 * loader->loadFrom("/home/myself/some-script.py", new OutputRetriever);
51 * \endcode
52 *
53 * That'd make the Loader use a custom algorithm for retrieving the RSS data;
54 * 'OutputRetriever' will make it execute the script
55 * '/home/myself/some-script.py' and assume whatever that script prints to
56 * stdout is RSS/Azom markup. This is e.g. handy for conversion scripts, which
57 * download a HTML file and convert it's contents into RSS markup.
58 *
59 * No matter what kind of retrieval algorithm you employ, your
60 * 'slotLoadingComplete' method might look like this:
61 *
62 * \code
63 * void MyClass::slotLoadingComplete(Loader* loader, FeedPtr feed, ErrorCode status)
64 * {
65 * // Note that Loader::~Loader() is private, so you cannot delete Loader instances.
66 * // You don't need to do that anyway since Loader instances delete themselves.
67 *
68 * if (status != Syndication::Success)
69 * return;
70 *
71 * QString title = feed->title();
72 * // do whatever you want with the information.
73 * }
74 * \endcode
75 */
76class SYNDICATION_EXPORT Loader : public QObject
77{
78 Q_OBJECT
79
80public:
81 /*!
82 * Constructs a Loader instance.
83 *
84 * This is pretty much what the
85 * default constructor would do, except that it ensures that all
86 * Loader instances have been allocated on the heap (this is
87 * required so that Loader's can delete themselves safely after they
88 * emitted the loadingComplete() signal.).
89 *
90 * Returns a pointer to a new Loader instance.
91 */
92 static Loader *create();
93
94 /*!
95 * Convenience method.
96 *
97 * Does the same as the above method except that
98 * it also does the job of connecting the loadingComplete() signal
99 * to the given slot for you.
100 *
101 * \a object A QObject which features the specified slot
102 *
103 * \a slot Which slot to connect to.
104 */
105 static Loader *create(QObject *object, const char *slot);
106
107 /*!
108 * Loads the feed source referenced by the given URL using the
109 * specified retrieval algorithm.
110 *
111 * Make sure that you connected
112 * to the loadingComplete() signal before calling this method so
113 * that you're guaranteed to get notified when the loading finished.
114 *
115 * \note A Loader object cannot load from multiple URLs simultaneously;
116 * consequently, subsequent calls to loadFrom will be discarded
117 * silently, only the first loadFrom request will be executed.
118 *
119 * \a url A URL referencing the input file.
120 *
121 * \a retriever A subclass of DataRetriever which implements a
122 * specialized retrieval behaviour. Note that the ownership of the
123 * retriever is transferred to the Loader, i.e. the Loader will
124 * delete it when it doesn't need it anymore.
125 *
126 * \sa DataRetriever, Loader::loadingComplete()
127 */
128 void loadFrom(const QUrl &url, DataRetriever *retriever);
129
130 /*!
131 * Retrieves the error code of the last loading process (if any).
132 */
133 Q_REQUIRED_RESULT ErrorCode errorCode() const;
134
135 /*!
136 * the error code returned from the retriever.
137 * Use this if you use your custom retriever implementation and
138 * need the specific error, not covered by errorCode().
139 */
140 Q_REQUIRED_RESULT int retrieverError() const;
141
142 /*!
143 * returns the URL of a feed discovered in the feed source
144 */
145 Q_REQUIRED_RESULT QUrl discoveredFeedURL() const;
146
147 /*!
148 * aborts the loading process
149 */
150 void abort();
151
152Q_SIGNALS:
153
154 /*!
155 * This signal gets emitted when the loading process triggered by
156 * calling loadFrom() finished.
157 *
158 * \a loader A pointer pointing to the loader object which
159 * emitted this signal; this is handy in case you connect multiple
160 * loaders to a single slot.
161 *
162 * \a feed In case errortus is Success, this parameter holds the
163 * parsed feed. If fetching/parsing failed, feed is NULL.
164 *
165 * \a error An error code telling whether there were any
166 * problems while retrieving or parsing the data.
167 *
168 * \sa Feed, ErrorCode
169 */
170 void loadingComplete(Syndication::Loader *loader, Syndication::FeedPtr feed, Syndication::ErrorCode error);
171
172private Q_SLOTS:
173 SYNDICATION_NO_EXPORT void slotRetrieverDone(const QByteArray &data, bool success);
174
175private:
176 SYNDICATION_NO_EXPORT Loader();
177 Loader(const Loader &other);
178 Loader &operator=(const Loader &other);
179 SYNDICATION_NO_EXPORT ~Loader() override;
180 SYNDICATION_NO_EXPORT void discoverFeeds(const QByteArray &data);
181
182 struct LoaderPrivate;
183 std::unique_ptr<LoaderPrivate> const d;
184};
185
186} // namespace Syndication
187
188#endif // SYNDICATION_LOADER_H
189

source code of syndication/src/loader.h