File indexing completed on 2024-04-21 04:01:05

0001 /*
0002     loader.h
0003     SPDX-FileCopyrightText: 2001, 2002, 2003 Frerich Raabe <raabe@kde.org>
0004 
0005     SPDX-License-Identifier: BSD-2-Clause
0006 */
0007 
0008 #ifndef SYNDICATION_LOADER_H
0009 #define SYNDICATION_LOADER_H
0010 
0011 #include "global.h"
0012 
0013 #include "syndication_export.h"
0014 
0015 #include <QObject>
0016 
0017 #include <memory>
0018 
0019 class QUrl;
0020 
0021 namespace Syndication
0022 {
0023 class DataRetriever;
0024 class Feed;
0025 //@cond PRIVATE
0026 typedef QSharedPointer<Feed> FeedPtr;
0027 //@endcond
0028 
0029 /**
0030  * This class is the preferred way of loading feed sources. Usage is very
0031  * straightforward:
0032  *
0033  * \code
0034  * Loader *loader = Loader::create();
0035  * connect(loader, SIGNAL(loadingComplete(Loader*, FeedPtr, ErrorCode)),
0036  *         this, SLOT(slotLoadingComplete(Loader*, FeedPtr, ErrorCode)));
0037  * loader->loadFrom("http://www.blah.org/foobar.rdf");
0038  * \endcode
0039  *
0040  * This creates a Loader object, connects it's loadingComplete() signal to
0041  * your custom slot and then makes it load the file
0042  * 'http://www.blah.org/foobar.rdf'. You could've
0043  * done something like this as well:
0044  *
0045  * \code
0046  * // create the Loader, connect it's signal...
0047  * loader->loadFrom("/home/myself/some-script.py", new OutputRetriever);
0048  * \endcode
0049  *
0050  * That'd make the Loader use a custom algorithm for retrieving the RSS data;
0051  * 'OutputRetriever' will make it execute the script
0052  * '/home/myself/some-script.py' and assume whatever that script prints to
0053  * stdout is RSS/Azom markup. This is e.g. handy for conversion scripts, which
0054  * download a HTML file and convert it's contents into RSS markup.
0055  *
0056  * No matter what kind of retrieval algorithm you employ, your
0057  * 'slotLoadingComplete' method might look like this:
0058  *
0059  * \code
0060  * void MyClass::slotLoadingComplete(Loader* loader, FeedPtr feed, ErrorCode status)
0061  * {
0062  *     // Note that Loader::~Loader() is private, so you cannot delete Loader instances.
0063  *     // You don't need to do that anyway since Loader instances delete themselves.
0064  *
0065  *     if (status != Syndication::Success)
0066  *         return;
0067  *
0068  *     QString title = feed->title();
0069  *     // do whatever you want with the information.
0070  * }
0071  * \endcode
0072  */
0073 class SYNDICATION_EXPORT Loader : public QObject
0074 {
0075     Q_OBJECT
0076 
0077 public:
0078     /**
0079      * Constructs a Loader instance. This is pretty much what the
0080      * default constructor would do, except that it ensures that all
0081      * Loader instances have been allocated on the heap (this is
0082      * required so that Loader's can delete themselves safely after they
0083      * emitted the loadingComplete() signal.).
0084      * @return A pointer to a new Loader instance.
0085      */
0086     static Loader *create();
0087 
0088     /**
0089      * Convenience method. Does the same as the above method except that
0090      * it also does the job of connecting the loadingComplete() signal
0091      * to the given slot for you.
0092      * @param object A QObject which features the specified slot
0093      * @param slot Which slot to connect to.
0094      */
0095     static Loader *create(QObject *object, const char *slot);
0096 
0097     /**
0098      * Loads the feed source referenced by the given URL using the
0099      * specified retrieval algorithm. Make sure that you connected
0100      * to the loadingComplete() signal before calling this method so
0101      * that you're guaranteed to get notified when the loading finished.
0102      * \note A Loader object cannot load from multiple URLs simultaneously;
0103      * consequently, subsequent calls to loadFrom will be discarded
0104      * silently, only the first loadFrom request will be executed.
0105      * @param url A URL referencing the input file.
0106      * @param retriever A subclass of DataRetriever which implements a
0107      * specialized retrieval behaviour. Note that the ownership of the
0108      * retriever is transferred to the Loader, i.e. the Loader will
0109      * delete it when it doesn't need it anymore.
0110      * @see DataRetriever, Loader::loadingComplete()
0111      */
0112     void loadFrom(const QUrl &url, DataRetriever *retriever);
0113 
0114     /**
0115      * Retrieves the error code of the last loading process (if any).
0116      */
0117     Q_REQUIRED_RESULT ErrorCode errorCode() const;
0118 
0119     /**
0120      * the error code returned from the retriever.
0121      * Use this if you use your custom retriever implementation and
0122      * need the specific error, not covered by errorCode().
0123      */
0124     Q_REQUIRED_RESULT int retrieverError() const;
0125 
0126     /**
0127      * returns the URL of a feed discovered in the feed source
0128      */
0129     Q_REQUIRED_RESULT QUrl discoveredFeedURL() const;
0130 
0131     /**
0132      * aborts the loading process
0133      */
0134     void abort();
0135 
0136 Q_SIGNALS:
0137 
0138     /**
0139      * This signal gets emitted when the loading process triggered by
0140      * calling loadFrom() finished.
0141      * @param loader A pointer pointing to the loader object which
0142      * emitted this signal; this is handy in case you connect multiple
0143      * loaders to a single slot.
0144      * @param feed In case errortus is Success, this parameter holds the
0145      * parsed feed. If fetching/parsing failed, feed is NULL.
0146      * @param error An error code telling whether there were any
0147      * problems while retrieving or parsing the data.
0148      * @see Feed, ErrorCode
0149      */
0150     void loadingComplete(Syndication::Loader *loader, Syndication::FeedPtr feed, Syndication::ErrorCode error);
0151 
0152 private Q_SLOTS:
0153     SYNDICATION_NO_EXPORT void slotRetrieverDone(const QByteArray &data, bool success);
0154 
0155 private:
0156     SYNDICATION_NO_EXPORT Loader();
0157     Loader(const Loader &other);
0158     Loader &operator=(const Loader &other);
0159     SYNDICATION_NO_EXPORT ~Loader() override;
0160     SYNDICATION_NO_EXPORT void discoverFeeds(const QByteArray &data);
0161 
0162     struct LoaderPrivate;
0163     std::unique_ptr<LoaderPrivate> const d;
0164 };
0165 
0166 } // namespace Syndication
0167 
0168 #endif // SYNDICATION_LOADER_H