From 9edb4f3fa91b3907809375794d75a1b1a77c94a0 Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk@hohndel.org>
Date: Fri, 6 Nov 2015 10:39:59 -0800
Subject: Move ImageDownloader out of the desktop widgets

This required a bit more untangling, but with this it seems we can build
subsurface-mobile again (at least on the desktop).

Interesting is the removal from inside the ImageDownloader of the call to
DivePictureModel::instance()->updateDivePictures() - which actually could
cause some interesting recursion issues. If it turns out we did indeed
need this, it needs to be re-architected.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
---
 subsurface-core/CMakeLists.txt      |  1 +
 subsurface-core/imagedownloader.cpp | 79 +++++++++++++++++++++++++++++++++++++
 subsurface-core/imagedownloader.h   | 29 ++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 subsurface-core/imagedownloader.cpp
 create mode 100644 subsurface-core/imagedownloader.h

(limited to 'subsurface-core')

diff --git a/subsurface-core/CMakeLists.txt b/subsurface-core/CMakeLists.txt
index 9532ff35a..bd4950767 100644
--- a/subsurface-core/CMakeLists.txt
+++ b/subsurface-core/CMakeLists.txt
@@ -76,6 +76,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
 	metrics.cpp
 	color.cpp
 	pluginmanager.cpp
+	imagedownloader.cpp
 	${SERIAL_FTDI}
 	${PLATFORM_SRC}
 	${BT_CORE_SRC_FILES}
diff --git a/subsurface-core/imagedownloader.cpp b/subsurface-core/imagedownloader.cpp
new file mode 100644
index 000000000..8be1daccc
--- /dev/null
+++ b/subsurface-core/imagedownloader.cpp
@@ -0,0 +1,79 @@
+#include "dive.h"
+#include "metrics.h"
+#include "divelist.h"
+#include "qthelper.h"
+#include "imagedownloader.h"
+#include <unistd.h>
+
+#include <QtConcurrent>
+
+ImageDownloader::ImageDownloader(struct picture *pic)
+{
+	picture = pic;
+}
+
+void ImageDownloader::load(){
+	QUrl url = QUrl::fromUserInput(QString(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();
+	QImage image = QImage();
+	image.loadFromData(imageData);
+	if (image.isNull())
+		return;
+	QCryptographicHash hash(QCryptographicHash::Sha1);
+	hash.addData(imageData);
+	QString path = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).first();
+	QDir dir(path);
+	if (!dir.exists())
+		dir.mkpath(path);
+	QFile imageFile(path.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());
+	}
+	reply->manager()->deleteLater();
+	reply->deleteLater();
+}
+
+void loadPicture(struct picture *picture)
+{
+	ImageDownloader download(picture);
+	download.load();
+}
+
+SHashedImage::SHashedImage(struct picture *picture) : QImage()
+{
+	QUrl url = QUrl::fromUserInput(QString(picture->filename));
+	if(url.isLocalFile())
+		load(url.toLocalFile());
+	if (isNull()) {
+		// Hash lookup.
+		load(fileFromHash(picture->hash));
+		if (!isNull()) {
+			QtConcurrent::run(updateHash, picture);
+		} else {
+			QtConcurrent::run(loadPicture, picture);
+		}
+	} else {
+		QByteArray hash = hashFile(url.toLocalFile());
+		free(picture->hash);
+		picture->hash = strdup(hash.toHex().data());
+	}
+}
diff --git a/subsurface-core/imagedownloader.h b/subsurface-core/imagedownloader.h
new file mode 100644
index 000000000..fd6a91158
--- /dev/null
+++ b/subsurface-core/imagedownloader.h
@@ -0,0 +1,29 @@
+#ifndef IMAGEDOWNLOADER_H
+#define IMAGEDOWNLOADER_H
+
+#include <QImage>
+#include <QFuture>
+#include <QNetworkReply>
+
+typedef QPair<QString, QByteArray> SHashedFilename;
+
+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 SHashedImage : public QImage {
+public:
+	SHashedImage(struct picture *picture);
+};
+
+#endif // IMAGEDOWNLOADER_H
-- 
cgit v1.2.3-70-g09d2