downloadmanager.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "app.h"
  2. #include "filesystem.h"
  3. #include <QFileInfo>
  4. #include <QApplication>
  5. #include <QNetworkRequest>
  6. #include <QNetworkReply>
  7. #include <QString>
  8. #include <QStringList>
  9. #include <QTimer>
  10. #include <stdio.h>
  11. DownloadManager::DownloadManager(QObject *parent)
  12. : QObject(parent), downloadedCount(0), totalCount(0)
  13. {
  14. }
  15. void DownloadManager::append(const QStringList &urlList){
  16. foreach (QString url, urlList)
  17. append(QUrl::fromEncoded(url.toLocal8Bit()));
  18. if (downloadQueue.isEmpty())
  19. QTimer::singleShot(0, this, SIGNAL(finished()));
  20. }
  21. void DownloadManager::append(const QUrl &url){
  22. App *app = &App::getInstance();
  23. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Добавлен: ", app->helper->stringToChar(url.fileName()));
  24. if (downloadQueue.isEmpty())
  25. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  26. downloadQueue.enqueue(url);
  27. ++totalCount;
  28. qDebug("%s:%i: %s%i", __FILE__, __LINE__, "Загрузок в списке: ", totalCount);
  29. }
  30. void DownloadManager::startNextDownload()
  31. {
  32. App *app = &App::getInstance();
  33. if (downloadQueue.isEmpty()) {
  34. app->helper->setState("free");// говорим что приложение освободилось
  35. qDebug("%s:%i: %s%d/%d", __FILE__, __LINE__, "Загрузка завершена. Загружено файлов: ", downloadedCount, totalCount);
  36. emit finished();
  37. return;
  38. }
  39. QUrl url = downloadQueue.dequeue();
  40. QString filename = QFileInfo(url.path()).fileName();
  41. output.setFileName(QApplication::applicationDirPath() + "/data/" + filename);
  42. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начата загрузка файла: ", app->helper->stringToChar(filename));
  43. // Проверяем целостность файла и игнорируем в случае если он цел
  44. QString hash = FileSystem::fileHash(QApplication::applicationDirPath() + "/data/" + filename, QCryptographicHash::Md5);
  45. QStringList pname = output.fileName().split("/");
  46. QStringList ptype = pname.last().split("_");
  47. qDebug() << ptype.first();
  48. QString keyname = ptype.first();
  49. if(keyname == "loadscreens") keyname = "screens";
  50. if(hash == app->config->getValue("Hashes", ptype.first()) && app->config->getValue("Editor", keyname) == "true"){
  51. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Проверка хэша успешно завершена: ", app->helper->stringToChar(filename));
  52. startNextDownload();
  53. return;
  54. }
  55. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Хэш файла не совпал: ", app->helper->stringToChar(filename));
  56. QStringList parsename = filename.split("_");
  57. QString name = parsename[0] + "Status";
  58. download_name = parsename[0];
  59. app->writtenLabel = app->window->ui->mainbox->findChild<QLabel *>(name);
  60. if (!output.open(QIODevice::WriteOnly)) {
  61. qCritical("%s:%i: %s%s", __FILE__, __LINE__, "Произошла остановка скачивания ", app->helper->stringToChar(filename));
  62. /*fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
  63. qPrintable(filename), url.toEncoded().constData(),
  64. qPrintable(output.errorString()));*/
  65. if(app->writtenLabel != nullptr) app->writtenLabel->setText("Не удалась");
  66. startNextDownload();
  67. return;
  68. }
  69. qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем скачивание ", app->helper->stringToChar(url.fileName()));
  70. app->helper->setState("busy");// говорим что приложение занято
  71. QNetworkRequest request(url);
  72. currentDownload = manager.get(request);
  73. connect(this, SIGNAL(cancelDownload()), currentDownload, SLOT(abort()));
  74. connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)),
  75. SLOT(downloadProgress(qint64,qint64)));
  76. connect(currentDownload, SIGNAL(finished()),
  77. SLOT(downloadFinished()));
  78. connect(currentDownload, SIGNAL(readyRead()),
  79. SLOT(downloadReadyRead()));
  80. // prepare the output
  81. downloadTime.start();
  82. }
  83. void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
  84. {
  85. double speed = bytesReceived * 1000.0 / downloadTime.elapsed();
  86. double percent = double(std::ceil(((double)bytesReceived/ bytesTotal) * 100 * 10)) / 10.0;
  87. QString unit;
  88. if (speed < 1024) {
  89. unit = "bytes/sec";
  90. } else if (speed < 1024*1024) {
  91. speed /= 1024;
  92. unit = "kB/s";
  93. } else {
  94. speed /= 1024*1024;
  95. unit = "MB/s";
  96. }
  97. QString speedtext = QString::fromLatin1("%1 %2").arg(speed, 3, 'f', 1).arg(unit);
  98. QString percenttext = QString::fromLatin1("%1").arg(percent, 3);
  99. App *app = &App::getInstance();
  100. if(app->writtenLabel != nullptr) app->writtenLabel->setText("Загрузка ... <br/>" + percenttext+ "% (" + speedtext + ")");
  101. }
  102. void DownloadManager::downloadFinished()
  103. {
  104. output.close();
  105. App *app = &App::getInstance();
  106. app->helper->setState("free");// говорим что приложение освободилось
  107. if (currentDownload->error()) {
  108. qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Загрузка не удалась: ", app->helper->stringToChar(currentDownload->errorString()));
  109. //fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
  110. if(app->writtenLabel != nullptr) app->writtenLabel->setText("Не удалась.");
  111. } else {
  112. if(app->writtenLabel != nullptr) app->writtenLabel->setText("Готово");
  113. qInfo("%s:%i: %s", __FILE__, __LINE__, "Все загрузки завершены. Загрузчик завершил свою работу.");
  114. ++downloadedCount;
  115. app->network->getPaths();
  116. }
  117. currentDownload->deleteLater();
  118. startNextDownload();
  119. }
  120. void DownloadManager::downloadReadyRead(){
  121. output.write(currentDownload->readAll());
  122. }
  123. void DownloadManager::abortDownload(QString name){
  124. App *app = &App::getInstance();
  125. if(download_name == name){
  126. if(app->state != "free" && currentDownload != NULL && currentDownload->isOpen()) {
  127. qDebug() << "Прерываем закачку " + download_name;
  128. qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Пользователь прервал закачку файла ", app->helper->stringToChar(download_name));
  129. if(app->writtenLabel != nullptr) app->writtenLabel->setText("Не выбран");
  130. currentDownload->abort();
  131. }
  132. }
  133. }