mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-18 06:28:03 -06:00
Compare commits
1 Commits
release-1.
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22f0f20a45 |
2
INSTALL
2
INSTALL
@@ -25,7 +25,7 @@ Dependencies:
|
||||
|
||||
- libboost: libboost-filesystem, libboost-date-time, libboost-thread, libboost-serialization
|
||||
|
||||
- libcommoncpp2
|
||||
- libcurl
|
||||
|
||||
- python >= 2.3 (needed by search engine)
|
||||
|
||||
|
||||
10
TODO
10
TODO
@@ -50,14 +50,11 @@
|
||||
-> in download list
|
||||
-> in seeding list
|
||||
|
||||
// TODO v1.0.0
|
||||
- Fix libcommoncpp proxy support
|
||||
- Fix layout in preferences/Proxy
|
||||
|
||||
rc8->rc9 changelog:
|
||||
- FEATURE: Better media file preview (player detected automatically)
|
||||
- BUGFIX: Remember properties window size and position
|
||||
- BUGFIX: Added proxy support in search engine, RSS, downloads from urls
|
||||
- BUGFIX: Added HTTP and SOCKS5 proxy support in downloads from urls, RSS
|
||||
- BUGFIX: Added HTTP proxy support in search engine (no SOCKS yet)
|
||||
- BUGFIX: Do no pause torrents before saving fastresume data anymore (no longer needed)
|
||||
- BUGFIX: Save fast resume data regularly (every 60 seconds) to avoid downloading from scratch if qBittorrent crashes
|
||||
- BUGFIX: Do not save fastresume data for checking torrents anymore
|
||||
@@ -66,3 +63,6 @@ rc8->rc9 changelog:
|
||||
- BUGFIX: Fixed possible overflow in ETA calculation
|
||||
- BUGFIX: title bar is now reset when "Display speed in title" is disabled
|
||||
- BUGFIX: Fixed HTTP_PW and SOCKS5_PW in proxy combobox
|
||||
- BUGFIX: Fixed proxy auth disable problem when disabling proxy
|
||||
- BUGFIX: Fixed proxy layout in program preferences
|
||||
- BUGFIX: Fixed everlasting libtorrent session destruction on exit
|
||||
|
||||
58
configure
vendored
58
configure
vendored
@@ -22,8 +22,8 @@ Dependency options:
|
||||
--with-libtorrent-lib=[path] Path to libtorrent library files
|
||||
--with-libtorrent-static-lib=[path] Path to libtorrent .a file
|
||||
--with-libboost-inc=[path] Path to libboost include files
|
||||
--with-libcommoncpp2-inc=[path] Path to libcommoncpp2 include files
|
||||
--with-libcommoncpp2-lib=[path] Path to libcommoncpp2 library files
|
||||
--with-libcurl-inc=[path] Path to libcurl include files
|
||||
--with-libcurl-lib=[path] Path to libcurl library files
|
||||
--disable-libmagick Disable use of libmagick
|
||||
--with-libmagick-inc=[path] Path to libmagick++ include files
|
||||
--with-libmagick-lib=[path] Path to libmagick++ library files
|
||||
@@ -166,13 +166,13 @@ while [ $# -gt 0 ]; do
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libcommoncpp2-inc=*)
|
||||
QC_WITH_LIBCOMMONCPP2_INC=$optarg
|
||||
--with-libcurl-inc=*)
|
||||
QC_WITH_LIBCURL_INC=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
--with-libcommoncpp2-lib=*)
|
||||
QC_WITH_LIBCOMMONCPP2_LIB=$optarg
|
||||
--with-libcurl-lib=*)
|
||||
QC_WITH_LIBCURL_LIB=$optarg
|
||||
shift
|
||||
;;
|
||||
|
||||
@@ -231,8 +231,8 @@ echo QC_WITH_LIBTORRENT_INC=$QC_WITH_LIBTORRENT_INC
|
||||
echo QC_WITH_LIBTORRENT_LIB=$QC_WITH_LIBTORRENT_LIB
|
||||
echo QC_WITH_LIBTORRENT_STATIC_LIB=$QC_WITH_LIBTORRENT_STATIC_LIB
|
||||
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
||||
echo QC_WITH_LIBCOMMONCPP2_INC=$QC_WITH_LIBCOMMONCPP2_INC
|
||||
echo QC_WITH_LIBCOMMONCPP2_LIB=$QC_WITH_LIBCOMMONCPP2_LIB
|
||||
echo QC_WITH_LIBCURL_INC=$QC_WITH_LIBCURL_INC
|
||||
echo QC_WITH_LIBCURL_LIB=$QC_WITH_LIBCURL_LIB
|
||||
echo QC_DISABLE_libmagick=$QC_DISABLE_libmagick
|
||||
echo QC_WITH_LIBMAGICK_INC=$QC_WITH_LIBMAGICK_INC
|
||||
echo QC_WITH_LIBMAGICK_LIB=$QC_WITH_LIBMAGICK_LIB
|
||||
@@ -485,25 +485,25 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#line 1 "libcommoncpp2.qcm"
|
||||
#line 1 "libcurl.qcm"
|
||||
/*
|
||||
-----BEGIN QCMOD-----
|
||||
name: libcommoncpp2
|
||||
arg: with-libcommoncpp2-inc=[path], Path to libcommoncpp2 include files
|
||||
arg: with-libcommoncpp2-lib=[path], Path to libcommoncpp2 library files
|
||||
arg: with-libcurl-inc=[path], Path to libcurl include files
|
||||
arg: with-libcurl-lib=[path], Path to libcurl library files
|
||||
-----END QCMOD-----
|
||||
*/
|
||||
class qc_libcommoncpp2 : public ConfObj
|
||||
class qc_libcurl : public ConfObj
|
||||
{
|
||||
public:
|
||||
qc_libcommoncpp2(Conf *c) : ConfObj(c) {}
|
||||
QString name() const { return "GNU Common C++ library (libcommoncpp2)"; }
|
||||
QString shortname() const { return "libcommoncpp2"; }
|
||||
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_LIBCOMMONCPP2_INC");
|
||||
s = conf->getenv("QC_WITH_LIBCURL_INC");
|
||||
if(!s.isEmpty()) {
|
||||
if(!conf->checkHeader(s, "cc++/url.h")) {
|
||||
if(!conf->checkHeader(s, "curl/curl.h")) {
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
@@ -512,7 +512,7 @@ public:
|
||||
sl << "/usr/local/include";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(conf->checkHeader(s, "cc++/url.h")){
|
||||
if(conf->checkHeader(s, "curl/curl.h")){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@@ -523,12 +523,10 @@ public:
|
||||
}
|
||||
conf->addIncludePath(s);
|
||||
|
||||
s = conf->getenv("QC_WITH_LIBCOMMONCPP2_LIB");
|
||||
s = conf->getenv("QC_WITH_LIBCURL_LIB");
|
||||
if(!s.isEmpty()) {
|
||||
if(!QFile::exists(s+QString("/libccext2.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("/libccgnu2.so")))
|
||||
return false;
|
||||
if(!QFile::exists(s+QString("/libcurl.so")))
|
||||
return false;
|
||||
conf->addLib(QString("-L") + s);
|
||||
}else{
|
||||
QStringList sl;
|
||||
@@ -538,11 +536,9 @@ public:
|
||||
sl << "/usr/local/lib64/";
|
||||
bool found = false;
|
||||
foreach(s, sl){
|
||||
if(QFile::exists(s+QString("libccext2.so"))){
|
||||
if(QFile::exists(s+QString("libccgnu2.so"))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if(QFile::exists(s+QString("libcurl.so"))){
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!found) return false;
|
||||
@@ -715,7 +711,7 @@ cat >$1/modules_new.cpp <<EOT
|
||||
o = new qc_libboost(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libcommoncpp2(conf);
|
||||
o = new qc_libcurl(conf);
|
||||
o->required = true;
|
||||
o->disabled = false;
|
||||
o = new qc_libmagick(conf);
|
||||
@@ -1673,8 +1669,8 @@ export QC_WITH_LIBTORRENT_INC
|
||||
export QC_WITH_LIBTORRENT_LIB
|
||||
export QC_WITH_LIBTORRENT_STATIC_LIB
|
||||
export QC_WITH_LIBBOOST_INC
|
||||
export QC_WITH_LIBCOMMONCPP2_INC
|
||||
export QC_WITH_LIBCOMMONCPP2_LIB
|
||||
export QC_WITH_LIBCURL_INC
|
||||
export QC_WITH_LIBCURL_LIB
|
||||
export QC_DISABLE_libmagick
|
||||
export QC_WITH_LIBMAGICK_INC
|
||||
export QC_WITH_LIBMAGICK_LIB
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<dep type='libboost'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libcommoncpp2'>
|
||||
<dep type='libcurl'>
|
||||
<required/>
|
||||
</dep>
|
||||
<dep type='libmagick'/>
|
||||
|
||||
61
qcm/libcurl.qcm
Normal file
61
qcm/libcurl.qcm
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
-----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;
|
||||
}
|
||||
};
|
||||
@@ -43,7 +43,7 @@
|
||||
#define MAX_TRACKER_ERRORS 2
|
||||
|
||||
// Main constructor
|
||||
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1) {
|
||||
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false) {
|
||||
// To avoid some exceptions
|
||||
fs::path::default_name_check(fs::no_check);
|
||||
// Creating bittorrent session
|
||||
@@ -59,7 +59,7 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
|
||||
connect(ETARefresher, SIGNAL(timeout()), this, SLOT(updateETAs()));
|
||||
ETARefresher->start(ETA_REFRESH_INTERVAL);
|
||||
fastResumeSaver = new QTimer();
|
||||
connect(fastResumeSaver, SIGNAL(timeout()), this, SLOT(saveFastResumeAndRatioDataUnfinished()));
|
||||
connect(fastResumeSaver, SIGNAL(timeout()), this, SLOT(saveFastResumeAndRatioData()));
|
||||
fastResumeSaver->start(60000);
|
||||
// To download from urls
|
||||
downloader = new downloadThread(this);
|
||||
@@ -321,6 +321,8 @@ bool bittorrent::pauseTorrent(QString hash) {
|
||||
if(h.is_valid() && !h.is_paused()) {
|
||||
h.pause();
|
||||
change = true;
|
||||
// Save fast resume data
|
||||
saveFastResumeAndRatioData(hash);
|
||||
qDebug("Torrent paused successfully");
|
||||
}else{
|
||||
if(!h.is_valid()) {
|
||||
@@ -629,25 +631,49 @@ bool bittorrent::isDHTEnabled() const{
|
||||
|
||||
void bittorrent::enableUPnP(bool b) {
|
||||
if(b) {
|
||||
s->start_upnp();
|
||||
if(!UPnPEnabled) {
|
||||
qDebug("Enabling UPnP");
|
||||
s->start_upnp();
|
||||
UPnPEnabled = true;
|
||||
}
|
||||
} else {
|
||||
s->stop_upnp();
|
||||
if(UPnPEnabled) {
|
||||
qDebug("Disabling UPnP");
|
||||
s->stop_upnp();
|
||||
UPnPEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::enableNATPMP(bool b) {
|
||||
if(b) {
|
||||
s->start_natpmp();
|
||||
if(!NATPMPEnabled) {
|
||||
qDebug("Enabling NAT-PMP");
|
||||
s->start_natpmp();
|
||||
NATPMPEnabled = true;
|
||||
}
|
||||
} else {
|
||||
s->stop_natpmp();
|
||||
if(NATPMPEnabled) {
|
||||
qDebug("Disabling NAT-PMP");
|
||||
s->stop_natpmp();
|
||||
NATPMPEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bittorrent::enableLSD(bool b) {
|
||||
if(b) {
|
||||
s->start_lsd();
|
||||
if(!LSDEnabled) {
|
||||
qDebug("Enabling LSD");
|
||||
s->start_lsd();
|
||||
LSDEnabled = true;
|
||||
}
|
||||
} else {
|
||||
s->stop_lsd();
|
||||
if(LSDEnabled) {
|
||||
qDebug("Disabling LSD");
|
||||
s->stop_lsd();
|
||||
LSDEnabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -833,32 +859,23 @@ void bittorrent::saveDownloadUploadForTorrent(QString hash) {
|
||||
ratio_file.close();
|
||||
}
|
||||
|
||||
// Only save fast resume data for unfinished torrents (Optimization)
|
||||
void bittorrent::saveFastResumeAndRatioDataUnfinished() {
|
||||
// Only save fast resume data for unfinished and unpaused torrents (Optimization)
|
||||
// Called periodically and on exit
|
||||
void bittorrent::saveFastResumeAndRatioData() {
|
||||
QString hash;
|
||||
QStringList hashes = getUnfinishedTorrents();
|
||||
foreach(hash, hashes) {
|
||||
saveFastResumeAndRatioData(hash);
|
||||
}
|
||||
}
|
||||
|
||||
// Save fastresume data for all torrents (called periodically)
|
||||
void bittorrent::saveFastResumeAndRatioData() {
|
||||
qDebug("Saving fast resume and ratio data");
|
||||
std::vector<torrent_handle> handles = s->get_torrents();
|
||||
// It is not necessary to pause the torrents before saving fastresume data anymore
|
||||
// because we either use Full allocation or sparse mode.
|
||||
// Write fast resume data
|
||||
for(unsigned int i=0; i<handles.size(); ++i) {
|
||||
QTorrentHandle h = handles[i];
|
||||
QTorrentHandle h = getTorrentHandle(hash);
|
||||
if(!h.is_valid()) {
|
||||
qDebug("/!\\ Error: Invalid handle");
|
||||
continue;
|
||||
}
|
||||
QString hash = h.hash();
|
||||
if(h.is_paused()) {
|
||||
// Do not need to save fast resume data for paused torrents
|
||||
continue;
|
||||
}
|
||||
saveFastResumeAndRatioData(hash);
|
||||
}
|
||||
qDebug("Fast resume and ratio data saved");
|
||||
}
|
||||
|
||||
void bittorrent::saveFastResumeAndRatioData(QString hash) {
|
||||
|
||||
@@ -62,6 +62,9 @@ class bittorrent : public QObject{
|
||||
int maxConnecsPerTorrent;
|
||||
int maxUploadsPerTorrent;
|
||||
float max_ratio;
|
||||
bool UPnPEnabled;
|
||||
bool NATPMPEnabled;
|
||||
bool LSDEnabled;
|
||||
|
||||
protected:
|
||||
QString getSavePath(QString hash);
|
||||
@@ -99,7 +102,6 @@ class bittorrent : public QObject{
|
||||
void preAllocateAllFiles(bool b);
|
||||
void saveFastResumeAndRatioData();
|
||||
void saveFastResumeAndRatioData(QString hash);
|
||||
void saveFastResumeAndRatioDataUnfinished();
|
||||
void enableDirectoryScanning(QString scan_dir);
|
||||
void disableDirectoryScanning();
|
||||
void enablePeerExchange();
|
||||
|
||||
@@ -21,56 +21,48 @@
|
||||
|
||||
#include "downloadThread.h"
|
||||
#include <iostream>
|
||||
#include <cc++/common.h>
|
||||
#include <QSettings>
|
||||
#include <stdio.h>
|
||||
|
||||
QString subDownloadThread::errorCodeToString(int status) {
|
||||
// http://curl.rtin.bz/libcurl/c/libcurl-errors.html
|
||||
QString subDownloadThread::errorCodeToString(CURLcode status) {
|
||||
switch(status){
|
||||
case 1://ost::URLStream::errUnreachable:
|
||||
case CURLE_FTP_CANT_GET_HOST:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
return tr("Host is unreachable");
|
||||
case 2://ost::URLStream::errMissing:
|
||||
case CURLE_READ_ERROR:
|
||||
case CURLE_FILE_COULDNT_READ_FILE:
|
||||
return tr("File was not found (404)");
|
||||
case 3://ost::URLStream::errDenied:
|
||||
case CURLE_FTP_ACCESS_DENIED:
|
||||
case CURLE_LOGIN_DENIED:
|
||||
case CURLE_FTP_USER_PASSWORD_INCORRECT:
|
||||
return tr("Connection was denied");
|
||||
case 4://ost::URLStream::errInvalid:
|
||||
case CURLE_URL_MALFORMAT:
|
||||
return tr("Url is invalid");
|
||||
case 5://ost::URLStream::errForbidden:
|
||||
return tr("Connection forbidden (403)");
|
||||
case 6://ost::URLStream::errUnauthorized:
|
||||
return tr("Connection was not authorized (401)");
|
||||
case 7://ost::URLStream::errRelocated:
|
||||
return tr("Content has moved (301)");
|
||||
case 8://ost::URLStream::errFailure:
|
||||
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 9://ost::URLStream::errTimeout:
|
||||
case CURLE_OPERATION_TIMEOUTED:
|
||||
return tr("Connection was timed out");
|
||||
case 10://ost::URLStream::errInterface:
|
||||
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){
|
||||
url_stream = new ost::URLStream();
|
||||
// Proxy support
|
||||
QSettings settings("qBittorrent", "qBittorrent");
|
||||
int intValue = settings.value(QString::fromUtf8("Preferences/Connection/ProxyType"), 0).toInt();
|
||||
if(intValue > 0) {
|
||||
// Proxy enabled
|
||||
url_stream->setProxy(settings.value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString().toUtf8().data(), settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toInt());
|
||||
if(settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Authentication"), false).toBool()) {
|
||||
// Authentication required
|
||||
url_stream->setProxyUser(settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Username"), QString()).toString().toUtf8().data());
|
||||
url_stream->setProxyPassword(settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString().toUtf8().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
subDownloadThread::subDownloadThread(QObject *parent, QString url) : QThread(parent), url(url), abort(false){}
|
||||
|
||||
subDownloadThread::~subDownloadThread(){
|
||||
abort = true;
|
||||
wait();
|
||||
delete url_stream;
|
||||
}
|
||||
|
||||
void subDownloadThread::run(){
|
||||
@@ -81,38 +73,57 @@ void subDownloadThread::run(){
|
||||
filePath = tmpfile->fileName();
|
||||
}
|
||||
delete tmpfile;
|
||||
QFile dest_file(filePath);
|
||||
if(!dest_file.open(QIODevice::WriteOnly | QIODevice::Text)){
|
||||
std::cerr << "Error: could't create temporary file: " << (const char*)filePath.toUtf8() << '\n';
|
||||
FILE *f = fopen(filePath.toUtf8().data(), "w");
|
||||
if(!f) {
|
||||
std::cerr << "couldn't open destination file" << "\n";
|
||||
return;
|
||||
}
|
||||
ost::URLStream::Error status = url_stream->get((const char*)url.toUtf8());
|
||||
if(status){
|
||||
// Failure
|
||||
QString error_msg = errorCodeToString((int)status);
|
||||
qDebug("Download failed for %s, reason: %s", (const char*)url.toUtf8(), (const char*)error_msg.toUtf8());
|
||||
url_stream->close();
|
||||
emit downloadFailureST(this, url, error_msg);
|
||||
return;
|
||||
}
|
||||
qDebug("Downloading %s...", (const char*)url.toUtf8());
|
||||
char cbuf[1024];
|
||||
int len;
|
||||
while(!url_stream->eof()) {
|
||||
url_stream->read(cbuf, sizeof(cbuf));
|
||||
len = url_stream->gcount();
|
||||
if(len > 0)
|
||||
dest_file.write(cbuf, len);
|
||||
if(abort){
|
||||
dest_file.close();
|
||||
url_stream->close();
|
||||
return;
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
std::string c_url = url.toUtf8().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/ProxyType"), 0).toInt();
|
||||
if(intValue > 0) {
|
||||
// Proxy enabled
|
||||
QString IP = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/IP"), "0.0.0.0").toString();
|
||||
QString port = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Port"), 8080).toString();
|
||||
qDebug("Using proxy: %s", (IP+QString(":")+port).toUtf8().data());
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYPORT, (IP+QString(":")+port).toUtf8().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/Proxy/Username"), QString()).toString();
|
||||
QString password = settings.value(QString::fromUtf8("Preferences/Connection/Proxy/Password"), QString()).toString();
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, (username+QString(":")+password).toUtf8().data());
|
||||
}
|
||||
}
|
||||
// TODO: define CURLOPT_WRITEFUNCTION or it will crash on windows
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
|
||||
qDebug("Downloading %s", url.toUtf8().data());
|
||||
res = curl_easy_perform(curl);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
fclose(f);
|
||||
if(res) {
|
||||
emit downloadFailureST(this, url, errorCodeToString(res));
|
||||
} else {
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Could not initialize CURL" << "\n";
|
||||
}
|
||||
dest_file.close();
|
||||
url_stream->close();
|
||||
emit downloadFinishedST(this, url, filePath);
|
||||
qDebug("download completed here: %s", (const char*)filePath.toUtf8());
|
||||
}
|
||||
|
||||
/** Download Thread **/
|
||||
|
||||
@@ -29,29 +29,18 @@
|
||||
#include <QMutexLocker>
|
||||
#include <QWaitCondition>
|
||||
#include <QStringList>
|
||||
|
||||
namespace ost {
|
||||
class URLStream;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
QString IP;
|
||||
int port;
|
||||
QString username;
|
||||
QString password;
|
||||
} tmp_proxy;
|
||||
#include <curl/curl.h>
|
||||
|
||||
class subDownloadThread : public QThread {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QString url;
|
||||
ost::URLStream *url_stream;
|
||||
bool abort;
|
||||
|
||||
public:
|
||||
subDownloadThread(QObject *parent, QString url);
|
||||
~subDownloadThread();
|
||||
QString errorCodeToString(int status);
|
||||
QString errorCodeToString(CURLcode status);
|
||||
|
||||
signals:
|
||||
// For subthreads
|
||||
@@ -90,7 +79,6 @@ class downloadThread : public QThread {
|
||||
|
||||
protected slots:
|
||||
void propagateDownloadedFile(subDownloadThread* st, QString url, QString path);
|
||||
|
||||
void propagateDownloadFailure(subDownloadThread* st, QString url, QString reason);
|
||||
};
|
||||
|
||||
|
||||
@@ -190,7 +190,6 @@ void DownloadingTorrents::setInfoBar(QString info, QColor color) {
|
||||
infoBar->clear();
|
||||
nbLines = 1;
|
||||
}
|
||||
qDebug("Color is %s", color.name().toUtf8().data());
|
||||
infoBar->append(QString::fromUtf8("<font color='grey'>")+ QTime::currentTime().toString(QString::fromUtf8("hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + info + QString::fromUtf8("</i></font>"));
|
||||
}
|
||||
|
||||
|
||||
130
src/options.ui
130
src/options.ui
@@ -947,70 +947,72 @@
|
||||
<property name="title" >
|
||||
<string>Affected connections</string>
|
||||
</property>
|
||||
<widget class="QCheckBox" name="checkProxyTrackers" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>341</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to trackers</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="checkProxyPeers" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>40</y>
|
||||
<width>341</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to regular peers</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="checkProxyWebseeds" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>60</y>
|
||||
<width>341</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to web seeds</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="checkProxyDHT" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>80</y>
|
||||
<width>341</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for DHT messages</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" >
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkProxyTrackers" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to trackers</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkProxyPeers" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to regular peers</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkProxyDHT" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for DHT messages</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkProxyWebseeds" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Use proxy for connections to web seeds</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -871,6 +871,7 @@ void options_imp::enableProxy(int index){
|
||||
textProxyIP->setEnabled(false);
|
||||
lblProxyPort->setEnabled(false);
|
||||
spinProxyPort->setEnabled(false);
|
||||
checkProxyAuth->setChecked(false);
|
||||
checkProxyAuth->setEnabled(false);
|
||||
ProxyConnecsBox->setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ TARGET = qbittorrent
|
||||
CONFIG += qt thread x11 network
|
||||
|
||||
# Update this VERSION for each release
|
||||
DEFINES += VERSION=\\\"v1.0.0rc8\\\"
|
||||
DEFINES += VERSION=\\\"v1.0.0rc9\\\"
|
||||
DEFINES += VERSION_MAJOR=1
|
||||
DEFINES += VERSION_MINOR=0
|
||||
DEFINES += VERSION_BUGFIX=0
|
||||
@@ -81,7 +81,7 @@ QMAKE_CXXFLAGS_RELEASE += -fwrapv -O2
|
||||
QMAKE_CXXFLAGS_DEBUG += -fwrapv -O1
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG += libtorrent libccext2 libccgnu2
|
||||
PKGCONFIG += "libtorrent libcurl"
|
||||
|
||||
!contains(DEFINES, HAVE_MAGICK){
|
||||
message(ImageMagick disabled)
|
||||
|
||||
Reference in New Issue
Block a user