mirror of
https://github.com/KDE/kasts.git
synced 2025-01-09 07:18:07 +01:00
Add filesize units to download progress
This adds the currently downloaded size and the total enclosure size to the entry delegate.
This commit is contained in:
parent
d7debaaf30
commit
bcafb26c8c
@ -28,19 +28,6 @@ Enclosure::Enclosure(Entry *entry)
|
||||
{
|
||||
connect(this, &Enclosure::statusChanged, &DownloadModel::instance(), &DownloadModel::monitorDownloadStatus);
|
||||
connect(this, &Enclosure::downloadError, &ErrorLogModel::instance(), &ErrorLogModel::monitorErrorMessages);
|
||||
connect(&Fetcher::instance(), &Fetcher::downloadFileSizeUpdated, this, [this](QString url, int fileSize, int resumedAt) {
|
||||
if ((url == m_url) && ((m_size != fileSize) && (m_size != fileSize + resumedAt)) && (fileSize > 1000)) {
|
||||
// Sometimes, when resuming a download, the complete file size is
|
||||
// reported. Other times only the remaining part.
|
||||
// Sometimes the value is rubbish (e.g. 2)
|
||||
// We assume that the value when starting a new download is correct.
|
||||
if (fileSize < resumedAt) {
|
||||
fileSize += resumedAt;
|
||||
}
|
||||
qDebug() << "Correct filesize for enclosure" << url << "from" << m_size << "to" << fileSize;
|
||||
setSize(fileSize);
|
||||
}
|
||||
});
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare(QStringLiteral("SELECT * FROM Enclosures WHERE id=:id"));
|
||||
@ -60,27 +47,7 @@ Enclosure::Enclosure(Entry *entry)
|
||||
m_status = dbToStatus(query.value(QStringLiteral("downloaded")).toInt());
|
||||
m_playposition_dbsave = m_playposition;
|
||||
|
||||
// In principle the database contains this status, we check anyway in case
|
||||
// something changed on disk
|
||||
QFile file(path());
|
||||
if (file.exists()) {
|
||||
if (file.size() == m_size && file.size() > 0) {
|
||||
// file is on disk and has correct size, write to database if it
|
||||
// wasn't already registered so
|
||||
// this should, in principle, never happen unless the db was deleted
|
||||
setStatus(Downloaded);
|
||||
} else if (file.size() > 0) {
|
||||
// file was downloaded, but there is a size mismatch
|
||||
// set to PartiallyDownloaded such that download can be resumed
|
||||
setStatus(PartiallyDownloaded);
|
||||
} else {
|
||||
// file is empty
|
||||
setStatus(Downloadable);
|
||||
}
|
||||
} else {
|
||||
// file does not exist
|
||||
setStatus(Downloadable);
|
||||
}
|
||||
checkSizeOnDisk();
|
||||
}
|
||||
|
||||
int Enclosure::statusToDb(Enclosure::Status status)
|
||||
@ -117,9 +84,11 @@ Enclosure::Status Enclosure::dbToStatus(int value)
|
||||
|
||||
void Enclosure::download()
|
||||
{
|
||||
checkSizeOnDisk();
|
||||
EnclosureDownloadJob *downloadJob = new EnclosureDownloadJob(m_url, path(), m_entry->title());
|
||||
downloadJob->start();
|
||||
|
||||
qint64 resumedAt = m_sizeOnDisk;
|
||||
m_downloadProgress = 0;
|
||||
Q_EMIT downloadProgressChanged();
|
||||
|
||||
@ -127,6 +96,7 @@ void Enclosure::download()
|
||||
m_entry->feed()->setErrorString(QString());
|
||||
|
||||
connect(downloadJob, &KJob::result, this, [this, downloadJob]() {
|
||||
checkSizeOnDisk();
|
||||
if (downloadJob->error() == 0) {
|
||||
processDownloadedFile();
|
||||
} else {
|
||||
@ -148,6 +118,7 @@ void Enclosure::download()
|
||||
|
||||
connect(this, &Enclosure::cancelDownload, this, [this, downloadJob]() {
|
||||
downloadJob->doKill();
|
||||
checkSizeOnDisk();
|
||||
QFile file(path());
|
||||
if (file.exists() && file.size() > 0) {
|
||||
setStatus(PartiallyDownloaded);
|
||||
@ -157,9 +128,24 @@ void Enclosure::download()
|
||||
disconnect(this, &Enclosure::cancelDownload, this, nullptr);
|
||||
});
|
||||
|
||||
connect(downloadJob, &KJob::percentChanged, this, [=](KJob *, unsigned long percent) {
|
||||
m_downloadProgress = percent;
|
||||
connect(downloadJob, &KJob::processedAmountChanged, this, [=](KJob *kjob, KJob::Unit unit, qulonglong amount) {
|
||||
Q_ASSERT(unit == KJob::Unit::Bytes);
|
||||
|
||||
qint64 totalSize = static_cast<qint64>(kjob->totalAmount(unit));
|
||||
qint64 currentSize = static_cast<qint64>(amount);
|
||||
|
||||
if ((totalSize > 0) && (m_size != totalSize + resumedAt)) {
|
||||
qCDebug(kastsEnclosure) << "Correct filesize for enclosure" << m_entry->title() << "from" << m_size << "to" << totalSize + resumedAt;
|
||||
setSize(totalSize + resumedAt);
|
||||
}
|
||||
|
||||
m_downloadSize = currentSize + resumedAt;
|
||||
m_downloadProgress = static_cast<double>(m_downloadSize) / static_cast<double>(m_size);
|
||||
Q_EMIT downloadProgressChanged();
|
||||
|
||||
qCDebug(kastsEnclosure) << "m_downloadSize" << m_downloadSize;
|
||||
qCDebug(kastsEnclosure) << "m_downloadProgress" << m_downloadProgress;
|
||||
qCDebug(kastsEnclosure) << "m_size" << m_size;
|
||||
});
|
||||
|
||||
setStatus(Downloading);
|
||||
@ -171,8 +157,8 @@ void Enclosure::processDownloadedFile()
|
||||
|
||||
// First check if file size is larger than 0; otherwise something unexpected
|
||||
// must have happened
|
||||
QFile file(path());
|
||||
if (file.size() == 0) {
|
||||
checkSizeOnDisk();
|
||||
if (m_sizeOnDisk == 0) {
|
||||
deleteFile();
|
||||
return;
|
||||
}
|
||||
@ -180,15 +166,16 @@ void Enclosure::processDownloadedFile()
|
||||
// Check if reported filesize in rss feed corresponds to real file size
|
||||
// if not, correct the filesize in the database
|
||||
// otherwise the file will get deleted because of mismatch in signature
|
||||
if (file.size() != m_size) {
|
||||
qCDebug(kastsEnclosure) << "enclosure file size mismatch" << m_entry->title() << "from" << m_size << "to" << file.size();
|
||||
setSize(file.size());
|
||||
if (m_sizeOnDisk != size()) {
|
||||
qCDebug(kastsEnclosure) << "Correcting enclosure file size mismatch" << m_entry->title() << "from" << size() << "to" << m_sizeOnDisk;
|
||||
setSize(m_sizeOnDisk);
|
||||
setStatus(Downloaded);
|
||||
}
|
||||
|
||||
setStatus(Downloaded);
|
||||
// Unset "new" status of item
|
||||
if (m_entry->getNew())
|
||||
if (m_entry->getNew()) {
|
||||
m_entry->setNew(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Enclosure::deleteFile()
|
||||
@ -198,11 +185,16 @@ void Enclosure::deleteFile()
|
||||
qCDebug(kastsEnclosure) << "Track is still playing; let's unload it before deleting";
|
||||
AudioManager::instance().setEntry(nullptr);
|
||||
}
|
||||
|
||||
// First check if file still exists; you never know what has happened
|
||||
if (QFile(path()).exists())
|
||||
if (QFile(path()).exists()) {
|
||||
QFile(path()).remove();
|
||||
}
|
||||
|
||||
// If file disappeared unexpectedly, then still change status to downloadable
|
||||
setStatus(Downloadable);
|
||||
m_sizeOnDisk = 0;
|
||||
Q_EMIT sizeOnDiskChanged();
|
||||
}
|
||||
|
||||
QString Enclosure::path() const
|
||||
@ -225,11 +217,16 @@ qint64 Enclosure::duration() const
|
||||
return m_duration;
|
||||
}
|
||||
|
||||
int Enclosure::size() const
|
||||
qint64 Enclosure::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
qint64 Enclosure::sizeOnDisk() const
|
||||
{
|
||||
return m_sizeOnDisk;
|
||||
}
|
||||
|
||||
void Enclosure::setStatus(Enclosure::Status status)
|
||||
{
|
||||
if (m_status != status) {
|
||||
@ -286,7 +283,7 @@ void Enclosure::setDuration(const qint64 &duration)
|
||||
}
|
||||
}
|
||||
|
||||
void Enclosure::setSize(const int &size)
|
||||
void Enclosure::setSize(const qint64 &size)
|
||||
{
|
||||
if (m_size != size) {
|
||||
m_size = size;
|
||||
@ -303,11 +300,53 @@ void Enclosure::setSize(const int &size)
|
||||
}
|
||||
}
|
||||
|
||||
void Enclosure::checkSizeOnDisk()
|
||||
{
|
||||
// In principle the database contains this status, we check anyway in case
|
||||
// something changed on disk
|
||||
QFile file(path());
|
||||
if (file.exists()) {
|
||||
if (file.size() == m_size && file.size() > 0) {
|
||||
// file is on disk and has correct size, write to database if it
|
||||
// wasn't already registered so
|
||||
// this should, in principle, never happen unless the db was deleted
|
||||
setStatus(Downloaded);
|
||||
} else if (file.size() > 0) {
|
||||
// file was downloaded, but there is a size mismatch
|
||||
// set to PartiallyDownloaded such that download can be resumed
|
||||
setStatus(PartiallyDownloaded);
|
||||
} else {
|
||||
// file is empty
|
||||
setStatus(Downloadable);
|
||||
}
|
||||
if (file.size() != m_sizeOnDisk) {
|
||||
m_sizeOnDisk = file.size();
|
||||
m_downloadSize = m_sizeOnDisk;
|
||||
m_downloadProgress = (m_size == 0) ? 0.0 : static_cast<double>(m_sizeOnDisk) / static_cast<double>(m_size);
|
||||
Q_EMIT sizeOnDiskChanged();
|
||||
}
|
||||
} else {
|
||||
// file does not exist
|
||||
setStatus(Downloadable);
|
||||
if (m_sizeOnDisk != 0) {
|
||||
m_sizeOnDisk = 0;
|
||||
m_downloadSize = 0;
|
||||
m_downloadProgress = 0.0;
|
||||
Q_EMIT sizeOnDiskChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString Enclosure::formattedSize() const
|
||||
{
|
||||
return m_kformat.formatByteSize(m_size);
|
||||
}
|
||||
|
||||
QString Enclosure::formattedDownloadSize() const
|
||||
{
|
||||
return m_kformat.formatByteSize(m_downloadSize);
|
||||
}
|
||||
|
||||
QString Enclosure::formattedDuration() const
|
||||
{
|
||||
return m_kformat.formatDuration(m_duration * 1000);
|
||||
|
@ -21,13 +21,15 @@ class Enclosure : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(int size READ size WRITE setSize NOTIFY sizeChanged)
|
||||
Q_PROPERTY(qint64 size READ size WRITE setSize NOTIFY sizeChanged)
|
||||
Q_PROPERTY(QString formattedSize READ formattedSize NOTIFY sizeChanged)
|
||||
Q_PROPERTY(qint64 sizeOnDisk READ sizeOnDisk NOTIFY sizeOnDiskChanged)
|
||||
Q_PROPERTY(QString title MEMBER m_title CONSTANT)
|
||||
Q_PROPERTY(QString type MEMBER m_type CONSTANT)
|
||||
Q_PROPERTY(QString url MEMBER m_url CONSTANT)
|
||||
Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged)
|
||||
Q_PROPERTY(double downloadProgress MEMBER m_downloadProgress NOTIFY downloadProgressChanged)
|
||||
Q_PROPERTY(QString formattedDownloadSize READ formattedDownloadSize NOTIFY downloadProgressChanged)
|
||||
Q_PROPERTY(QString path READ path CONSTANT)
|
||||
Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged)
|
||||
Q_PROPERTY(QString formattedPlayPosition READ formattedPlayPosition NOTIFY playPositionChanged);
|
||||
@ -56,15 +58,18 @@ public:
|
||||
Status status() const;
|
||||
qint64 playPosition() const;
|
||||
qint64 duration() const;
|
||||
int size() const;
|
||||
qint64 size() const;
|
||||
qint64 sizeOnDisk() const;
|
||||
QString formattedSize() const;
|
||||
QString formattedDuration() const;
|
||||
QString formattedPlayPosition() const;
|
||||
QString formattedDownloadSize() const;
|
||||
|
||||
void setStatus(Status status);
|
||||
void setPlayPosition(const qint64 &position);
|
||||
void setDuration(const qint64 &duration);
|
||||
void setSize(const int &size);
|
||||
void setSize(const qint64 &size);
|
||||
void checkSizeOnDisk();
|
||||
|
||||
Q_SIGNALS:
|
||||
void statusChanged(Entry *entry, Status status);
|
||||
@ -73,6 +78,7 @@ Q_SIGNALS:
|
||||
void playPositionChanged();
|
||||
void durationChanged();
|
||||
void sizeChanged();
|
||||
void sizeOnDiskChanged();
|
||||
void downloadError(const Error::Type type, const QString &url, const QString &id, const int errorId, const QString &errorString);
|
||||
|
||||
private:
|
||||
@ -80,13 +86,15 @@ private:
|
||||
|
||||
Entry *m_entry;
|
||||
qint64 m_duration;
|
||||
int m_size;
|
||||
qint64 m_size = 0;
|
||||
qint64 m_sizeOnDisk;
|
||||
QString m_title;
|
||||
QString m_type;
|
||||
QString m_url;
|
||||
qint64 m_playposition;
|
||||
qint64 m_playposition_dbsave;
|
||||
double m_downloadProgress = 0;
|
||||
qint64 m_downloadSize = 0;
|
||||
Status m_status;
|
||||
KFormat m_kformat;
|
||||
};
|
||||
|
@ -376,15 +376,16 @@ QNetworkReply *Fetcher::download(const QString &url, const QString &filePath) co
|
||||
file->open(QIODevice::WriteOnly);
|
||||
}
|
||||
|
||||
/*
|
||||
QNetworkReply *headerReply = head(request);
|
||||
connect(headerReply, &QNetworkReply::finished, this, [=]() {
|
||||
if (headerReply->isOpen()) {
|
||||
int fileSize = headerReply->header(QNetworkRequest::ContentLengthHeader).toInt();
|
||||
qCDebug(kastsFetcher) << "Reported download size" << fileSize;
|
||||
Q_EMIT downloadFileSizeUpdated(url, fileSize, resumedAt);
|
||||
}
|
||||
headerReply->deleteLater();
|
||||
});
|
||||
*/
|
||||
|
||||
QNetworkReply *reply = get(request);
|
||||
|
||||
|
@ -54,7 +54,6 @@ Q_SIGNALS:
|
||||
void error(Error::Type type, const QString &url, const QString &id, const int errorId, const QString &errorString);
|
||||
void entryAdded(const QString &feedurl, const QString &id);
|
||||
void downloadFinished(QString url) const;
|
||||
void downloadFileSizeUpdated(QString url, int fileSize, int resumedAt) const;
|
||||
|
||||
void updateProgressChanged(int progress);
|
||||
void updateTotalChanged(int nrOfFeeds);
|
||||
|
@ -121,7 +121,7 @@ Kirigami.ScrollablePage {
|
||||
text: i18n("Delete Download")
|
||||
icon.name: "delete"
|
||||
onTriggered: entry.enclosure.deleteFile();
|
||||
visible: entry.enclosure && (entry.enclosure.status === Enclosure.Downloaded || entry.enclosure.status === Enclosure.PartiallyDownloaded) && entry.queueStatus
|
||||
visible: entry.enclosure && ((entry.enclosure.status === Enclosure.Downloaded && entry.queueStatus) || entry.enclosure.status === Enclosure.PartiallyDownloaded)
|
||||
}
|
||||
|
||||
contextualActions: [
|
||||
|
@ -104,7 +104,7 @@ Kirigami.SwipeListItem {
|
||||
font.weight: Font.Normal
|
||||
}
|
||||
Loader {
|
||||
sourceComponent: entry.enclosure && entry.enclosure.status === Enclosure.Downloading ? downloadProgress : ( entry.enclosure && entry.enclosure.playPosition > 0 ? playProgress : subtitle)
|
||||
sourceComponent: entry.enclosure && (entry.enclosure.status === Enclosure.Downloading || (isDownloads && entry.enclosure.status === Enclosure.PartiallyDownloaded)) ? downloadProgress : ( entry.enclosure && entry.enclosure.playPosition > 0 ? playProgress : subtitle)
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Component {
|
||||
@ -120,12 +120,25 @@ Kirigami.SwipeListItem {
|
||||
}
|
||||
Component {
|
||||
id: downloadProgress
|
||||
Controls.ProgressBar {
|
||||
from: 0
|
||||
to: 100
|
||||
value: entry.enclosure.downloadProgress
|
||||
visible: entry.enclosure && entry.enclosure.status === Enclosure.Downloading
|
||||
Layout.fillWidth: true
|
||||
RowLayout {
|
||||
Controls.Label {
|
||||
text: entry.enclosure.formattedDownloadSize
|
||||
elide: Text.ElideRight
|
||||
font: Kirigami.Theme.smallFont
|
||||
opacity: 0.7
|
||||
}
|
||||
Controls.ProgressBar {
|
||||
from: 0
|
||||
to: 1
|
||||
value: entry.enclosure.downloadProgress
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Controls.Label {
|
||||
text: entry.enclosure.formattedSize
|
||||
elide: Text.ElideRight
|
||||
font: Kirigami.Theme.smallFont
|
||||
opacity: 0.7
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
|
Loading…
Reference in New Issue
Block a user