aboutsummaryrefslogtreecommitdiffstats
path: root/core/imagedownloader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/imagedownloader.cpp')
-rw-r--r--core/imagedownloader.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/core/imagedownloader.cpp b/core/imagedownloader.cpp
new file mode 100644
index 000000000..f406ee45a
--- /dev/null
+++ b/core/imagedownloader.cpp
@@ -0,0 +1,113 @@
+#include "dive.h"
+#include "metrics.h"
+#include "divelist.h"
+#include "qthelper.h"
+#include "imagedownloader.h"
+#include <unistd.h>
+
+#include <QtConcurrent>
+
+QUrl cloudImageURL(const char *hash)
+{
+ return QUrl::fromUserInput(QString("https://cloud.subsurface-divelog.org/images/").append(hash));
+}
+
+ImageDownloader::ImageDownloader(struct picture *pic)
+{
+ picture = pic;
+}
+
+ImageDownloader::~ImageDownloader()
+{
+ picture_free(picture);
+}
+
+void ImageDownloader::load(bool fromHash){
+ QUrl url;
+ loadFromHash = fromHash;
+ if(fromHash)
+ url = cloudImageURL(picture->hash);
+ else
+ 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()) {
+ if (loadFromHash)
+ load(false);
+ 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();
+ // This should be called to make the picture actually show.
+ // Problem is DivePictureModel is not in core.
+ // Nevertheless, the image shows when the dive is selected the next time.
+ // DivePictureModel::instance()->updateDivePictures();
+
+}
+
+void loadPicture(struct picture *picture, bool fromHash)
+{
+ ImageDownloader download(picture);
+ download.load(fromHash);
+}
+
+SHashedImage::SHashedImage(struct picture *picture) : QImage()
+{
+ QUrl url = QUrl::fromUserInput(localFilePath(QString(picture->filename)));
+ if(url.isLocalFile())
+ load(url.toLocalFile());
+ if (isNull()) {
+ // This did not load anything. Let's try to get the image from other sources
+ // Let's try to load it locally via its hash
+ QString filename = fileFromHash(picture->hash);
+ if (filename.isNull()) {
+ // That didn't produce a local filename.
+ // Try the cloud server
+ QtConcurrent::run(loadPicture, clone_picture(picture), true);
+ } else {
+ // Load locally from translated file name
+ load(filename);
+ if (!isNull()) {
+ // Make sure the hash still matches the image file
+ QtConcurrent::run(updateHash, clone_picture(picture));
+ } else {
+ // Interpret filename as URL
+ QtConcurrent::run(loadPicture, clone_picture(picture), false);
+ }
+ }
+ } else {
+ // We loaded successfully. Now, make sure hash is up to date.
+ QtConcurrent::run(hashPicture, clone_picture(picture));
+ }
+}
+