From 39082a62cdf7ae9f36b925d43111973496c423f1 Mon Sep 17 00:00:00 2001 From: "Robert C. Helling" Date: Mon, 2 Mar 2015 16:18:16 +0100 Subject: [PATCH 3/3] Load remote images When loading an image by filename and by hash fails, try to interpret the filename as URL and download the image. Signed-off-by: Robert C. Helling --- dives/test39.xml | 29 ++++++++++++++++++++++ qt-ui/divepicturewidget.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++--- qt-ui/divepicturewidget.h | 13 ++++++++++ qthelper.cpp | 7 ++++++ qthelper.h | 1 + 5 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 dives/test39.xml diff --git a/dives/test39.xml b/dives/test39.xml new file mode 100644 index 0000000..9b75754 --- /dev/null +++ b/dives/test39.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + This is a dive with an image on a remote server. + + + + + + + + + + + + + + + + diff --git a/qt-ui/divepicturewidget.cpp b/qt-ui/divepicturewidget.cpp index a0d209b..9c5ac4f 100644 --- a/qt-ui/divepicturewidget.cpp +++ b/qt-ui/divepicturewidget.cpp @@ -6,16 +6,28 @@ #include #include #include +#include +#include #include #include +#include + +void loadPicuture(struct picture *picture) +{ + ImageDownloader download(picture); + download.load(); +} SHashedImage::SHashedImage(struct picture *picture) : QImage(picture->filename) { if (isNull()) { // Hash lookup. load(fileFromHash(picture->hash)); - if (!isNull()) + if (!isNull()) { QtConcurrent::run(updateHash, picture); + } else { + QtConcurrent::run(loadPicuture, picture); + } } else { QByteArray hash = hashFile(QString(picture->filename)); free(picture->hash); @@ -23,6 +35,45 @@ SHashedImage::SHashedImage(struct picture *picture) : QImage(picture->filename) } } +ImageDownloader::ImageDownloader(struct picture *pic) +{ + picture = pic; +} + +void ImageDownloader::load(){ + QUrl url(picture->filename); + if (url.isValid()) { + QEventLoop loop; + QNetworkRequest request(url); + connect(&manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(saveImage(QNetworkReply *))); + QNetworkReply *reply = manager.get(request); + while (reply->isRunning()) { + loop.processEvents(); + sleep(1); + } + } + +} + +void ImageDownloader::saveImage(QNetworkReply *reply) +{ + QByteArray imageData = reply->readAll(); + QCryptographicHash hash(QCryptographicHash::Sha1); + hash.addData(imageData); + QFile imageFile(QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first().append("/").append(hash.result().toHex())); + if (imageFile.open(QIODevice::WriteOnly)) { + QDataStream stream(&imageFile); + stream.writeRawData(imageData.data(), imageData.length()); + imageFile.waitForBytesWritten(-1); + imageFile.close(); + add_hash(imageFile.fileName(), hash.result()); + learnHash(picture, hash.result()); + DivePictureModel::instance()->updateDivePictures(); + } + reply->manager()->deleteLater(); + reply->deleteLater(); +} + DivePictureModel *DivePictureModel::instance() { static DivePictureModel *self = new DivePictureModel(); @@ -46,8 +97,10 @@ SPixmap scaleImages(picturepointer picture) ret.second = cache.value(picture->filename); } else { int dim = defaultIconMetrics().sz_pic; - QImage p = SHashedImage(picture).scaled(dim, dim, Qt::KeepAspectRatio); - cache.insert(picture->filename, p); + QImage p = SHashedImage(picture); + if(!p.isNull()) + p = p.scaled(dim, dim, Qt::KeepAspectRatio); + cache.insert(picture->filename, p); ret.second = p; } return ret; diff --git a/qt-ui/divepicturewidget.h b/qt-ui/divepicturewidget.h index e8104a1..f879d31 100644 --- a/qt-ui/divepicturewidget.h +++ b/qt-ui/divepicturewidget.h @@ -4,6 +4,7 @@ #include #include #include +#include typedef QPair SHashedFilename; @@ -17,6 +18,18 @@ public: SHashedImage(struct picture *picture); }; +class ImageDownloader : public QObject { + Q_OBJECT; +public: + ImageDownloader(struct picture *picture); + void load(); +private: + struct picture *picture; + QNetworkAccessManager manager; +private slots: + void saveImage(QNetworkReply *reply); +}; + class DivePictureModel : public QAbstractTableModel { Q_OBJECT public: diff --git a/qthelper.cpp b/qthelper.cpp index 14e67e0..3b0ce10 100644 --- a/qthelper.cpp +++ b/qthelper.cpp @@ -832,6 +832,13 @@ QByteArray hashFile(const QString filename) return hash.result(); } +void learnHash(struct picture *picture, QByteArray hash) +{ + free(picture->hash); + hashOf[QString(picture->filename)] = hash; + picture->hash = strdup(hash.toHex()); +} + QString localFilePath(const QString originalFilename) { return localFilenameOf[hashOf[originalFilename]]; diff --git a/qthelper.h b/qthelper.h index 113aee3..b0765ae 100644 --- a/qthelper.h +++ b/qthelper.h @@ -25,4 +25,5 @@ void learnImages(const QDir dir, int max_recursions, bool recursed); void add_hash(const QString filename, QByteArray hash); QString localFilePath(const QString originalFilename); QString fileFromHash(char *hash); +void learnHash(struct picture *picture, QByteArray hash); #endif // QTHELPER_H -- 1.9.3 (Apple Git-50)