mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Merge pull request #4413 from glassez/dlmgr
Improve Download Manager. Closes #4305
This commit is contained in:
commit
52d08f7112
@ -462,10 +462,10 @@ void Application::cleanup()
|
|||||||
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
#ifndef DISABLE_COUNTRIES_RESOLUTION
|
||||||
Net::GeoIPManager::freeInstance();
|
Net::GeoIPManager::freeInstance();
|
||||||
#endif
|
#endif
|
||||||
|
Net::DownloadManager::freeInstance();
|
||||||
Preferences::freeInstance();
|
Preferences::freeInstance();
|
||||||
Logger::freeInstance();
|
Logger::freeInstance();
|
||||||
IconProvider::freeInstance();
|
IconProvider::freeInstance();
|
||||||
Net::DownloadManager::freeInstance();
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
typedef BOOL (WINAPI *PSHUTDOWNBRDESTROY)(HWND);
|
typedef BOOL (WINAPI *PSHUTDOWNBRDESTROY)(HWND);
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "base/utils/misc.h"
|
#include "base/utils/misc.h"
|
||||||
#include "base/utils/string.h"
|
#include "base/utils/string.h"
|
||||||
#include "base/qinisettings.h"
|
#include "base/qinisettings.h"
|
||||||
|
#include "base/preferences.h"
|
||||||
|
|
||||||
bool userAcceptsUpgrade()
|
bool userAcceptsUpgrade()
|
||||||
{
|
{
|
||||||
@ -114,6 +115,9 @@ bool upgradeResumeFile(const QString &filepath, const QVariantHash &oldTorrent,
|
|||||||
|
|
||||||
bool upgrade(bool ask = true)
|
bool upgrade(bool ask = true)
|
||||||
{
|
{
|
||||||
|
// Move RSS cookies to common storage
|
||||||
|
Preferences::instance()->moveRSSCookies();
|
||||||
|
|
||||||
QIniSettings *oldResumeSettings = new QIniSettings("qBittorrent", "qBittorrent-resume");
|
QIniSettings *oldResumeSettings = new QIniSettings("qBittorrent", "qBittorrent-resume");
|
||||||
QString oldResumeFilename = oldResumeSettings->fileName();
|
QString oldResumeFilename = oldResumeSettings->fileName();
|
||||||
QVariantHash oldResumeData = oldResumeSettings->value("torrents").toHash();
|
QVariantHash oldResumeData = oldResumeSettings->value("torrents").toHash();
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
* Contact : chris@qbittorrent.org
|
* Contact : chris@qbittorrent.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
@ -37,6 +36,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "base/logger.h"
|
#include "base/logger.h"
|
||||||
|
#include "base/net/downloadmanager.h"
|
||||||
|
#include "base/net/downloadhandler.h"
|
||||||
#include "dnsupdater.h"
|
#include "dnsupdater.h"
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
@ -76,65 +77,62 @@ DNSUpdater::~DNSUpdater()
|
|||||||
void DNSUpdater::checkPublicIP()
|
void DNSUpdater::checkPublicIP()
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_state == OK);
|
Q_ASSERT(m_state == OK);
|
||||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
|
||||||
connect(manager, SIGNAL(finished(QNetworkReply *)), SLOT(ipRequestFinished(QNetworkReply *)));
|
DownloadHandler *handler = DownloadManager::instance()->downloadUrl(
|
||||||
|
"http://checkip.dyndns.org", false, 0, false,
|
||||||
|
QString("qBittorrent/%1").arg(VERSION));
|
||||||
|
connect(handler, SIGNAL(downloadFinished(QString, QByteArray)), SLOT(ipRequestFinished(QString, QByteArray)));
|
||||||
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), SLOT(ipRequestFailed(QString, QString)));
|
||||||
|
|
||||||
m_lastIPCheckTime = QDateTime::currentDateTime();
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
QNetworkRequest request;
|
|
||||||
request.setUrl(QUrl("http://checkip.dyndns.org"));
|
|
||||||
request.setRawHeader("User-Agent", "qBittorrent/" VERSION);
|
|
||||||
manager->get(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSUpdater::ipRequestFinished(QNetworkReply *reply)
|
void DNSUpdater::ipRequestFinished(const QString &url, const QByteArray &data)
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
Q_UNUSED(url);
|
||||||
if (reply->error()) {
|
|
||||||
// Error
|
// Parse response
|
||||||
qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString();
|
QRegExp ipregex("Current IP Address:\\s+([^<]+)</body>");
|
||||||
}
|
if (ipregex.indexIn(data) >= 0) {
|
||||||
else {
|
QString ipStr = ipregex.cap(1);
|
||||||
// Parse response
|
qDebug() << Q_FUNC_INFO << "Regular expression captured the following IP:" << ipStr;
|
||||||
QRegExp ipregex("Current IP Address:\\s+([^<]+)</body>");
|
QHostAddress newIp(ipStr);
|
||||||
QString ret = reply->readAll();
|
if (!newIp.isNull()) {
|
||||||
if (ipregex.indexIn(ret) >= 0) {
|
if (m_lastIP != newIp) {
|
||||||
QString ip_str = ipregex.cap(1);
|
qDebug() << Q_FUNC_INFO << "The IP address changed, report the change to DynDNS...";
|
||||||
qDebug() << Q_FUNC_INFO << "Regular expression captured the following IP:" << ip_str;
|
qDebug() << m_lastIP.toString() << "->" << newIp.toString();
|
||||||
QHostAddress new_ip(ip_str);
|
m_lastIP = newIp;
|
||||||
if (!new_ip.isNull()) {
|
updateDNSService();
|
||||||
if (m_lastIP != new_ip) {
|
|
||||||
qDebug() << Q_FUNC_INFO << "The IP address changed, report the change to DynDNS...";
|
|
||||||
qDebug() << m_lastIP.toString() << "->" << new_ip.toString();
|
|
||||||
m_lastIP = new_ip;
|
|
||||||
updateDNSService();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qWarning() << Q_FUNC_INFO << "Failed to construct a QHostAddress from the IP string";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qWarning() << Q_FUNC_INFO << "Regular expression failed to capture the IP address";
|
qWarning() << Q_FUNC_INFO << "Failed to construct a QHostAddress from the IP string";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Clean up
|
else {
|
||||||
reply->deleteLater();
|
qWarning() << Q_FUNC_INFO << "Regular expression failed to capture the IP address";
|
||||||
sender()->deleteLater();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DNSUpdater::ipRequestFailed(const QString &url, const QString &error)
|
||||||
|
{
|
||||||
|
Q_UNUSED(url);
|
||||||
|
qWarning() << "IP request failed:" << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSUpdater::updateDNSService()
|
void DNSUpdater::updateDNSService()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
// Prepare request
|
|
||||||
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
|
|
||||||
connect(manager, SIGNAL(finished(QNetworkReply *)), SLOT(ipUpdateFinished(QNetworkReply *)));
|
|
||||||
m_lastIPCheckTime = QDateTime::currentDateTime();
|
m_lastIPCheckTime = QDateTime::currentDateTime();
|
||||||
QNetworkRequest request;
|
DownloadHandler *handler = DownloadManager::instance()->downloadUrl(
|
||||||
request.setUrl(getUpdateUrl());
|
getUpdateUrl(), false, 0, false,
|
||||||
request.setRawHeader("User-Agent", "qBittorrent/" VERSION);
|
QString("qBittorrent/%1").arg(VERSION));
|
||||||
manager->get(request);
|
connect(handler, SIGNAL(downloadFinished(QString, QByteArray)), SLOT(ipUpdateFinished(QString, QByteArray)));
|
||||||
|
connect(handler, SIGNAL(downloadFailed(QString, QString)), SLOT(ipUpdateFailed(QString, QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl DNSUpdater::getUpdateUrl() const
|
QString DNSUpdater::getUpdateUrl() const
|
||||||
{
|
{
|
||||||
QUrl url;
|
QUrl url;
|
||||||
#ifdef QT_NO_OPENSSL
|
#ifdef QT_NO_OPENSSL
|
||||||
@ -172,22 +170,20 @@ QUrl DNSUpdater::getUpdateUrl() const
|
|||||||
Q_ASSERT(url.isValid());
|
Q_ASSERT(url.isValid());
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << url.toString();
|
qDebug() << Q_FUNC_INFO << url.toString();
|
||||||
return url;
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSUpdater::ipUpdateFinished(QNetworkReply *reply)
|
void DNSUpdater::ipUpdateFinished(const QString &url, const QByteArray &data)
|
||||||
{
|
{
|
||||||
if (reply->error()) {
|
Q_UNUSED(url);
|
||||||
// Error
|
// Parse reply
|
||||||
qWarning() << Q_FUNC_INFO << "Error:" << reply->errorString();
|
processIPUpdateReply(data);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Parse reply
|
void DNSUpdater::ipUpdateFailed(const QString &url, const QString &error)
|
||||||
processIPUpdateReply(reply->readAll());
|
{
|
||||||
}
|
Q_UNUSED(url);
|
||||||
// Clean up
|
qWarning() << "IP update failed:" << error;
|
||||||
reply->deleteLater();
|
|
||||||
sender()->deleteLater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DNSUpdater::processIPUpdateReply(const QString &reply)
|
void DNSUpdater::processIPUpdateReply(const QString &reply)
|
||||||
@ -196,16 +192,19 @@ void DNSUpdater::processIPUpdateReply(const QString &reply)
|
|||||||
qDebug() << Q_FUNC_INFO << reply;
|
qDebug() << Q_FUNC_INFO << reply;
|
||||||
QString code = reply.split(" ").first();
|
QString code = reply.split(" ").first();
|
||||||
qDebug() << Q_FUNC_INFO << "Code:" << code;
|
qDebug() << Q_FUNC_INFO << "Code:" << code;
|
||||||
if (code == "good" || code == "nochg") {
|
|
||||||
|
if ((code == "good") || (code == "nochg")) {
|
||||||
logger->addMessage(tr("Your dynamic DNS was successfully updated."), Log::INFO);
|
logger->addMessage(tr("Your dynamic DNS was successfully updated."), Log::INFO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((code == "911") || (code == "dnserr")) {
|
if ((code == "911") || (code == "dnserr")) {
|
||||||
logger->addMessage(tr("Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes."), Log::CRITICAL);
|
logger->addMessage(tr("Dynamic DNS error: The service is temporarily unavailable, it will be retried in 30 minutes."), Log::CRITICAL);
|
||||||
m_lastIP.clear();
|
m_lastIP.clear();
|
||||||
// It will retry in 30 minutes because the timer was not stopped
|
// It will retry in 30 minutes because the timer was not stopped
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything bellow is an error, stop updating until the user updates something
|
// Everything bellow is an error, stop updating until the user updates something
|
||||||
m_ipCheckTimer.stop();
|
m_ipCheckTimer.stop();
|
||||||
m_lastIP.clear();
|
m_lastIP.clear();
|
||||||
@ -214,23 +213,27 @@ void DNSUpdater::processIPUpdateReply(const QString &reply)
|
|||||||
m_state = INVALID_CREDS;
|
m_state = INVALID_CREDS;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == "badauth") {
|
if (code == "badauth") {
|
||||||
logger->addMessage(tr("Dynamic DNS error: Invalid username/password."), Log::CRITICAL);
|
logger->addMessage(tr("Dynamic DNS error: Invalid username/password."), Log::CRITICAL);
|
||||||
m_state = INVALID_CREDS;
|
m_state = INVALID_CREDS;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == "badagent") {
|
if (code == "badagent") {
|
||||||
logger->addMessage(tr("Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org."),
|
logger->addMessage(tr("Dynamic DNS error: qBittorrent was blacklisted by the service, please report a bug at http://bugs.qbittorrent.org."),
|
||||||
Log::CRITICAL);
|
Log::CRITICAL);
|
||||||
m_state = FATAL;
|
m_state = FATAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == "!donator") {
|
if (code == "!donator") {
|
||||||
logger->addMessage(tr("Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org.").arg("!donator"),
|
logger->addMessage(tr("Dynamic DNS error: %1 was returned by the service, please report a bug at http://bugs.qbittorrent.org.").arg("!donator"),
|
||||||
Log::CRITICAL);
|
Log::CRITICAL);
|
||||||
m_state = FATAL;
|
m_state = FATAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == "abuse") {
|
if (code == "abuse") {
|
||||||
logger->addMessage(tr("Dynamic DNS error: Your username was blocked due to abuse."), Log::CRITICAL);
|
logger->addMessage(tr("Dynamic DNS error: Your username was blocked due to abuse."), Log::CRITICAL);
|
||||||
m_state = FATAL;
|
m_state = FATAL;
|
||||||
|
@ -33,15 +33,15 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "base/preferences.h"
|
#include "base/preferences.h"
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
// Based on http://www.dyndns.com/developers/specs/
|
// Based on http://www.dyndns.com/developers/specs/
|
||||||
class DNSUpdater : public QObject
|
class DNSUpdater: public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -56,15 +56,25 @@ namespace Net
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void checkPublicIP();
|
void checkPublicIP();
|
||||||
void ipRequestFinished(QNetworkReply *reply);
|
void ipRequestFinished(const QString &url, const QByteArray &data);
|
||||||
|
void ipRequestFailed(const QString &url, const QString &error);
|
||||||
void updateDNSService();
|
void updateDNSService();
|
||||||
void ipUpdateFinished(QNetworkReply *reply);
|
void ipUpdateFinished(const QString &url, const QByteArray &data);
|
||||||
|
void ipUpdateFailed(const QString &url, const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QUrl getUpdateUrl() const;
|
enum State
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
INVALID_CREDS,
|
||||||
|
FATAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int IP_CHECK_INTERVAL_MS = 1800000; // 30 min
|
||||||
|
|
||||||
|
QString getUpdateUrl() const;
|
||||||
void processIPUpdateReply(const QString &reply);
|
void processIPUpdateReply(const QString &reply);
|
||||||
|
|
||||||
private:
|
|
||||||
QHostAddress m_lastIP;
|
QHostAddress m_lastIP;
|
||||||
QDateTime m_lastIPCheckTime;
|
QDateTime m_lastIPCheckTime;
|
||||||
QTimer m_ipCheckTimer;
|
QTimer m_ipCheckTimer;
|
||||||
@ -74,16 +84,6 @@ namespace Net
|
|||||||
QString m_domain;
|
QString m_domain;
|
||||||
QString m_username;
|
QString m_username;
|
||||||
QString m_password;
|
QString m_password;
|
||||||
|
|
||||||
private:
|
|
||||||
static const int IP_CHECK_INTERVAL_MS = 1800000; // 30 min
|
|
||||||
|
|
||||||
enum State
|
|
||||||
{
|
|
||||||
OK,
|
|
||||||
INVALID_CREDS,
|
|
||||||
FATAL
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,11 +27,13 @@
|
|||||||
* exception statement from your version.
|
* exception statement from your version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
#include <QNetworkCookieJar>
|
#include <QNetworkCookieJar>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QNetworkCookie>
|
#include <QNetworkCookie>
|
||||||
|
#include <QNetworkCookieJar>
|
||||||
#include <QSslError>
|
#include <QSslError>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -40,6 +42,74 @@
|
|||||||
#include "downloadhandler.h"
|
#include "downloadhandler.h"
|
||||||
#include "downloadmanager.h"
|
#include "downloadmanager.h"
|
||||||
|
|
||||||
|
// Spoof Firefox 38 user agent to avoid web server banning
|
||||||
|
const char DEFAULT_USER_AGENT[] = "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0";
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class NetworkCookieJar: public QNetworkCookieJar
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NetworkCookieJar(QObject *parent = 0)
|
||||||
|
: QNetworkCookieJar(parent)
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = Preferences::instance()->getNetworkCookies();
|
||||||
|
foreach (const QNetworkCookie &cookie, Preferences::instance()->getNetworkCookies()) {
|
||||||
|
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
setAllCookies(cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
~NetworkCookieJar()
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = allCookies();
|
||||||
|
foreach (const QNetworkCookie &cookie, allCookies()) {
|
||||||
|
if (cookie.isSessionCookie() || (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences::instance()->setNetworkCookies(cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QBT_USES_QT5
|
||||||
|
virtual bool deleteCookie(const QNetworkCookie &cookie)
|
||||||
|
{
|
||||||
|
auto myCookies = allCookies();
|
||||||
|
myCookies.removeAll(cookie);
|
||||||
|
setAllCookies(myCookies);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const override
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
|
||||||
|
foreach (const QNetworkCookie &cookie, QNetworkCookieJar::cookiesForUrl(url)) {
|
||||||
|
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url) override
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QList<QNetworkCookie> cookies = cookieList;
|
||||||
|
foreach (const QNetworkCookie &cookie, cookieList) {
|
||||||
|
if (!cookie.isSessionCookie() && (cookie.expirationDate() <= now))
|
||||||
|
cookies.removeAll(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QNetworkCookieJar::setCookiesFromUrl(cookies, url);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
using namespace Net;
|
using namespace Net;
|
||||||
|
|
||||||
DownloadManager *DownloadManager::m_instance = 0;
|
DownloadManager *DownloadManager::m_instance = 0;
|
||||||
@ -50,10 +120,7 @@ DownloadManager::DownloadManager(QObject *parent)
|
|||||||
#ifndef QT_NO_OPENSSL
|
#ifndef QT_NO_OPENSSL
|
||||||
connect(&m_networkManager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply *, QList<QSslError>)));
|
connect(&m_networkManager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply *, QList<QSslError>)));
|
||||||
#endif
|
#endif
|
||||||
}
|
m_networkManager.setCookieJar(new NetworkCookieJar(this));
|
||||||
|
|
||||||
DownloadManager::~DownloadManager()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadManager::initInstance()
|
void DownloadManager::initInstance()
|
||||||
@ -75,7 +142,7 @@ DownloadManager *DownloadManager::instance()
|
|||||||
return m_instance;
|
return m_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFile, qint64 limit, bool handleRedirectToMagnet)
|
DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFile, qint64 limit, bool handleRedirectToMagnet, const QString &userAgent)
|
||||||
{
|
{
|
||||||
// Update proxy settings
|
// Update proxy settings
|
||||||
applyProxySettings();
|
applyProxySettings();
|
||||||
@ -85,29 +152,36 @@ DownloadHandler *DownloadManager::downloadUrl(const QString &url, bool saveToFil
|
|||||||
const QUrl qurl = QUrl::fromEncoded(url.toUtf8());
|
const QUrl qurl = QUrl::fromEncoded(url.toUtf8());
|
||||||
QNetworkRequest request(qurl);
|
QNetworkRequest request(qurl);
|
||||||
|
|
||||||
// Spoof Firefox 38 user agent to avoid web server banning
|
if (userAgent.isEmpty())
|
||||||
request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0");
|
request.setRawHeader("User-Agent", DEFAULT_USER_AGENT);
|
||||||
|
else
|
||||||
|
request.setRawHeader("User-Agent", userAgent.toUtf8());
|
||||||
|
|
||||||
// Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents
|
// Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents
|
||||||
request.setRawHeader("Referer", request.url().toEncoded().data());
|
request.setRawHeader("Referer", request.url().toEncoded().data());
|
||||||
|
|
||||||
qDebug("Downloading %s...", request.url().toEncoded().data());
|
qDebug("Downloading %s...", request.url().toEncoded().data());
|
||||||
|
qDebug() << "Cookies:" << m_networkManager.cookieJar()->cookiesForUrl(request.url());
|
||||||
// accept gzip
|
// accept gzip
|
||||||
request.setRawHeader("Accept-Encoding", "gzip");
|
request.setRawHeader("Accept-Encoding", "gzip");
|
||||||
return new DownloadHandler(m_networkManager.get(request), this, saveToFile, limit, handleRedirectToMagnet);
|
return new DownloadHandler(m_networkManager.get(request), this, saveToFile, limit, handleRedirectToMagnet);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QNetworkCookie> DownloadManager::cookiesForUrl(const QString &url) const
|
QList<QNetworkCookie> DownloadManager::cookiesForUrl(const QUrl &url) const
|
||||||
{
|
{
|
||||||
return m_networkManager.cookieJar()->cookiesForUrl(url);
|
return m_networkManager.cookieJar()->cookiesForUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DownloadManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
bool DownloadManager::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
|
||||||
{
|
{
|
||||||
qDebug("Setting %d cookies for url: %s", cookieList.size(), qPrintable(url.toString()));
|
|
||||||
return m_networkManager.cookieJar()->setCookiesFromUrl(cookieList, url);
|
return m_networkManager.cookieJar()->setCookiesFromUrl(cookieList, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
||||||
|
{
|
||||||
|
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->deleteCookie(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
void DownloadManager::applyProxySettings()
|
void DownloadManager::applyProxySettings()
|
||||||
{
|
{
|
||||||
QNetworkProxy proxy;
|
QNetworkProxy proxy;
|
||||||
|
@ -33,12 +33,10 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QNetworkCookie;
|
class QNetworkCookie;
|
||||||
class QSslError;
|
class QSslError;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
{
|
{
|
||||||
@ -53,9 +51,10 @@ namespace Net
|
|||||||
static void freeInstance();
|
static void freeInstance();
|
||||||
static DownloadManager *instance();
|
static DownloadManager *instance();
|
||||||
|
|
||||||
DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false);
|
DownloadHandler *downloadUrl(const QString &url, bool saveToFile = false, qint64 limit = 0, bool handleRedirectToMagnet = false, const QString &userAgent = "");
|
||||||
QList<QNetworkCookie> cookiesForUrl(const QString &url) const;
|
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
|
||||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
||||||
|
bool deleteCookie(const QNetworkCookie &cookie);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#ifndef QT_NO_OPENSSL
|
#ifndef QT_NO_OPENSSL
|
||||||
@ -63,8 +62,7 @@ namespace Net
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DownloadManager(QObject *parent = 0);
|
explicit DownloadManager(QObject *parent = 0);
|
||||||
~DownloadManager();
|
|
||||||
|
|
||||||
void applyProxySettings();
|
void applyProxySettings();
|
||||||
|
|
||||||
|
@ -996,12 +996,12 @@ void Preferences::setFilteringEnabled(bool enabled)
|
|||||||
|
|
||||||
bool Preferences::isFilteringTrackerEnabled() const
|
bool Preferences::isFilteringTrackerEnabled() const
|
||||||
{
|
{
|
||||||
return value("Preferences/IPFilter/FilterTracker", false).toBool();
|
return value("Preferences/IPFilter/FilterTracker", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::setFilteringTrackerEnabled(bool enabled)
|
void Preferences::setFilteringTrackerEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
setValue("Preferences/IPFilter/FilterTracker", enabled);
|
setValue("Preferences/IPFilter/FilterTracker", enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Preferences::getFilter() const
|
QString Preferences::getFilter() const
|
||||||
@ -2494,45 +2494,57 @@ void Preferences::setToolbarTextPosition(const int position)
|
|||||||
setValue("Toolbar/textPosition", position);
|
setValue("Toolbar/textPosition", position);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> Preferences::getHostNameCookies(const QString &host_name) const
|
void Preferences::moveRSSCookies()
|
||||||
{
|
{
|
||||||
QMap<QString, QVariant> hosts_table = value("Rss/hosts_cookies").toMap();
|
QList<QNetworkCookie> cookies = getNetworkCookies();
|
||||||
if (!hosts_table.contains(host_name)) return QList<QByteArray>();
|
QVariantMap hostsTable = value("Rss/hosts_cookies").toMap();
|
||||||
QByteArray raw_cookies = hosts_table.value(host_name).toByteArray();
|
foreach (const QString &key, hostsTable.keys()) {
|
||||||
return raw_cookies.split(':');
|
QVariant value = hostsTable[key];
|
||||||
}
|
QList<QByteArray> rawCookies = value.toByteArray().split(':');
|
||||||
|
foreach (const QByteArray &rawCookie, rawCookies) {
|
||||||
QList<QNetworkCookie> Preferences::getHostNameQNetworkCookies(const QString& host_name) const
|
foreach (QNetworkCookie cookie, QNetworkCookie::parseCookies(rawCookie)) {
|
||||||
{
|
cookie.setDomain(key);
|
||||||
QList<QNetworkCookie> cookies;
|
cookie.setPath("/");
|
||||||
const QList<QByteArray> raw_cookies = getHostNameCookies(host_name);
|
cookie.setExpirationDate(QDateTime::currentDateTime().addYears(10));
|
||||||
foreach (const QByteArray& raw_cookie, raw_cookies) {
|
cookies << cookie;
|
||||||
QList<QByteArray> cookie_parts = raw_cookie.split('=');
|
}
|
||||||
if (cookie_parts.size() == 2) {
|
|
||||||
qDebug("Loading cookie: %s = %s", cookie_parts.first().constData(), cookie_parts.last().constData());
|
|
||||||
cookies << QNetworkCookie(cookie_parts.first(), cookie_parts.last());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setNetworkCookies(cookies);
|
||||||
|
|
||||||
|
QWriteLocker locker(&lock);
|
||||||
|
dirty = true;
|
||||||
|
timer.start();
|
||||||
|
m_data.remove("Rss/hosts_cookies");
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QNetworkCookie> Preferences::getNetworkCookies() const
|
||||||
|
{
|
||||||
|
QList<QNetworkCookie> cookies;
|
||||||
|
QStringList rawCookies = value("Network/Cookies").toStringList();
|
||||||
|
foreach (const QString &rawCookie, rawCookies)
|
||||||
|
cookies << QNetworkCookie::parseCookies(rawCookie.toUtf8());
|
||||||
|
|
||||||
return cookies;
|
return cookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::setHostNameCookies(const QString &host_name, const QList<QByteArray> &cookies)
|
void Preferences::setNetworkCookies(const QList<QNetworkCookie> &cookies)
|
||||||
{
|
{
|
||||||
QMap<QString, QVariant> hosts_table = value("Rss/hosts_cookies").toMap();
|
QStringList rawCookies;
|
||||||
QByteArray raw_cookies = "";
|
foreach (const QNetworkCookie &cookie, cookies)
|
||||||
foreach (const QByteArray& cookie, cookies)
|
rawCookies << cookie.toRawForm();
|
||||||
raw_cookies += cookie + ":";
|
|
||||||
if (raw_cookies.endsWith(":"))
|
setValue("Network/Cookies", rawCookies);
|
||||||
raw_cookies.chop(1);
|
|
||||||
hosts_table.insert(host_name, raw_cookies);
|
|
||||||
setValue("Rss/hosts_cookies", hosts_table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Preferences::getSpeedWidgetPeriod() const {
|
int Preferences::getSpeedWidgetPeriod() const
|
||||||
|
{
|
||||||
return value("SpeedWidget/period", 1).toInt();
|
return value("SpeedWidget/period", 1).toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preferences::setSpeedWidgetPeriod(const int period) {
|
void Preferences::setSpeedWidgetPeriod(const int period)
|
||||||
|
{
|
||||||
setValue("SpeedWidget/period", period);
|
setValue("SpeedWidget/period", period);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,9 +534,12 @@ public:
|
|||||||
void setRssFeedsUrls(const QStringList &rssFeeds);
|
void setRssFeedsUrls(const QStringList &rssFeeds);
|
||||||
QStringList getRssFeedsAliases() const;
|
QStringList getRssFeedsAliases() const;
|
||||||
void setRssFeedsAliases(const QStringList &rssAliases);
|
void setRssFeedsAliases(const QStringList &rssAliases);
|
||||||
QList<QByteArray> getHostNameCookies(const QString &host_name) const;
|
|
||||||
QList<QNetworkCookie> getHostNameQNetworkCookies(const QString& host_name) const;
|
// Network
|
||||||
void setHostNameCookies(const QString &host_name, const QList<QByteArray> &cookies);
|
QList<QNetworkCookie> getNetworkCookies() const;
|
||||||
|
void setNetworkCookies(const QList<QNetworkCookie> &cookies);
|
||||||
|
// Temporary method for upgrade purposes
|
||||||
|
void moveRSSCookies();
|
||||||
|
|
||||||
// SpeedWidget
|
// SpeedWidget
|
||||||
int getSpeedWidgetPeriod() const;
|
int getSpeedWidgetPeriod() const;
|
||||||
|
@ -28,23 +28,20 @@
|
|||||||
* Contact : chris@qbittorrent.org
|
* Contact : chris@qbittorrent.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
#include <QNetworkProxy>
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include "programupdater.h"
|
|
||||||
#include "base/utils/fs.h"
|
#include "base/utils/fs.h"
|
||||||
#include "base/preferences.h"
|
#include "base/net/downloadmanager.h"
|
||||||
|
#include "base/net/downloadhandler.h"
|
||||||
|
#include "programupdater.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const QUrl RSS_URL("http://www.fosshub.com/software/feedqBittorent");
|
const QString RSS_URL("http://www.fosshub.com/software/feedqBittorent");
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
const QString OS_TYPE("Mac OS X");
|
const QString OS_TYPE("Mac OS X");
|
||||||
@ -59,99 +56,73 @@ ProgramUpdater::ProgramUpdater(QObject *parent, bool invokedByUser)
|
|||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_invokedByUser(invokedByUser)
|
, m_invokedByUser(invokedByUser)
|
||||||
{
|
{
|
||||||
m_networkManager = new QNetworkAccessManager(this);
|
|
||||||
Preferences* const pref = Preferences::instance();
|
|
||||||
// Proxy support
|
|
||||||
if (pref->isProxyEnabled()) {
|
|
||||||
QNetworkProxy proxy;
|
|
||||||
switch(pref->getProxyType()) {
|
|
||||||
case Proxy::SOCKS4:
|
|
||||||
case Proxy::SOCKS5:
|
|
||||||
case Proxy::SOCKS5_PW:
|
|
||||||
proxy.setType(QNetworkProxy::Socks5Proxy);
|
|
||||||
default:
|
|
||||||
proxy.setType(QNetworkProxy::HttpProxy);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
proxy.setHostName(pref->getProxyIp());
|
|
||||||
proxy.setPort(pref->getProxyPort());
|
|
||||||
// Proxy authentication
|
|
||||||
if (pref->isProxyAuthEnabled()) {
|
|
||||||
proxy.setUser(pref->getProxyUsername());
|
|
||||||
proxy.setPassword(pref->getProxyPassword());
|
|
||||||
}
|
|
||||||
m_networkManager->setProxy(proxy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramUpdater::~ProgramUpdater()
|
|
||||||
{
|
|
||||||
delete m_networkManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramUpdater::checkForUpdates()
|
void ProgramUpdater::checkForUpdates()
|
||||||
{
|
{
|
||||||
// SIGNAL/SLOT
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(
|
||||||
connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
|
RSS_URL, false, 0, false,
|
||||||
this, SLOT(rssDownloadFinished(QNetworkReply*)));
|
// Don't change this User-Agent. In case our updater goes haywire,
|
||||||
// Send the request
|
// the filehost can identify it and contact us.
|
||||||
QNetworkRequest request(RSS_URL);
|
QString("qBittorrent/%1 ProgramUpdater (www.qbittorrent.org)").arg(VERSION));
|
||||||
// Don't change this User-Agent. In case our updater goes haywire, the filehost can indetify it and contact us.
|
connect(handler, SIGNAL(downloadFinished(QString,QByteArray)), SLOT(rssDownloadFinished(QString,QByteArray)));
|
||||||
request.setRawHeader("User-Agent", QString("qBittorrent/%1 ProgramUpdater (www.qbittorrent.org)").arg(VERSION).toLocal8Bit());
|
connect(handler, SIGNAL(downloadFailed(QString,QString)), SLOT(rssDownloadFailed(QString,QString)));
|
||||||
m_networkManager->get(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramUpdater::rssDownloadFinished(QNetworkReply *reply)
|
void ProgramUpdater::rssDownloadFinished(const QString &url, const QByteArray &data)
|
||||||
{
|
{
|
||||||
// Disconnect SIGNAL/SLOT
|
Q_UNUSED(url);
|
||||||
disconnect(m_networkManager, 0, this, 0);
|
|
||||||
qDebug("Finished downloading the new qBittorrent updates RSS");
|
qDebug("Finished downloading the new qBittorrent updates RSS");
|
||||||
QString version;
|
QString version;
|
||||||
|
|
||||||
if (!reply->error()) {
|
QXmlStreamReader xml(data);
|
||||||
qDebug("No download error, good.");
|
bool inItem = false;
|
||||||
QXmlStreamReader xml(reply);
|
QString updateLink;
|
||||||
bool inItem = false;
|
QString type;
|
||||||
QString updateLink;
|
|
||||||
QString type;
|
|
||||||
|
|
||||||
while (!xml.atEnd()) {
|
while (!xml.atEnd()) {
|
||||||
xml.readNext();
|
xml.readNext();
|
||||||
|
|
||||||
if (xml.isStartElement()) {
|
if (xml.isStartElement()) {
|
||||||
if (xml.name() == "item")
|
if (xml.name() == "item")
|
||||||
inItem = true;
|
inItem = true;
|
||||||
else if (inItem && xml.name() == "link")
|
else if (inItem && xml.name() == "link")
|
||||||
updateLink = getStringValue(xml);
|
updateLink = getStringValue(xml);
|
||||||
else if (inItem && xml.name() == "type")
|
else if (inItem && xml.name() == "type")
|
||||||
type = getStringValue(xml);
|
type = getStringValue(xml);
|
||||||
else if (inItem && xml.name() == "version")
|
else if (inItem && xml.name() == "version")
|
||||||
version = getStringValue(xml);
|
version = getStringValue(xml);
|
||||||
}
|
}
|
||||||
else if (xml.isEndElement()) {
|
else if (xml.isEndElement()) {
|
||||||
if (inItem && xml.name() == "item") {
|
if (inItem && xml.name() == "item") {
|
||||||
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0) {
|
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0) {
|
||||||
qDebug("The last update available is %s", qPrintable(version));
|
qDebug("The last update available is %s", qPrintable(version));
|
||||||
if (!version.isEmpty()) {
|
if (!version.isEmpty()) {
|
||||||
qDebug("Detected version is %s", qPrintable(version));
|
qDebug("Detected version is %s", qPrintable(version));
|
||||||
if (isVersionMoreRecent(version))
|
if (isVersionMoreRecent(version))
|
||||||
m_updateUrl = updateLink;
|
m_updateUrl = updateLink;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
inItem = false;
|
|
||||||
updateLink.clear();
|
|
||||||
type.clear();
|
|
||||||
version.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inItem = false;
|
||||||
|
updateLink.clear();
|
||||||
|
type.clear();
|
||||||
|
version.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit updateCheckFinished(!m_updateUrl.isEmpty(), version, m_invokedByUser);
|
emit updateCheckFinished(!m_updateUrl.isEmpty(), version, m_invokedByUser);
|
||||||
// Clean up
|
}
|
||||||
reply->deleteLater();
|
|
||||||
|
void ProgramUpdater::rssDownloadFailed(const QString &url, const QString &error)
|
||||||
|
{
|
||||||
|
Q_UNUSED(url);
|
||||||
|
|
||||||
|
qDebug() << "Downloading the new qBittorrent updates RSS failed:" << error;
|
||||||
|
emit updateCheckFinished(false, QString(), m_invokedByUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProgramUpdater::updateProgram()
|
void ProgramUpdater::updateProgram()
|
||||||
|
@ -34,30 +34,27 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
class QNetworkReply;
|
|
||||||
class QNetworkAccessManager;
|
|
||||||
|
|
||||||
class ProgramUpdater: public QObject
|
class ProgramUpdater: public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ProgramUpdater(QObject *parent = 0, bool invokedByUser = false);
|
explicit ProgramUpdater(QObject *parent = 0, bool invokedByUser = false);
|
||||||
~ProgramUpdater();
|
|
||||||
void checkForUpdates();
|
void checkForUpdates();
|
||||||
void updateProgram();
|
void updateProgram();
|
||||||
|
|
||||||
protected:
|
|
||||||
bool isVersionMoreRecent(const QString &remoteVersion) const;
|
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void rssDownloadFinished(QNetworkReply* reply);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updateCheckFinished(bool updateAvailable, QString version, bool invokedByUser);
|
void updateCheckFinished(bool updateAvailable, QString version, bool invokedByUser);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void rssDownloadFinished(const QString &url, const QByteArray &data);
|
||||||
|
void rssDownloadFailed(const QString &url, const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool isVersionMoreRecent(const QString &remoteVersion) const;
|
||||||
|
|
||||||
QString m_updateUrl;
|
QString m_updateUrl;
|
||||||
QNetworkAccessManager *m_networkManager;
|
|
||||||
bool m_invokedByUser;
|
bool m_invokedByUser;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,12 +31,14 @@
|
|||||||
#include "cookiesdlg.h"
|
#include "cookiesdlg.h"
|
||||||
#include "ui_cookiesdlg.h"
|
#include "ui_cookiesdlg.h"
|
||||||
#include "guiiconprovider.h"
|
#include "guiiconprovider.h"
|
||||||
|
#include "base/net/downloadmanager.h"
|
||||||
|
|
||||||
#include <QNetworkCookie>
|
#include <QNetworkCookie>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
enum CookiesCols { COOKIE_KEY, COOKIE_VALUE};
|
enum CookiesCols { COOKIE_KEY, COOKIE_VALUE};
|
||||||
|
|
||||||
CookiesDlg::CookiesDlg(QWidget *parent, const QList<QByteArray> &raw_cookies) :
|
CookiesDlg::CookiesDlg(const QUrl &url, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::CookiesDlg)
|
ui(new Ui::CookiesDlg)
|
||||||
{
|
{
|
||||||
@ -46,13 +48,13 @@ CookiesDlg::CookiesDlg(QWidget *parent, const QList<QByteArray> &raw_cookies) :
|
|||||||
ui->del_btn->setIcon(GuiIconProvider::instance()->getIcon("list-remove"));
|
ui->del_btn->setIcon(GuiIconProvider::instance()->getIcon("list-remove"));
|
||||||
|
|
||||||
ui->infos_lbl->setText(tr("Common keys for cookies are: '%1', '%2'.\nYou should get this information from your Web browser preferences.").arg("uid").arg("pass"));
|
ui->infos_lbl->setText(tr("Common keys for cookies are: '%1', '%2'.\nYou should get this information from your Web browser preferences.").arg("uid").arg("pass"));
|
||||||
foreach (const QByteArray &raw_cookie, raw_cookies) {
|
|
||||||
QList<QByteArray> cookie_parts = raw_cookie.split('=');
|
QList<QNetworkCookie> cookies = Net::DownloadManager::instance()->cookiesForUrl(url);
|
||||||
if (cookie_parts.size() != 2) continue;
|
foreach (const QNetworkCookie &cookie, cookies) {
|
||||||
const int i = ui->cookiesTable->rowCount();
|
const int i = ui->cookiesTable->rowCount();
|
||||||
ui->cookiesTable->setRowCount(i+1);
|
ui->cookiesTable->setRowCount(i+1);
|
||||||
ui->cookiesTable->setItem(i, COOKIE_KEY, new QTableWidgetItem(cookie_parts.first().data()));
|
ui->cookiesTable->setItem(i, COOKIE_KEY, new QTableWidgetItem(QString(cookie.name())));
|
||||||
ui->cookiesTable->setItem(i, COOKIE_VALUE, new QTableWidgetItem(cookie_parts.last().data()));
|
ui->cookiesTable->setItem(i, COOKIE_VALUE, new QTableWidgetItem(QString(cookie.value())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +77,9 @@ void CookiesDlg::on_del_btn_clicked() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> CookiesDlg::getCookies() const {
|
QList<QNetworkCookie> CookiesDlg::getCookies() const {
|
||||||
QList<QByteArray> ret;
|
QList<QNetworkCookie> ret;
|
||||||
|
auto now = QDateTime::currentDateTime();
|
||||||
for (int i=0; i<ui->cookiesTable->rowCount(); ++i) {
|
for (int i=0; i<ui->cookiesTable->rowCount(); ++i) {
|
||||||
QString key;
|
QString key;
|
||||||
if (ui->cookiesTable->item(i, COOKIE_KEY))
|
if (ui->cookiesTable->item(i, COOKIE_KEY))
|
||||||
@ -85,20 +88,23 @@ QList<QByteArray> CookiesDlg::getCookies() const {
|
|||||||
if (ui->cookiesTable->item(i, COOKIE_VALUE))
|
if (ui->cookiesTable->item(i, COOKIE_VALUE))
|
||||||
value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed();
|
value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed();
|
||||||
if (!key.isEmpty() && !value.isEmpty()) {
|
if (!key.isEmpty() && !value.isEmpty()) {
|
||||||
const QString raw_cookie = key+"="+value;
|
QNetworkCookie cookie(key.toUtf8(), value.toUtf8());
|
||||||
qDebug("Cookie: %s", qPrintable(raw_cookie));
|
// TODO: Delete this hack when advanced Cookie dialog will be implemented.
|
||||||
ret << raw_cookie.toLocal8Bit();
|
cookie.setExpirationDate(now.addYears(10));
|
||||||
|
qDebug("Cookie: %s", cookie.toRawForm().data());
|
||||||
|
ret << cookie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> CookiesDlg::askForCookies(QWidget *parent, const QList<QByteArray> &raw_cookies, bool *ok) {
|
bool CookiesDlg::askForCookies(QWidget *parent, const QUrl &url, QList<QNetworkCookie> &out)
|
||||||
CookiesDlg dlg(parent, raw_cookies);
|
{
|
||||||
|
CookiesDlg dlg(url, parent);
|
||||||
if (dlg.exec()) {
|
if (dlg.exec()) {
|
||||||
*ok = true;
|
out = dlg.getCookies();
|
||||||
return dlg.getCookies();
|
return true;
|
||||||
}
|
}
|
||||||
*ok = false;
|
|
||||||
return QList<QByteArray>();
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -32,22 +32,24 @@
|
|||||||
#define COOKIESDLG_H
|
#define COOKIESDLG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
class QNetworkCookie;
|
||||||
|
class QUrl;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class CookiesDlg;
|
class CookiesDlg;
|
||||||
}
|
}
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class CookiesDlg : public QDialog
|
class CookiesDlg : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CookiesDlg(QWidget *parent = 0, const QList<QByteArray> &raw_cookies = QList<QByteArray>());
|
explicit CookiesDlg(const QUrl &url, QWidget *parent = 0);
|
||||||
~CookiesDlg();
|
~CookiesDlg();
|
||||||
QList<QByteArray> getCookies() const;
|
QList<QNetworkCookie> getCookies() const;
|
||||||
static QList<QByteArray> askForCookies(QWidget *parent, const QList<QByteArray> &raw_cookies, bool *ok);
|
static bool askForCookies(QWidget *parent, const QUrl &url, QList<QNetworkCookie> &out);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void on_add_btn_clicked();
|
void on_add_btn_clicked();
|
||||||
|
@ -142,18 +142,19 @@ void RSSImp::displayItemsListMenu(const QPoint&)
|
|||||||
void RSSImp::on_actionManage_cookies_triggered()
|
void RSSImp::on_actionManage_cookies_triggered()
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_feedList->selectedItems().empty());
|
Q_ASSERT(!m_feedList->selectedItems().empty());
|
||||||
// Get feed hostname
|
|
||||||
QString feed_url = m_feedList->getItemID(m_feedList->selectedItems().first());
|
// TODO: Create advanced application wide Cookie dialog and use it everywhere.
|
||||||
QString feed_hostname = QUrl::fromEncoded(feed_url.toUtf8()).host();
|
QUrl feedUrl = QUrl::fromEncoded(m_feedList->getItemID(m_feedList->selectedItems().first()).toUtf8());
|
||||||
qDebug("RSS Feed hostname is: %s", qPrintable(feed_hostname));
|
QList<QNetworkCookie> cookies;
|
||||||
Q_ASSERT(!feed_hostname.isEmpty());
|
if (CookiesDlg::askForCookies(this, feedUrl, cookies)) {
|
||||||
bool ok = false;
|
auto downloadManager = Net::DownloadManager::instance();
|
||||||
Preferences* const pref = Preferences::instance();
|
QList<QNetworkCookie> oldCookies = downloadManager->cookiesForUrl(feedUrl);
|
||||||
QList<QByteArray> raw_cookies = CookiesDlg::askForCookies(this, pref->getHostNameCookies(feed_hostname), &ok);
|
foreach (const QNetworkCookie &oldCookie, oldCookies) {
|
||||||
if (ok) {
|
if (!cookies.contains(oldCookie))
|
||||||
qDebug() << "Settings cookies for host name: " << feed_hostname;
|
downloadManager->deleteCookie(oldCookie);
|
||||||
pref->setHostNameCookies(feed_hostname, raw_cookies);
|
}
|
||||||
Net::DownloadManager::instance()->setCookiesFromUrl(pref->getHostNameQNetworkCookies(feed_hostname), feed_hostname);
|
|
||||||
|
downloadManager->setCookiesFromUrl(cookies, feedUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user