File indexing completed on 2024-07-21 12:16:49

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