From 994c79826412632ab7430cc9c53469f8f87b1f94 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Mon, 17 May 2010 14:57:45 +0000 Subject: [PATCH] Added cookie support for RSS feeds (Needs testing) --- src/cookiesdlg.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++ src/cookiesdlg.h | 58 ++++++++++++++++++++++++++ src/downloadthread.cpp | 30 ++++++++++++- src/downloadthread.h | 1 + src/icons.qrc | 1 + src/preferences.h | 22 ++++++++++ src/rss_imp.cpp | 21 +++++++++- src/rss_imp.h | 1 + src/src.pro | 10 +++-- src/ui/rss.ui | 15 ++++--- 10 files changed, 243 insertions(+), 11 deletions(-) create mode 100644 src/cookiesdlg.cpp create mode 100644 src/cookiesdlg.h diff --git a/src/cookiesdlg.cpp b/src/cookiesdlg.cpp new file mode 100644 index 000000000..fa2dedc58 --- /dev/null +++ b/src/cookiesdlg.cpp @@ -0,0 +1,95 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ + +#include "cookiesdlg.h" +#include "ui_cookiesdlg.h" + +#include + +enum CookiesCols { COOKIE_KEY, COOKIE_VALUE}; + +CookiesDlg::CookiesDlg(QWidget *parent, const QList &raw_cookies) : + QDialog(parent), + ui(new Ui::CookiesDlg) +{ + ui->setupUi(this); + 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 cookie_parts = raw_cookie.split('='); + if(cookie_parts.size() != 2) continue; + const int i = ui->cookiesTable->rowCount(); + ui->cookiesTable->setRowCount(i+1); + ui->cookiesTable->setItem(i, COOKIE_KEY, new QTableWidgetItem(cookie_parts.first().data())); + ui->cookiesTable->setItem(i, COOKIE_VALUE, new QTableWidgetItem(cookie_parts.last().data())); + } +} + +CookiesDlg::~CookiesDlg() +{ + delete ui; +} + +void CookiesDlg::on_add_btn_clicked() { + ui->cookiesTable->setRowCount(ui->cookiesTable->rowCount()+1); + // Edit first column + ui->cookiesTable->editItem(ui->cookiesTable->item(ui->cookiesTable->rowCount()-1, COOKIE_KEY)); +} + +void CookiesDlg::on_del_btn_clicked() { + // Get selected cookie + QList selection = ui->cookiesTable->selectedItems(); + if(!selection.isEmpty()) { + ui->cookiesTable->removeRow(selection.first()->row()); + } +} + +QList CookiesDlg::getCookies() const { + QList ret; + for(int i=0; icookiesTable->rowCount(); ++i) { + QString key = ui->cookiesTable->item(i, COOKIE_KEY)->text().trimmed(); + QString value = ui->cookiesTable->item(i, COOKIE_VALUE)->text().trimmed(); + if(!key.isEmpty() && !value.isEmpty()) { + const QString raw_cookie = key+"="+value; + qDebug("Cookie: %s", qPrintable(raw_cookie)); + ret << raw_cookie.toLocal8Bit(); + } + } + return ret; +} + +QList CookiesDlg::askForCookies(QWidget *parent, const QList &raw_cookies, bool *ok) { + CookiesDlg dlg(parent, raw_cookies); + if(dlg.exec()) { + *ok = true; + return dlg.getCookies(); + } + *ok = false; + return QList(); +} diff --git a/src/cookiesdlg.h b/src/cookiesdlg.h new file mode 100644 index 000000000..9f32c936c --- /dev/null +++ b/src/cookiesdlg.h @@ -0,0 +1,58 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2010 Christophe Dumez + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : chris@qbittorrent.org arnaud@qbittorrent.org + */ + +#ifndef COOKIESDLG_H +#define COOKIESDLG_H + +#include + +namespace Ui { + class CookiesDlg; +} + +class CookiesDlg : public QDialog +{ + Q_OBJECT + +public: + explicit CookiesDlg(QWidget *parent = 0, const QList &raw_cookies = QList()); + ~CookiesDlg(); + QList getCookies() const; + static QList askForCookies(QWidget *parent, const QList &raw_cookies, bool *ok); + + protected slots: + void on_add_btn_clicked(); + void on_del_btn_clicked(); + +private: + Ui::CookiesDlg *ui; +}; + +#endif // COOKIESDLG_H diff --git a/src/downloadthread.cpp b/src/downloadthread.cpp index e9143ab07..8b6f91ae8 100644 --- a/src/downloadthread.cpp +++ b/src/downloadthread.cpp @@ -28,12 +28,16 @@ * Contact : chris@qbittorrent.org */ -#include "downloadthread.h" #include #include #include #include #include +#include +#include + +#include "downloadthread.h" +#include "preferences.h" enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5}; @@ -95,7 +99,27 @@ void downloadThread::processDlFinished(QNetworkReply* reply) { reply->deleteLater(); } +void downloadThread::loadCookies(QString host_name, QString url) { + const QList &raw_cookies = Preferences::getHostNameCookies(host_name); + QNetworkCookieJar *cookie_jar = networkManager.cookieJar(); + QList cookies; + foreach(const QByteArray& raw_cookie, raw_cookies) { + QList cookie_parts = raw_cookie.split('='); + if(cookie_parts.size() == 2) { + qDebug("Loading cookie: %s", raw_cookie.constData()); + cookies << QNetworkCookie(cookie_parts.first(), cookie_parts.last()); + } + } + cookie_jar->setCookiesFromUrl(cookies, url); + networkManager.setCookieJar(cookie_jar); +} + void downloadThread::downloadTorrentUrl(QString url){ + // Load cookies + QString host_name = QUrl::fromEncoded(url.toLocal8Bit()).host(); + if(!host_name.isEmpty()) + loadCookies(host_name, url); + // Process request QNetworkReply *reply = downloadUrl(url); connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(checkDownloadSize(qint64,qint64))); } @@ -103,6 +127,10 @@ void downloadThread::downloadTorrentUrl(QString url){ QNetworkReply* downloadThread::downloadUrl(QString url){ // Update proxy settings applyProxySettings(); + // Load cookies + QString host_name = QUrl::fromEncoded(url.toLocal8Bit()).host(); + if(!host_name.isEmpty()) + loadCookies(host_name, url); // Process download request qDebug("url is %s", qPrintable(url)); const QUrl &qurl = QUrl::fromEncoded(url.toLocal8Bit()); diff --git a/src/downloadthread.h b/src/downloadthread.h index ed5ba1d74..3712d094f 100644 --- a/src/downloadthread.h +++ b/src/downloadthread.h @@ -58,6 +58,7 @@ public: protected: QString errorCodeToString(QNetworkReply::NetworkError status); void applyProxySettings(); + void loadCookies(QString host_name, QString url); protected slots: void processDlFinished(QNetworkReply* reply); diff --git a/src/icons.qrc b/src/icons.qrc index 5c6073270..b43c07bd5 100644 --- a/src/icons.qrc +++ b/src/icons.qrc @@ -149,6 +149,7 @@ Icons/oxygen/encrypted.png Icons/oxygen/edit_clear.png Icons/oxygen/download.png + Icons/oxygen/cookies.png Icons/oxygen/gear32.png Icons/oxygen/gear.png Icons/oxygen/remove.png diff --git a/src/preferences.h b/src/preferences.h index 48c99d0cd..e8b50c0e2 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -951,6 +951,28 @@ public: } #endif + static QList getHostNameCookies(QString host_name) { + QSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + QList ret; + QMap hosts_table = qBTRSS.value("hosts_cookies", QMap()).toMap(); + if(!hosts_table.contains(host_name)) return ret; + QByteArray raw_cookies = hosts_table.value(host_name).toByteArray(); + return raw_cookies.split(':'); + } + + static void setHostNameCookies(QString host_name, const QList &cookies) { + QSettings qBTRSS("qBittorrent", "qBittorrent-rss"); + QMap hosts_table = qBTRSS.value("hosts_cookies", QMap()).toMap(); + QByteArray raw_cookies = ""; + foreach(const QByteArray& cookie, cookies) { + raw_cookies += cookie + ":"; + } + if(raw_cookies.endsWith(":")) + raw_cookies.chop(1); + hosts_table.insert(host_name, raw_cookies); + qBTRSS.setValue("hosts_cookies", hosts_table); + } + }; #endif // PREFERENCES_H diff --git a/src/rss_imp.cpp b/src/rss_imp.cpp index 207f281bb..633795c57 100644 --- a/src/rss_imp.cpp +++ b/src/rss_imp.cpp @@ -41,6 +41,8 @@ #include "feeddownloader.h" #include "feedList.h" #include "bittorrent.h" +#include "cookiesdlg.h" +#include "preferences.h" enum NewsCols { NEWS_ICON, NEWS_TITLE_COL, NEWS_URL_COL, NEWS_ID }; @@ -61,8 +63,11 @@ void RSSImp::displayRSSListMenu(const QPoint& pos){ myRSSListMenu.addAction(actionRename); myRSSListMenu.addAction(actionDelete); myRSSListMenu.addSeparator(); - if(listStreams->getItemType(selectedItems.first()) == RssFile::FOLDER) + if(listStreams->getItemType(selectedItems.first()) == RssFile::FOLDER) { myRSSListMenu.addAction(actionNew_folder); + } else { + myRSSListMenu.addAction(actionManage_cookies); + } } } myRSSListMenu.addAction(actionNew_subscription); @@ -103,6 +108,20 @@ void RSSImp::displayItemsListMenu(const QPoint&){ myItemListMenu.exec(QCursor::pos()); } +void RSSImp::on_actionManage_cookies_triggered() { + Q_ASSERT(!listStreams->selectedItems().empty()); + // Get feed hostname + QString feed_url = listStreams->getItemID(listStreams->selectedItems().first()); + QString feed_hostname = QUrl::fromEncoded(feed_url.toLocal8Bit()).host(); + qDebug("RSS Feed hostname is: %s", qPrintable(feed_hostname)); + Q_ASSERT(!feed_hostname.isEmpty()); + bool ok = false; + QList raw_cookies = CookiesDlg::askForCookies(this, Preferences::getHostNameCookies(feed_hostname), &ok); + if(ok) { + Preferences::setHostNameCookies(feed_hostname, raw_cookies); + } +} + void RSSImp::askNewFolder() { QTreeWidgetItem *parent_item = 0; RssFolder *rss_parent; diff --git a/src/rss_imp.h b/src/rss_imp.h index 04b3549c2..b0a0a4d38 100644 --- a/src/rss_imp.h +++ b/src/rss_imp.h @@ -79,6 +79,7 @@ protected slots: void saveFoldersOpenState(); void loadFoldersOpenState(); void displayOverwriteError(QString filename); + void on_actionManage_cookies_triggered(); public: RSSImp(Bittorrent *BTSession); diff --git a/src/src.pro b/src/src.pro index f75e41d43..f2919d635 100644 --- a/src/src.pro +++ b/src/src.pro @@ -247,7 +247,8 @@ HEADERS += misc.h \ filesystemwatcher.h \ preferences.h \ bandwidthscheduler.h \ - scannedfoldersmodel.h + scannedfoldersmodel.h \ + cookiesdlg.h contains(DEFINES, DISABLE_GUI):HEADERS += headlessloader.h else:HEADERS += GUI.h \ @@ -309,7 +310,8 @@ else:HEADERS += GUI.h \ ui/feeddownloader.ui \ ui/propertieswidget.ui \ ui/peer.ui \ - ui/confirmdeletiondlg.ui + ui/confirmdeletiondlg.ui \ + ui/cookiesdlg.ui SOURCES += main.cpp \ bittorrent.cpp \ @@ -321,7 +323,8 @@ SOURCES += main.cpp \ httpresponsegenerator.cpp \ eventmanager.cpp \ scannedfoldersmodel.cpp \ - misc.cpp + misc.cpp \ + cookiesdlg.cpp !contains(DEFINES, DISABLE_GUI):SOURCES += GUI.cpp \ options_imp.cpp \ @@ -337,3 +340,4 @@ SOURCES += main.cpp \ peerlistwidget.cpp DESTDIR = . + diff --git a/src/ui/rss.ui b/src/ui/rss.ui index 72cecac46..c6ec3f2a8 100644 --- a/src/ui/rss.ui +++ b/src/ui/rss.ui @@ -148,12 +148,6 @@ p, li { white-space: pre-wrap; } true - - false - - - true - Bullet @@ -292,6 +286,15 @@ p, li { white-space: pre-wrap; } New folder + + + + :/Icons/oxygen/cookies.png:/Icons/oxygen/cookies.png + + + Manage cookies + +