diff options
Diffstat (limited to 'librss/loader.h')
-rw-r--r-- | librss/loader.h | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/librss/loader.h b/librss/loader.h new file mode 100644 index 00000000..5f0c1447 --- /dev/null +++ b/librss/loader.h @@ -0,0 +1,322 @@ +/* + * loader.h + * + * Copyright (c) 2001, 2002, 2003, 2004 Frerich Raabe <[email protected]> + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. For licensing and distribution details, check the + * accompanying file 'COPYING'. + */ +#ifndef LIBRSS_LOADER_H +#define LIBRSS_LOADER_H + +#include "global.h" + +class KURL; + +#include <qobject.h> + +namespace KIO +{ + class Job; +} +class KProcess; + +namespace RSS +{ + class Document; + + /** + * Abstract baseclass for all data retriever classes. Subclass this to add + * a new retrieval algorithm which can then be plugged into the RSS loader. + * @see Loader, FileRetriever, OutputRetriever + */ + class DataRetriever : public QObject + { + Q_OBJECT + public: + /** + * Default constructor. + */ + DataRetriever(); + + /** + * Destructor. + */ + virtual ~DataRetriever(); + + /** + * Retrieve data from the given URL. This method is supposed to get + * reimplemented by subclasses. It will be called by the Loader + * class in case it needs to retrieve the data. + * @see Loader::loadFrom() + */ + virtual void retrieveData(const KURL &url) = 0; + + /** + * @return An error code which might give a more precise information + * about what went wrong in case the 'success' flag returned with + * the dataRetrieved() signal was 'false'. Note that the meaning of + * the returned integer depends on the actual data retriever. + */ + virtual int errorCode() const = 0; + + signals: + /** + * Emit this signal to tell the Loader class that the retrieval + * process was finished. + * @param data Should contain the retrieved data and will get + * parsed by the Loader class. + * @param success Indicates whether there were any problems during + * the retrieval process. Pass 'true' to indicate that everything + * went seamlessy, 'false' to tell the Loader that something went + * wrong and that the data parameter might contain no or invalid + * data. + */ + void dataRetrieved(const QByteArray &data, bool success); + + private: + DataRetriever(const DataRetriever &other); + DataRetriever &operator=(const DataRetriever &other); + }; + + /** + * Implements a file retriever, to be used with Loader::loadFrom(). + * @see DataRetriever, Loader::loadFrom() + */ + class LIBRSS_EXPORT FileRetriever : public DataRetriever + { + Q_OBJECT + public: + /** + * Default constructor. + */ + FileRetriever(); + + /** + * Destructor. + */ + virtual ~FileRetriever(); + + /** + * Downloads the file referenced by the given URL and passes it's + * contents on to the Loader. + * @param url An URL referencing a file which is assumed to + * reference valid XML. + * @see Loader::loadFrom() + */ + virtual void retrieveData(const KURL &url); + + /** + * @return The error code for the last process of retrieving data. + * The returned numbers correspond directly to the error codes + * <a href="http://developer.kde.org/documentation/library/cvs-api/classref/kio/KIO.html#Error">as + * defined by KIO</a>. + */ + virtual int errorCode() const; + + signals: + /** + * Signals a permanent redirection. The redirection itself is + * handled internally, so you don't need to call Loader::loadFrom() + * with the new URL. This signal is useful in case you want to + * notify the user, or adjust a database entry. + * @see Loader::loadFrom() + */ + void permanentRedirection(const KURL &url); + + private slots: + void slotData(KIO::Job *job, const QByteArray &data); + void slotResult(KIO::Job *job); + void slotPermanentRedirection(KIO::Job *job, const KURL &fromUrl, + const KURL &toUrl); + + private: + FileRetriever(const FileRetriever &other); + FileRetriever &operator=(const FileRetriever &other); + + struct Private; + Private *d; + }; + + /** + * Implements a data retriever which executes a program and stores returned + * by the program on stdout. To be used with Loader::loadFrom(). + * @see DataRetriever, Loader::loadFrom() + */ + class OutputRetriever : public DataRetriever + { + Q_OBJECT + public: + /** + * Default constructor. + */ + OutputRetriever(); + + /** + * Destructor. + */ + virtual ~OutputRetriever(); + + /** + * Executes the program referenced by the given URL and retrieves + * the data which the program prints to stdout. + * @param url An URL which is supposed to reference an executable + * file. + * @see Loader::loadFrom() + */ + virtual void retrieveData(const KURL &url); + + /** + * @return The error code for the last process of retrieving data. + * 0 is returned in case there was no error, otherwise an error + * code which depends on the particular program which was run is + * returned. + */ + virtual int errorCode() const; + + private slots: + void slotOutput(KProcess *process, char *data, int length); + void slotExited(KProcess *process); + + private: + OutputRetriever(const OutputRetriever &other); + OutputRetriever &operator=(const OutputRetriever &other); + + struct Private; + Private *d; + }; + + /** + * This class is the preferred way of loading RSS files. Usage is very + * straightforward: + * + * \code + * Loader *loader = Loader::create(); + * connect(loader, SIGNAL(loadingComplete(Loader *, Document, Status)), + * this, SLOT(slotLoadingComplete(Loader *, Document, Status))); + * loader->loadFrom("http://www.blah.org/foobar.rdf", new FileRetriever); + * \endcode + * + * This creates a Loader object, connects it's loadingComplete() signal to + * your custom slot and then makes it load the file + * 'http://www.blah.org/foobar.rdf' using the FileRetriever. You could've + * done something like this as well: + * + * \code + * // create the Loader, connect it's signal... + * loader->loadFrom("/home/myself/some-script.py", new OutputRetriever); + * \endcode + * + * That'd make the Loader use another algorithm for retrieving the RSS data; + * 'OutputRetriever' will make it execute the script + * '/home/myself/some-script.py' and assume whatever that script prints to + * stdout is RSS markup. This is e.g. handy for conversion scripts, which + * download a HTML file and convert it's contents into RSS markup. + * + * No matter what kind of retrieval algorithm you employ, your + * 'slotLoadingComplete' method might look like this: + * + * \code + * void MyClass::slotLoadingComplete(Loader *loader, Document doc, Status status) + * { + * // Note that Loader::~Loader() is private, so you cannot delete Loader instances. + * // You don't need to do that anyway since Loader instances delete themselves. + * + * if (status != RSS::Success) + * return; + * + * QString title = doc.title(); + * // do whatever you want with the information. + * } + * \endcode + * + * \note You have to create a copy of the passed Document instance in + * case you want/need to use it after the slot attached to the + * loadingComplete signal goes out of scope. This is e.g. the case if you + * intend to call getPixmap() on Document::image()! + */ + class LIBRSS_EXPORT Loader : public QObject + { + Q_OBJECT + friend class someClassWhichDoesNotExist; + public: + /** + * Constructs a Loader instance. This is pretty much what the + * default constructor would do, except that it ensures that all + * Loader instances have been allocated on the heap (this is + * required so that Loader's can delete themselves safely after they + * emitted the loadingComplete() signal.). + * @return A pointer to a new Loader instance. + */ + static Loader *create(); + + /** + * Convenience method. Does the same as the above method except that + * it also does the job of connecting the loadingComplete() signal + * to the given slot for you. + * @param object A QObject which features the specified slot + * @param slot Which slot to connect to. + */ + static Loader *create(QObject *object, const char *slot); + + /** + * Loads the RSS file referenced by the given URL using the + * specified retrieval algorithm. Make sure that you connected + * to the loadingComplete() signal before calling this method so + * that you're guaranteed to get notified when the loading finished. + * \note A Loader object cannot load from multiple URLs simultaneously; + * consequently, subsequent calls to loadFrom will be discarded + * silently, only the first loadFrom request will be executed. + * @param url An URL referencing the input file. + * @param retriever A subclass of DataRetriever which implements a + * specialized retrieval behaviour. Note that the ownership of the + * retriever is transferred to the Loader, i.e. the Loader will + * delete it when it doesn't need it anymore. + * @see DataRetriever, Loader::loadingComplete() + */ + void loadFrom(const KURL &url, DataRetriever *retriever); + + /** + * Retrieves the error code of the last loading process (if any), + * as reported by the employed data retrever. + */ + int errorCode() const; + + signals: + /** + * This signal gets emitted when the loading process triggered by + * calling loadFrom() finished. + * @param loader A pointer pointing to the loader object which + * emitted this signal; this is handy in case you connect multiple + * loaders to a single slot. + * @param doc In case status is Success, this parameter holds the + * parsed RSS file. In case it's RetrieveError, you should query + * loader->errorCode() for the actual error code. + * Note that you have to create a copy of the passed Document + * instance in case you want/need to use it after the slot attached + * to the loadingComplete signal goes out of scope. This is e.g. + * the case if you intend to call getPixmap() on Document::image()! + * @param status A status byte telling whether there were any problems + * while retrieving or parsing the data. + * @see Document, Status + */ + void loadingComplete(Loader *loader, Document doc, Status status); + + private slots: + void slotRetrieverDone(const QByteArray &data, bool success); + + private: + Loader(); + Loader(const Loader &other); + Loader &operator=(const Loader &other); + ~Loader(); + + struct Private; + Private *d; + }; +} + +#endif // LIBRSS_LOADER_H +// vim: noet:ts=4 |