36
38
const QString DATA_FILE_NAME = "data.download";
37
const QString METADATA_FILE_NAME = "metadata";
38
const QString METADATA_COMMAND_KEY = "post-download-command";
39
const QString METADATA_COMMAND_FILE_KEY = "$file";
40
39
const QString NETWORK_ERROR = "NETWORK ERROR";
41
40
const QString HASH_ERROR = "HASH ERROR";
42
41
const QString COMMAND_ERROR = "COMMAND ERROR";
43
42
const QString SSL_ERROR = "SSL ERROR";
44
43
const QString FILE_SYSTEM_ERROR = "FILE SYSTEM ERROR: %1";
44
const QString TEMP_EXTENSION = ".tmp";
45
45
const QString AUTH_ERROR = "AUTHENTICATION ERROR";
46
46
const QString PROXY_AUTH_ERROR = "PROXY_AUTHENTICATION ERROR";
47
47
const QString UNEXPECTED_ERROR = "UNEXPECTED_ERROR";
467
469
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
468
470
// remove the file since we are done with it
469
471
cleanUpCurrentData();
470
setState(Download::FINISH);
471
DOWN_LOG(INFO) << "EMIT finished" << filePath();
472
emit finished(filePath());
473
// remove the file because that is the contract that we have with
475
auto fileMan = FileManager::instance();
477
if (fileMan->exists(_tempFilePath)) {
478
LOG(INFO) << "Removing '" << _tempFilePath << "'";
479
fileMan->remove(_tempFilePath);
482
if (fileMan->exists(_filePath)) {
483
LOG(INFO) << "Removing '" << _filePath << "'";
484
fileMan->remove(_filePath);
474
487
auto standardOut = p->readAllStandardOutput();
475
488
auto standardErr = p->readAllStandardError();
567
FileDownload::getSaveFileName() {
581
FileDownload::initFileNames() {
582
// the mutex will ensure that we do not have race conditions about
583
// the file names in the download manager
568
584
QString path = _url.path();
569
585
QString basename = QFileInfo(path).fileName();
571
587
if (basename.isEmpty())
572
588
basename = DATA_FILE_NAME;
574
QVariantMap metadataMap = metadata();
590
auto metadataMap = metadata();
577
if (!isConfined() && metadataMap.contains(LOCAL_PATH_KEY)) {
578
finalPath = metadataMap[LOCAL_PATH_KEY].toString();
592
if (!isConfined() && metadataMap.contains(Metadata::LOCAL_PATH_KEY)) {
593
_filePath = metadataMap[Metadata::LOCAL_PATH_KEY].toString();
594
_tempFilePath = _fileNameMutex->lockFileName(
595
_filePath + TEMP_EXTENSION);
580
597
// in this case and because the app is not confined we are
581
598
// going to check if the file exists, if it does we will
582
599
// raise an error
583
if (QFile::exists(finalPath)) {
600
if (QFile::exists(_filePath)) {
584
601
setIsValid(false);
585
602
setLastError(QString("File already exists at: '%1'").arg(
589
finalPath = rootPath() + QDir::separator() + basename;
590
if (QFile::exists(finalPath)) {
591
finalPath = uniqueFilePath(finalPath);
606
auto desiredPath = rootPath() + QDir::separator() + basename;
607
_filePath = _fileNameMutex->lockFileName(desiredPath);
608
_tempFilePath = _filePath + TEMP_EXTENSION;
600
FileDownload::uniqueFilePath(QString path) {
601
QFileInfo fileInfo(path);
603
// Split the file into 2 parts - dot+extension, and everything else. For
604
// example, "path/file.tar.gz" becomes "path/file"+".tar.gz", while
605
// "path/file" (note lack of extension) becomes "path/file"+"".
606
auto secondPart = fileInfo.completeSuffix();
607
auto firstPart = path;
609
if (!secondPart.isEmpty()) {
610
secondPart = "." + secondPart;
611
firstPart = path.left(path.size() - secondPart.size());
613
FileDownload::emitFinished() {
614
auto fileMan = FileManager::instance();
616
LOG(INFO) << "EMIT finished" << filePath();
617
setState(Download::FINISH);
619
if (fileMan->exists(_tempFilePath)) {
620
LOG(INFO) << "Rename '" << _tempFilePath << "' to '"
622
fileMan->rename(_tempFilePath, _filePath);
614
// Try with an ever-increasing number suffix, until we've reached a file
615
// that does not yet exist.
616
for (int ii = 1; ; ii++) {
617
// Construct the new file name by adding the unique number between the
618
// first and second part.
619
auto finalPath = QString("%1 (%2)%3").arg(firstPart).arg(ii).arg(secondPart);
620
// If no file exists with the new name, return it.
621
if (!QFile::exists(finalPath)) {
624
_fileNameMutex->unlockFileName(_filePath);
625
emit finished(_filePath);