You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktorrent/plugins/rssfeed/rss/loader.h

344 lines
10 KiB

/*
* loader.h
*
* Copyright (c) 2001, 2002, 2003 Frerich Raabe <raabe@kde.org>
*
* 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 <tqobject.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 TQObject
{
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;
virtual void abort() = 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 TQByteArray &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 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;
virtual void abort();
static void setUseCache(bool enabled);
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);
protected slots:
void slotTimeout();
private slots:
void slotData(KIO::Job *job, const TQByteArray &data);
void slotResult(KIO::Job *job);
void slotPermanentRedirection(KIO::Job *job, const KURL &fromUrl,
const KURL &toUrl);
private:
static bool m_useCache;
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;
virtual void abort() {}
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, TQT_SIGNAL(loadingComplete(Loader *, Document, Status)),
* this, TQT_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;
*
* TQString 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 Loader : public TQObject
{
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 TQObject which features the specified slot
* @param slot Which slot to connect to.
*/
static Loader *create(TQObject *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;
const KURL &discoveredFeedURL() const;
void abort();
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 TQByteArray &data, bool success);
private:
Loader();
Loader(const Loader &other);
Loader &operator=(const Loader &other);
~Loader();
void discoverFeeds(const TQByteArray &data);
struct Private;
Private *d;
};
}
#endif // LIBRSS_LOADER_H
// vim: noet:ts=4