downloadmanager.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #include "app.h"
  2. #include "filesystem.h"
  3. #include "lotromanager.h"
  4. #include <QFileInfo>
  5. #include <QApplication>
  6. #include <QNetworkRequest>
  7. #include <QNetworkReply>
  8. #include <QString>
  9. #include <QStringList>
  10. #include <QTimer>
  11. #include <stdio.h>
  12. DownloadManager::DownloadManager(QObject *parent)
  13. : QObject(parent), downloadedCount(0), totalCount(0)
  14. {
  15. busy = false;
  16. }
  17. void DownloadManager::append(const QStringList &urlList){
  18. foreach (QString url, urlList)
  19. append(QUrl::fromEncoded(url.toUtf8()));
  20. if (downloadQueue.isEmpty())
  21. QTimer::singleShot(0, this, SIGNAL(finished()));
  22. }
  23. void DownloadManager::append(const QUrl &url){
  24. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Добавлен файл для скачивания: ", url.fileName().toUtf8().data());
  25. if (downloadQueue.count(url) == 0) {
  26. downloadQueue.enqueue(url);
  27. ++totalCount;
  28. } else {
  29. qDebug("%s:%i: %s %s%s", __FILE__, __LINE__, "Не добавляю закачку "
  30. , url.fileName().toUtf8().data()
  31. , ", так как она уже находится в очереди закачек");
  32. }
  33. qDebug("%s:%i: %s%i", __FILE__, __LINE__, "Загрузок в списке: ", totalCount);
  34. //if (!busy)
  35. // QTimer::singleShot(0, this, SLOT(startNextDownload()));
  36. }
  37. void DownloadManager::startDownloads() {
  38. if (!busy)
  39. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  40. }
  41. void DownloadManager::startNextDownload() {
  42. current_speed = "";
  43. bytesReceivedBeforeSecond = 0;
  44. timeElapsedBeforeSecond = 0;
  45. elapsed_time = "высчитывается...";
  46. if (busy) {
  47. qWarning("%s:%i: %s", __FILE__, __LINE__, "Ошибка! Обнаружена попытка начала загрузки, когда не завершилась другая загрузка");
  48. return;
  49. }
  50. App *app = &App::getInstance();
  51. app->helper->setState("busy");
  52. busy = true;
  53. if (downloadQueue.isEmpty()) {
  54. app->helper->setState("free");// говорим что приложение освободилось
  55. qDebug("%s:%i: %s%d/%d", __FILE__, __LINE__, "Загрузка завершена. Загружено файлов: ", downloadedCount, totalCount);
  56. busy = false;
  57. emit finished();
  58. return;
  59. }
  60. QUrl url = downloadQueue.dequeue();
  61. QString filename = QFileInfo(url.path()).fileName();
  62. output.setFileName(QApplication::applicationDirPath() + "/data/" + filename);
  63. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Начата загрузка файла: ", filename.toUtf8().data());
  64. // Проверяем целостность файла и игнорируем в случае если он цел
  65. QString hash = FileSystem::fileHash(QApplication::applicationDirPath() + "/data/" + filename, QCryptographicHash::Md5);
  66. QStringList pname = output.fileName().split("/");
  67. QStringList ptype = pname.last().split("_");
  68. qDebug() << ptype.first();
  69. QString keyname = ptype.first();
  70. if(keyname == "loadscreens") keyname = "screens";
  71. if(hash == app->config->getValue("Hashes", ptype.first()) && app->config->getValue("Editor", keyname) == "true"){
  72. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Проверка хэша успешно завершена: ", filename.toUtf8().data());
  73. busy = false;
  74. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  75. return;
  76. }
  77. qDebug("%s:%i: %s%s", __FILE__, __LINE__, "Хэш файла не совпал: ", filename.toUtf8().data());
  78. QStringList parsename = filename.split("_");
  79. QString name = parsename[0] + "Status";
  80. download_name = parsename[0];
  81. // Проверка, что файл не был отменён
  82. if(app->config->getValue("Editor", download_name) == "false") {
  83. emit changePatchStatus(download_name, "Отменён");
  84. busy = false;
  85. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  86. return;
  87. }
  88. if (!output.open(QIODevice::WriteOnly)) {
  89. qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Произошла остановка скачивания (не могу открыть файл) "
  90. , filename.toUtf8().data());
  91. emit changePatchStatus(download_name, "Ошибка записи");
  92. busy = false;
  93. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  94. return;
  95. }
  96. qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Начинаем скачивание ", url.fileName().toUtf8().data());
  97. QNetworkRequest request(url);
  98. currentDownload = manager.get(request);
  99. connect(this, SIGNAL(cancelDownload()), currentDownload, SLOT(abort()));
  100. connect(currentDownload, SIGNAL(downloadProgress(qint64,qint64)), SLOT(downloadProgress(qint64,qint64)));
  101. connect(currentDownload, SIGNAL(finished()), SLOT(downloadFinished()));
  102. connect(currentDownload, SIGNAL(readyRead()), SLOT(downloadReadyRead()));
  103. // prepare the output
  104. downloadTime.start();
  105. }
  106. void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
  107. App* app = &App::getInstance();
  108. double speed = (bytesReceived - bytesReceivedBeforeSecond) * 1000.0 / (downloadTime.elapsed() - timeElapsedBeforeSecond);
  109. double percent = double(std::ceil(((double)bytesReceived/ bytesTotal) * 100 * 10)) / 10.0;
  110. QString unit;
  111. if (speed < 1024) {
  112. unit = "bytes/sec";
  113. } else if (speed < 1024*1024) {
  114. speed /= 1024;
  115. unit = "kB/s";
  116. } else {
  117. speed /= 1024*1024;
  118. unit = "MB/s";
  119. }
  120. QString speedtext = QString::fromLatin1("%1 %2").arg(speed, 3, 'f', 1).arg(unit);
  121. QString percenttext = QString::fromLatin1("%1").arg(percent, 3, 'f', 1);
  122. if (downloadTime.elapsed() - timeElapsedBeforeSecond >= 1000) {
  123. timeElapsedBeforeSecond = downloadTime.elapsed();
  124. bytesReceivedBeforeSecond = bytesReceived;
  125. current_speed = speedtext;
  126. elapsed_time = app->helper->countFormattedElapsedTime(bytesTotal - bytesReceived, bytesReceived * 1000.0 / downloadTime.elapsed());
  127. }
  128. if (current_speed == "")
  129. current_speed = speedtext;
  130. emit changePatchStatus(download_name, "Загрузка ... <br/>" + percenttext + "% (" + current_speed + ")");
  131. emit changeHint("Загрузка патча " + LotroManager::getInstance().patchTitleFromName(download_name),
  132. "Завершено " + percenttext + "% (" + current_speed + "). Оставшееся время: " + elapsed_time);
  133. }
  134. void DownloadManager::downloadFinished() {
  135. busy = false;
  136. output.close();
  137. qDebug() << "Finished download: " << output.fileName().split('/').last().split('_')[0];
  138. downloaded_list.append(output.fileName().split('/').last().split('_')[0]);
  139. App *app = &App::getInstance();
  140. app->helper->setState("free");// говорим что приложение освободилось
  141. if (currentDownload->error()) {
  142. qWarning("%s:%i: %s%s", __FILE__, __LINE__, "Загрузка не удалась: ", currentDownload->errorString().toUtf8().data());
  143. emit changePatchStatus(download_name, "Не удалась");
  144. } else {
  145. emit changePatchStatus(download_name, "Готово");
  146. ++downloadedCount;
  147. }
  148. if (downloadQueue.isEmpty()) {
  149. qInfo("%s:%i: %s", __FILE__, __LINE__, "Все загрузки завершены. Загрузчик завершил свою работу.");
  150. emit allDownloadsFinished(downloaded_list);
  151. } else {
  152. QTimer::singleShot(0, this, SLOT(startNextDownload()));
  153. }
  154. currentDownload->deleteLater();
  155. }
  156. void DownloadManager::downloadReadyRead(){
  157. output.write(currentDownload->readAll());
  158. }
  159. void DownloadManager::abortDownload(QString name){
  160. App *app = &App::getInstance();
  161. if(download_name == name){
  162. if(app->state != "free" && currentDownload != NULL && currentDownload->isOpen()) {
  163. qDebug() << "Прерываем закачку " + download_name;
  164. qInfo("%s:%i: %s%s", __FILE__, __LINE__, "Пользователь прервал закачку файла ", download_name.toUtf8().data());
  165. emit changePatchStatus(name, "Отменён");
  166. currentDownload->abort();
  167. }
  168. }
  169. downloadQueue.removeAll(name);
  170. }
  171. int DownloadManager::getDownloadedCount() {
  172. return downloadedCount;
  173. }
  174. void DownloadManager::resetDownloadedCount() {
  175. totalCount = 0;
  176. downloadedCount = 0;
  177. downloaded_list.clear();
  178. }