aheinecke@10: #ifndef DOWNLOADER_H
aheinecke@10: #define DOWNLOADER_H
aheinecke@10: /**
aheinecke@10:  * @file downloader.h
aheinecke@10:  * @brief High level API to download necessary data.
aheinecke@10:  *
aheinecke@10:  */
aheinecke@10: 
aheinecke@10: #include <QThread>
aheinecke@45: #include <QDateTime>
aheinecke@10: #include <QString>
aheinecke@10: #include <QByteArray>
aheinecke@15: 
aheinecke@45: #include "sslconnection.h"
aheinecke@10: 
aheinecke@10: class Downloader: public QThread
aheinecke@10: {
aheinecke@10:     Q_OBJECT
aheinecke@10: 
aheinecke@10: public:
aheinecke@10:     /**
aheinecke@15:      * @brief Construct a downloader with a specific certificate
aheinecke@10:      *
aheinecke@15:      * The downloader will check the last-modified date of the
aheinecke@15:      * certificate list / sw on the server at the specified url
aheinecke@15:      * and download those accordingly. If newestSW or newestList is
aheinecke@15:      * are valid datetimes only files modified after the respective date
aheinecke@15:      * are downloaded.
aheinecke@15:      *
aheinecke@15:      * Downloaded files are placed in QStandardPaths::DataLocation
aheinecke@10:      *
aheinecke@10:      * @param[in] parent the parent object.
aheinecke@10:      * @param[in] url the Url to download data from
aheinecke@15:      * @param[in] certificate optional certificate to validate https connection
aheinecke@15:      * @param[in] newestSW datetime after which software should be downloaded
aheinecke@15:      * @param[in] newestList datetime after which the list should be downloaded
aheinecke@45:      * @param[in] resourceSW the path where the software is to be found
aheinecke@45:      * @param[in] resourceList the path where the list is to be found
aheinecke@10:      */
aheinecke@10:     Downloader(QObject* parent, const QString& url,
aheinecke@15:                const QByteArray& certificate = QByteArray(),
aheinecke@15:                const QDateTime& newestSW = QDateTime(),
aheinecke@45:                const QDateTime& newestList = QDateTime(),
aheinecke@45:                const QString& resourceSW = QString(),
aheinecke@45:                const QString& resourceList = QString());
aheinecke@10: 
andre@27:     ~Downloader();
aheinecke@10: 
aheinecke@10:     /**
aheinecke@15:      * @brief get the directory where the downloader saves data
aheinecke@10:      *
aheinecke@15:      * If the directory does not exist this function ensures that it
aheinecke@15:      * is created.
aheinecke@15:      *
aheinecke@15:      * @returns The directory in which downloaded files are placed.
aheinecke@15:      **/
aheinecke@15:     QString getDataDirectory();
aheinecke@15: 
andre@27:     /**
andre@27:      * @brief get the current error state
andre@27:      *
andre@27:      * @returns The current error state.
andre@27:      **/
aheinecke@45:     SSLConnection::ErrorCode getErrorState();
aheinecke@10: 
aheinecke@10: protected:
aheinecke@10:     void run();
aheinecke@10: 
aheinecke@10: private:
aheinecke@15:     QDateTime mLastModSW;
aheinecke@15:     QDateTime mLastModList;
aheinecke@15: 
aheinecke@45:     QString mResourceSW;
aheinecke@45:     QString mResourceList;
andre@27: 
aheinecke@45:     SSLConnection mSSLConnection;
andre@32: 
andre@32:     /** @brief get the last modified header of a resource.
andre@32:      *
andre@32:      * Connection should be established beforehand.
andre@32:      * Modifies the error state.
andre@32:      *
andre@32:      * @param[in] resource The resource to check
andre@32:      *
andre@32:      * @returns the last modified date or a null datetime in case of errors
andre@32:      */
andre@32:     QDateTime getLastModifiedHeader(const QString &resource);
andre@32: 
andre@32:     /** @brief Download resource
andre@32:      *
andre@32:      * Download a resource with the established connection.
andre@32:      * Modifies the error state.
andre@32:      *
andre@32:      * @param[in] resource the resource to download
andre@32:      * @param[in] filename where the file should be saved.
andre@32:      * @param[in] maxSize maximum amount of bytes to download
andre@32:      *
andre@32:      * @returns True if the download was successful.
andre@32:      */
andre@32:     bool downloadFile(const QString &resource, const QString &filename,
andre@32:                       size_t maxSize);
aheinecke@54:     /**
aheinecke@54:      * @brief parses the Headers of a repsonse.
aheinecke@54:      *
aheinecke@54:      * This removes the headers from the byte array passed as
aheinecke@54:      * parameter.
aheinecke@54:      *
aheinecke@54:      * @param[inout] data: The response to parse.
aheinecke@54:      *
aheinecke@54:      * @returns: A map of the header fields. Or an empty map on error.
aheinecke@54:      */
aheinecke@54:     QMap<QString, QString> parseHeaders(QByteArray *data);
aheinecke@15: 
aheinecke@10: Q_SIGNALS:
aheinecke@10:     /**
aheinecke@15:      * @brief software update is available
aheinecke@15:      */
aheinecke@15:     void newSoftwareAvailable(const QString &fileName,
aheinecke@15:             const QDateTime &lastMod);
aheinecke@15: 
aheinecke@15:     /**
aheinecke@15:      * @brief new certificate list available
aheinecke@15:      */
aheinecke@15:     void newListAvailable(const QString &fileName, const QDateTime &lastMod);
aheinecke@15: 
aheinecke@15:     /**
aheinecke@10:      * @brief Some progress has been made.
aheinecke@10:      *
aheinecke@10:      * @param[out] message: A message to show. Can be empty.
aheinecke@10:      * @param[out] current: Value of current progress.
aheinecke@10:      * @param[out] total: Total value of possible progress
aheinecke@10:      */
aheinecke@10:     void progress(const QString &message, int current, int total);
aheinecke@10: 
aheinecke@10:     /**
aheinecke@10:      * @brief An error happened
aheinecke@10:      *
aheinecke@10:      * @param[out] message: A message to show. Can be empty.
aheinecke@10:      * @param[out] errorCode: ErrorCode of this error.
aheinecke@10:      */
aheinecke@45:     void error(const QString &message, SSLConnection::ErrorCode error);
aheinecke@10: };
aheinecke@10: #endif