downloader.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #ifndef INCLUDEILEDOWNLOADER_H
  2. #define INCLUDEILEDOWNLOADER_H
  3. #include <QObject>
  4. #include <QNetworkAccessManager>
  5. #include <QNetworkRequest>
  6. #include <QNetworkReply>
  7. #include <QFile>
  8. #include <QTime>
  9. #include <QByteArray>
  10. class Downloader : public QObject
  11. {
  12. Q_OBJECT
  13. public:
  14. struct Status {
  15. bool running = false;
  16. double percent = 0.0;
  17. quint64 total_bytes = 0;
  18. quint64 downloaded_bytes = 0;
  19. quint64 current_speed = 0;
  20. quint64 average_speed = 0;
  21. quint64 elapsed_time = 0;
  22. };
  23. friend Status operator+(const Status& a, const Status &b) {
  24. Status result;
  25. result.running = a.running || b.running;
  26. result.total_bytes = a.total_bytes + b.total_bytes;
  27. result.downloaded_bytes = a.downloaded_bytes + b.downloaded_bytes;
  28. result.percent = double(result.downloaded_bytes) * 100.0 / double(result.total_bytes);
  29. result.average_speed = a.average_speed + b.average_speed;
  30. result.current_speed = a.current_speed + b.current_speed;
  31. // Counting elapsed time
  32. quint64 delta_size = result.total_bytes - result.downloaded_bytes;
  33. quint64 avg_speed = qMax(quint64(1), result.average_speed);
  34. while (delta_size > 1024 && avg_speed > 1024) { // Making precision smaller to get smoother dynamics
  35. delta_size /= 1024;
  36. avg_speed /= 1024;
  37. }
  38. result.elapsed_time = delta_size / avg_speed;
  39. return result;
  40. }
  41. explicit Downloader(QObject *parent = 0);
  42. private:
  43. Q_DISABLE_COPY(Downloader)
  44. public:
  45. virtual ~Downloader();
  46. QUrl getUrl() const;
  47. void setUrl(const QUrl& _url);
  48. void waitForDownloaded() const;
  49. bool isStarted() const;
  50. double getPercent() const;
  51. quint64 getBytesTotal() const;
  52. quint64 getBytesDownloaded() const;
  53. quint64 getElapsedTime() const;
  54. quint64 getCurrentSpeed() const;
  55. quint64 getAverageSpeed() const;
  56. Status getDownloadStatus() const;
  57. static QString getSizeFormatted(quint64 bytes);
  58. static QString getSpeedFormatted(quint64 speed_bytes_per_sec);
  59. static QString getElapsedTimeFormatted(quint64 elapsed_time_secs);
  60. signals:
  61. void downloadFinished(Downloader* this_downloader_ptr);
  62. void progressChanged(Downloader* this_downloader_ptr, Status status);
  63. public slots:
  64. void start();
  65. void updateDownloadSpeedLimit(int bytes_per_sec);
  66. void stop();
  67. private slots:
  68. void onDownloadProgressChanged(qint64 bytesReceived, qint64 bytesTotal);
  69. void onDownloadFinished(QNetworkReply* pReply);
  70. void onReadyRead();
  71. public:
  72. QFile* targetFile {nullptr};
  73. QByteArray* targetBytearray {nullptr};
  74. private:
  75. QTime last_tick_time_;
  76. quint64 download_speed_ = 0; // bytes per second
  77. quint64 average_speed_ = 0;
  78. quint64 update_ticks_counter_ = 0;
  79. quint64 bytes_total_ = 0;
  80. quint64 bytes_downloaded_ = 0;
  81. quint64 bytes_downloaded_before_tick_ = 0; // Нужны для подсчёта текущей скорости скачивания, а не
  82. bool busy_;
  83. QUrl url_;
  84. QNetworkReply* m_CurrentReply {nullptr};
  85. QNetworkAccessManager m_WebCtrl;
  86. unsigned download_speed_limit {0};
  87. };
  88. Q_DECLARE_METATYPE(Downloader::Status)
  89. #endif // INCLUDEILEDOWNLOADER_H