- FEATURE: Dropped dependency on libcurl (Using Qt >= 4.4 for downloads now)

- FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is required)
This commit is contained in:
Christophe Dumez 2009-11-04 15:04:11 +00:00
parent 66590bfa4a
commit bc308741b7
13 changed files with 152 additions and 466 deletions

View file

@ -11,6 +11,8 @@
- FEATURE: Tracker connections are now also subject to IP filtering - FEATURE: Tracker connections are now also subject to IP filtering
- FEATURE: Include DHT traffic in the rate limiter - FEATURE: Include DHT traffic in the rate limiter
- FEATURE: Support for bitcomet padding files - FEATURE: Support for bitcomet padding files
- FEATURE: Dropped dependency on libcurl
- FEATURE: Dropped Qt 4.3 support (Qt >= 4.4 is required)
* Thu Sep 3 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.0 * Thu Sep 3 2009 - Christophe Dumez <chris@qbittorrent.org> - v1.5.0
- FEATURE: Added Magnet URI support - FEATURE: Added Magnet URI support

14
INSTALL
View file

@ -1,12 +1,6 @@
qBittorrent - A BitTorrent client in C++ / Qt4 qBittorrent - A BitTorrent client in C++ / Qt4
------------------------------------------ ------------------------------------------
*** Necessary if qt3 is default on your system ***
export QTDIR=/usr/include/qt4
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib
*** End ***
./configure ./configure
make && make install make && make install
qbittorrent qbittorrent
@ -14,8 +8,7 @@ qbittorrent
will install and execute qBittorrent hopefully without any problems. will install and execute qBittorrent hopefully without any problems.
Dependencies: Dependencies:
- Qt >= 4.3.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml) - Qt >= 4.4.0 (libqt-devel, libqtgui, libqtcore, libqtnetwork, libqtxml)
Qt >= 4.4.0 is advised
- libtorrent-rasterbar by Arvid Norberg (>= v0.15.0 REQUIRED) - libtorrent-rasterbar by Arvid Norberg (>= v0.15.0 REQUIRED)
-> http://www.qbittorrent.org/download.php (advised) -> http://www.qbittorrent.org/download.php (advised)
@ -24,13 +17,8 @@ Dependencies:
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization - libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
- libcurl
- python >= 2.3 (needed by search engine) - python >= 2.3 (needed by search engine)
- libmagick++ (advised, not required)
* Needed for favicons support (RSS / Search plugins)
- libzzip (advised, not required) - libzzip (advised, not required)
* Needed for zip support (Search plugins) * Needed for zip support (Search plugins)

90
configure vendored
View file

@ -19,8 +19,6 @@ Main options:
Dependency options: Dependency options:
--with-libboost-inc=[path] Path to libboost include files --with-libboost-inc=[path] Path to libboost include files
--with-libcurl-inc=[path] Path to libcurl include files
--with-libcurl-lib=[path] Path to libcurl library files
--disable-libzzip Disable use of libzzip --disable-libzzip Disable use of libzzip
--with-libzzip-inc=[path] Path to libzzip++ include files --with-libzzip-inc=[path] Path to libzzip++ include files
--with-libzzip-lib=[path] Path to libzzip++ library files --with-libzzip-lib=[path] Path to libzzip++ library files
@ -145,16 +143,6 @@ while [ $# -gt 0 ]; do
shift shift
;; ;;
--with-libcurl-inc=*)
QC_WITH_LIBCURL_INC=$optarg
shift
;;
--with-libcurl-lib=*)
QC_WITH_LIBCURL_LIB=$optarg
shift
;;
--disable-libzzip) --disable-libzzip)
QC_DISABLE_libzzip="Y" QC_DISABLE_libzzip="Y"
shift shift
@ -192,8 +180,6 @@ echo BINDIR=$BINDIR
echo DATADIR=$DATADIR echo DATADIR=$DATADIR
echo EX_QTDIR=$EX_QTDIR echo EX_QTDIR=$EX_QTDIR
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip echo QC_DISABLE_libzzip=$QC_DISABLE_libzzip
echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC echo QC_WITH_LIBZZIP_INC=$QC_WITH_LIBZZIP_INC
echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB echo QC_WITH_LIBZZIP_LIB=$QC_WITH_LIBZZIP_LIB
@ -308,14 +294,11 @@ class qc_qt4 : public ConfObj
{ {
public: public:
qc_qt4(Conf *c) : ConfObj(c) {} qc_qt4(Conf *c) : ConfObj(c) {}
QString name() const { return "Qt >= 4.3"; } QString name() const { return "Qt >= 4.4"; }
QString shortname() const { return "Qt 4.3"; } QString shortname() const { return "Qt 4.4"; }
bool exec() bool exec()
{ {
if(QT_VERSION >= 0x040400) { return(QT_VERSION >= 0x040400);
conf->addDefine("QT_4_4");
}
return(QT_VERSION >= 0x040300);
} }
}; };
@ -403,68 +386,6 @@ public:
return true; return true;
} }
}; };
#line 1 "libcurl.qcm"
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD-----
*/
class qc_libcurl : public ConfObj
{
public:
qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "libcurl"; }
QString shortname() const { return "libcurl"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "curl/curl.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "curl/curl.h")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libcurl.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libcurl.so"))){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};
#line 1 "libzzip.qcm" #line 1 "libzzip.qcm"
/* /*
-----BEGIN QCMOD----- -----BEGIN QCMOD-----
@ -549,9 +470,6 @@ cat >$1/modules_new.cpp <<EOT
o = new qc_libboost(conf); o = new qc_libboost(conf);
o->required = true; o->required = true;
o->disabled = false; o->disabled = false;
o = new qc_libcurl(conf);
o->required = true;
o->disabled = false;
o = new qc_libzzip(conf); o = new qc_libzzip(conf);
o->required = false; o->required = false;
o->disabled = false; o->disabled = false;
@ -1501,8 +1419,6 @@ export BINDIR
export DATADIR export DATADIR
export EX_QTDIR export EX_QTDIR
export QC_WITH_LIBBOOST_INC export QC_WITH_LIBBOOST_INC
export QC_WITH_LIBCURL_INC
export QC_WITH_LIBCURL_LIB
export QC_DISABLE_libzzip export QC_DISABLE_libzzip
export QC_WITH_LIBZZIP_INC export QC_WITH_LIBZZIP_INC
export QC_WITH_LIBZZIP_LIB export QC_WITH_LIBZZIP_LIB

View file

@ -12,8 +12,5 @@
<dep type='libboost'> <dep type='libboost'>
<required/> <required/>
</dep> </dep>
<dep type='libcurl'>
<required/>
</dep>
<dep type='libzzip'/> <dep type='libzzip'/>
</qconf> </qconf>

View file

@ -1,61 +0,0 @@
/*
-----BEGIN QCMOD-----
name: libcommoncpp2
arg: with-libcurl-inc=[path], Path to libcurl include files
arg: with-libcurl-lib=[path], Path to libcurl library files
-----END QCMOD-----
*/
class qc_libcurl : public ConfObj
{
public:
qc_libcurl(Conf *c) : ConfObj(c) {}
QString name() const { return "libcurl"; }
QString shortname() const { return "libcurl"; }
bool exec(){
QString s;
s = conf->getenv("QC_WITH_LIBCURL_INC");
if(!s.isEmpty()) {
if(!conf->checkHeader(s, "curl/curl.h")) {
return false;
}
}else{
QStringList sl;
sl << "/usr/include";
sl << "/usr/local/include";
bool found = false;
foreach(s, sl){
if(conf->checkHeader(s, "curl/curl.h")){
found = true;
break;
}
}
if(!found) {
return false;
}
}
conf->addIncludePath(s);
s = conf->getenv("QC_WITH_LIBCURL_LIB");
if(!s.isEmpty()) {
if(!QFile::exists(s+QString("/libcurl.so")))
return false;
conf->addLib(QString("-L") + s);
}else{
QStringList sl;
sl << "/usr/lib/";
sl << "/usr/lib64/";
sl << "/usr/local/lib/";
sl << "/usr/local/lib64/";
bool found = false;
foreach(s, sl){
if(QFile::exists(s+QString("libcurl.so"))){
found = true;
break;
}
}
if(!found) return false;
conf->addLib(QString("-L") + s);
}
return true;
}
};

View file

@ -7,14 +7,11 @@ class qc_qt4 : public ConfObj
{ {
public: public:
qc_qt4(Conf *c) : ConfObj(c) {} qc_qt4(Conf *c) : ConfObj(c) {}
QString name() const { return "Qt >= 4.3"; } QString name() const { return "Qt >= 4.4"; }
QString shortname() const { return "Qt 4.3"; } QString shortname() const { return "Qt 4.4"; }
bool exec() bool exec()
{ {
if(QT_VERSION >= 0x040400) { return(QT_VERSION >= 0x040400);
conf->addDefine("QT_4_4");
}
return(QT_VERSION >= 0x040300);
} }
}; };

View file

@ -35,15 +35,10 @@
#include <QStatusBar> #include <QStatusBar>
#include <QFrame> #include <QFrame>
#include <QClipboard> #include <QClipboard>
#ifdef QT_4_4
#include <QLocalServer> #include <QLocalServer>
#include <QLocalSocket> #include <QLocalSocket>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#else
#include <QTcpServer>
#include <QTcpSocket>
#endif
#include <stdlib.h> #include <stdlib.h>
#include <QCloseEvent> #include <QCloseEvent>
#include <QShortcut> #include <QShortcut>
@ -189,7 +184,6 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
initWebUi(username, password, port); initWebUi(username, password, port);
} }
// Use a tcp server to allow only one instance of qBittorrent // Use a tcp server to allow only one instance of qBittorrent
#ifdef QT_4_4
localServer = new QLocalServer(); localServer = new QLocalServer();
QString uid = QString::number(getuid()); QString uid = QString::number(getuid());
#ifdef Q_WS_X11 #ifdef Q_WS_X11
@ -200,18 +194,8 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
} }
#endif #endif
if (!localServer->listen("qBittorrent-"+uid)) { if (!localServer->listen("qBittorrent-"+uid)) {
#else
localServer = new QTcpServer();
if (!localServer->listen(QHostAddress::LocalHost)) {
#endif
std::cerr << "Couldn't create socket, single instance mode won't work...\n"; std::cerr << "Couldn't create socket, single instance mode won't work...\n";
} }
#ifndef QT_4_4
else {
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
settings.setValue(QString::fromUtf8("uniqueInstancePort"), localServer->serverPort());
}
#endif
connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection())); connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
// Start connection checking timer // Start connection checking timer
checkConnect = new QTimer(this); checkConnect = new QTimer(this);

View file

@ -44,13 +44,8 @@ class DownloadingTorrents;
class FinishedTorrents; class FinishedTorrents;
class downloadFromURL; class downloadFromURL;
class SearchEngine; class SearchEngine;
#ifdef QT_4_4 class QLocalServer;
class QLocalServer; class QLocalSocket;
class QLocalSocket;
#else
class QTcpServer;
class QTcpSocket;
#endif
class QCloseEvent; class QCloseEvent;
class RSSImp; class RSSImp;
class QShortcut; class QShortcut;
@ -109,13 +104,8 @@ class GUI : public QMainWindow, private Ui::MainWindow{
// Web UI // Web UI
QPointer<HttpServer> httpServer; QPointer<HttpServer> httpServer;
// Misc // Misc
#ifdef QT_4_4
QLocalServer *localServer; QLocalServer *localServer;
QLocalSocket *clientConnection; QLocalSocket *clientConnection;
#else
QTcpServer *localServer;
QTcpSocket *clientConnection;
#endif
protected slots: protected slots:
// GUI related slots // GUI related slots

View file

@ -29,215 +29,139 @@
*/ */
#include "downloadThread.h" #include "downloadThread.h"
#include <iostream> #include <QTemporaryFile>
#include <QSettings> #include <QSettings>
#include <stdio.h> #include <QNetworkAccessManager>
#include <QNetworkRequest>
#define MAX_THREADS 3 #include <QNetworkProxy>
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
QString subDownloadThread::errorCodeToString(CURLcode status) {
switch(status){
case CURLE_FTP_CANT_GET_HOST:
case CURLE_COULDNT_RESOLVE_HOST:
return tr("Host is unreachable");
case CURLE_READ_ERROR:
case CURLE_FILE_COULDNT_READ_FILE:
return tr("File was not found (404)");
case CURLE_FTP_ACCESS_DENIED:
case CURLE_LOGIN_DENIED:
case CURLE_FTP_USER_PASSWORD_INCORRECT:
return tr("Connection was denied");
case CURLE_URL_MALFORMAT:
return tr("Url is invalid");
case CURLE_COULDNT_RESOLVE_PROXY:
return tr("Could not resolve proxy");
//case 5:
// return tr("Connection forbidden (403)");
//case 6:
// return tr("Connection was not authorized (401)");
//case 7:
// return tr("Content has moved (301)");
case CURLE_COULDNT_CONNECT:
return tr("Connection failure");
case CURLE_OPERATION_TIMEOUTED:
return tr("Connection was timed out");
case CURLE_INTERFACE_FAILED:
return tr("Incorrect network interface");
default:
return tr("Unknown error");
}
}
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
subDownloadThread::~subDownloadThread(){
abort = true;
wait();
}
void subDownloadThread::run(){
// Get a unique filename
QString filePath;
QTemporaryFile tmpfile;
tmpfile.setAutoRemove(false);
if (tmpfile.open()) {
filePath = tmpfile.fileName();
qDebug("Temporary filename is: %s", filePath.toLocal8Bit().data());
} else {
emit downloadFailureST(this, url, tr("I/O Error"));
return;
}
tmpfile.close();
// Now temporary file is created but closed so that
// curl can use it
FILE *f = fopen(filePath.toLocal8Bit().data(), "wb");
if(!f) {
std::cerr << "couldn't open destination file" << "\n";
return;
}
CURL *curl;
CURLcode res = (CURLcode)-1;
curl = curl_easy_init();
if(curl) {
std::string c_url = url.toLocal8Bit().data();
curl_easy_setopt(curl, CURLOPT_URL, c_url.c_str());
// SSL support
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
// PROXY SUPPORT
QSettings settings("qBittorrent", "qBittorrent");
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxyType"), 0).toInt();
if(intValue > 0) {
// Proxy enabled
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString();
QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString();
qDebug("Using proxy: %s", (IP+QString(":")+port).toLocal8Bit().data());
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toLocal8Bit().data());
// Default proxy type is HTTP, we must change if it is SOCKS5
if(intValue%2==0) {
qDebug("Proxy is SOCKS5, not HTTP");
curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
}
// Authentication?
if(intValue > 2) {
qDebug("Proxy requires authentication, authenticating");
QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString();
QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString();
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toLocal8Bit().data());
}
}
// We have to define CURLOPT_WRITEFUNCTION or it will crash on windows
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
// Verbose
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
// No progress info (we don't use it)
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
// Redirections
curl_easy_setopt(curl, CURLOPT_AUTOREFERER, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, -1);
qDebug("Downloading %s", url.toLocal8Bit().data());
if(!abort)
res = curl_easy_perform(curl);
qDebug("done downloading %s", url.toLocal8Bit().data());
/* always cleanup */
curl_easy_cleanup(curl);
fclose(f);
if(abort)
return;
if(res) {
emit downloadFailureST(this, url, errorCodeToString(res));
} else {
emit downloadFinishedST(this, url, filePath);
}
qDebug("%s Raised the signal", url.toLocal8Bit().data());
} else {
std::cerr << "Could not initialize CURL" << "\n";
}
}
/** Download Thread **/ /** Download Thread **/
downloadThread::downloadThread(QObject* parent) : QThread(parent), abort(false){} downloadThread::downloadThread(QObject* parent) : QObject(parent) {
networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished (QNetworkReply*)), this, SLOT(processDlFinished(QNetworkReply*)));
}
downloadThread::~downloadThread(){ downloadThread::~downloadThread(){
mutex.lock(); delete networkManager;
abort = true; }
condition.wakeOne();
mutex.unlock(); void downloadThread::processDlFinished(QNetworkReply* reply) {
//qDebug("downloadThread deleting subthreads..."); QString url = reply->url().toString();
qDeleteAll(subThreads); if(reply->error() != QNetworkReply::NoError) {
//qDebug("downloadThread deleted subthreads"); // Failure
wait(); emit downloadFailure(url, errorCodeToString(reply->error()));
} else {
// Success
QString filePath;
QTemporaryFile tmpfile;
tmpfile.setAutoRemove(false);
if (tmpfile.open()) {
filePath = tmpfile.fileName();
qDebug("Temporary filename is: %s", filePath.toLocal8Bit().data());
if(reply->open(QIODevice::ReadOnly)) {
tmpfile.write(reply->readAll());
reply->close();
// Send finished signal
emit downloadFinished(url, filePath);
} else {
// Error when reading the request
emit downloadFailure(url, tr("I/O Error"));
}
tmpfile.close();
} else {
emit downloadFailure(url, tr("I/O Error"));
}
}
// Clean up
reply->deleteLater();
} }
void downloadThread::downloadUrl(QString url){ void downloadThread::downloadUrl(QString url){
QMutexLocker locker(&mutex); // Update proxy settings
urls_queue.enqueue(url); applyProxySettings();
if(!isRunning()){ // Process download request
start(); networkManager->get(QNetworkRequest(QUrl(url)));
}else{
condition.wakeOne();
}
} }
void downloadThread::run(){ void downloadThread::applyProxySettings() {
forever{ QNetworkProxy proxy;
if(abort) { QSettings settings("qBittorrent", "qBittorrent");
qDebug("DownloadThread aborting..."); int intValue = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxyType"), 0).toInt();
return; if(intValue > 0) {
// Proxy enabled
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/IP"), "0.0.0.0").toString();
proxy.setHostName(IP);
QString port = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Port"), 8080).toString();
qDebug("Using proxy: %s", (IP+QString(":")+port).toLocal8Bit().data());
proxy.setPort(port.toUShort());
// Default proxy type is HTTP, we must change if it is SOCKS5
if(intValue%2==0) {
qDebug("Proxy is SOCKS5, not HTTP");
proxy.setType(QNetworkProxy::Socks5Proxy);
} else {
proxy.setType(QNetworkProxy::HttpProxy);
} }
mutex.lock(); // Authentication?
if(!urls_queue.empty() && subThreads.size() < MAX_THREADS){ if(intValue > 2) {
QString url = urls_queue.dequeue(); qDebug("Proxy requires authentication, authenticating");
mutex.unlock(); QString username = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Username"), QString()).toString();
//qDebug("DownloadThread downloading %s...", url.toLocal8Bit().data()); proxy.setUser(username);
subDownloadThread *st = new subDownloadThread(0, url); QString password = settings.value(QString::fromUtf8("Preferences/Connection/HTTPProxy/Password"), QString()).toString();
subThreads << st; proxy.setPassword(password);
connect(st, SIGNAL(downloadFinishedST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadedFile(subDownloadThread*, QString, QString)));
connect(st, SIGNAL(downloadFailureST(subDownloadThread*, QString, QString)), this, SLOT(propagateDownloadFailure(subDownloadThread*, QString, QString)));
st->start();
}else{
//qDebug("DownloadThread sleeping...");
condition.wait(&mutex);
//qDebug("DownloadThread woke up");
mutex.unlock();
} }
} else {
proxy.setType(QNetworkProxy::NoProxy);
} }
networkManager->setProxy(proxy);
} }
void downloadThread::propagateDownloadedFile(subDownloadThread* st, QString url, QString path){ QString downloadThread::errorCodeToString(QNetworkReply::NetworkError status) {
qDebug("Downloading %s was successful", url.toLocal8Bit().data()); switch(status){
mutex.lock(); case QNetworkReply::HostNotFoundError:
int index = subThreads.indexOf(st); return tr("The remote host name was not found (invalid hostname)");
Q_ASSERT(index != -1); case QNetworkReply::OperationCanceledError:
subThreads.removeAt(index); return tr("The operation was canceled");
mutex.unlock(); case QNetworkReply::RemoteHostClosedError:
qDebug("Deleting subthread"); return tr("The remote server closed the connection prematurely, before the entire reply was received and processed");
delete st; case QNetworkReply::TimeoutError:
emit downloadFinished(url, path); return tr("The connection to the remote server timed out");
mutex.lock(); case QNetworkReply::SslHandshakeFailedError:
if(!urls_queue.empty()) { return tr("SSL/TLS handshake failed");
condition.wakeOne(); case QNetworkReply::ConnectionRefusedError:
return tr("The remote server refused the connection");
case QNetworkReply::ProxyConnectionRefusedError:
return tr("The connection to the proxy server was refused");
case QNetworkReply::ProxyConnectionClosedError:
return tr("The proxy server closed the connection prematurely");
case QNetworkReply::ProxyNotFoundError:
return tr("The proxy host name was not found");
case QNetworkReply::ProxyTimeoutError:
return tr("The connection to the proxy timed out or the proxy did not reply in time to the request sent");
case QNetworkReply::ProxyAuthenticationRequiredError:
return tr("The proxy requires authentication in order to honour the request but did not accept any credentials offered");
case QNetworkReply::ContentAccessDenied:
return tr("The access to the remote content was denied (401)");
case QNetworkReply::ContentOperationNotPermittedError:
return tr("The operation requested on the remote content is not permitted");
case QNetworkReply::ContentNotFoundError:
return tr("The remote content was not found at the server (404)");
case QNetworkReply::AuthenticationRequiredError:
return tr("The remote server requires authentication to serve the content but the credentials provided were not accepted");
case QNetworkReply::ProtocolUnknownError:
return tr("The Network Access API cannot honor the request because the protocol is not known");
case QNetworkReply::ProtocolInvalidOperationError:
return tr("The requested operation is invalid for this protocol");
case QNetworkReply::UnknownNetworkError:
return tr("An unknown network-related error was detected");
case QNetworkReply::UnknownProxyError:
return tr("An unknown proxy-related error was detected");
case QNetworkReply::UnknownContentError:
return tr("An unknown error related to the remote content was detected");
case QNetworkReply::ProtocolFailure:
return tr("A breakdown in protocol was detected");
default:
return tr("Unknown error");
} }
mutex.unlock();
qDebug("Out of propagateDownloadedFile");
}
void downloadThread::propagateDownloadFailure(subDownloadThread* st, QString url, QString reason){
qDebug("Downloading %s failed", url.toLocal8Bit().data());
mutex.lock();
int index = subThreads.indexOf(st);
Q_ASSERT(index != -1);
subThreads.removeAt(index);
mutex.unlock();
delete st;
emit downloadFailure(url, reason);
mutex.lock();
if(!urls_queue.empty()) {
condition.wakeOne();
}
mutex.unlock();
} }

View file

@ -31,64 +31,34 @@
#ifndef DOWNLOADTHREAD_H #ifndef DOWNLOADTHREAD_H
#define DOWNLOADTHREAD_H #define DOWNLOADTHREAD_H
#include <QThread> #include <QNetworkReply>
#include <QFile> #include <QObject>
#include <QTemporaryFile>
#include <QMutex>
#include <QMutexLocker>
#include <QWaitCondition>
#include <QStringList>
#include <curl/curl.h>
#include <QQueue>
class subDownloadThread : public QThread { class QNetworkAccessManager;
Q_OBJECT
private:
QString url;
bool abort;
public: class downloadThread : public QObject {
subDownloadThread(QObject *parent, QString url);
~subDownloadThread();
QString errorCodeToString(CURLcode status);
signals:
// For subthreads
void downloadFinishedST(subDownloadThread* st, QString url, QString file_path);
void downloadFailureST(subDownloadThread* st, QString url, QString reason);
protected:
void run();
};
class downloadThread : public QThread {
Q_OBJECT Q_OBJECT
private: private:
QQueue<QString> urls_queue; QNetworkAccessManager *networkManager;
QMutex mutex;
QWaitCondition condition;
bool abort;
QList<subDownloadThread*> subThreads;
signals: signals:
void downloadFinished(QString url, QString file_path); void downloadFinished(QString url, QString file_path);
void downloadFailure(QString url, QString reason); void downloadFailure(QString url, QString reason);
public: public:
downloadThread(QObject* parent); downloadThread(QObject* parent);
~downloadThread();
void downloadUrl(QString url);
//void setProxy(QString IP, int port, QString username, QString password);
~downloadThread(); protected:
QString errorCodeToString(QNetworkReply::NetworkError status);
void applyProxySettings();
void downloadUrl(QString url); protected slots:
void setProxy(QString IP, int port, QString username, QString password); void processDlFinished(QNetworkReply* reply);
protected:
void run();
protected slots:
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
}; };
#endif #endif

View file

@ -41,6 +41,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QDropEvent> #include <QDropEvent>
#include <QInputDialog> #include <QInputDialog>
#include <QTemporaryFile>
#ifdef HAVE_ZZIP #ifdef HAVE_ZZIP
#include <zzip/zzip.h> #include <zzip/zzip.h>

View file

@ -34,14 +34,9 @@
#include <QFile> #include <QFile>
#include <QSplashScreen> #include <QSplashScreen>
#include <QSettings> #include <QSettings>
#ifdef QT_4_4
#include <QLocalSocket> #include <QLocalSocket>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#else
#include <QTcpSocket>
#include <QHostAddress>
#endif
#include <QPlastiqueStyle> #include <QPlastiqueStyle>
#include "qgnomelook.h" #include "qgnomelook.h"
#include <QMotifStyle> #include <QMotifStyle>
@ -143,19 +138,9 @@ int main(int argc, char *argv[]){
std::cerr << "Couldn't set environment variable...\n"; std::cerr << "Couldn't set environment variable...\n";
} }
//Check if there is another instance running //Check if there is another instance running
#ifdef QT_4_4
QLocalSocket localSocket; QLocalSocket localSocket;
QString uid = QString::number(getuid()); QString uid = QString::number(getuid());
#else
QTcpSocket localSocket;
#endif
#ifdef QT_4_4
localSocket.connectToServer("qBittorrent-"+uid, QIODevice::WriteOnly); localSocket.connectToServer("qBittorrent-"+uid, QIODevice::WriteOnly);
#else
int serverPort = settings.value(QString::fromUtf8("uniqueInstancePort"), -1).toInt();
if(serverPort != -1) {
localSocket.connectToHost(QHostAddress::LocalHost, serverPort, QIODevice::WriteOnly);
#endif
if (localSocket.waitForConnected(1000)){ if (localSocket.waitForConnected(1000)){
std::cout << "Another qBittorrent instance is already running...\n"; std::cout << "Another qBittorrent instance is already running...\n";
// Send parameters // Send parameters
@ -174,19 +159,12 @@ int main(int argc, char *argv[]){
}else{ }else{
std::cerr << "Writing to the socket timed out\n"; std::cerr << "Writing to the socket timed out\n";
} }
#ifdef QT_4_4
localSocket.disconnectFromServer(); localSocket.disconnectFromServer();
#else
localSocket.disconnectFromHost();
#endif
std::cout << "disconnected\n"; std::cout << "disconnected\n";
} }
localSocket.close(); localSocket.close();
return 0; return 0;
} }
#ifndef QT_4_4
}
#endif
app = new QApplication(argc, argv); app = new QApplication(argc, argv);
useStyle(app, settings.value("Preferences/General/Style", 0).toInt()); useStyle(app, settings.value("Preferences/General/Style", 0).toInt());
app->setStyleSheet("QStatusBar::item { border-width: 0; }"); app->setStyleSheet("QStatusBar::item { border-width: 0; }");

View file

@ -14,7 +14,7 @@ CONFIG += qt \
network network
# Update this VERSION for each release # Update this VERSION for each release
DEFINES += VERSION=\\\"v1.6.0alpha2\\\" DEFINES += VERSION=\\\"v1.6.0beta1\\\"
DEFINES += VERSION_MAJOR=1 DEFINES += VERSION_MAJOR=1
DEFINES += VERSION_MINOR=6 DEFINES += VERSION_MINOR=6
DEFINES += VERSION_BUGFIX=0 DEFINES += VERSION_BUGFIX=0
@ -90,7 +90,7 @@ contains(DEBUG_MODE, 0) {
# QMAKE_CXXFLAGS_DEBUG += -fwrapv # QMAKE_CXXFLAGS_DEBUG += -fwrapv
unix:QMAKE_LFLAGS_SHAPP += -rdynamic unix:QMAKE_LFLAGS_SHAPP += -rdynamic
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
PKGCONFIG += "libtorrent-rasterbar libcurl" PKGCONFIG += "libtorrent-rasterbar"
QT += network \ QT += network \
xml xml
DEFINES += QT_NO_CAST_TO_ASCII DEFINES += QT_NO_CAST_TO_ASCII
@ -98,7 +98,7 @@ DEFINES += QT_NO_CAST_TO_ASCII
# QT_NO_CAST_FROM_ASCII # QT_NO_CAST_FROM_ASCII
# Windows # Windows
# usually built as static # usually built as static
# win32:LIBS += -ltorrent -lcurl -lboost_system # win32:LIBS += -ltorrent -lboost_system
# win32:LIBS += -lz ? # win32:LIBS += -lz ?
win32:LIBS += -lssl32 \ win32:LIBS += -lssl32 \
-lws2_32 \ -lws2_32 \