]> git.sur5r.net Git - minitube/blob - src/downloaditem.cpp
Imported Upstream version 1.2
[minitube] / src / downloaditem.cpp
1 #include "downloaditem.h"
2 #include "networkaccess.h"
3 #include "video.h"
4
5 #include <QDesktopServices>
6
7 namespace The {
8     NetworkAccess* http();
9 }
10
11 DownloadItem::DownloadItem(Video *video, QUrl url, QString filename, QObject *parent)
12     : QObject(parent)
13     , m_bytesReceived(0)
14     , m_startedSaving(false)
15     , m_finishedDownloading(false)
16     , m_url(url)
17     , m_file(filename)
18     , m_reply(0)
19     , video(video)
20     , m_status(Idle)
21 { }
22
23 void DownloadItem::start() {
24     m_reply = The::http()->simpleGet(m_url);
25     init();
26 }
27
28 void DownloadItem::init() {
29     if (!m_reply)
30         return;
31
32     m_status = Starting;
33
34     m_startedSaving = false;
35     m_finishedDownloading = false;
36
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()));
48
49     // start timer for the download estimation
50     m_downloadTime.start();
51
52     if (m_reply->error() != QNetworkReply::NoError) {
53         error(m_reply->error());
54         requestFinished();
55     }
56 }
57
58
59 void DownloadItem::stop() {
60     if (m_reply)
61         m_reply->abort();
62     m_status = Idle;
63     emit statusChanged();
64 }
65
66 void DownloadItem::open() {
67     QFileInfo info(m_file);
68     QUrl url = QUrl::fromLocalFile(info.absoluteFilePath());
69     QDesktopServices::openUrl(url);
70 }
71
72 void DownloadItem::openFolder() {
73     QFileInfo info(m_file);
74     QUrl url = QUrl::fromLocalFile(info.absolutePath());
75     QDesktopServices::openUrl(url);
76 }
77
78 void DownloadItem::tryAgain() {
79     if (m_reply)
80         m_reply->abort();
81
82     if (m_file.exists())
83         m_file.remove();
84
85     m_reply = The::http()->simpleGet(m_url);
86     init();
87     emit statusChanged();
88 }
89
90 void DownloadItem::downloadReadyRead() {
91
92     if (!m_file.isOpen()) {
93         if (!m_file.open(QIODevice::WriteOnly)) {
94             qDebug() << QString("Error opening output file: %1").arg(m_file.errorString());
95             stop();
96             emit statusChanged();
97             return;
98         }
99         emit statusChanged();
100     }
101
102     m_status = Downloading;
103     if (-1 == m_file.write(m_reply->readAll())) {
104         /*
105         downloadInfoLabel->setText(tr("Error saving: %1")
106                                    .arg(m_output.errorString()));
107         stopButton->click();
108         */
109     } else {
110         m_startedSaving = true;
111         if (m_finishedDownloading)
112             requestFinished();
113     }
114 }
115
116 void DownloadItem::error(QNetworkReply::NetworkError) {
117
118 #ifdef DOWNLOADMANAGER_DEBUG
119     qDebug() << "DownloadItem::" << __FUNCTION__ << m_reply->errorString() << m_url;
120 #endif
121
122     m_errorMessage = m_reply->errorString();
123     m_reply = 0;
124     m_status = Failed;
125
126     emit finished();
127 }
128
129 QString DownloadItem::errorMessage() const {
130     return m_errorMessage;
131 }
132
133 void DownloadItem::metaDataChanged() {
134     QVariant locationHeader = m_reply->header(QNetworkRequest::LocationHeader);
135     if (locationHeader.isValid()) {
136         m_url = locationHeader.toUrl();
137         m_reply->deleteLater();
138         m_reply = The::http()->simpleGet(m_url);
139         init();
140         return;
141     }
142
143 #ifdef DOWNLOADMANAGER_DEBUG
144     qDebug() << "DownloadItem::" << __FUNCTION__ << "not handled.";
145 #endif
146 }
147
148 void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
149     QTime now = QTime::currentTime();
150     if (m_lastProgressTime.msecsTo(now) < 200)
151         return;
152
153     m_lastProgressTime = now;
154
155     m_bytesReceived = bytesReceived;
156     if (bytesTotal > 0) {
157         percent = bytesReceived * 100 / bytesTotal;
158     }
159
160     emit progress(percent);
161     // emit statusChanged();
162 }
163
164 qint64 DownloadItem::bytesTotal() const {
165     if (!m_reply) return 0;
166     return m_reply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
167 }
168
169 qint64 DownloadItem::bytesReceived() const {
170     return m_bytesReceived;
171 }
172
173 double DownloadItem::remainingTime() const {
174     if (m_finishedDownloading)
175         return -1.0;
176
177     double timeRemaining = ((double)(bytesTotal() - bytesReceived())) / currentSpeed();
178
179     // When downloading the eta should never be 0
180     if (timeRemaining == 0)
181         timeRemaining = 1;
182
183     return timeRemaining;
184 }
185
186 double DownloadItem::currentSpeed() const {
187     if (m_finishedDownloading)
188         return -1.0;
189
190     return m_bytesReceived * 1000.0 / m_downloadTime.elapsed();
191 }
192
193 void DownloadItem::requestFinished() {
194     m_reply = 0;
195     m_finishedDownloading = true;
196     if (!m_startedSaving) {
197         return;
198     }
199     m_file.close();
200     m_status = Finished;
201     emit statusChanged();
202     emit finished();
203 }
204
205 QString DownloadItem::formattedFilesize(qint64 size) {
206     /*
207     if (size < 1024) return tr("%1 bytes").arg(size);
208     else if (size < 1024*1024) return tr("%1 KB").arg(size/1024);
209     else if (size < 1024*1024*1024) return tr("%1 MB").arg(size/1024/1024);
210     else return tr("%1 GB").arg(size/1024/1024/1024);
211     */
212     QString unit;
213     if (size < 1024) {
214         unit = tr("bytes");
215     } else if (size < 1024*1024) {
216         size /= 1024;
217         unit = tr("KB");
218     } else {
219         size /= 1024*1024;
220         unit = tr("MB");
221     }
222     return QString(QLatin1String("%1 %2")).arg(size).arg(unit);
223 }
224
225 QString DownloadItem::formattedSpeed(double speed) {
226     /*
227     static const int K = 1024;
228     if (speed < K) return tr("%1 bytes/s").arg(speed);
229     else if (speed < K*K) return tr("%1 KB/s").arg(speed/K);
230     else if (speed < K*K*K) return tr("%1 MB/s").arg(speed/K/K);
231     else return tr("%1 GB/s").arg(speed/K/K/K);
232     */
233     int speedInt = (int) speed;
234     QString unit;
235     if (speedInt < 1024) {
236         unit = tr("bytes/sec");
237     } else if (speedInt < 1024*1024) {
238         speedInt /= 1024;
239         unit = tr("KB/sec");
240     } else {
241         speedInt /= 1024*1024;
242         unit = tr("MB/sec");
243     }
244     return QString(QLatin1String("%1 %2")).arg(speedInt).arg(unit);
245 }
246
247 QString DownloadItem::formattedTime(double timeRemaining) {
248     QString timeRemainingString = tr("seconds");
249     if (timeRemaining > 60) {
250         timeRemaining = timeRemaining / 60;
251         timeRemainingString = tr("minutes");
252     }
253     timeRemaining = floor(timeRemaining);
254     return tr("%4 %5 remaining")
255             .arg(timeRemaining)
256             .arg(timeRemainingString);
257 }