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