+/* $BEGIN_LICENSE
+
+This file is part of Minitube.
+Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
+
+Minitube is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Minitube is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Minitube. If not, see <http://www.gnu.org/licenses/>.
+
+$END_LICENSE */
+
#include "downloaditem.h"
-#include "networkaccess.h"
+#include "http.h"
+#include "httputils.h"
#include "video.h"
#include <QDesktopServices>
#include "macutils.h"
#endif
-namespace The {
- NetworkAccess* http();
-}
-
DownloadItem::DownloadItem(Video *video, QUrl url, QString filename, QObject *parent)
: QObject(parent)
, m_bytesReceived(0)
, m_startedSaving(false)
, m_finishedDownloading(false)
, m_url(url)
+ , m_offset(0)
+ , sendStatusChanges(true)
, m_file(filename)
, m_reply(0)
, video(video)
speedCheckTimer->setInterval(2000);
speedCheckTimer->setSingleShot(true);
connect(speedCheckTimer, SIGNAL(timeout()), SLOT(speedCheck()));
+
+ if (m_file.exists())
+ m_file.remove();
}
DownloadItem::~DownloadItem() {
}
}
+bool DownloadItem::needsDownload(qint64 offset) {
+ return offset < m_offset || offset > m_offset + m_bytesReceived;
+}
+
+bool DownloadItem::isBuffered(qint64 offset) {
+ QMap<qint64, qint64>::iterator i;
+ for (i = buffers.begin(); i != buffers.end(); ++i) {
+ if (offset >= i.key() && offset <= i.value()) {
+ // qDebug() << "Buffered! " << i.key() << ":" << i.value();
+ return true;
+ }
+ }
+ // qDebug() << offset << "is not buffered";
+ return false;
+}
+
+qint64 DownloadItem::blankAtOffset(qint64 offset) {
+ // qDebug() << buffers;
+ QMap<qint64, qint64>::iterator i;
+ for (i = buffers.begin(); i != buffers.end(); ++i) {
+ if (offset >= i.key() && offset <= i.value()) {
+ // qDebug() << "Offset was" << offset << "now" << i.value();
+ return i.value() + 1;
+ }
+ }
+ return offset;
+}
+
+void DownloadItem::seekTo(qint64 offset, bool sendStatusChanges) {
+ // qDebug() << __PRETTY_FUNCTION__ << offset << sendStatusChanges;
+ stop();
+ if (m_bytesReceived > 0) {
+ bool bufferModified = false;
+ QMap<qint64, qint64>::iterator i;
+ for (i = buffers.begin(); i != buffers.end(); ++i) {
+ if (m_offset - 1 <= i.value()) {
+ /*
+ qDebug() << "Extending existing buffer "
+ << i.key() << i.value() << "now" << m_offset + m_bytesReceived;
+ */
+ bufferModified = true;
+ i.value() = m_offset + m_bytesReceived;
+ break;
+ }
+ }
+ if (!bufferModified)
+ buffers.insert(m_offset, m_offset + m_bytesReceived);
+ }
+ m_offset = offset;
+ this->sendStatusChanges = sendStatusChanges;
+ bool seekSuccess = m_file.seek(offset);
+ if (!seekSuccess) {
+ qWarning() << "Cannot seek to offset" << offset << "in file" << m_file.fileName();
+ return;
+ }
+ start();
+}
+
void DownloadItem::start() {
- m_reply = The::http()->simpleGet(m_url);
+ // qDebug() << "Starting download at" << m_offset;
+ HttpRequest req;
+ req.url = m_url;
+ if (m_offset > 0) req.offset = m_offset;
+ m_reply = HttpUtils::yt().networkReply(req);
+
init();
}
if (!m_reply)
return;
- if (m_file.exists())
- m_file.remove();
-
m_status = Starting;
-
+ m_bytesReceived = 0;
m_startedSaving = false;
m_finishedDownloading = false;
this, SLOT(requestFinished()));
// start timer for the download estimation
+ m_totalTime = 0;
m_downloadTime.start();
speedCheckTimer->start();
emit statusChanged();
}
+ // qWarning() << __PRETTY_FUNCTION__ << m_file.pos();
if (-1 == m_file.write(m_reply->readAll())) {
qWarning() << "Error saving." << m_file.errorString();
} else {
QVariant locationHeader = m_reply->header(QNetworkRequest::LocationHeader);
if (locationHeader.isValid()) {
m_url = locationHeader.toUrl();
- qDebug() << "Redirecting to" << m_url;
+ // qDebug() << "Redirecting to" << m_url;
tryAgain();
return;
}
-
-#ifdef DOWNLOADMANAGER_DEBUG
- qDebug() << "DownloadItem::" << __FUNCTION__ << "not handled.";
-#endif
+ // qDebug() << m_reply->rawHeaderList();
}
int DownloadItem::initialBufferSize() {
void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
- // qDebug() << bytesReceived << bytesTotal << m_downloadTime.elapsed();
+ // qDebug() << __PRETTY_FUNCTION__ << bytesReceived << bytesTotal << m_downloadTime.elapsed();
+
+ m_bytesReceived = bytesReceived;
+
+ if (!sendStatusChanges) return;
if (m_lastProgressTime.elapsed() < 150) return;
m_lastProgressTime.start();
- m_bytesReceived = bytesReceived;
-
if (m_status != Downloading) {
int neededBytes = (int) (bytesTotal * .005);
if (bufferSize > bytesTotal) bufferSize = bytesTotal;
// qDebug() << bytesReceived << bytesTotal << neededBytes << bufferSize << m_downloadTime.elapsed();
if (bytesReceived > bufferSize
- && bytesReceived > neededBytes
- && m_downloadTime.elapsed() > 2000) {
+ && bytesReceived > neededBytes
+ && m_downloadTime.elapsed() > 2000) {
emit bufferProgress(100);
m_status = Downloading;
emit statusChanged();
} else {
- int bufferPercent = bytesReceived * 100 / qMax(bufferSize, neededBytes);
+ int bytes = qMax(bufferSize, neededBytes);
+ int bufferPercent = 0;
+ if (bytes > 0)
+ bufferPercent = bytesReceived * 100 / bytes;
emit bufferProgress(bufferPercent);
}
if (m_finishedDownloading)
return -1.0;
- double timeRemaining = ((double)(bytesTotal() - bytesReceived())) / currentSpeed();
+ double speed = currentSpeed();
+ double timeRemaining = 0.0;
+ if (speed > 0.0)
+ timeRemaining = ((double)(bytesTotal() - bytesReceived())) / speed;
// When downloading the eta should never be 0
if (timeRemaining == 0)
if (m_finishedDownloading)
return -1.0;
- return m_bytesReceived * 1000.0 / m_downloadTime.elapsed();
+ int elapsed = m_downloadTime.elapsed();
+ double speed = -1.0;
+ if (elapsed > 0)
+ speed = m_bytesReceived * 1000.0 / elapsed;
+ return speed;
}
void DownloadItem::requestFinished() {
m_status = Downloading;
emit statusChanged();
}
- m_file.close();
+ if (m_offset == 0) m_file.close();
m_status = Finished;
+ m_totalTime = m_downloadTime.elapsed() / 1000.0;
emit statusChanged();
emit finished();
m_reply->deleteLater();
return QString(QLatin1String("%1 %2")).arg(speedInt).arg(unit);
}
-QString DownloadItem::formattedTime(double timeRemaining) {
+QString DownloadItem::formattedTime(double timeRemaining, bool remaining) {
QString timeRemainingString = tr("seconds");
if (timeRemaining > 60) {
timeRemaining = timeRemaining / 60;
timeRemainingString = tr("minutes");
}
timeRemaining = floor(timeRemaining);
- return tr("%4 %5 remaining")
+ QString msg = remaining ? tr("%4 %5 remaining") : "%4 %5";
+ return msg
.arg(timeRemaining)
.arg(timeRemainingString);
}