1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "filedownloadthread.h"
// TODO don't include curl result, move defaultClient elsewere
#include "curlresult.h"
#include <curl/curl.h>
#include <QFileInfo>
#include <QDir>
#include <QDebug>
#include <QUrl>
FileDownloadThread::FileDownloadThread(QString url, QString downloadPath, bool overwriteExisting, bool keepRemoteName) :
url(url),
downloadPath(downloadPath),
overwriteExisting(overwriteExisting),
keepRemoteName(keepRemoteName)
{
}
void FileDownloadThread::run() {
// create dir
QDir dir;
if (keepRemoteName) {
dir = QDir(downloadPath);
} else {
dir = QFileInfo(downloadPath).absoluteDir();
}
if (!dir.exists()) {
if (!QDir::root().mkpath(dir.absolutePath())) {
qDebug() << "could not create director for fileDownload" << dir.absolutePath();
return;
}
}
QString finalPath;
QString filename;
if (keepRemoteName) {
filename = QFileInfo(QUrl(url).path()).fileName();
finalPath = dir.absoluteFilePath(filename);
} else {
finalPath = downloadPath;
filename = QFileInfo(downloadPath).fileName();
}
if (QFile::exists(finalPath) && !overwriteExisting) {
return;
}
const QString tmpFilename(QString().sprintf("%p", this).append(filename));
QFile tmpFile(QDir::temp().absoluteFilePath(tmpFilename));
if (tmpFile.open(QFile::WriteOnly)) {
CURL* handle = curlClient(url.toLocal8Bit().data(), tmpFile);
int error = curl_easy_perform(handle);
curl_easy_cleanup(handle);
tmpFile.close();
if (error) {
qDebug() << "could not fetch file " << url;
tmpFile.remove();
} else {
qDebug() << "finished file-download of " << finalPath;
emit downloadSucceeded(finalPath);
}
QFile::remove(finalPath);
if (!tmpFile.rename(finalPath)) {
qDebug() << "could not rename downloaded tmp file to destination file: " << finalPath;
tmpFile.remove();
}
} else {
qDebug() << "could not write download to " << finalPath;
}
}
CURL* FileDownloadThread::curlClient(const char* url, QFile& file) {
CURL* handle = CurlResult::defaultClient();
curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, FileDownloadThread::write_data);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &file);
return handle;
}
int FileDownloadThread::write_data(void *buffer, size_t characterSize, size_t bufferSize, void *userp)
{
QFile* file = static_cast<QFile*>(userp);
if (file) {
return file->write((const char*)buffer, characterSize*bufferSize);
}
return 0;
}