From db440ddf83dc5fdd178492ea5b24920bf9aeff03 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Tue, 31 Jul 2012 23:51:16 +0200 Subject: Download Manager --- src/CMakeLists.txt | 4 + src/download/.downloadmanager.cpp.kate-swp | Bin 0 -> 64 bytes src/download/downloaditem.cpp | 157 ++++++++++++++++ src/download/downloaditem.h | 117 ++++++++++++ src/download/downloadmanager.cpp | 276 +++++++++++++++++++++++++++++ src/download/downloadmanager.h | 97 ++++++++++ 6 files changed, 651 insertions(+) create mode 100644 src/download/.downloadmanager.cpp.kate-swp create mode 100644 src/download/downloaditem.cpp create mode 100644 src/download/downloaditem.h create mode 100644 src/download/downloadmanager.cpp create mode 100644 src/download/downloadmanager.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3e937655..25b97871 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,9 @@ set(rekonq_KDEINIT_SRCS bookmarks/bookmarkstoolbar.cpp bookmarks/bookmarkowner.cpp #---------------------------------------- + download/downloaditem.cpp + download/downloadmanager.cpp + #---------------------------------------- history/historymanager.cpp history/historymodels.cpp #---------------------------------------- @@ -124,6 +127,7 @@ KDE4_ADD_UI_FILES( rekonq_KDEINIT_SRCS INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/adblock ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks + ${CMAKE_CURRENT_SOURCE_DIR}/download ${CMAKE_CURRENT_SOURCE_DIR}/history ${CMAKE_CURRENT_SOURCE_DIR}/icons ${CMAKE_CURRENT_SOURCE_DIR}/settings diff --git a/src/download/.downloadmanager.cpp.kate-swp b/src/download/.downloadmanager.cpp.kate-swp new file mode 100644 index 00000000..3dec0e40 Binary files /dev/null and b/src/download/.downloadmanager.cpp.kate-swp differ diff --git a/src/download/downloaditem.cpp b/src/download/downloaditem.cpp new file mode 100644 index 00000000..38edbf1e --- /dev/null +++ b/src/download/downloaditem.cpp @@ -0,0 +1,157 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini +* Copyright (C) 2011 by Pierre Rossi +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see . +* +* ============================================================ */ + + +// Self includes +#include "downloaditem.h" +#include "downloaditem.moc" + +// Qt Includes +#include +#include + +// KDE Includes +#include +#include +#include +#include + + +DownloadItem::DownloadItem(const QString &srcUrl, const QString &destUrl, const QDateTime &d, QObject *parent) + : QObject(parent) + , m_srcUrlString(srcUrl) + , m_destUrl(KUrl(destUrl)) + , m_dateTime(d) + , m_job(0) + , m_state(0) +{ +} + + +DownloadItem::DownloadItem(KIO::CopyJob *job, const QDateTime &d, QObject *parent) + : QObject(parent) + , m_srcUrlString(job->srcUrls().at(0).url()) + , m_destUrl(job->destUrl()) + , m_dateTime(d) + , m_job(job) + , m_state(0) +{ + QObject::connect(job, SIGNAL(percent(KJob*, ulong)), this, SLOT(updateProgress(KJob*, ulong))); + QObject::connect(job, SIGNAL(finished(KJob*)), this, SLOT(onFinished(KJob*))); + QObject::connect(job, SIGNAL(suspended(KJob*)), this, SLOT(onSuspended(KJob*))); +} + + +KUrl DownloadItem::destUrl() const +{ + return m_destUrl; +} + + +QString DownloadItem::originUrl() const +{ + return m_srcUrlString; +} + + +QString DownloadItem::fileDirectory() const +{ + KUrl u = destUrl(); + return (QL1S("file://") + u.directory()); +} + + +QString DownloadItem::fileName() const +{ + return destUrl().fileName(); +} + + +QString DownloadItem::destinationUrlString() const +{ + return destUrl().url(KUrl::RemoveTrailingSlash); +} + + +QString DownloadItem::icon() const +{ + KIconLoader *loader = KIconLoader::global(); + QString iconForMimeType = KMimeType::iconNameForUrl(destUrl()); + return (QL1S("file://") + loader->iconPath(iconForMimeType, KIconLoader::Desktop)); +} + + +void DownloadItem::setIsKGetDownload() +{ + m_state = KGetManaged; +} + + +// update progress for the plain KIO::Job backend +void DownloadItem::updateProgress(KJob *job, unsigned long value) +{ + Q_UNUSED(job); + + if (value > 0 && value < 100) + m_state = Downloading; + + emit downloadProgress(value); +} + + +// emit downloadFinished signal in KJob case +void DownloadItem::onFinished(KJob *job) +{ + if (job->error()) + { + m_state = Errors; + m_errorString = job->errorString(); + } + else + { + m_state = Done; + emit downloadProgress(100); + } + + emit downloadFinished(!job->error()); +} + + +void DownloadItem::onSuspended(KJob *job) +{ + Q_UNUSED(job); + + m_state = Suspended; + + // TODO: + // connect to job->resume() to let rekonq resume it +} + + +QString DownloadItem::errorString() const +{ + return m_errorString; +} diff --git a/src/download/downloaditem.h b/src/download/downloaditem.h new file mode 100644 index 00000000..0b244c34 --- /dev/null +++ b/src/download/downloaditem.h @@ -0,0 +1,117 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini +* Copyright (C) 2011 by Pierre Rossi +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see . +* +* ============================================================ */ + + +#ifndef DOWNLOADITEM_H +#define DOWNLOADITEM_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include +#include +#include + +// KDE Includes +#include +#include +#include + + +class DownloadItem : public QObject +{ + Q_OBJECT + +public: + + enum JobState + { + Done = 0, + Downloading = 1, + Errors = 2, + Suspended = 3, + KGetManaged = 4 + }; + + explicit DownloadItem(const QString &srcUrl, const QString &destUrl, const QDateTime &d, QObject *parent = 0); + + // This is used to add a DownloadItem managed with KIO + explicit DownloadItem(KIO::CopyJob *job, const QDateTime &d, QObject *parent = 0); + + + inline QDateTime dateTime() const + { + return m_dateTime; + } + + KUrl destUrl() const; + + QString originUrl() const; + QString destinationUrlString() const; + QString fileName() const; + QString fileDirectory() const; + QString icon() const; + QString errorString() const; + + inline int state() const + { + return m_state; + } + + void setIsKGetDownload(); + + +Q_SIGNALS: + void downloadProgress(int percent); + void downloadFinished(bool success); + +public Q_SLOTS: + void updateProgress(KJob *job, unsigned long value); + void onFinished(KJob *job); + void onSuspended(KJob*); + +private: + QString m_srcUrlString; + KUrl m_destUrl; + + QDateTime m_dateTime; + + KIO::CopyJob *m_job; + int m_state; + + QString m_errorString; +}; + + +Q_DECLARE_METATYPE(DownloadItem*) + + +typedef QList DownloadList; + + +#endif //DOWNLAODITEM_H diff --git a/src/download/downloadmanager.cpp b/src/download/downloadmanager.cpp new file mode 100644 index 00000000..cae65cd9 --- /dev/null +++ b/src/download/downloadmanager.cpp @@ -0,0 +1,276 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2012 by Andrea Diamantini +* Copyright (C) 2011 by Pierre Rossi +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see . +* +* ============================================================ */ + + +// Self Includes +#include "downloadmanager.h" +#include "downloadmanager.moc" + +// Auto Includes +#include "rekonq.h" + +// KDE Includes +#include +#include +#include + +#include + +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +QWeakPointer DownloadManager::s_downloadManager; + + +DownloadManager *DownloadManager::self() +{ + if (s_downloadManager.isNull()) + { + s_downloadManager = new DownloadManager(qApp); + } + return s_downloadManager.data(); +} + + +// ---------------------------------------------------------------------------------------------- + + +DownloadManager::DownloadManager(QObject *parent) + : QObject(parent) + , m_needToSave(false) +{ + init(); +} + + +DownloadManager::~DownloadManager() +{ + if (!m_needToSave) + return; + + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + + if (!downloadFile.open(QFile::WriteOnly)) + { + kDebug() << "Unable to open download file (WRITE mode).."; + return; + } + + QDataStream out(&downloadFile); + Q_FOREACH(DownloadItem * item, m_downloadList) + { + out << item->originUrl(); + out << item->destinationUrlString(); + out << item->dateTime(); + } + + downloadFile.close(); +} + + +void DownloadManager::init() +{ + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + if (!downloadFile.open(QFile::ReadOnly)) + { + kDebug() << "Unable to open download file (READ mode).."; + return; + } + + QDataStream in(&downloadFile); + while (!in.atEnd()) + { + QString srcUrl; + in >> srcUrl; + QString destUrl; + in >> destUrl; + QDateTime dt; + in >> dt; + DownloadItem *item = new DownloadItem(srcUrl, destUrl, dt, this); + m_downloadList.append(item); + } +} + + +DownloadItem* DownloadManager::addDownload(KIO::CopyJob *job) +{ + QWebSettings *globalSettings = QWebSettings::globalSettings(); + if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) + return 0; + + KIO::CopyJob *cJob = qobject_cast(job); + + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + if (!downloadFile.open(QFile::WriteOnly | QFile::Append)) + { + kDebug() << "Unable to open download file (WRITE mode).."; + return 0; + } + QDataStream out(&downloadFile); + out << cJob->srcUrls().at(0).url(); + out << cJob->destUrl().url(); + out << QDateTime::currentDateTime(); + downloadFile.close(); + DownloadItem *item = new DownloadItem(job, QDateTime::currentDateTime(), this); + m_downloadList.append(item); + emit newDownloadAdded(item); + return item; +} + + +DownloadItem* DownloadManager::addKGetDownload(const QString &srcUrl, const QString &destUrl) +{ + QWebSettings *globalSettings = QWebSettings::globalSettings(); + if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) + return 0; + + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + if (!downloadFile.open(QFile::WriteOnly | QFile::Append)) + { + kDebug() << "Unable to open download file (WRITE mode).."; + return 0; + } + QDataStream out(&downloadFile); + out << srcUrl; + out << destUrl; + out << QDateTime::currentDateTime(); + downloadFile.close(); + DownloadItem *item = new DownloadItem(srcUrl, destUrl, QDateTime::currentDateTime(), this); + item->setIsKGetDownload(); + m_downloadList.append(item); + emit newDownloadAdded(item); + return item; +} + + +bool DownloadManager::clearDownloadsHistory() +{ + m_downloadList.clear(); + QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads"); + QFile downloadFile(downloadFilePath); + return downloadFile.remove(); +} + + +void DownloadManager::downloadLinksWithKGet(const QVariant &contentList) +{ + if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) + { + KToolInvocation::kdeinitExecWait("kget"); + } + QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main"); + if (kget.isValid()) + { + kget.call("importLinks", contentList); + } +} + + +void DownloadManager::removeDownloadItem(int index) +{ + DownloadItem *item = m_downloadList.takeAt(index); + delete item; + + m_needToSave = true; +} + + +// NOTE +// These 2 functions have been copied from the KWebPage class to implement a local version of the downloadResponse method. +// In this way, we can easily provide the extra functionality we need: +// 1. KGet Integration +// 2. Save downloads history +bool DownloadManager::downloadResource(const KUrl &srcUrl, const KIO::MetaData &metaData, + QWidget *parent, bool forceDirRequest, const QString &suggestedName) +{ + KUrl destUrl; + + const QString fileName((suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName)); + + if (forceDirRequest || ReKonfig::askDownloadPath()) + { + // follow bug:184202 fixes + destUrl = KFileDialog::getSaveFileName(KUrl::fromPath(fileName), QString(), parent); + } + else + { + destUrl = KUrl(ReKonfig::downloadPath().path() + QL1C('/') + fileName); + } + + kDebug() << "DEST URL: " << destUrl; + + if (!destUrl.isValid()) + return false; + + // manage downloads with KGet if found + if (ReKonfig::kgetDownload() && !KStandardDirs::findExe("kget").isNull()) + { + //KGet integration: + if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) + { + KToolInvocation::kdeinitExecWait("kget"); + } + QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main"); + if (!kget.isValid()) + return false; + + QDBusMessage transfer = kget.call(QL1S("addTransfer"), srcUrl.prettyUrl(), destUrl.prettyUrl(), true); + + addKGetDownload(srcUrl.pathOrUrl(), destUrl.pathOrUrl()); + return true; + } + + KIO::CopyJob *job = KIO::copy(srcUrl, destUrl, KIO::Overwrite); + + if (!metaData.isEmpty()) + job->setMetaData(metaData); + + job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache. + job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available. + job->uiDelegate()->setAutoErrorHandlingEnabled(true); + + addDownload(job); + return true; +} diff --git a/src/download/downloadmanager.h b/src/download/downloadmanager.h new file mode 100644 index 00000000..5ac4d628 --- /dev/null +++ b/src/download/downloadmanager.h @@ -0,0 +1,97 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2011 by Pierre Rossi +* Copyright (C) 2012 by Andrea Diamantini +* +* +* This program 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 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program 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 this program. If not, see . +* +* ============================================================ */ + + +#ifndef DOWNLOADMANAGER_H +#define DOWNLOADMANAGER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "downloaditem.h" + +// KDE Includes +#include +#include + +// Qt Includes +#include +#include + +// Forward Includes +class KUrl; +class QNetworkReply; + + +class REKONQ_TESTS_EXPORT DownloadManager : public QObject +{ + Q_OBJECT + +public: + /** + * Entry point. + * Access to DownloadManager class by using + * DownloadManager::self()->thePublicMethodYouNeed() + */ + static DownloadManager *self(); + + ~DownloadManager(); + + DownloadList downloads() const + { + return m_downloadList; + } + + bool clearDownloadsHistory(); + + bool downloadResource(const KUrl &url, const KIO::MetaData &metaData = KIO::MetaData(), + QWidget *parent = 0, bool forceDirRequest = false, const QString &suggestedName = QString()); + + void downloadLinksWithKGet(const QVariant &contentList); + + void removeDownloadItem(int index); + +private: + DownloadManager(QObject *parent = 0); + void init(); + + DownloadItem* addDownload(KIO::CopyJob *job); + DownloadItem* addKGetDownload(const QString &srcUrl, const QString &destUrl); + +Q_SIGNALS: + void newDownloadAdded(QObject *item); + +private: + DownloadList m_downloadList; + + bool m_needToSave; + + static QWeakPointer s_downloadManager; +}; + +#endif // DOWNLOADMANAGER_H -- cgit v1.2.1