mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-14 01:03:08 -07:00
- Merged headless branch
This commit is contained in:
commit
cbe4bbac6a
16 changed files with 466 additions and 114 deletions
1
AUTHORS
1
AUTHORS
|
@ -6,6 +6,7 @@ Contributors:
|
||||||
* Ishan Arora <ishan@qbittorrent.org>
|
* Ishan Arora <ishan@qbittorrent.org>
|
||||||
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
* Arnaud Demaizière <arnaud@qbittorrent.org>
|
||||||
* Grigis Gaëtan <cipher16@gmail.com>
|
* Grigis Gaëtan <cipher16@gmail.com>
|
||||||
|
* Frédéric Lassabe <frederic.lassabe@utbm.fr>
|
||||||
|
|
||||||
Code from other projects:
|
Code from other projects:
|
||||||
* files src/ico.cpp src/ico.h
|
* files src/ico.cpp src/ico.h
|
||||||
|
|
21
configure
vendored
21
configure
vendored
|
@ -18,6 +18,8 @@ Main options:
|
||||||
--help This help text.
|
--help This help text.
|
||||||
|
|
||||||
Dependency options:
|
Dependency options:
|
||||||
|
--disable-gui Disable qBittorrent Graphical user
|
||||||
|
interface for headless running
|
||||||
--with-libboost-inc=[path] Path to libboost include files
|
--with-libboost-inc=[path] Path to libboost include files
|
||||||
--disable-libnotify Disable use of libnotify
|
--disable-libnotify Disable use of libnotify
|
||||||
--disable-geoip-database Disable use of geoip-database
|
--disable-geoip-database Disable use of geoip-database
|
||||||
|
@ -140,6 +142,11 @@ while [ $# -gt 0 ]; do
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
--disable-gui)
|
||||||
|
QC_DISABLE_GUI="Y"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
--with-libboost-inc=*)
|
--with-libboost-inc=*)
|
||||||
QC_WITH_LIBBOOST_INC=$optarg
|
QC_WITH_LIBBOOST_INC=$optarg
|
||||||
shift
|
shift
|
||||||
|
@ -181,6 +188,7 @@ echo PREFIX=$PREFIX
|
||||||
echo BINDIR=$BINDIR
|
echo BINDIR=$BINDIR
|
||||||
echo DATADIR=$DATADIR
|
echo DATADIR=$DATADIR
|
||||||
echo EX_QTDIR=$EX_QTDIR
|
echo EX_QTDIR=$EX_QTDIR
|
||||||
|
echo QC_DISABLE_GUI=$QC_DISABLE_GUI
|
||||||
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
echo QC_WITH_LIBBOOST_INC=$QC_WITH_LIBBOOST_INC
|
||||||
echo QC_DISABLE_libnotify=$QC_DISABLE_libnotify
|
echo QC_DISABLE_libnotify=$QC_DISABLE_libnotify
|
||||||
echo QC_DISABLE_geoip_database=$QC_DISABLE_geoip_database
|
echo QC_DISABLE_geoip_database=$QC_DISABLE_geoip_database
|
||||||
|
@ -290,6 +298,7 @@ cat >$1/modules.cpp <<EOT
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: Qt >= 4.4
|
name: Qt >= 4.4
|
||||||
|
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_qt4 : public ConfObj
|
class qc_qt4 : public ConfObj
|
||||||
|
@ -300,6 +309,9 @@ public:
|
||||||
QString shortname() const { return "Qt 4.4"; }
|
QString shortname() const { return "Qt 4.4"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
conf->addDefine("DISABLE_GUI");
|
||||||
|
}
|
||||||
if(QT_VERSION >= 0x040500) {
|
if(QT_VERSION >= 0x040500) {
|
||||||
conf->addDefine("QT_4_5");
|
conf->addDefine("QT_4_5");
|
||||||
}
|
}
|
||||||
|
@ -410,6 +422,10 @@ public:
|
||||||
QString name() const { return "libnotify >= 0.4.2 (optional)"; }
|
QString name() const { return "libnotify >= 0.4.2 (optional)"; }
|
||||||
QString shortname() const { return "libnotify"; }
|
QString shortname() const { return "libnotify"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
printf("\nNot Required");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
QStringList incs;
|
QStringList incs;
|
||||||
QString req_ver = "0.4.2";
|
QString req_ver = "0.4.2";
|
||||||
QString version, libs, other;
|
QString version, libs, other;
|
||||||
|
@ -453,6 +469,10 @@ public:
|
||||||
QString name() const { return "GeoIP Database (optional)"; }
|
QString name() const { return "GeoIP Database (optional)"; }
|
||||||
QString shortname() const { return "GeoIP Database"; }
|
QString shortname() const { return "GeoIP Database"; }
|
||||||
bool exec() {
|
bool exec() {
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
printf("\nNot Required");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
||||||
#endif
|
#endif
|
||||||
|
@ -1431,6 +1451,7 @@ export PREFIX
|
||||||
export BINDIR
|
export BINDIR
|
||||||
export DATADIR
|
export DATADIR
|
||||||
export EX_QTDIR
|
export EX_QTDIR
|
||||||
|
export QC_DISABLE_GUI
|
||||||
export QC_WITH_LIBBOOST_INC
|
export QC_WITH_LIBBOOST_INC
|
||||||
export QC_DISABLE_libnotify
|
export QC_DISABLE_libnotify
|
||||||
export QC_DISABLE_geoip_database
|
export QC_DISABLE_geoip_database
|
||||||
|
|
|
@ -12,6 +12,10 @@ public:
|
||||||
QString name() const { return "GeoIP Database (optional)"; }
|
QString name() const { return "GeoIP Database (optional)"; }
|
||||||
QString shortname() const { return "GeoIP Database"; }
|
QString shortname() const { return "GeoIP Database"; }
|
||||||
bool exec() {
|
bool exec() {
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
printf("\nNot Required");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
if(!conf->getenv("QC_WITH_GEOIP_DATABASE_EMBEDDED").isEmpty()) {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,10 @@ public:
|
||||||
QString name() const { return "libnotify >= 0.4.2 (optional)"; }
|
QString name() const { return "libnotify >= 0.4.2 (optional)"; }
|
||||||
QString shortname() const { return "libnotify"; }
|
QString shortname() const { return "libnotify"; }
|
||||||
bool exec(){
|
bool exec(){
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
printf("\nNot Required");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
QStringList incs;
|
QStringList incs;
|
||||||
QString req_ver = "0.4.2";
|
QString req_ver = "0.4.2";
|
||||||
QString version, libs, other;
|
QString version, libs, other;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
-----BEGIN QCMOD-----
|
-----BEGIN QCMOD-----
|
||||||
name: Qt >= 4.4
|
name: Qt >= 4.4
|
||||||
|
arg: disable-gui, Disable qBittorrent Graphical user interface for headless running
|
||||||
-----END QCMOD-----
|
-----END QCMOD-----
|
||||||
*/
|
*/
|
||||||
class qc_qt4 : public ConfObj
|
class qc_qt4 : public ConfObj
|
||||||
|
@ -11,6 +12,9 @@ public:
|
||||||
QString shortname() const { return "Qt 4.4"; }
|
QString shortname() const { return "Qt 4.4"; }
|
||||||
bool exec()
|
bool exec()
|
||||||
{
|
{
|
||||||
|
if(!conf->getenv("QC_DISABLE_GUI").isEmpty()) {
|
||||||
|
conf->addDefine("DISABLE_GUI");
|
||||||
|
}
|
||||||
if(QT_VERSION >= 0x040500) {
|
if(QT_VERSION >= 0x040500) {
|
||||||
conf->addDefine("QT_4_5");
|
conf->addDefine("QT_4_5");
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,9 @@
|
||||||
#include "downloadthread.h"
|
#include "downloadthread.h"
|
||||||
#include "filterparserthread.h"
|
#include "filterparserthread.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "geoip.h"
|
#ifndef DISABLE_GUI
|
||||||
|
#include "geoip.h"
|
||||||
|
#endif
|
||||||
#include "torrentpersistentdata.h"
|
#include "torrentpersistentdata.h"
|
||||||
#include "httpserver.h"
|
#include "httpserver.h"
|
||||||
#include <libtorrent/extensions/ut_metadata.hpp>
|
#include <libtorrent/extensions/ut_metadata.hpp>
|
||||||
|
@ -65,8 +67,11 @@ enum ProxyType {HTTP=1, SOCKS5=2, HTTP_PW=3, SOCKS5_PW=4, SOCKS4=5};
|
||||||
enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL };
|
enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL };
|
||||||
|
|
||||||
// Main constructor
|
// Main constructor
|
||||||
Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), DHTEnabled(false), current_dht_port(0), queueingEnabled(false), geoipDBLoaded(false), exiting(false) {
|
Bittorrent::Bittorrent() : preAllocateAll(false), addInPause(false), ratio_limit(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), DHTEnabled(false), current_dht_port(0), queueingEnabled(false), exiting(false) {
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
|
geoipDBLoaded = false;
|
||||||
resolve_countries = false;
|
resolve_countries = false;
|
||||||
|
#endif
|
||||||
// To avoid some exceptions
|
// To avoid some exceptions
|
||||||
fs::path::default_name_check(fs::no_check);
|
fs::path::default_name_check(fs::no_check);
|
||||||
// For backward compatibility
|
// For backward compatibility
|
||||||
|
@ -299,6 +304,7 @@ void Bittorrent::configureSession() {
|
||||||
// Enabled
|
// Enabled
|
||||||
setUploadRateLimit(up_limit*1024);
|
setUploadRateLimit(up_limit*1024);
|
||||||
}
|
}
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
// Resolve countries
|
// Resolve countries
|
||||||
qDebug("Loading country resolution settings");
|
qDebug("Loading country resolution settings");
|
||||||
bool new_resolv_countries = Preferences::resolvePeerCountries();
|
bool new_resolv_countries = Preferences::resolvePeerCountries();
|
||||||
|
@ -319,6 +325,7 @@ void Bittorrent::configureSession() {
|
||||||
h.resolve_countries(resolve_countries);
|
h.resolve_countries(resolve_countries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// * UPnP
|
// * UPnP
|
||||||
if(Preferences::isUPnPEnabled()) {
|
if(Preferences::isUPnPEnabled()) {
|
||||||
enableUPnP(true);
|
enableUPnP(true);
|
||||||
|
@ -553,7 +560,7 @@ bool Bittorrent::initWebUi(QString username, QString password, int port) {
|
||||||
if (success)
|
if (success)
|
||||||
addConsoleMessage(tr("The Web UI is listening on port %1").arg(port));
|
addConsoleMessage(tr("The Web UI is listening on port %1").arg(port));
|
||||||
else
|
else
|
||||||
addConsoleMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), QColor("red"));
|
addConsoleMessage(tr("Web User Interface Error - Unable to bind Web UI to port %1").arg(port), "red");
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -788,8 +795,10 @@ QTorrentHandle Bittorrent::addMagnetUri(QString magnet_uri, bool resumed) {
|
||||||
h.set_max_connections(Preferences::getMaxConnecsPerTorrent());
|
h.set_max_connections(Preferences::getMaxConnecsPerTorrent());
|
||||||
// Uploads limit per torrent
|
// Uploads limit per torrent
|
||||||
h.set_max_uploads(Preferences::getMaxUploadsPerTorrent());
|
h.set_max_uploads(Preferences::getMaxUploadsPerTorrent());
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
// Resolve countries
|
// Resolve countries
|
||||||
h.resolve_countries(resolve_countries);
|
h.resolve_countries(resolve_countries);
|
||||||
|
#endif
|
||||||
// Load filtered files
|
// Load filtered files
|
||||||
if(!resumed) {
|
if(!resumed) {
|
||||||
// Sequential download
|
// Sequential download
|
||||||
|
@ -955,9 +964,11 @@ QTorrentHandle Bittorrent::addTorrent(QString path, bool fromScanDir, QString fr
|
||||||
h.set_max_connections(Preferences::getMaxConnecsPerTorrent());
|
h.set_max_connections(Preferences::getMaxConnecsPerTorrent());
|
||||||
// Uploads limit per torrent
|
// Uploads limit per torrent
|
||||||
h.set_max_uploads(Preferences::getMaxUploadsPerTorrent());
|
h.set_max_uploads(Preferences::getMaxUploadsPerTorrent());
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
// Resolve countries
|
// Resolve countries
|
||||||
qDebug("AddTorrent: Resolve_countries: %d", (int)resolve_countries);
|
qDebug("AddTorrent: Resolve_countries: %d", (int)resolve_countries);
|
||||||
h.resolve_countries(resolve_countries);
|
h.resolve_countries(resolve_countries);
|
||||||
|
#endif
|
||||||
if(!resumed) {
|
if(!resumed) {
|
||||||
// Sequential download
|
// Sequential download
|
||||||
if(TorrentTempData::hasTempData(hash)) {
|
if(TorrentTempData::hasTempData(hash)) {
|
||||||
|
@ -1254,11 +1265,16 @@ QStringList Bittorrent::getPeerBanMessages() const {
|
||||||
return peerBanMessages;
|
return peerBanMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DISABLE_GUI
|
||||||
|
void Bittorrent::addConsoleMessage(QString msg, QString) {
|
||||||
|
#else
|
||||||
void Bittorrent::addConsoleMessage(QString msg, QColor color) {
|
void Bittorrent::addConsoleMessage(QString msg, QColor color) {
|
||||||
if(consoleMessages.size() > 100) {
|
if(consoleMessages.size() > 100) {
|
||||||
consoleMessages.removeFirst();
|
consoleMessages.removeFirst();
|
||||||
}
|
}
|
||||||
consoleMessages.append(QString::fromUtf8("<font color='grey'>")+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + msg + QString::fromUtf8("</i></font>"));
|
consoleMessages.append(QString::fromUtf8("<font color='grey'>")+ QDateTime::currentDateTime().toString(QString::fromUtf8("dd/MM/yyyy hh:mm:ss")) + QString::fromUtf8("</font> - <font color='") + color.name() +QString::fromUtf8("'><i>") + msg + QString::fromUtf8("</i></font>"));
|
||||||
|
#endif
|
||||||
|
emit newConsoleMessage(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss") + " - " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bittorrent::addPeerBanMessage(QString ip, bool from_ipfilter) {
|
void Bittorrent::addPeerBanMessage(QString ip, bool from_ipfilter) {
|
||||||
|
@ -1782,12 +1798,12 @@ void Bittorrent::readAlerts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
|
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
|
||||||
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(QString(p->message().c_str())), QColor("red"));
|
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(QString(p->message().c_str())), "red");
|
||||||
//emit UPnPError(QString(p->msg().c_str()));
|
//emit UPnPError(QString(p->msg().c_str()));
|
||||||
}
|
}
|
||||||
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
|
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
|
||||||
qDebug("UPnP Success, msg: %s", p->message().c_str());
|
qDebug("UPnP Success, msg: %s", p->message().c_str());
|
||||||
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(QString(p->message().c_str())), QColor("blue"));
|
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(QString(p->message().c_str())), "blue");
|
||||||
//emit UPnPSuccess(QString(p->msg().c_str()));
|
//emit UPnPSuccess(QString(p->msg().c_str()));
|
||||||
}
|
}
|
||||||
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
|
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
|
||||||
|
@ -1895,7 +1911,11 @@ QString Bittorrent::getSavePath(QString hash) {
|
||||||
// download the torrent file to a tmp location, then
|
// download the torrent file to a tmp location, then
|
||||||
// add it to download list
|
// add it to download list
|
||||||
void Bittorrent::downloadFromUrl(QString url) {
|
void Bittorrent::downloadFromUrl(QString url) {
|
||||||
addConsoleMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url), QPalette::WindowText);
|
addConsoleMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(url)
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
|
, QPalette::WindowText
|
||||||
|
#endif
|
||||||
|
);
|
||||||
//emit aboutToDownloadFromUrl(url);
|
//emit aboutToDownloadFromUrl(url);
|
||||||
// Launch downloader thread
|
// Launch downloader thread
|
||||||
downloader->downloadUrl(url);
|
downloader->downloadUrl(url);
|
||||||
|
|
|
@ -34,8 +34,12 @@
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QApplication>
|
#ifdef DISABLE_GUI
|
||||||
#include <QPalette>
|
#include <QCoreApplication>
|
||||||
|
#else
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPalette>
|
||||||
|
#endif
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
#include <libtorrent/session.hpp>
|
#include <libtorrent/session.hpp>
|
||||||
|
@ -117,8 +121,10 @@ private:
|
||||||
QString defaultSavePath;
|
QString defaultSavePath;
|
||||||
QString defaultTempPath;
|
QString defaultTempPath;
|
||||||
// GeoIP
|
// GeoIP
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
bool resolve_countries;
|
bool resolve_countries;
|
||||||
bool geoipDBLoaded;
|
bool geoipDBLoaded;
|
||||||
|
#endif
|
||||||
// ETA Computation
|
// ETA Computation
|
||||||
QPointer<QTimer> timerETA;
|
QPointer<QTimer> timerETA;
|
||||||
QHash<QString, QList<int> > ETA_samples;
|
QHash<QString, QList<int> > ETA_samples;
|
||||||
|
@ -219,7 +225,11 @@ public slots:
|
||||||
void enableNATPMP(bool b);
|
void enableNATPMP(bool b);
|
||||||
void enableLSD(bool b);
|
void enableLSD(bool b);
|
||||||
bool enableDHT(bool b);
|
bool enableDHT(bool b);
|
||||||
|
#ifdef DISABLE_GUI
|
||||||
|
void addConsoleMessage(QString msg, QString color=QString::null);
|
||||||
|
#else
|
||||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||||
|
#endif
|
||||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||||
void processDownloadedFile(QString, QString);
|
void processDownloadedFile(QString, QString);
|
||||||
void addMagnetSkipAddDlg(QString uri);
|
void addMagnetSkipAddDlg(QString uri);
|
||||||
|
@ -248,6 +258,7 @@ signals:
|
||||||
void torrentFinishedChecking(QTorrentHandle& h);
|
void torrentFinishedChecking(QTorrentHandle& h);
|
||||||
void metadataReceived(QTorrentHandle &h);
|
void metadataReceived(QTorrentHandle &h);
|
||||||
void savePathChanged(QTorrentHandle &h);
|
void savePathChanged(QTorrentHandle &h);
|
||||||
|
void newConsoleMessage(QString msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "bittorrent.h"
|
#include "bittorrent.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "proplistdelegate.h"
|
//#include "proplistdelegate.h"
|
||||||
#include "torrentpersistentdata.h"
|
#include "torrentpersistentdata.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QMessageBox>
|
#include <QRegExp>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#include <libtorrent/session.hpp>
|
#include <libtorrent/session.hpp>
|
||||||
#include <libtorrent/ip_filter.hpp>
|
#include <libtorrent/ip_filter.hpp>
|
||||||
|
@ -103,7 +104,7 @@ class FilterParserThread : public QThread {
|
||||||
QFile file(filePath);
|
QFile file(filePath);
|
||||||
if (file.exists()){
|
if (file.exists()){
|
||||||
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned int nbLine = 0;
|
unsigned int nbLine = 0;
|
||||||
|
@ -224,7 +225,7 @@ class FilterParserThread : public QThread {
|
||||||
QStringList IP;
|
QStringList IP;
|
||||||
if (file.exists()){
|
if (file.exists()){
|
||||||
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned int nbLine = 0;
|
unsigned int nbLine = 0;
|
||||||
|
@ -292,7 +293,7 @@ class FilterParserThread : public QThread {
|
||||||
QFile file(filePath);
|
QFile file(filePath);
|
||||||
if (file.exists()){
|
if (file.exists()){
|
||||||
if(!file.open(QIODevice::ReadOnly)){
|
if(!file.open(QIODevice::ReadOnly)){
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("Couldn't open %1 in read mode.").arg(filePath));
|
std::cerr << "I/O Error: Could not open ip filer file in read mode." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QDataStream stream(&file);
|
QDataStream stream(&file);
|
||||||
|
@ -304,7 +305,7 @@ class FilterParserThread : public QThread {
|
||||||
memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) ||
|
memcmp(buf, "\xFF\xFF\xFF\xFFP2B", 7) ||
|
||||||
!stream.readRawData((char*)&version, sizeof(version))
|
!stream.readRawData((char*)&version, sizeof(version))
|
||||||
) {
|
) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +319,7 @@ class FilterParserThread : public QThread {
|
||||||
!stream.readRawData((char*)&start, sizeof(start)) ||
|
!stream.readRawData((char*)&start, sizeof(start)) ||
|
||||||
!stream.readRawData((char*)&end, sizeof(end))
|
!stream.readRawData((char*)&end, sizeof(end))
|
||||||
) {
|
) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Network byte order to Host byte order
|
// Network byte order to Host byte order
|
||||||
|
@ -334,7 +335,7 @@ class FilterParserThread : public QThread {
|
||||||
qDebug ("p2b version 3");
|
qDebug ("p2b version 3");
|
||||||
unsigned int namecount;
|
unsigned int namecount;
|
||||||
if(!stream.readRawData((char*)&namecount, sizeof(namecount))) {
|
if(!stream.readRawData((char*)&namecount, sizeof(namecount))) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
namecount=ntohl(namecount);
|
namecount=ntohl(namecount);
|
||||||
|
@ -342,7 +343,7 @@ class FilterParserThread : public QThread {
|
||||||
for(unsigned int i=0; i<namecount; i++) {
|
for(unsigned int i=0; i<namecount; i++) {
|
||||||
string name;
|
string name;
|
||||||
if(!getlineInStream(stream, name, '\0')) {
|
if(!getlineInStream(stream, name, '\0')) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(abort) return;
|
if(abort) return;
|
||||||
|
@ -350,7 +351,7 @@ class FilterParserThread : public QThread {
|
||||||
// Reading the ranges
|
// Reading the ranges
|
||||||
unsigned int rangecount;
|
unsigned int rangecount;
|
||||||
if(!stream.readRawData((char*)&rangecount, sizeof(rangecount))) {
|
if(!stream.readRawData((char*)&rangecount, sizeof(rangecount))) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rangecount=ntohl(rangecount);
|
rangecount=ntohl(rangecount);
|
||||||
|
@ -363,7 +364,7 @@ class FilterParserThread : public QThread {
|
||||||
!stream.readRawData((char*)&start, sizeof(start)) ||
|
!stream.readRawData((char*)&start, sizeof(start)) ||
|
||||||
!stream.readRawData((char*)&end, sizeof(end))
|
!stream.readRawData((char*)&end, sizeof(end))
|
||||||
) {
|
) {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Network byte order to Host byte order
|
// Network byte order to Host byte order
|
||||||
|
@ -376,7 +377,7 @@ class FilterParserThread : public QThread {
|
||||||
if(abort) return;
|
if(abort) return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(0, tr("I/O Error", "Input/Output Error"), tr("%1 is not a valid PeerGuardian P2B file.").arg(filePath));
|
std::cerr << "Parsing Error: The filter file is not a valid PeerGuardian P2B file." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
|
|
138
src/headlessloader.h
Normal file
138
src/headlessloader.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
/*
|
||||||
|
* Bittorrent Client using Qt4 and libtorrent.
|
||||||
|
* Copyright (C) 2006 Christophe Dumez, Frédéric Lassabe
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADLESSLOADER_H
|
||||||
|
#define HEADLESSLOADER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include "preferences.h"
|
||||||
|
#include "bittorrent.h"
|
||||||
|
|
||||||
|
class HeadlessLoader: QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLocalServer *localServer;
|
||||||
|
Bittorrent *BTSession;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HeadlessLoader(QStringList torrentCmdLine) {
|
||||||
|
// Enable Web UI
|
||||||
|
Preferences::setWebUiEnabled(true);
|
||||||
|
// Instanciate Bittorrent Object
|
||||||
|
BTSession = new Bittorrent();
|
||||||
|
connect(BTSession, SIGNAL(newConsoleMessage(QString)), this, SLOT(displayConsoleMessage(QString)));
|
||||||
|
// Resume unfinished torrents
|
||||||
|
BTSession->startUpTorrents();
|
||||||
|
// Process command line parameters
|
||||||
|
processParams(torrentCmdLine);
|
||||||
|
// Use a tcp server to allow only one instance of qBittorrent
|
||||||
|
localServer = new QLocalServer();
|
||||||
|
QString uid = QString::number(getuid());
|
||||||
|
#ifdef Q_WS_X11
|
||||||
|
if(QFile::exists(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid)) {
|
||||||
|
// Socket was not closed cleanly
|
||||||
|
std::cerr << "Warning: Local domain socket was not closed cleanly, deleting file...\n";
|
||||||
|
QFile::remove(QDir::tempPath()+QDir::separator()+QString("qBittorrent-")+uid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!localServer->listen("qBittorrent-"+uid)) {
|
||||||
|
std::cerr << "Couldn't create socket, single instance mode won't work...\n";
|
||||||
|
}
|
||||||
|
connect(localServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||||
|
// Display some information to the user
|
||||||
|
std::cout << std::endl << "******** " << tr("Information").toStdString() << " ********" << std::endl;
|
||||||
|
std::cout << tr("To control qBittorrent, access the Web UI at http://localhost:%1").arg(QString::number(Preferences::getWebUiPort())).toStdString() << std::endl;
|
||||||
|
std::cout << tr("The Web UI administrator user name is: %1").arg(Preferences::getWebUiUsername()).toStdString() << std::endl;
|
||||||
|
if(Preferences::getWebUiPassword() == "f6fdffe48c908deb0f4c3bd36c032e72") {
|
||||||
|
std::cout << tr("The Web UI administrator password is still the default one: %1").arg("adminadmin").toStdString() << std::endl;
|
||||||
|
std::cout << tr("This is a security risk, please consider changing your password from program preferences").toStdString() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~HeadlessLoader() {
|
||||||
|
delete BTSession;
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
// Call this function to exit qBittorrent headless loader
|
||||||
|
// and return to prompt (object will be deleted by main)
|
||||||
|
void exit() {
|
||||||
|
qApp->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayConsoleMessage(QString msg) {
|
||||||
|
std::cout << msg.toLocal8Bit().data() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// As program parameters, we can get paths or urls.
|
||||||
|
// This function parse the parameters and call
|
||||||
|
// the right addTorrent function, considering
|
||||||
|
// the parameter type.
|
||||||
|
void processParams(const QStringList& params) {
|
||||||
|
foreach(QString param, params) {
|
||||||
|
param = param.trimmed();
|
||||||
|
if(param.startsWith("--")) continue;
|
||||||
|
if(param.startsWith(QString::fromUtf8("http://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("ftp://"), Qt::CaseInsensitive) || param.startsWith(QString::fromUtf8("https://"), Qt::CaseInsensitive)) {
|
||||||
|
BTSession->downloadFromUrl(param);
|
||||||
|
}else{
|
||||||
|
if(param.startsWith("magnet:", Qt::CaseInsensitive)) {
|
||||||
|
BTSession->addMagnetUri(param);
|
||||||
|
} else {
|
||||||
|
BTSession->addTorrent(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void acceptConnection() {
|
||||||
|
QLocalSocket *clientConnection = localServer->nextPendingConnection();
|
||||||
|
connect(clientConnection, SIGNAL(disconnected()), this, SLOT(readParamsOnSocket()));
|
||||||
|
qDebug("accepted connection from another instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
void readParamsOnSocket() {
|
||||||
|
QLocalSocket *clientConnection = static_cast<QLocalSocket*>(sender());
|
||||||
|
if(clientConnection) {
|
||||||
|
QByteArray params = clientConnection->readAll();
|
||||||
|
if(!params.isEmpty()) {
|
||||||
|
processParams(QString::fromUtf8(params.data()).split(QString::fromUtf8("\n")));
|
||||||
|
qDebug("Received parameters from another instance");
|
||||||
|
}
|
||||||
|
clientConnection->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
73
src/main.cpp
73
src/main.cpp
|
@ -28,25 +28,34 @@
|
||||||
* Contact : chris@qbittorrent.org
|
* Contact : chris@qbittorrent.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QSplashScreen>
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QSplashScreen>
|
||||||
|
#include <QPlastiqueStyle>
|
||||||
|
#include "qgnomelook.h"
|
||||||
|
#include <QMotifStyle>
|
||||||
|
#include <QCDEStyle>
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
#include <QWindowsXPStyle>
|
||||||
|
#endif
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
#include <QMacStyle>
|
||||||
|
#endif
|
||||||
|
#include "GUI.h"
|
||||||
|
#include "ico.h"
|
||||||
|
#else
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include "headlessloader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <QPlastiqueStyle>
|
|
||||||
#include "qgnomelook.h"
|
|
||||||
#include <QMotifStyle>
|
|
||||||
#include <QCDEStyle>
|
|
||||||
#ifdef Q_WS_WIN
|
|
||||||
#include <QWindowsXPStyle>
|
|
||||||
#endif
|
|
||||||
#ifdef Q_WS_MAC
|
|
||||||
#include <QMacStyle>
|
|
||||||
#endif
|
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
@ -54,12 +63,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "GUI.h"
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "ico.h"
|
|
||||||
|
|
||||||
QApplication *app;
|
#ifdef DISABLE_GUI
|
||||||
|
QCoreApplication *app;
|
||||||
|
#else
|
||||||
|
QApplication *app;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
void sigtermHandler(int) {
|
void sigtermHandler(int) {
|
||||||
|
@ -82,6 +93,7 @@ void sigabrtHandler(int) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
void useStyle(QApplication *app, int style){
|
void useStyle(QApplication *app, int style){
|
||||||
switch(style) {
|
switch(style) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -114,13 +126,16 @@ void useStyle(QApplication *app, int style){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
QFile file;
|
QFile file;
|
||||||
QString locale;
|
QString locale;
|
||||||
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
QSettings settings(QString::fromUtf8("qBittorrent"), QString::fromUtf8("qBittorrent"));
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
bool no_splash = false;
|
bool no_splash = false;
|
||||||
|
#endif
|
||||||
if(argc > 1){
|
if(argc > 1){
|
||||||
if(QString::fromUtf8(argv[1]) == QString::fromUtf8("--version")){
|
if(QString::fromUtf8(argv[1]) == QString::fromUtf8("--version")){
|
||||||
std::cout << "qBittorrent " << VERSION << '\n';
|
std::cout << "qBittorrent " << VERSION << '\n';
|
||||||
|
@ -129,16 +144,21 @@ int main(int argc, char *argv[]){
|
||||||
if(QString::fromUtf8(argv[1]) == QString::fromUtf8("--help")){
|
if(QString::fromUtf8(argv[1]) == QString::fromUtf8("--help")){
|
||||||
std::cout << "Usage: \n";
|
std::cout << "Usage: \n";
|
||||||
std::cout << '\t' << argv[0] << " --version : displays program version\n";
|
std::cout << '\t' << argv[0] << " --version : displays program version\n";
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
std::cout << '\t' << argv[0] << " --no-splash : disable splash screen\n";
|
std::cout << '\t' << argv[0] << " --no-splash : disable splash screen\n";
|
||||||
|
#endif
|
||||||
std::cout << '\t' << argv[0] << " --help : displays this help message\n";
|
std::cout << '\t' << argv[0] << " --help : displays this help message\n";
|
||||||
std::cout << '\t' << argv[0] << " --webui-port=x : changes the webui port (default: 8080)\n";
|
std::cout << '\t' << argv[0] << " --webui-port=x : changes the webui port (default: 8080)\n";
|
||||||
std::cout << '\t' << argv[0] << " [files or urls] : starts program and download given parameters (optional)\n";
|
std::cout << '\t' << argv[0] << " [files or urls] : starts program and download given parameters (optional)\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=1; i<argc; ++i) {
|
for(int i=1; i<argc; ++i) {
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
if(QString::fromUtf8(argv[i]) == QString::fromUtf8("--no-splash")) {
|
if(QString::fromUtf8(argv[i]) == QString::fromUtf8("--no-splash")) {
|
||||||
no_splash = true;
|
no_splash = true;
|
||||||
} else {
|
} else {
|
||||||
|
#endif
|
||||||
if(QString::fromUtf8(argv[i]).startsWith("--webui-port=")) {
|
if(QString::fromUtf8(argv[i]).startsWith("--webui-port=")) {
|
||||||
QStringList parts = QString::fromUtf8(argv[i]).split("=");
|
QStringList parts = QString::fromUtf8(argv[i]).split("=");
|
||||||
if(parts.size() == 2) {
|
if(parts.size() == 2) {
|
||||||
|
@ -149,12 +169,17 @@ int main(int argc, char *argv[]){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
if(settings.value(QString::fromUtf8("Preferences/General/NoSplashScreen"), false).toBool()) {
|
if(settings.value(QString::fromUtf8("Preferences/General/NoSplashScreen"), false).toBool()) {
|
||||||
no_splash = true;
|
no_splash = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Set environment variable
|
// Set environment variable
|
||||||
if(putenv((char*)"QBITTORRENT="VERSION)) {
|
if(putenv((char*)"QBITTORRENT="VERSION)) {
|
||||||
std::cerr << "Couldn't set environment variable...\n";
|
std::cerr << "Couldn't set environment variable...\n";
|
||||||
|
@ -187,7 +212,12 @@ int main(int argc, char *argv[]){
|
||||||
localSocket.close();
|
localSocket.close();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef DISABLE_GUI
|
||||||
|
app = new QCoreApplication(argc, argv);
|
||||||
|
#else
|
||||||
app = new QApplication(argc, argv);
|
app = new QApplication(argc, argv);
|
||||||
|
#endif
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
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; }");
|
||||||
QSplashScreen *splash = 0;
|
QSplashScreen *splash = 0;
|
||||||
|
@ -195,6 +225,7 @@ int main(int argc, char *argv[]){
|
||||||
splash = new QSplashScreen(QPixmap(QString::fromUtf8(":/Icons/skin/splash.png")));
|
splash = new QSplashScreen(QPixmap(QString::fromUtf8(":/Icons/skin/splash.png")));
|
||||||
splash->show();
|
splash->show();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Open options file to read locale
|
// Open options file to read locale
|
||||||
locale = settings.value(QString::fromUtf8("Preferences/General/Locale"), QString()).toString();
|
locale = settings.value(QString::fromUtf8("Preferences/General/Locale"), QString()).toString();
|
||||||
QTranslator translator;
|
QTranslator translator;
|
||||||
|
@ -209,24 +240,36 @@ int main(int argc, char *argv[]){
|
||||||
}
|
}
|
||||||
app->installTranslator(&translator);
|
app->installTranslator(&translator);
|
||||||
app->setApplicationName(QString::fromUtf8("qBittorrent"));
|
app->setApplicationName(QString::fromUtf8("qBittorrent"));
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
app->setQuitOnLastWindowClosed(false);
|
app->setQuitOnLastWindowClosed(false);
|
||||||
|
#endif
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
signal(SIGABRT, sigabrtHandler);
|
signal(SIGABRT, sigabrtHandler);
|
||||||
signal(SIGTERM, sigtermHandler);
|
signal(SIGTERM, sigtermHandler);
|
||||||
|
signal(SIGINT, sigtermHandler);
|
||||||
signal(SIGSEGV, sigsegvHandler);
|
signal(SIGSEGV, sigsegvHandler);
|
||||||
#endif
|
#endif
|
||||||
// Read torrents given on command line
|
// Read torrents given on command line
|
||||||
QStringList torrentCmdLine = app->arguments();
|
QStringList torrentCmdLine = app->arguments();
|
||||||
// Remove first argument (program name)
|
// Remove first argument (program name)
|
||||||
torrentCmdLine.removeFirst();
|
torrentCmdLine.removeFirst();
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
GUI *window = new GUI(0, torrentCmdLine);
|
GUI *window = new GUI(0, torrentCmdLine);
|
||||||
if(!no_splash) {
|
if(!no_splash) {
|
||||||
splash->finish(window);
|
splash->finish(window);
|
||||||
delete splash;
|
delete splash;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Load Headless class
|
||||||
|
HeadlessLoader *loader = new HeadlessLoader(torrentCmdLine);
|
||||||
|
#endif
|
||||||
int ret = app->exec();
|
int ret = app->exec();
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
delete window;
|
delete window;
|
||||||
qDebug("GUI was deleted!");
|
qDebug("GUI was deleted!");
|
||||||
|
#else
|
||||||
|
delete loader;
|
||||||
|
#endif
|
||||||
qDebug("Deleting app...");
|
qDebug("Deleting app...");
|
||||||
delete app;
|
delete app;
|
||||||
qDebug("App was deleted! All good.");
|
qDebug("App was deleted! All good.");
|
||||||
|
|
86
src/misc.h
86
src/misc.h
|
@ -43,10 +43,24 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||||
#include <boost/date_time/posix_time/conversion.hpp>
|
#include <boost/date_time/posix_time/conversion.hpp>
|
||||||
|
|
||||||
|
#ifdef DISABLE_GUI
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#else
|
||||||
|
#include <QApplication>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
#include <shlobj.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
#include <Files.h>
|
||||||
|
#include <Folders.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef Q_WS_WIN
|
#ifndef Q_WS_WIN
|
||||||
#ifdef Q_WS_MAC
|
#ifdef Q_WS_MAC
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -168,8 +182,72 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
static QString getFullPath(const FSRef &ref)
|
||||||
|
{
|
||||||
|
QByteArray ba(2048, 0);
|
||||||
|
if (FSRefMakePath(&ref, reinterpret_cast<UInt8 *>(ba.data()), ba.size()) == noErr)
|
||||||
|
return QString::fromUtf8(ba).normalized(QString::NormalizationForm_C);
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static QString QDesktopServicesDataLocation() {
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
#if defined Q_WS_WINCE
|
||||||
|
if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
|
||||||
|
#else
|
||||||
|
if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
|
||||||
|
#endif
|
||||||
|
result = QString::fromWCharArray(path);
|
||||||
|
if (!QCoreApplication::applicationName().isEmpty())
|
||||||
|
result = result + QLatin1String("\\") + qApp->applicationName();
|
||||||
|
#else
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
// http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
|
||||||
|
FSRef ref;
|
||||||
|
OSErr err = FSFindFolder(kUserDomain, kApplicationSupportFolderType, false, &ref);
|
||||||
|
if (err)
|
||||||
|
return QString();
|
||||||
|
QString path = getFullPath(ref);
|
||||||
|
path += QLatin1Char('/') + qApp->applicationName();
|
||||||
|
return path;
|
||||||
|
#else
|
||||||
|
QString xdgDataHome = QLatin1String(qgetenv("XDG_DATA_HOME"));
|
||||||
|
if (xdgDataHome.isEmpty())
|
||||||
|
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
|
||||||
|
xdgDataHome += QLatin1String("/data/")
|
||||||
|
+ qApp->applicationName();
|
||||||
|
return xdgDataHome;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString QDesktopServicesCacheLocation() {
|
||||||
|
#ifdef Q_WS_WIN
|
||||||
|
return QDesktopServicesDataLocation() + QLatin1String("\\cache");
|
||||||
|
#else
|
||||||
|
#ifdef Q_WS_MAC
|
||||||
|
// http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
|
||||||
|
FSRef ref;
|
||||||
|
OSErr err = FSFindFolder(kUserDomain, kCachedDataFolderType, false, &ref);
|
||||||
|
if (err)
|
||||||
|
return QString();
|
||||||
|
QString path = getFullPath(ref);
|
||||||
|
path += QLatin1Char('/') + qApp->applicationName();
|
||||||
|
return path;
|
||||||
|
#else
|
||||||
|
QString xdgCacheHome = QLatin1String(qgetenv("XDG_CACHE_HOME"));
|
||||||
|
if (xdgCacheHome.isEmpty())
|
||||||
|
xdgCacheHome = QDir::homePath() + QLatin1String("/.cache");
|
||||||
|
xdgCacheHome += QLatin1Char('/') + QCoreApplication::applicationName();
|
||||||
|
return xdgCacheHome;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static QString searchEngineLocation() {
|
static QString searchEngineLocation() {
|
||||||
QString location = QDir::cleanPath(QDesktopServices::storageLocation(QDesktopServices::DataLocation)
|
QString location = QDir::cleanPath(QDesktopServicesDataLocation()
|
||||||
+ QDir::separator() + "search_engine");
|
+ QDir::separator() + "search_engine");
|
||||||
QDir locationDir(location);
|
QDir locationDir(location);
|
||||||
if(!locationDir.exists())
|
if(!locationDir.exists())
|
||||||
|
@ -178,7 +256,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString BTBackupLocation() {
|
static QString BTBackupLocation() {
|
||||||
QString location = QDir::cleanPath(QDesktopServices::storageLocation(QDesktopServices::DataLocation)
|
QString location = QDir::cleanPath(QDesktopServicesDataLocation()
|
||||||
+ QDir::separator() + "BT_backup");
|
+ QDir::separator() + "BT_backup");
|
||||||
QDir locationDir(location);
|
QDir locationDir(location);
|
||||||
if(!locationDir.exists())
|
if(!locationDir.exists())
|
||||||
|
@ -187,7 +265,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString cacheLocation() {
|
static QString cacheLocation() {
|
||||||
QString location = QDir::cleanPath(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
|
QString location = QDir::cleanPath(QDesktopServicesCacheLocation());
|
||||||
QDir locationDir(location);
|
QDir locationDir(location);
|
||||||
if(!locationDir.exists())
|
if(!locationDir.exists())
|
||||||
locationDir.mkpath(locationDir.absolutePath());
|
locationDir.mkpath(locationDir.absolutePath());
|
||||||
|
|
|
@ -676,6 +676,11 @@ public:
|
||||||
return settings.value("Preferences/WebUI/Enabled", false).toBool();
|
return settings.value("Preferences/WebUI/Enabled", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setWebUiEnabled(bool enabled) {
|
||||||
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
|
settings.setValue("Preferences/WebUI/Enabled", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
static quint16 getWebUiPort() {
|
static quint16 getWebUiPort() {
|
||||||
QSettings settings("qBittorrent", "qBittorrent");
|
QSettings settings("qBittorrent", "qBittorrent");
|
||||||
return settings.value("Preferences/WebUI/Port", 8080).toInt();
|
return settings.value("Preferences/WebUI/Port", 8080).toInt();
|
||||||
|
|
|
@ -417,10 +417,12 @@ bool QTorrentHandle::is_sequential_download() const {
|
||||||
return h.is_sequential_download();
|
return h.is_sequential_download();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
bool QTorrentHandle::resolve_countries() const {
|
bool QTorrentHandle::resolve_countries() const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
return h.resolve_countries();
|
return h.resolve_countries();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool QTorrentHandle::priv() const {
|
bool QTorrentHandle::priv() const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
|
@ -547,10 +549,12 @@ void QTorrentHandle::super_seeding(bool on) const {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
void QTorrentHandle::resolve_countries(bool r) {
|
void QTorrentHandle::resolve_countries(bool r) {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
h.resolve_countries(r);
|
h.resolve_countries(r);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void QTorrentHandle::connect_peer(libtorrent::asio::ip::tcp::endpoint const& adr, int source) const {
|
void QTorrentHandle::connect_peer(libtorrent::asio::ip::tcp::endpoint const& adr, int source) const {
|
||||||
Q_ASSERT(h.is_valid());
|
Q_ASSERT(h.is_valid());
|
||||||
|
|
|
@ -121,7 +121,9 @@ class QTorrentHandle {
|
||||||
#endif
|
#endif
|
||||||
QString creation_date() const;
|
QString creation_date() const;
|
||||||
void get_peer_info(std::vector<peer_info>&) const;
|
void get_peer_info(std::vector<peer_info>&) const;
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
bool resolve_countries() const;
|
bool resolve_countries() const;
|
||||||
|
#endif
|
||||||
bool priv() const;
|
bool priv() const;
|
||||||
bool first_last_piece_first() const;
|
bool first_last_piece_first() const;
|
||||||
|
|
||||||
|
@ -152,7 +154,9 @@ class QTorrentHandle {
|
||||||
#ifdef LIBTORRENT_0_15
|
#ifdef LIBTORRENT_0_15
|
||||||
void super_seeding(bool on) const;
|
void super_seeding(bool on) const;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DISABLE_GUI
|
||||||
void resolve_countries(bool r);
|
void resolve_countries(bool r);
|
||||||
|
#endif
|
||||||
void connect_peer(libtorrent::asio::ip::tcp::endpoint const& adr, int source = 0) const;
|
void connect_peer(libtorrent::asio::ip::tcp::endpoint const& adr, int source = 0) const;
|
||||||
void set_peer_upload_limit(libtorrent::asio::ip::tcp::endpoint ip, int limit) const;
|
void set_peer_upload_limit(libtorrent::asio::ip::tcp::endpoint ip, int limit) const;
|
||||||
void set_peer_download_limit(libtorrent::asio::ip::tcp::endpoint ip, int limit) const;
|
void set_peer_download_limit(libtorrent::asio::ip::tcp::endpoint ip, int limit) const;
|
||||||
|
|
164
src/src.pro
164
src/src.pro
|
@ -172,28 +172,10 @@ TRANSLATIONS = $$LANG_PATH/qbittorrent_fr.ts \
|
||||||
$$LANG_PATH/qbittorrent_sr.ts
|
$$LANG_PATH/qbittorrent_sr.ts
|
||||||
|
|
||||||
# Source code
|
# Source code
|
||||||
HEADERS += GUI.h \
|
HEADERS += misc.h \
|
||||||
misc.h \
|
|
||||||
options_imp.h \
|
|
||||||
about_imp.h \
|
|
||||||
createtorrent_imp.h \
|
|
||||||
searchlistdelegate.h \
|
|
||||||
proplistdelegate.h \
|
|
||||||
previewselect.h \
|
|
||||||
previewlistdelegate.h \
|
|
||||||
trackerlogin.h \
|
|
||||||
downloadthread.h \
|
downloadthread.h \
|
||||||
downloadfromurldlg.h \
|
|
||||||
torrentadditiondlg.h \
|
|
||||||
bittorrent.h \
|
bittorrent.h \
|
||||||
searchEngine.h \
|
|
||||||
rss.h \
|
|
||||||
rss_imp.h \
|
|
||||||
speedlimitdlg.h \
|
|
||||||
qtorrenthandle.h \
|
qtorrenthandle.h \
|
||||||
engineselectdlg.h \
|
|
||||||
pluginsource.h \
|
|
||||||
qgnomelook.h \
|
|
||||||
httpserver.h \
|
httpserver.h \
|
||||||
httpconnection.h \
|
httpconnection.h \
|
||||||
httprequestparser.h \
|
httprequestparser.h \
|
||||||
|
@ -201,70 +183,102 @@ HEADERS += GUI.h \
|
||||||
json.h \
|
json.h \
|
||||||
eventmanager.h \
|
eventmanager.h \
|
||||||
filterparserthread.h \
|
filterparserthread.h \
|
||||||
trackersadditiondlg.h \
|
|
||||||
searchtab.h \
|
|
||||||
console_imp.h \
|
|
||||||
ico.h \
|
|
||||||
stacktrace.h \
|
stacktrace.h \
|
||||||
torrentpersistentdata.h \
|
torrentpersistentdata.h \
|
||||||
feeddownloader.h \
|
|
||||||
feedList.h \
|
|
||||||
supportedengines.h \
|
|
||||||
transferlistwidget.h \
|
|
||||||
transferlistdelegate.h \
|
|
||||||
transferlistfilterswidget.h \
|
|
||||||
propertieswidget.h \
|
|
||||||
torrentfilesmodel.h \
|
|
||||||
filesystemwatcher.h \
|
filesystemwatcher.h \
|
||||||
peerlistwidget.h \
|
preferences.h
|
||||||
peerlistdelegate.h \
|
|
||||||
reverseresolution.h \
|
contains(DEFINES, DISABLE_GUI) {
|
||||||
preferences.h \
|
HEADERS += headlessloader.h
|
||||||
geoip.h \
|
} else {
|
||||||
peeraddition.h \
|
HEADERS += GUI.h \
|
||||||
deletionconfirmationdlg.h \
|
feedList.h \
|
||||||
statusbar.h \
|
supportedengines.h \
|
||||||
trackerlist.h \
|
transferlistwidget.h \
|
||||||
downloadedpiecesbar.h \
|
transferlistdelegate.h \
|
||||||
pieceavailabilitybar.h
|
transferlistfilterswidget.h \
|
||||||
FORMS += ui/mainwindow.ui \
|
propertieswidget.h \
|
||||||
ui/options.ui \
|
torrentfilesmodel.h \
|
||||||
ui/about.ui \
|
geoip.h \
|
||||||
ui/createtorrent.ui \
|
peeraddition.h \
|
||||||
ui/preview.ui \
|
deletionconfirmationdlg.h \
|
||||||
ui/login.ui \
|
statusbar.h \
|
||||||
ui/downloadfromurldlg.ui \
|
trackerlist.h \
|
||||||
ui/torrentadditiondlg.ui \
|
downloadedpiecesbar.h \
|
||||||
ui/search.ui \
|
peerlistwidget.h \
|
||||||
ui/rss.ui \
|
peerlistdelegate.h \
|
||||||
ui/bandwidth_limit.ui \
|
reverseresolution.h \
|
||||||
ui/engineselect.ui \
|
feeddownloader.h \
|
||||||
ui/pluginsource.ui \
|
trackersadditiondlg.h \
|
||||||
ui/trackersadditiondlg.ui \
|
searchtab.h \
|
||||||
ui/console.ui \
|
console_imp.h \
|
||||||
ui/feeddownloader.ui \
|
ico.h \
|
||||||
ui/propertieswidget.ui \
|
engineselectdlg.h \
|
||||||
ui/peer.ui \
|
pluginsource.h \
|
||||||
ui/confirmdeletiondlg.ui
|
qgnomelook.h \
|
||||||
SOURCES += GUI.cpp \
|
searchEngine.h \
|
||||||
main.cpp \
|
rss.h \
|
||||||
options_imp.cpp \
|
rss_imp.h \
|
||||||
createtorrent_imp.cpp \
|
speedlimitdlg.h \
|
||||||
|
options_imp.h \
|
||||||
|
about_imp.h \
|
||||||
|
createtorrent_imp.h \
|
||||||
|
searchlistdelegate.h \
|
||||||
|
proplistdelegate.h \
|
||||||
|
previewselect.h \
|
||||||
|
previewlistdelegate.h \
|
||||||
|
downloadfromurldlg.h \
|
||||||
|
torrentadditiondlg.h \
|
||||||
|
trackerlogin.h \
|
||||||
|
pieceavailabilitybar.h
|
||||||
|
}
|
||||||
|
|
||||||
|
!contains(DEFINES, DISABLE_GUI) {
|
||||||
|
message(adding forms)
|
||||||
|
FORMS += ui/mainwindow.ui \
|
||||||
|
ui/options.ui \
|
||||||
|
ui/about.ui \
|
||||||
|
ui/createtorrent.ui \
|
||||||
|
ui/preview.ui \
|
||||||
|
ui/login.ui \
|
||||||
|
ui/downloadfromurldlg.ui \
|
||||||
|
ui/torrentadditiondlg.ui \
|
||||||
|
ui/search.ui \
|
||||||
|
ui/rss.ui \
|
||||||
|
ui/bandwidth_limit.ui \
|
||||||
|
ui/engineselect.ui \
|
||||||
|
ui/pluginsource.ui \
|
||||||
|
ui/trackersadditiondlg.ui \
|
||||||
|
ui/console.ui \
|
||||||
|
ui/feeddownloader.ui \
|
||||||
|
ui/propertieswidget.ui \
|
||||||
|
ui/peer.ui \
|
||||||
|
ui/confirmdeletiondlg.ui
|
||||||
|
}
|
||||||
|
|
||||||
|
SOURCES += main.cpp \
|
||||||
bittorrent.cpp \
|
bittorrent.cpp \
|
||||||
searchengine.cpp \
|
|
||||||
rss_imp.cpp \
|
|
||||||
qtorrenthandle.cpp \
|
qtorrenthandle.cpp \
|
||||||
engineselectdlg.cpp \
|
|
||||||
downloadthread.cpp \
|
downloadthread.cpp \
|
||||||
httpserver.cpp \
|
httpserver.cpp \
|
||||||
httpconnection.cpp \
|
httpconnection.cpp \
|
||||||
httprequestparser.cpp \
|
httprequestparser.cpp \
|
||||||
httpresponsegenerator.cpp \
|
httpresponsegenerator.cpp \
|
||||||
eventmanager.cpp \
|
eventmanager.cpp
|
||||||
searchtab.cpp \
|
|
||||||
ico.cpp \
|
!contains(DEFINES, DISABLE_GUI) {
|
||||||
rss.cpp \
|
SOURCES += GUI.cpp \
|
||||||
transferlistwidget.cpp \
|
options_imp.cpp \
|
||||||
propertieswidget.cpp \
|
createtorrent_imp.cpp \
|
||||||
peerlistwidget.cpp
|
searchengine.cpp \
|
||||||
|
rss_imp.cpp \
|
||||||
|
engineselectdlg.cpp \
|
||||||
|
searchtab.cpp \
|
||||||
|
ico.cpp \
|
||||||
|
rss.cpp \
|
||||||
|
transferlistwidget.cpp \
|
||||||
|
propertieswidget.cpp \
|
||||||
|
peerlistwidget.cpp
|
||||||
|
}
|
||||||
|
|
||||||
DESTDIR = .
|
DESTDIR = .
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue