mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
e32ae20ca3
This was broken when introducing loading images from the server. Now it first tries the server and if that fails tries the actual URL. Still, the image does not show up immediately, since the DivePictureModel is unavailable to the image downloader to be told to update the images. This needs to be fixed but in the mean time, the image is shown when the dive is reselected (possibly on the next run) since it is then loaded from the cache. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
113 lines
3.1 KiB
C++
113 lines
3.1 KiB
C++
#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 subsurface-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));
|
|
}
|
|
}
|
|
|