26 #include <QNetworkInterface> 27 #include <QNetworkProxy> 30 #include <QStandardPaths> 31 #include <QStorageInfo> 50 , mLocalPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))
52 , mIndexFileName(
"index.txt")
55 , pNetworkReply(nullptr)
57 , mIsWaitingForConnection(false)
58 , mForcedDownload(false)
59 , mIsDownloading(false)
75 QList<QNetworkInterface> networkInterfaces = QNetworkInterface::allInterfaces();
76 bool connectionFound =
false;
77 LOGMESSAGE <<
"Checking network interfaces and internet connections:";
78 for (
auto &networkInterface : networkInterfaces)
80 if ( networkInterface.flags().testFlag(QNetworkInterface::IsUp)
81 and not networkInterface.flags().testFlag(QNetworkInterface::IsLoopBack))
83 LOGMESSAGE <<
"Testing" << networkInterface.name()
84 <<
"MAC:" << networkInterface.hardwareAddress() <<
":";
85 if (networkInterface.addressEntries().empty())
86 {
LOGMESSAGE <<
"This adapter is not connected."; }
87 else for (QNetworkAddressEntry &entry : networkInterface.addressEntries())
90 if (networkInterface.name().startsWith(
"utun"))
92 LOGMESSAGE <<
"Ignoring connected MAC device" << networkInterface.name();
98 LOGMESSAGE <<
"/ Netmask:" << entry.netmask().toString();
100 connectionFound =
true;
105 return connectionFound;
123 LOGMESSAGE <<
"Start downloading, forced =" << forced;
129 LOGERROR <<
"Downloader is already downloading. Do not call start() twice.";
137 LOGMESSAGE <<
"Downloader has already been started and is waiting for internet connection. Ignore call to start().";
143 if (not directory.exists()) directory.mkpath(
".");
144 if (not directory.exists())
153 LOGWARNING <<
"Not connected to the internet, retry in 5 secs.";
156 LOGMESSAGE <<
"Emit a warning to Qml that forced download failed because of missing connection";
189 LOGWARNING <<
"Still not connected to the internet, retry in 60 secs.";
196 #ifndef QT_NO_NETWORKPROXY 198 QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(query);
199 LOGMESSAGE <<
"Number of available proxies" << listOfProxies.size();
201 if (listOfProxies.size())
203 LOGMESSAGE <<
"Set the first proxy in the list";
204 QNetworkProxy::setApplicationProxy(listOfProxies[0]);
215 LOGWARNING <<
"Error requesting file" << index.fileName() <<
"for download";
221 LOGMESSAGE <<
"Downloading file, waiting for network reply on the URL:";
271 LOGWARNING <<
"A network error occured during download of the index file";
274 LOGWARNING <<
"After network error: Retry downloading in 60 secs.";
280 QTextStream inputStream(pReply);
282 while (not inputStream.atEnd())
mIndexOfFiles << inputStream.readLine();
283 pReply->deleteLater();
294 if (not indexFile.open(QIODevice::WriteOnly))
300 QTextStream outputStream(&indexFile);
301 for (
auto &line :
mIndexOfFiles) outputStream << line <<
"\n";
302 if (indexFile.isOpen()) indexFile.close();
303 LOGMESSAGE <<
"Successfully downloaded" << pReply->url().toString();
321 QStringList nameFilter(
"*.int");
323 QStringList list = directory.entryList(nameFilter);
325 QStringList filteredList;
326 if (not indexFile.open(QIODevice::ReadOnly)) filteredList = list;
329 QStringList indexFileContent;
330 QTextStream inputStream(&indexFile);
331 while (not inputStream.atEnd()) indexFileContent << inputStream.readLine();
332 if (indexFile.isOpen()) indexFile.close();
333 for (QString &e : indexFileContent)
if (list.contains(e))
334 filteredList.append(
fullPath(directory.path(),e));
337 for (QString &e : filteredList)
if (
mIndexOfFiles.contains(e))
338 filteredList.append(
fullPath(directory.path(),e));
361 QNetworkRequest request;
362 request.setUrl(QUrl(remotefile));
388 qint64 remotefilesize =
pNetworkReply->header(QNetworkRequest::ContentLengthHeader).toUInt();
389 QDateTime remotefilelastmodified =
390 pNetworkReply->header(QNetworkRequest::LastModifiedHeader).value<QDateTime>();
396 LOGMESSAGE <<
"Found file " << remotefile <<
", size =" << remotefilesize;
400 QFileInfo fileinfo(localfile);
401 if (fileinfo.exists() and fileinfo.isFile())
404 qint64 localfilesize = fileinfo.size();
405 QDateTime localfilecreated = fileinfo.created();
406 LOGSTATUS <<
"Local file data:" << localfilecreated;
407 LOGSTATUS <<
"Remote file date:" << remotefilelastmodified;
408 if (localfilesize != remotefilesize or localfilecreated < remotefilelastmodified)
411 LOGWARNING <<
"Length of date is different, hence delete file" << localfile;
412 QFile::remove(localfile);
416 LOGMESSAGE <<
"Forced download: File" << localfile <<
"will be deleted";
417 QFile::remove(localfile);
422 LOGMESSAGE <<
"File" << localfile <<
"already exists, skipping download.";
430 diskspace = 10000000000;
432 LOGSTATUS <<
"Free disk space =" << diskspace;
433 if (2*remotefilesize > diskspace)
435 LOGWARNING <<
"Device does not provide enough disk space for downloading.";
441 QString tmpfile = localfile +
".part";
442 mFile.setFileName(tmpfile);
443 if (not
mFile.open(QIODevice::WriteOnly))
445 LOGWARNING <<
"Could not open file for writing: " << localfile;
451 LOGMESSAGE <<
"downloading" << remotefile <<
"to" << localfile;
481 LOGSTATUS << bytesReceived <<
"of" << bytesTotal <<
"bytes downloaded.";
509 if (pReply->isOpen())
511 QByteArray lastchunk = pReply->readAll();
512 mFile.write(lastchunk);
519 QString tmpfile = localfile +
".part";
520 if (QFile::rename(tmpfile,localfile))
521 {
LOGMESSAGE <<
"Completed download of file" << localfile; }
522 else LOGWARNING <<
"Could not rename temporary file" << tmpfile;
531 QString tmpfile = localfile +
".part";
532 QFile::remove(tmpfile);
534 pReply->deleteLater();
576 if (not path.endsWith(
'/'))
return path+
"/"+file;
577 else return path+file;
void signalNewFileDownloaded(QString localpath)
void checkWhetherFileExistsAndDownload()
Private slot: Start downloading if necessary.
QString mLocalPath
Local path of the file to be downloaded.
void downloadIndexFile()
Download index file.
void setModuleName(const QString &name)
Specify the name of the class-specific module.
void signalDownloading(QVariant downloading)
void stop()
Stop downloading.
void finalize()
Finalize download.
bool isConnectedToInternet()
Check internet connection.
bool mForcedDownload
Flag for forced download.
#define INT_SAMPLES_REPOSITORY
Downloader(QString url, QObject *parent=0)
Constructor, resetting the member variables.
void start(bool forced)
Start the downloading process in the background.
void signalNoInternetConnection(QVariant forced)
QNetworkAccessManager mNetworkManager
Instance of the Qt network access manager.
QString mRemotePath
Remote path of the file to be downloaded.
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
Private slot: Download a data chunk and report progress.
QNetworkReply * pNetworkReply
Pointer to the network reply structure.
void initiateDownloadOfNextFile()
Private slot: Initiate download of next file.
QString fullPath(const QString &path, const QString &file) const
Helper function: Construct a full path out of a path and a file name.
QString mIndexFileName
Name of the remote index file.
#define INT_FILEFORMAT_ROLLING_VERSION
QFile mFile
File to be written.
bool mIsWaitingForConnection
Flag indicating waiting status.
void signalProgress(QVariant filesRemaining, QVariant percent)
void signalAllFilesDownloaded()
QStringList getPathsOfDownloadedFiles()
Get a list of paths of all downloaded files.
void indexFileDownloadFinished(QNetworkReply *pReply)
Private slot: Index file downloaded.
QStringList mIndexOfFiles
The content of the index file as a QStringList.
void downloadComplete(QNetworkReply *pReply)
Private slot: Download completed.
bool mIsDownloading
Flag indicating active download.