1 #include "downloaditem.h"
2 #include "networkaccess.h"
5 #include <QDesktopServices>
11 DownloadItem::DownloadItem(Video *video, QUrl url, QString filename, QObject *parent)
14 , m_startedSaving(false)
15 , m_finishedDownloading(false)
23 void DownloadItem::start() {
24 m_reply = The::http()->simpleGet(m_url);
28 void DownloadItem::init() {
34 m_startedSaving = false;
35 m_finishedDownloading = false;
37 // attach to the m_reply
38 m_url = m_reply->url();
39 connect(m_reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));
40 connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
41 this, SLOT(error(QNetworkReply::NetworkError)));
42 connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)),
43 this, SLOT(downloadProgress(qint64, qint64)));
44 connect(m_reply, SIGNAL(metaDataChanged()),
45 this, SLOT(metaDataChanged()));
46 connect(m_reply, SIGNAL(finished()),
47 this, SLOT(requestFinished()));
49 // start timer for the download estimation
50 m_downloadTime.start();
52 if (m_reply->error() != QNetworkReply::NoError) {
53 error(m_reply->error());
59 void DownloadItem::stop() {
66 void DownloadItem::open() {
67 QFileInfo info(m_file);
68 QUrl url = QUrl::fromLocalFile(info.absoluteFilePath());
69 QDesktopServices::openUrl(url);
72 void DownloadItem::openFolder() {
73 QFileInfo info(m_file);
74 QUrl url = QUrl::fromLocalFile(info.absolutePath());
75 QDesktopServices::openUrl(url);
78 void DownloadItem::tryAgain() {
85 m_reply = The::http()->simpleGet(m_url);
90 void DownloadItem::downloadReadyRead() {
92 if (!m_file.isOpen()) {
93 if (!m_file.open(QIODevice::WriteOnly)) {
94 qDebug() << QString("Error opening output file: %1").arg(m_file.errorString());
102 if (-1 == m_file.write(m_reply->readAll())) {
104 downloadInfoLabel->setText(tr("Error saving: %1")
105 .arg(m_output.errorString()));
109 m_startedSaving = true;
110 if (m_status != Downloading) {
111 // m_status = Downloading;
112 // emit statusChanged();
113 } else if (m_finishedDownloading)
118 void DownloadItem::error(QNetworkReply::NetworkError) {
120 #ifdef DOWNLOADMANAGER_DEBUG
121 qDebug() << "DownloadItem::" << __FUNCTION__ << m_reply->errorString() << m_url;
124 m_errorMessage = m_reply->errorString();
131 QString DownloadItem::errorMessage() const {
132 return m_errorMessage;
135 void DownloadItem::metaDataChanged() {
136 QVariant locationHeader = m_reply->header(QNetworkRequest::LocationHeader);
137 if (locationHeader.isValid()) {
138 m_url = locationHeader.toUrl();
139 m_reply->deleteLater();
140 m_reply = The::http()->simpleGet(m_url);
145 #ifdef DOWNLOADMANAGER_DEBUG
146 qDebug() << "DownloadItem::" << __FUNCTION__ << "not handled.";
150 void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
151 QTime now = QTime::currentTime();
152 if (m_lastProgressTime.msecsTo(now) < 200)
155 m_lastProgressTime = now;
157 m_bytesReceived = bytesReceived;
158 if (bytesTotal > 0) {
159 percent = bytesReceived * 100 / bytesTotal;
162 // qDebug() << bytesReceived << bytesTotal;
163 if (m_status != Downloading
164 && bytesReceived > 1024 * 512
165 && bytesReceived > bytesTotal * .01) {
166 m_status = Downloading;
167 emit statusChanged();
170 emit progress(percent);
171 // emit statusChanged();
174 qint64 DownloadItem::bytesTotal() const {
175 if (!m_reply) return 0;
176 return m_reply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
179 qint64 DownloadItem::bytesReceived() const {
180 return m_bytesReceived;
183 double DownloadItem::remainingTime() const {
184 if (m_finishedDownloading)
187 double timeRemaining = ((double)(bytesTotal() - bytesReceived())) / currentSpeed();
189 // When downloading the eta should never be 0
190 if (timeRemaining == 0)
193 return timeRemaining;
196 double DownloadItem::currentSpeed() const {
197 if (m_finishedDownloading)
200 return m_bytesReceived * 1000.0 / m_downloadTime.elapsed();
203 void DownloadItem::requestFinished() {
205 m_finishedDownloading = true;
206 if (!m_startedSaving) {
211 emit statusChanged();
215 QString DownloadItem::formattedFilesize(qint64 size) {
217 if (size < 1024) return tr("%1 bytes").arg(size);
218 else if (size < 1024*1024) return tr("%1 KB").arg(size/1024);
219 else if (size < 1024*1024*1024) return tr("%1 MB").arg(size/1024/1024);
220 else return tr("%1 GB").arg(size/1024/1024/1024);
225 } else if (size < 1024*1024) {
232 return QString(QLatin1String("%1 %2")).arg(size).arg(unit);
235 QString DownloadItem::formattedSpeed(double speed) {
237 static const int K = 1024;
238 if (speed < K) return tr("%1 bytes/s").arg(speed);
239 else if (speed < K*K) return tr("%1 KB/s").arg(speed/K);
240 else if (speed < K*K*K) return tr("%1 MB/s").arg(speed/K/K);
241 else return tr("%1 GB/s").arg(speed/K/K/K);
243 int speedInt = (int) speed;
245 if (speedInt < 1024) {
246 unit = tr("bytes/sec");
247 } else if (speedInt < 1024*1024) {
251 speedInt /= 1024*1024;
254 return QString(QLatin1String("%1 %2")).arg(speedInt).arg(unit);
257 QString DownloadItem::formattedTime(double timeRemaining) {
258 QString timeRemainingString = tr("seconds");
259 if (timeRemaining > 60) {
260 timeRemaining = timeRemaining / 60;
261 timeRemainingString = tr("minutes");
263 timeRemaining = floor(timeRemaining);
264 return tr("%4 %5 remaining")
266 .arg(timeRemainingString);