2007-03-05 16:55:23 +03:00
/*
* Bittorrent Client using Qt4 and libtorrent .
2007-07-14 18:31:59 +04:00
* Copyright ( C ) 2006 Christophe Dumez
2007-03-05 16:55:23 +03:00
*
2007-07-14 18:31:59 +04:00
* 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 .
2007-03-05 16:55:23 +03:00
*
* 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
2007-07-14 18:31:59 +04:00
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
2009-04-05 21:00:55 +04:00
* 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 .
*
2007-07-14 18:31:59 +04:00
* Contact : chris @ qbittorrent . org
2007-03-05 16:55:23 +03:00
*/
2007-03-27 22:49:29 +04:00
# include <QDir>
2009-07-12 13:08:38 +04:00
# include <QDateTime>
2007-03-27 22:49:29 +04:00
# include <QString>
2010-05-11 19:53:14 +04:00
# include <QNetworkInterface>
# include <QHostAddress>
# include <QNetworkAddressEntry>
2010-08-20 17:20:23 +04:00
# include <QProcess>
2007-03-27 22:49:29 +04:00
2010-08-19 22:47:57 +04:00
# include "smtp.h"
2009-11-12 21:24:51 +03:00
# include "filesystemwatcher.h"
2010-12-18 18:34:38 +03:00
# include "torrentspeedmonitor.h"
2010-10-09 18:06:35 +04:00
# include "qbtsession.h"
2007-09-29 12:00:14 +04:00
# include "misc.h"
2012-05-16 22:19:05 +04:00
# include "fs_utils.h"
2009-11-20 10:48:44 +03:00
# include "downloadthread.h"
# include "filterparserthread.h"
2009-11-14 22:08:28 +03:00
# include "preferences.h"
2010-02-28 18:15:00 +03:00
# include "scannedfoldersmodel.h"
2010-01-03 01:20:37 +03:00
# ifndef DISABLE_GUI
2011-02-05 17:51:31 +03:00
# include "shutdownconfirm.h"
2010-11-20 18:59:17 +03:00
# include "geoipmanager.h"
2010-01-03 01:20:37 +03:00
# endif
2009-11-20 10:48:44 +03:00
# include "torrentpersistentdata.h"
2009-11-18 20:46:59 +03:00
# include "httpserver.h"
2010-07-16 19:03:18 +04:00
# include "qinisettings.h"
2010-01-24 14:57:15 +03:00
# include "bandwidthscheduler.h"
2011-04-17 00:08:32 +04:00
# include <libtorrent/version.hpp>
2008-11-02 22:22:10 +03:00
# include <libtorrent/extensions/ut_metadata.hpp>
2010-06-07 12:32:41 +04:00
# include <libtorrent/version.hpp>
2009-11-18 20:46:59 +03:00
# include <libtorrent/extensions/lt_trackers.hpp>
2007-07-23 16:46:36 +04:00
# include <libtorrent/extensions/ut_pex.hpp>
2008-11-02 22:22:10 +03:00
# include <libtorrent/extensions/smart_ban.hpp>
2009-10-24 18:36:17 +04:00
//#include <libtorrent/extensions/metadata_transfer.hpp>
2013-09-29 22:32:27 +04:00
# include <libtorrent/lazy_entry.hpp>
2007-07-23 16:46:36 +04:00
# include <libtorrent/bencode.hpp>
2011-04-17 14:29:44 +04:00
# include <libtorrent/error_code.hpp>
2007-07-23 16:46:36 +04:00
# include <libtorrent/identify_client.hpp>
# include <libtorrent/alert_types.hpp>
2007-08-26 20:25:22 +04:00
# include <libtorrent/torrent_info.hpp>
2013-10-23 23:16:23 +04:00
# include <libtorrent/error_code.hpp>
2010-03-04 22:29:48 +03:00
# include <queue>
2011-01-23 22:31:48 +03:00
# include <string.h>
2011-04-15 17:02:39 +04:00
# include "dnsupdater.h"
2007-07-23 16:46:36 +04:00
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2014-01-01 02:10:41 +04:00
# include <libtorrent/upnp.hpp>
# include <libtorrent/natpmp.hpp>
# endif
2013-05-04 16:01:24 +04:00
//initialize static member variables
QHash < QString , TorrentTempData : : TorrentData > TorrentTempData : : data = QHash < QString , TorrentTempData : : TorrentData > ( ) ;
2013-10-10 00:34:00 +04:00
QHash < QString , bool > HiddenData : : data = QHash < QString , bool > ( ) ;
2013-09-18 01:44:18 +04:00
unsigned int HiddenData : : metadata_counter = 0 ;
2013-05-04 16:01:24 +04:00
2010-11-23 00:55:32 +03:00
using namespace libtorrent ;
2010-11-13 22:36:46 +03:00
QBtSession * QBtSession : : m_instance = 0 ;
2011-02-26 18:04:15 +03:00
const qreal QBtSession : : MAX_RATIO = 9999. ;
2010-11-13 22:36:46 +03:00
2010-03-03 20:27:25 +03:00
const int MAX_TRACKER_ERRORS = 2 ;
2010-01-01 23:29:03 +03:00
2012-02-16 23:04:02 +04:00
/* Converts a QString hash into a libtorrent sha1_hash */
static libtorrent : : sha1_hash QStringToSha1 ( const QString & s ) {
QByteArray raw = s . toAscii ( ) ;
Q_ASSERT ( raw . size ( ) = = 40 ) ;
libtorrent : : sha1_hash ret ;
from_hex ( raw . constData ( ) , 40 , ( char * ) & ret [ 0 ] ) ;
return ret ;
}
2007-03-05 16:55:23 +03:00
// Main constructor
2010-10-17 18:46:01 +04:00
QBtSession : : QBtSession ( )
2010-03-20 14:30:11 +03:00
: m_scanFolders ( ScanFoldersModel : : instance ( this ) ) ,
2012-05-15 20:57:31 +04:00
preAllocateAll ( false ) , global_ratio_limit ( - 1 ) ,
2011-04-12 23:50:05 +04:00
LSDEnabled ( false ) ,
2010-10-17 15:45:53 +04:00
DHTEnabled ( false ) , current_dht_port ( 0 ) , queueingEnabled ( false ) ,
2012-08-21 11:16:49 +04:00
m_torrentExportEnabled ( false ) ,
2013-09-20 00:43:21 +04:00
m_finishedTorrentExportEnabled ( false )
2010-10-17 15:45:53 +04:00
# ifndef DISABLE_GUI
2010-03-20 14:30:11 +03:00
, geoipDBLoaded ( false ) , resolve_countries ( false )
2010-10-17 15:45:53 +04:00
# endif
2014-01-01 02:10:41 +04:00
, m_tracker ( 0 ) , m_shutdownAct ( NO_SHUTDOWN )
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2014-01-01 02:10:41 +04:00
, m_upnp ( 0 ) , m_natpmp ( 0 )
# endif
, m_dynDNSUpdater ( 0 )
2010-03-03 20:27:25 +03:00
{
2011-03-07 22:26:44 +03:00
BigRatioTimer = new QTimer ( this ) ;
BigRatioTimer - > setInterval ( 10000 ) ;
connect ( BigRatioTimer , SIGNAL ( timeout ( ) ) , SLOT ( processBigRatios ( ) ) ) ;
2010-11-16 23:34:31 +03:00
Preferences pref ;
2009-11-20 11:01:59 +03:00
// Creating Bittorrent session
2009-12-30 16:10:06 +03:00
QList < int > version ;
version < < VERSION_MAJOR ;
version < < VERSION_MINOR ;
version < < VERSION_BUGFIX ;
2011-06-18 17:35:25 +04:00
version < < 0 ;
2010-07-24 21:35:29 +04:00
const QString peer_id = " qB " ;
2009-12-30 16:10:06 +03:00
// Construct session
2010-03-04 23:19:25 +03:00
s = new session ( fingerprint ( peer_id . toLocal8Bit ( ) . constData ( ) , version . at ( 0 ) , version . at ( 1 ) , version . at ( 2 ) , version . at ( 3 ) ) , 0 ) ;
2012-06-24 10:59:12 +04:00
//std::cout << "Peer ID: " << fingerprint(peer_id.toLocal8Bit().constData(), version.at(0), version.at(1), version.at(2), version.at(3)).to_string() << std::endl;
2010-03-04 23:19:25 +03:00
addConsoleMessage ( " Peer ID: " + misc : : toQString ( fingerprint ( peer_id . toLocal8Bit ( ) . constData ( ) , version . at ( 0 ) , version . at ( 1 ) , version . at ( 2 ) , version . at ( 3 ) ) . to_string ( ) ) ) ;
2009-09-03 15:29:15 +04:00
2007-03-05 16:55:23 +03:00
// Set severity level of libtorrent session
2010-06-22 22:40:30 +04:00
s - > set_alert_mask ( alert : : error_notification | alert : : peer_notification | alert : : port_mapping_notification | alert : : storage_notification | alert : : tracker_notification | alert : : status_notification | alert : : ip_block_notification | alert : : progress_notification ) ;
2008-11-02 16:19:27 +03:00
// Load previous state
loadSessionState ( ) ;
2008-11-02 22:22:10 +03:00
// Enabling plugins
2009-10-24 18:28:00 +04:00
//s->add_extension(&create_metadata_plugin);
2008-11-02 22:22:10 +03:00
s - > add_extension ( & create_ut_metadata_plugin ) ;
2012-02-20 21:30:53 +04:00
if ( pref . trackerExchangeEnabled ( ) )
2011-06-05 20:08:30 +04:00
s - > add_extension ( & create_lt_trackers_plugin ) ;
2012-02-20 21:30:53 +04:00
if ( pref . isPeXEnabled ( ) ) {
2009-12-17 21:00:21 +03:00
PeXEnabled = true ;
s - > add_extension ( & create_ut_pex_plugin ) ;
} else {
PeXEnabled = false ;
}
2008-11-02 22:22:10 +03:00
s - > add_extension ( & create_smart_ban_plugin ) ;
2010-11-27 11:56:24 +03:00
timerAlerts = new QTimer ( this ) ;
2011-03-07 22:26:44 +03:00
connect ( timerAlerts , SIGNAL ( timeout ( ) ) , SLOT ( readAlerts ( ) ) ) ;
2011-03-19 18:48:45 +03:00
timerAlerts - > start ( 1000 ) ;
2010-11-16 23:34:31 +03:00
appendLabelToSavePath = pref . appendTorrentLabel ( ) ;
appendqBExtension = pref . useIncompleteFilesExtension ( ) ;
2011-03-07 22:26:44 +03:00
connect ( m_scanFolders , SIGNAL ( torrentsAdded ( QStringList & ) ) , SLOT ( addTorrentsFromScanFolder ( QStringList & ) ) ) ;
2009-11-14 22:08:28 +03:00
// Apply user settings to Bittorrent session
2010-11-29 19:55:23 +03:00
configureSession ( ) ;
2010-12-18 18:34:38 +03:00
// Torrent speed monitor
m_speedMonitor = new TorrentSpeedMonitor ( this ) ;
m_speedMonitor - > start ( ) ;
2011-04-13 21:18:56 +04:00
// To download from urls
downloader = new DownloadThread ( this ) ;
connect ( downloader , SIGNAL ( downloadFinished ( QString , QString ) ) , SLOT ( processDownloadedFile ( QString , QString ) ) ) ;
connect ( downloader , SIGNAL ( downloadFailure ( QString , QString ) ) , SLOT ( handleDownloadFailure ( QString , QString ) ) ) ;
// Regular saving of fastresume data
connect ( & resumeDataTimer , SIGNAL ( timeout ( ) ) , SLOT ( saveTempFastResumeData ( ) ) ) ;
resumeDataTimer . start ( 170000 ) ; // 3min
2007-08-26 20:25:22 +04:00
qDebug ( " * BTSession constructed " ) ;
2007-03-08 01:36:01 +03:00
}
2010-11-22 22:14:50 +03:00
// Main destructor
QBtSession : : ~ QBtSession ( ) {
qDebug ( " BTSession destructor IN " ) ;
2010-12-18 18:34:38 +03:00
delete m_speedMonitor ;
qDebug ( " Deleted the torrent speed monitor " ) ;
2008-11-02 16:19:27 +03:00
// Do some BT related saving
saveSessionState ( ) ;
2009-11-18 15:35:55 +03:00
saveFastResumeData ( ) ;
2007-07-29 18:54:39 +04:00
// Delete our objects
2012-02-20 21:30:53 +04:00
if ( m_tracker )
2010-10-16 01:55:56 +04:00
delete m_tracker ;
2007-07-30 17:56:31 +04:00
delete timerAlerts ;
2012-02-20 21:30:53 +04:00
if ( BigRatioTimer )
2007-11-25 00:55:19 +03:00
delete BigRatioTimer ;
2012-02-20 21:30:53 +04:00
if ( filterParser )
2008-05-18 00:32:03 +04:00
delete filterParser ;
2007-03-08 01:36:01 +03:00
delete downloader ;
2012-02-20 21:30:53 +04:00
if ( bd_scheduler )
2010-01-24 14:57:15 +03:00
delete bd_scheduler ;
2009-11-18 20:46:59 +03:00
// HTTP Server
2012-02-20 21:30:53 +04:00
if ( httpServer )
2009-11-18 20:46:59 +03:00
delete httpServer ;
2011-01-04 00:24:57 +03:00
qDebug ( " Deleting the session " ) ;
delete s ;
2009-12-01 00:30:14 +03:00
qDebug ( " BTSession destructor OUT " ) ;
2011-04-05 21:29:55 +04:00
# ifndef DISABLE_GUI
2012-02-20 21:30:53 +04:00
if ( m_shutdownAct ! = NO_SHUTDOWN ) {
2011-04-05 20:22:16 +04:00
qDebug ( ) < < " Sending computer shutdown/suspend signal... " ;
misc : : shutdownComputer ( m_shutdownAct = = SUSPEND_COMPUTER ) ;
}
2011-04-05 21:29:55 +04:00
# endif
2007-03-05 16:55:23 +03:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : preAllocateAllFiles ( bool b ) {
2010-03-03 20:27:25 +03:00
const bool change = ( preAllocateAll ! = b ) ;
2012-02-20 21:30:53 +04:00
if ( change ) {
2007-11-03 01:56:07 +03:00
qDebug ( " PreAllocateAll changed, reloading all torrents! " ) ;
preAllocateAll = b ;
2007-09-08 21:07:29 +04:00
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : processBigRatios ( ) {
2010-06-22 21:46:07 +04:00
qDebug ( " Process big ratios... " ) ;
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-03-12 00:43:09 +03:00
const QTorrentHandle h ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) continue ;
if ( h . is_seed ( ) ) {
2010-03-03 20:27:25 +03:00
const QString hash = h . hash ( ) ;
2011-01-25 20:04:55 +03:00
const qreal ratio = getRealRatio ( hash ) ;
2011-03-07 22:26:44 +03:00
qreal ratio_limit = TorrentPersistentData : : getRatioLimit ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ratio_limit = = TorrentPersistentData : : USE_GLOBAL_RATIO )
2011-03-07 22:26:44 +03:00
ratio_limit = global_ratio_limit ;
2012-05-27 19:46:00 +04:00
if ( ratio_limit = = TorrentPersistentData : : NO_RATIO_LIMIT )
continue ;
2010-06-22 21:46:07 +04:00
qDebug ( " Ratio: %f (limit: %f) " , ratio , ratio_limit ) ;
2011-03-07 22:26:44 +03:00
Q_ASSERT ( ratio_limit > = 0.f ) ;
2012-02-20 21:30:53 +04:00
if ( ratio < = MAX_RATIO & & ratio > = ratio_limit ) {
if ( high_ratio_action = = REMOVE_ACTION ) {
2010-06-22 21:46:07 +04:00
addConsoleMessage ( tr ( " %1 reached the maximum ratio you set. " ) . arg ( h . name ( ) ) ) ;
2010-06-22 21:06:11 +04:00
addConsoleMessage ( tr ( " Removing torrent %1... " ) . arg ( h . name ( ) ) ) ;
deleteTorrent ( hash ) ;
} else {
// Pause it
2012-02-20 21:30:53 +04:00
if ( ! h . is_paused ( ) ) {
2010-06-22 21:46:07 +04:00
addConsoleMessage ( tr ( " %1 reached the maximum ratio you set. " ) . arg ( h . name ( ) ) ) ;
addConsoleMessage ( tr ( " Pausing torrent %1... " ) . arg ( h . name ( ) ) ) ;
pauseTorrent ( hash ) ;
}
2010-06-22 21:06:11 +04:00
}
2009-08-16 07:09:20 +04:00
//emit torrent_ratio_deleted(fileName);
}
2007-09-09 13:09:24 +04:00
}
2009-08-16 07:09:20 +04:00
}
2007-09-09 13:09:24 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setDownloadLimit ( QString hash , long val ) {
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) ) {
2007-07-30 20:57:28 +04:00
h . set_download_limit ( val ) ;
2009-08-27 13:07:33 +04:00
}
2007-07-14 17:38:29 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setUploadLimit ( QString hash , long val ) {
2007-08-04 10:23:44 +04:00
qDebug ( " Set upload limit rate to %ld " , val ) ;
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) ) {
2007-07-30 20:57:28 +04:00
h . set_upload_limit ( val ) ;
2009-08-27 13:07:33 +04:00
}
2007-07-14 17:38:29 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : handleDownloadFailure ( QString url , QString reason ) {
2007-07-21 00:18:18 +04:00
emit downloadFromUrlFailure ( url , reason ) ;
2009-08-21 11:40:57 +04:00
// Clean up
2011-02-07 23:13:46 +03:00
const QUrl qurl = QUrl : : fromEncoded ( url . toUtf8 ( ) ) ;
2010-11-13 13:49:22 +03:00
url_skippingDlg . removeOne ( qurl ) ;
savepathLabel_fromurl . remove ( qurl ) ;
2007-07-21 00:18:18 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setQueueingEnabled ( bool enable ) {
2012-02-20 21:30:53 +04:00
if ( queueingEnabled ! = enable ) {
2008-08-19 04:28:44 +04:00
qDebug ( " Queueing system is changing state... " ) ;
2008-07-15 02:01:05 +04:00
queueingEnabled = enable ;
2008-07-14 23:20:18 +04:00
}
}
2009-11-14 22:08:28 +03:00
// Set BT session configuration
2010-10-17 18:46:01 +04:00
void QBtSession : : configureSession ( ) {
2009-11-14 22:08:28 +03:00
qDebug ( " Configuring session " ) ;
2012-08-29 02:55:08 +04:00
Preferences pref ;
2013-09-20 00:43:21 +04:00
if ( pref . useRandomPort ( ) ) {
pref . setSessionPort ( rand ( ) % USHRT_MAX + 1025 ) ;
}
2011-04-13 21:18:56 +04:00
const unsigned short old_listenPort = getListenPort ( ) ;
const unsigned short new_listenPort = pref . getSessionPort ( ) ;
2013-09-20 00:43:21 +04:00
if ( old_listenPort ! = new_listenPort ) {
qDebug ( " Session port changes in program preferences: %d -> %d " , old_listenPort , new_listenPort ) ;
setListeningPort ( new_listenPort ) ;
2011-04-13 21:18:56 +04:00
}
2009-11-14 22:08:28 +03:00
// Downloads
// * Save path
2010-11-16 23:34:31 +03:00
defaultSavePath = pref . getSavePath ( ) ;
2012-02-20 21:30:53 +04:00
if ( pref . isTempPathEnabled ( ) ) {
2010-11-16 23:34:31 +03:00
setDefaultTempPath ( pref . getTempPath ( ) ) ;
2009-11-14 22:08:28 +03:00
} else {
setDefaultTempPath ( QString : : null ) ;
}
2010-11-16 23:34:31 +03:00
setAppendLabelToSavePath ( pref . appendTorrentLabel ( ) ) ;
setAppendqBExtension ( pref . useIncompleteFilesExtension ( ) ) ;
preAllocateAllFiles ( pref . preAllocateAllFiles ( ) ) ;
2012-08-21 11:16:49 +04:00
// * Torrent export directory
const bool torrentExportEnabled = pref . isTorrentExportEnabled ( ) ;
if ( m_torrentExportEnabled ! = torrentExportEnabled ) {
m_torrentExportEnabled = torrentExportEnabled ;
if ( m_torrentExportEnabled ) {
2010-01-31 16:09:46 +03:00
qDebug ( " Torrent export is enabled, exporting the current torrents " ) ;
2012-08-21 11:16:49 +04:00
exportTorrentFiles ( pref . getTorrentExportDir ( ) ) ;
2010-01-31 16:09:46 +03:00
}
}
2012-08-21 11:16:49 +04:00
// * Finished Torrent export directory
const bool finishedTorrentExportEnabled = pref . isFinishedTorrentExportEnabled ( ) ;
if ( m_finishedTorrentExportEnabled ! = finishedTorrentExportEnabled )
m_finishedTorrentExportEnabled = finishedTorrentExportEnabled ;
2009-11-14 22:08:28 +03:00
// Connection
// * Global download limit
2010-11-16 23:34:31 +03:00
const bool alternative_speeds = pref . isAltBandwidthEnabled ( ) ;
2010-01-23 23:45:14 +03:00
int down_limit ;
2012-02-20 21:30:53 +04:00
if ( alternative_speeds )
2010-11-16 23:34:31 +03:00
down_limit = pref . getAltGlobalDownloadLimit ( ) ;
2010-01-23 23:45:14 +03:00
else
2010-11-16 23:34:31 +03:00
down_limit = pref . getGlobalDownloadLimit ( ) ;
2012-02-20 21:30:53 +04:00
if ( down_limit < = 0 ) {
2009-11-14 22:08:28 +03:00
// Download limit disabled
setDownloadRateLimit ( - 1 ) ;
} else {
// Enabled
setDownloadRateLimit ( down_limit * 1024 ) ;
}
2010-01-23 23:45:14 +03:00
int up_limit ;
2012-02-20 21:30:53 +04:00
if ( alternative_speeds )
2010-11-16 23:34:31 +03:00
up_limit = pref . getAltGlobalUploadLimit ( ) ;
2010-01-23 23:45:14 +03:00
else
2010-11-16 23:34:31 +03:00
up_limit = pref . getGlobalUploadLimit ( ) ;
2009-11-14 22:08:28 +03:00
// * Global Upload limit
2012-02-20 21:30:53 +04:00
if ( up_limit < = 0 ) {
2009-11-14 22:08:28 +03:00
// Upload limit disabled
setUploadRateLimit ( - 1 ) ;
} else {
// Enabled
setUploadRateLimit ( up_limit * 1024 ) ;
}
2012-02-20 21:30:53 +04:00
if ( pref . isSchedulerEnabled ( ) ) {
if ( ! bd_scheduler ) {
2010-01-24 14:57:15 +03:00
bd_scheduler = new BandwidthScheduler ( this ) ;
connect ( bd_scheduler , SIGNAL ( switchToAlternativeMode ( bool ) ) , this , SLOT ( useAlternativeSpeedsLimit ( bool ) ) ) ;
}
bd_scheduler - > start ( ) ;
} else {
2013-10-20 15:07:24 +04:00
delete bd_scheduler ;
2010-01-24 14:57:15 +03:00
}
2010-01-03 01:20:37 +03:00
# ifndef DISABLE_GUI
2009-11-15 13:59:11 +03:00
// Resolve countries
2009-11-15 23:03:23 +03:00
qDebug ( " Loading country resolution settings " ) ;
2010-11-16 23:34:31 +03:00
const bool new_resolv_countries = pref . resolvePeerCountries ( ) ;
2012-02-20 21:30:53 +04:00
if ( resolve_countries ! = new_resolv_countries ) {
2013-11-19 01:38:43 +04:00
qDebug ( " in country resolution settings " ) ;
2009-11-15 13:59:11 +03:00
resolve_countries = new_resolv_countries ;
2012-02-20 21:30:53 +04:00
if ( resolve_countries & & ! geoipDBLoaded ) {
2009-11-15 23:03:23 +03:00
qDebug ( " Loading geoip database " ) ;
2010-11-20 18:59:17 +03:00
GeoIPManager : : loadDatabase ( s ) ;
2009-11-15 23:03:23 +03:00
geoipDBLoaded = true ;
}
2009-11-15 13:59:11 +03:00
// Update torrent handles
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2009-11-15 13:59:11 +03:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) )
2009-11-15 13:59:11 +03:00
h . resolve_countries ( resolve_countries ) ;
}
}
2010-01-03 01:20:37 +03:00
# endif
2010-12-05 19:29:18 +03:00
// * UPnP / NAT-PMP
2012-02-20 21:30:53 +04:00
if ( pref . isUPnPEnabled ( ) ) {
2009-11-14 22:08:28 +03:00
enableUPnP ( true ) ;
2010-12-05 19:29:18 +03:00
addConsoleMessage ( tr ( " UPnP / NAT-PMP support [ON] " ) , QString : : fromUtf8 ( " blue " ) ) ;
2009-11-14 22:08:28 +03:00
} else {
enableUPnP ( false ) ;
2010-12-05 19:29:18 +03:00
addConsoleMessage ( tr ( " UPnP / NAT-PMP support [OFF] " ) , QString : : fromUtf8 ( " blue " ) ) ;
2009-11-14 22:08:28 +03:00
}
// * Session settings
2011-04-17 14:29:44 +04:00
session_settings sessionSettings = s - > settings ( ) ;
2010-07-24 21:35:29 +04:00
sessionSettings . user_agent = " qBittorrent " VERSION ;
2012-06-24 10:59:12 +04:00
//std::cout << "HTTP user agent is " << sessionSettings.user_agent << std::endl;
2009-12-30 16:10:06 +03:00
addConsoleMessage ( tr ( " HTTP user agent is %1 " ) . arg ( misc : : toQString ( sessionSettings . user_agent ) ) ) ;
2009-11-14 22:08:28 +03:00
sessionSettings . upnp_ignore_nonrouters = true ;
sessionSettings . use_dht_as_fallback = false ;
2013-01-16 21:07:22 +04:00
// Disable support for SSL torrents for now
sessionSettings . ssl_listen = 0 ;
2009-11-28 13:36:34 +03:00
// To prevent ISPs from blocking seeding
sessionSettings . lazy_bitfields = true ;
2009-11-28 18:03:27 +03:00
// Speed up exit
sessionSettings . stop_tracker_timeout = 1 ;
2009-11-19 18:50:57 +03:00
//sessionSettings.announce_to_all_trackers = true;
2009-12-02 21:19:16 +03:00
sessionSettings . auto_scrape_interval = 1200 ; // 20 minutes
2011-09-18 21:05:30 +04:00
bool announce_to_all = pref . announceToAllTrackers ( ) ;
sessionSettings . announce_to_all_trackers = announce_to_all ;
sessionSettings . announce_to_all_tiers = announce_to_all ;
2009-12-02 21:19:16 +03:00
sessionSettings . auto_scrape_min_interval = 900 ; // 15 minutes
2012-10-07 20:14:53 +04:00
int cache_size = pref . diskCacheSize ( ) ;
2012-12-01 16:08:46 +04:00
sessionSettings . cache_size = cache_size ? cache_size * 64 : - 1 ;
2013-03-18 13:45:30 +04:00
sessionSettings . cache_expiry = pref . diskCacheTTL ( ) ;
2012-12-26 22:24:36 +04:00
qDebug ( ) < < " Using a disk cache size of " < < cache_size < < " MiB " ;
2011-09-20 21:15:47 +04:00
sessionSettings . anonymous_mode = pref . isAnonymousModeEnabled ( ) ;
if ( sessionSettings . anonymous_mode ) {
addConsoleMessage ( tr ( " Anonymous mode [ON] " ) , " blue " ) ;
2012-09-07 15:44:21 +04:00
} else {
addConsoleMessage ( tr ( " Anonymous mode [OFF] " ) , " blue " ) ;
2011-09-20 21:15:47 +04:00
}
2009-11-14 22:08:28 +03:00
// Queueing System
2012-02-20 21:30:53 +04:00
if ( pref . isQueueingSystemEnabled ( ) ) {
2013-10-10 00:34:00 +04:00
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
2010-11-16 23:34:31 +03:00
sessionSettings . active_seeds = pref . getMaxActiveUploads ( ) ;
2011-09-18 20:34:29 +04:00
sessionSettings . dont_count_slow_torrents = pref . ignoreSlowTorrentsForQueueing ( ) ;
2009-11-14 22:08:28 +03:00
setQueueingEnabled ( true ) ;
} else {
sessionSettings . active_downloads = - 1 ;
sessionSettings . active_seeds = - 1 ;
sessionSettings . active_limit = - 1 ;
setQueueingEnabled ( false ) ;
}
2010-01-31 18:27:54 +03:00
// Outgoing ports
2010-11-16 23:34:31 +03:00
sessionSettings . outgoing_ports = std : : make_pair ( pref . outgoingPortsMin ( ) , pref . outgoingPortsMax ( ) ) ;
2010-01-31 18:42:24 +03:00
// Ignore limits on LAN
2010-11-24 23:31:14 +03:00
qDebug ( ) < < " Ignore limits on LAN " < < pref . ignoreLimitsOnLAN ( ) ;
2010-11-16 23:34:31 +03:00
sessionSettings . ignore_limits_on_local_network = pref . ignoreLimitsOnLAN ( ) ;
2010-01-31 18:57:07 +03:00
// Include overhead in transfer limits
2010-11-16 23:34:31 +03:00
sessionSettings . rate_limit_ip_overhead = pref . includeOverheadInLimits ( ) ;
2011-02-05 18:44:48 +03:00
// IP address to announce to trackers
QString announce_ip = pref . getNetworkAddress ( ) ;
2013-10-23 23:16:23 +04:00
if ( ! announce_ip . isEmpty ( ) )
2011-04-17 00:08:32 +04:00
sessionSettings . announce_ip = announce_ip . toStdString ( ) ;
2010-11-29 00:12:42 +03:00
// Super seeding
sessionSettings . strict_super_seeding = pref . isSuperSeedingEnabled ( ) ;
2011-04-17 00:08:32 +04:00
// * Max Half-open connections
sessionSettings . half_open_limit = pref . getMaxHalfOpenConnections ( ) ;
// * Max connections limit
sessionSettings . connections_limit = pref . getMaxConnecs ( ) ;
2013-07-22 02:20:48 +04:00
// * Global max upload slots
sessionSettings . unchoke_slots_limit = pref . getMaxUploads ( ) ;
2011-04-17 18:42:38 +04:00
// uTP
2013-06-27 16:29:02 +04:00
sessionSettings . enable_incoming_utp = pref . isuTPEnabled ( ) ;
sessionSettings . enable_outgoing_utp = pref . isuTPEnabled ( ) ;
2011-04-17 18:42:38 +04:00
// uTP rate limiting
sessionSettings . rate_limit_utp = pref . isuTPRateLimited ( ) ;
2013-11-20 02:21:48 +04:00
if ( sessionSettings . rate_limit_utp )
sessionSettings . mixed_mode_algorithm = session_settings : : prefer_tcp ;
else
sessionSettings . mixed_mode_algorithm = session_settings : : peer_proportional ;
2013-06-27 16:25:23 +04:00
sessionSettings . connection_speed = 20 ; //default is 10
2011-04-17 00:08:32 +04:00
qDebug ( ) < < " Settings SessionSettings " ;
setSessionSettings ( sessionSettings ) ;
// Bittorrent
2009-11-14 22:08:28 +03:00
// * Max connections per torrent limit
2010-11-16 23:34:31 +03:00
setMaxConnectionsPerTorrent ( pref . getMaxConnecsPerTorrent ( ) ) ;
2009-11-14 22:08:28 +03:00
// * Max uploads per torrent limit
2010-11-16 23:34:31 +03:00
setMaxUploadsPerTorrent ( pref . getMaxUploadsPerTorrent ( ) ) ;
2009-11-14 22:08:28 +03:00
// * DHT
2012-02-20 21:30:53 +04:00
if ( pref . isDHTEnabled ( ) ) {
2009-11-14 22:08:28 +03:00
// Set DHT Port
2012-02-20 21:30:53 +04:00
if ( enableDHT ( true ) ) {
2014-01-01 04:49:16 +04:00
int dht_port = 0 ;
# if LIBTORRENT_VERSION_NUM < 10000
if ( ! pref . isDHTPortSameAsBT ( ) )
2010-11-16 23:34:31 +03:00
dht_port = pref . getDHTPort ( ) ;
2009-11-14 22:08:28 +03:00
setDHTPort ( dht_port ) ;
2014-01-01 04:49:16 +04:00
# endif
2012-02-20 21:30:53 +04:00
if ( dht_port = = 0 ) dht_port = new_listenPort ;
2009-11-14 22:08:28 +03:00
addConsoleMessage ( tr ( " DHT support [ON], port: UDP/%1 " ) . arg ( dht_port ) , QString : : fromUtf8 ( " blue " ) ) ;
} else {
addConsoleMessage ( tr ( " DHT support [OFF] " ) , QString : : fromUtf8 ( " red " ) ) ;
}
} else {
enableDHT ( false ) ;
addConsoleMessage ( tr ( " DHT support [OFF] " ) , QString : : fromUtf8 ( " blue " ) ) ;
}
2014-01-01 04:49:16 +04:00
2009-11-14 22:08:28 +03:00
// * PeX
2012-02-20 21:30:53 +04:00
if ( PeXEnabled ) {
2009-12-17 21:00:21 +03:00
addConsoleMessage ( tr ( " PeX support [ON] " ) , QString : : fromUtf8 ( " blue " ) ) ;
} else {
addConsoleMessage ( tr ( " PeX support [OFF] " ) , QString : : fromUtf8 ( " red " ) ) ;
}
2012-02-20 21:30:53 +04:00
if ( PeXEnabled ! = pref . isPeXEnabled ( ) ) {
2009-12-17 21:00:21 +03:00
addConsoleMessage ( tr ( " Restart is required to toggle PeX support " ) , QString : : fromUtf8 ( " red " ) ) ;
}
2009-11-14 22:08:28 +03:00
// * LSD
2012-02-20 21:30:53 +04:00
if ( pref . isLSDEnabled ( ) ) {
2009-11-14 22:08:28 +03:00
enableLSD ( true ) ;
2010-12-05 19:36:02 +03:00
addConsoleMessage ( tr ( " Local Peer Discovery support [ON] " ) , QString : : fromUtf8 ( " blue " ) ) ;
2009-11-14 22:08:28 +03:00
} else {
enableLSD ( false ) ;
addConsoleMessage ( tr ( " Local Peer Discovery support [OFF] " ) , QString : : fromUtf8 ( " blue " ) ) ;
}
// * Encryption
2010-11-16 23:34:31 +03:00
const int encryptionState = pref . getEncryptionSetting ( ) ;
2009-11-14 22:08:28 +03:00
// The most secure, rc4 only so that all streams and encrypted
pe_settings encryptionSettings ;
encryptionSettings . allowed_enc_level = pe_settings : : rc4 ;
encryptionSettings . prefer_rc4 = true ;
switch ( encryptionState ) {
case 0 : //Enabled
encryptionSettings . out_enc_policy = pe_settings : : enabled ;
encryptionSettings . in_enc_policy = pe_settings : : enabled ;
addConsoleMessage ( tr ( " Encryption support [ON] " ) , QString : : fromUtf8 ( " blue " ) ) ;
break ;
case 1 : // Forced
encryptionSettings . out_enc_policy = pe_settings : : forced ;
encryptionSettings . in_enc_policy = pe_settings : : forced ;
addConsoleMessage ( tr ( " Encryption support [FORCED] " ) , QString : : fromUtf8 ( " blue " ) ) ;
break ;
default : // Disabled
encryptionSettings . out_enc_policy = pe_settings : : disabled ;
encryptionSettings . in_enc_policy = pe_settings : : disabled ;
addConsoleMessage ( tr ( " Encryption support [OFF] " ) , QString : : fromUtf8 ( " blue " ) ) ;
}
applyEncryptionSettings ( encryptionSettings ) ;
// * Maximum ratio
2010-11-16 23:34:31 +03:00
high_ratio_action = pref . getMaxRatioAction ( ) ;
2011-03-07 22:26:44 +03:00
setGlobalMaxRatio ( pref . getGlobalMaxRatio ( ) ) ;
updateRatioTimer ( ) ;
2009-11-14 22:08:28 +03:00
// Ip Filter
2010-11-16 23:34:31 +03:00
FilterParserThread : : processFilterList ( s , pref . bannedIPs ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( pref . isFilteringEnabled ( ) ) {
2010-11-16 23:34:31 +03:00
enableIPFilter ( pref . getFilter ( ) ) ;
2009-11-14 22:08:28 +03:00
} else {
disableIPFilter ( ) ;
}
2009-11-18 20:46:59 +03:00
// Update Web UI
2010-11-29 19:55:23 +03:00
// Use a QTimer because the function can be called from qBtSession constructor
QTimer : : singleShot ( 0 , this , SLOT ( initWebUi ( ) ) ) ;
2009-11-14 22:08:28 +03:00
// * Proxy settings
proxy_settings proxySettings ;
2012-02-20 21:30:53 +04:00
if ( pref . isProxyEnabled ( ) ) {
2009-11-14 22:08:28 +03:00
qDebug ( " Enabling P2P proxy " ) ;
2010-11-18 23:05:56 +03:00
proxySettings . hostname = pref . getProxyIp ( ) . toStdString ( ) ;
2009-11-14 22:08:28 +03:00
qDebug ( " hostname is %s " , proxySettings . hostname . c_str ( ) ) ;
2010-11-18 23:05:56 +03:00
proxySettings . port = pref . getProxyPort ( ) ;
2009-11-14 22:08:28 +03:00
qDebug ( " port is %d " , proxySettings . port ) ;
2012-02-20 21:30:53 +04:00
if ( pref . isProxyAuthEnabled ( ) ) {
2010-11-18 23:05:56 +03:00
proxySettings . username = pref . getProxyUsername ( ) . toStdString ( ) ;
proxySettings . password = pref . getProxyPassword ( ) . toStdString ( ) ;
2009-11-14 22:08:28 +03:00
qDebug ( " username is %s " , proxySettings . username . c_str ( ) ) ;
qDebug ( " password is %s " , proxySettings . password . c_str ( ) ) ;
}
}
2010-11-18 23:05:56 +03:00
switch ( pref . getProxyType ( ) ) {
2010-10-24 01:46:05 +04:00
case Proxy : : HTTP :
2009-12-30 13:53:58 +03:00
qDebug ( " type: http " ) ;
proxySettings . type = proxy_settings : : http ;
break ;
2010-10-24 01:46:05 +04:00
case Proxy : : HTTP_PW :
2009-12-30 13:53:58 +03:00
qDebug ( " type: http_pw " ) ;
proxySettings . type = proxy_settings : : http_pw ;
break ;
2010-10-24 01:46:05 +04:00
case Proxy : : SOCKS4 :
2009-12-30 13:53:58 +03:00
proxySettings . type = proxy_settings : : socks4 ;
2013-05-22 21:41:53 +04:00
break ;
2010-10-24 01:46:05 +04:00
case Proxy : : SOCKS5 :
2009-12-30 13:53:58 +03:00
qDebug ( " type: socks5 " ) ;
proxySettings . type = proxy_settings : : socks5 ;
break ;
2010-10-24 01:46:05 +04:00
case Proxy : : SOCKS5_PW :
2009-12-30 13:53:58 +03:00
qDebug ( " type: socks5_pw " ) ;
proxySettings . type = proxy_settings : : socks5_pw ;
break ;
default :
proxySettings . type = proxy_settings : : none ;
}
2010-11-18 23:05:56 +03:00
setProxySettings ( proxySettings ) ;
2010-10-16 01:55:56 +04:00
// Tracker
2012-02-20 21:30:53 +04:00
if ( pref . isTrackerEnabled ( ) ) {
if ( ! m_tracker ) {
2010-10-16 01:55:56 +04:00
m_tracker = new QTracker ( this ) ;
}
2012-02-20 21:30:53 +04:00
if ( m_tracker - > start ( ) ) {
2010-10-16 01:55:56 +04:00
addConsoleMessage ( tr ( " Embedded Tracker [ON] " ) , QString : : fromUtf8 ( " blue " ) ) ;
} else {
addConsoleMessage ( tr ( " Failed to start the embedded tracker! " ) , QString : : fromUtf8 ( " red " ) ) ;
}
} else {
addConsoleMessage ( tr ( " Embedded Tracker [OFF] " ) ) ;
2012-02-20 21:30:53 +04:00
if ( m_tracker )
2010-10-16 01:55:56 +04:00
delete m_tracker ;
}
2011-04-13 21:32:28 +04:00
// * Scan dirs
const QStringList scan_dirs = pref . getScanDirs ( ) ;
QList < bool > downloadInDirList = pref . getDownloadInScanDirs ( ) ;
while ( scan_dirs . size ( ) > downloadInDirList . size ( ) ) {
downloadInDirList < < false ;
}
int i = 0 ;
foreach ( const QString & dir , scan_dirs ) {
qDebug ( ) < < " Adding scan dir " < < dir < < downloadInDirList . at ( i ) ;
m_scanFolders - > addPath ( dir , downloadInDirList . at ( i ) ) ;
+ + i ;
}
2009-11-14 22:08:28 +03:00
qDebug ( " Session configured " ) ;
}
2010-11-29 19:55:23 +03:00
void QBtSession : : initWebUi ( ) {
Preferences pref ;
if ( pref . isWebUiEnabled ( ) ) {
const quint16 port = pref . getWebUiPort ( ) ;
const QString username = pref . getWebUiUsername ( ) ;
const QString password = pref . getWebUiPassword ( ) ;
2012-02-20 21:30:53 +04:00
if ( httpServer ) {
if ( httpServer - > serverPort ( ) ! = port ) {
2010-11-29 19:55:23 +03:00
httpServer - > close ( ) ;
}
} else {
2012-05-26 21:42:44 +04:00
httpServer = new HttpServer ( this ) ;
2009-12-30 12:46:06 +03:00
}
2011-06-05 20:08:30 +04:00
# ifndef QT_NO_OPENSSL
if ( pref . isWebUiHttpsEnabled ( ) ) {
QSslCertificate cert ( pref . getWebUiHttpsCertificate ( ) ) ;
QSslKey key ;
const QByteArray raw_key = pref . getWebUiHttpsKey ( ) ;
key = QSslKey ( raw_key , QSsl : : Rsa ) ;
if ( ! cert . isNull ( ) & & ! key . isNull ( ) )
httpServer - > enableHttps ( cert , key ) ;
else
httpServer - > disableHttps ( ) ;
} else {
httpServer - > disableHttps ( ) ;
}
# endif
2010-11-29 19:55:23 +03:00
httpServer - > setAuthorization ( username , password ) ;
2011-02-27 12:34:42 +03:00
httpServer - > setlocalAuthEnabled ( pref . isWebUiLocalAuthEnabled ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( ! httpServer - > isListening ( ) ) {
2010-11-29 19:55:23 +03:00
bool success = httpServer - > listen ( QHostAddress : : Any , port ) ;
if ( success )
addConsoleMessage ( tr ( " The Web UI is listening on port %1 " ) . arg ( port ) ) ;
else
addConsoleMessage ( tr ( " Web User Interface Error - Unable to bind Web UI to port %1 " ) . arg ( port ) , " red " ) ;
}
2011-04-15 17:02:39 +04:00
// DynDNS
2012-02-20 21:30:53 +04:00
if ( pref . isDynDNSEnabled ( ) ) {
if ( ! m_dynDNSUpdater )
2011-04-15 17:02:39 +04:00
m_dynDNSUpdater = new DNSUpdater ( this ) ;
else
m_dynDNSUpdater - > updateCredentials ( ) ;
} else {
2012-02-20 21:30:53 +04:00
if ( m_dynDNSUpdater ) {
2011-04-15 17:02:39 +04:00
delete m_dynDNSUpdater ;
m_dynDNSUpdater = 0 ;
}
}
} else {
2012-02-20 21:30:53 +04:00
if ( httpServer )
2011-04-17 00:08:32 +04:00
delete httpServer ;
2012-02-20 21:30:53 +04:00
if ( m_dynDNSUpdater ) {
2011-04-15 17:02:39 +04:00
delete m_dynDNSUpdater ;
m_dynDNSUpdater = 0 ;
}
2009-12-30 12:46:06 +03:00
}
2009-11-18 20:46:59 +03:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : useAlternativeSpeedsLimit ( bool alternative ) {
2010-12-02 20:10:34 +03:00
qDebug ( ) < < Q_FUNC_INFO < < alternative ;
2010-01-24 14:57:15 +03:00
// Save new state to remember it on startup
2010-11-16 23:34:31 +03:00
Preferences pref ;
2013-10-20 15:07:24 +04:00
// Stop the scheduler when the user has manually changed the bandwidth mode
if ( ! pref . isSchedulerEnabled ( ) )
delete bd_scheduler ;
2010-11-16 23:34:31 +03:00
pref . setAltBandwidthEnabled ( alternative ) ;
2010-01-24 14:57:15 +03:00
// Apply settings to the bittorrent session
2010-12-02 20:02:13 +03:00
int down_limit = alternative ? pref . getAltGlobalDownloadLimit ( ) : pref . getGlobalDownloadLimit ( ) ;
2012-02-20 21:30:53 +04:00
if ( down_limit < = 0 ) {
2010-12-02 20:02:13 +03:00
down_limit = - 1 ;
2010-01-24 14:57:15 +03:00
} else {
2010-12-02 20:02:13 +03:00
down_limit * = 1024 ;
2010-01-24 14:57:15 +03:00
}
2010-12-02 20:02:13 +03:00
setDownloadRateLimit ( down_limit ) ;
// Upload rate
int up_limit = alternative ? pref . getAltGlobalUploadLimit ( ) : pref . getGlobalUploadLimit ( ) ;
2012-02-20 21:30:53 +04:00
if ( up_limit < = 0 ) {
2010-12-02 20:02:13 +03:00
up_limit = - 1 ;
} else {
up_limit * = 1024 ;
}
setUploadRateLimit ( up_limit ) ;
// Notify
2010-01-24 14:57:15 +03:00
emit alternativeSpeedsModeChanged ( alternative ) ;
}
2007-03-05 16:55:23 +03:00
// Return the torrent handle, given its hash
2012-02-20 23:32:58 +04:00
QTorrentHandle QBtSession : : getTorrentHandle ( const QString & hash ) const {
2012-02-16 23:04:02 +04:00
return QTorrentHandle ( s - > find_torrent ( QStringToSha1 ( hash ) ) ) ;
2007-03-05 16:55:23 +03:00
}
2010-10-17 18:46:01 +04:00
bool QBtSession : : hasActiveTorrents ( ) const {
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-04-05 23:03:00 +04:00
const QTorrentHandle h ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) & & ! h . is_paused ( ) & & ! h . is_queued ( ) )
2009-11-07 22:55:33 +03:00
return true ;
2009-08-16 07:09:20 +04:00
}
2009-11-07 22:55:33 +03:00
return false ;
2008-05-18 13:26:02 +04:00
}
2010-10-17 18:46:01 +04:00
bool QBtSession : : hasDownloadingTorrents ( ) const {
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2012-02-20 21:30:53 +04:00
if ( torrentIT - > is_valid ( ) ) {
2010-08-20 13:02:27 +04:00
try {
2014-01-16 18:17:10 +04:00
const torrent_status status = torrentIT - > status ( ) ;
if ( status . state ! = torrent_status : : finished & & status . state ! = torrent_status : : seeding
& & ! status . paused )
2010-08-20 13:02:27 +04:00
return true ;
} catch ( std : : exception ) { }
}
2010-08-16 21:35:32 +04:00
}
return false ;
}
2010-10-17 18:46:01 +04:00
void QBtSession : : banIP ( QString ip ) {
2009-11-17 19:02:35 +03:00
FilterParserThread : : processFilterList ( s , QStringList ( ip ) ) ;
2010-11-16 23:34:31 +03:00
Preferences ( ) . banIP ( ip ) ;
2009-11-17 19:02:35 +03:00
}
2007-03-05 16:55:23 +03:00
// Delete a torrent from the session, given its hash
// permanent = true means that the torrent will be removed from the hard-drive too
2011-02-26 22:56:15 +03:00
void QBtSession : : deleteTorrent ( const QString & hash , bool delete_local_files ) {
2010-03-04 23:19:25 +03:00
qDebug ( " Deleting torrent with hash: %s " , qPrintable ( hash ) ) ;
2010-07-23 18:05:53 +04:00
const QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) {
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
2007-03-05 20:35:38 +03:00
return ;
}
2010-11-14 21:46:16 +03:00
emit torrentAboutToBeRemoved ( h ) ;
2010-10-28 20:50:45 +04:00
qDebug ( " h is valid, getting name or hash... " ) ;
QString fileName ;
2012-02-20 21:30:53 +04:00
if ( h . has_metadata ( ) )
2010-10-28 20:50:45 +04:00
fileName = h . name ( ) ;
else
fileName = h . hash ( ) ;
2007-10-19 20:00:42 +04:00
// Remove it from session
2012-02-20 21:30:53 +04:00
if ( delete_local_files ) {
if ( h . has_metadata ( ) ) {
2010-10-28 20:50:45 +04:00
QDir save_dir ( h . save_path ( ) ) ;
2012-03-17 17:41:32 +04:00
if ( save_dir ! = QDir ( defaultSavePath ) & & ( defaultTempPath . isEmpty ( ) | | save_dir ! = QDir ( defaultTempPath ) ) ) {
2010-10-28 20:50:45 +04:00
savePathsToRemove [ hash ] = save_dir . absolutePath ( ) ;
2012-03-17 17:41:32 +04:00
qDebug ( ) < < " Save path to remove (async): " < < save_dir . absolutePath ( ) ;
}
2010-10-28 20:50:45 +04:00
}
2010-10-20 00:00:50 +04:00
s - > remove_torrent ( h , session : : delete_files ) ;
2010-07-18 00:55:40 +04:00
} else {
2010-10-28 20:50:45 +04:00
QStringList uneeded_files ;
2012-02-20 21:30:53 +04:00
if ( h . has_metadata ( ) )
2011-04-17 14:29:44 +04:00
uneeded_files = h . absolute_files_path_uneeded ( ) ;
2010-10-20 00:00:50 +04:00
s - > remove_torrent ( h ) ;
2011-01-08 16:41:15 +03:00
// Remove unneeded and incomplete files
2012-02-20 21:30:53 +04:00
foreach ( const QString & uneeded_file , uneeded_files ) {
2010-10-18 21:44:37 +04:00
qDebug ( " Removing uneeded file: %s " , qPrintable ( uneeded_file ) ) ;
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( uneeded_file ) ;
2012-05-16 22:19:05 +04:00
const QString parent_folder = fsutils : : branchPath ( uneeded_file ) ;
2010-12-29 23:29:55 +03:00
qDebug ( " Attempt to remove parent folder (if empty): %s " , qPrintable ( parent_folder ) ) ;
2012-03-17 18:36:02 +04:00
QDir ( ) . rmpath ( parent_folder ) ;
2011-01-08 16:41:15 +03:00
}
2010-07-18 00:55:40 +04:00
}
2007-03-05 16:55:23 +03:00
// Remove it from torrent backup directory
2012-05-16 22:19:05 +04:00
QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2007-07-31 12:13:38 +04:00
QStringList filters ;
filters < < hash + " .* " ;
2010-07-23 18:05:53 +04:00
const QStringList files = torrentBackup . entryList ( filters , QDir : : Files , QDir : : Unsorted ) ;
2012-02-20 21:30:53 +04:00
foreach ( const QString & file , files ) {
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( torrentBackup . absoluteFilePath ( file ) ) ;
2007-07-31 12:13:38 +04:00
}
2009-08-16 07:09:20 +04:00
TorrentPersistentData : : deletePersistentData ( hash ) ;
2013-09-18 01:44:18 +04:00
TorrentTempData : : deleteTempData ( hash ) ;
HiddenData : : deleteData ( hash ) ;
2007-07-27 17:58:12 +04:00
// Remove tracker errors
2009-11-19 18:04:43 +03:00
trackersInfos . remove ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( delete_local_files )
2009-11-18 15:11:15 +03:00
addConsoleMessage ( tr ( " '%1' was removed from transfer list and hard disk. " , " 'xxx.avi' was removed... " ) . arg ( fileName ) ) ;
2008-09-07 15:31:29 +04:00
else
2009-11-18 15:11:15 +03:00
addConsoleMessage ( tr ( " '%1' was removed from transfer list. " , " 'xxx.avi' was removed... " ) . arg ( fileName ) ) ;
2010-10-28 20:50:45 +04:00
qDebug ( " Torrent deleted. " ) ;
2008-05-16 11:10:50 +04:00
emit deletedTorrent ( hash ) ;
2010-10-28 20:50:45 +04:00
qDebug ( " Deleted signal emitted. " ) ;
2007-03-05 16:55:23 +03:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : pauseAllTorrents ( ) {
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-11-14 22:22:39 +03:00
try {
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_paused ( ) ) {
2010-11-14 22:22:39 +03:00
h . pause ( ) ;
emit pausedTorrent ( h ) ;
}
} catch ( invalid_handle & ) { }
2009-08-16 07:09:20 +04:00
}
2008-05-16 11:10:50 +04:00
}
2010-10-17 18:46:01 +04:00
std : : vector < torrent_handle > QBtSession : : getTorrents ( ) const {
2010-08-20 13:02:27 +04:00
return s - > get_torrents ( ) ;
}
2010-10-17 18:46:01 +04:00
void QBtSession : : resumeAllTorrents ( ) {
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-11-14 22:22:39 +03:00
try {
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_paused ( ) ) {
2010-11-14 22:22:39 +03:00
h . resume ( ) ;
emit resumedTorrent ( h ) ;
}
} catch ( invalid_handle & ) { }
2009-08-16 07:09:20 +04:00
}
2008-05-16 11:10:50 +04:00
}
2011-02-26 22:56:15 +03:00
void QBtSession : : pauseTorrent ( const QString & hash ) {
2009-08-16 07:09:20 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_paused ( ) ) {
2009-08-16 07:09:20 +04:00
h . pause ( ) ;
emit pausedTorrent ( h ) ;
}
2008-12-27 13:14:16 +03:00
}
2011-02-26 22:56:15 +03:00
void QBtSession : : resumeTorrent ( const QString & hash ) {
2009-08-16 07:09:20 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_paused ( ) ) {
2009-08-16 07:09:20 +04:00
h . resume ( ) ;
emit resumedTorrent ( h ) ;
}
2008-12-27 13:14:16 +03:00
}
2011-02-26 22:56:15 +03:00
bool QBtSession : : loadFastResumeData ( const QString & hash , std : : vector < char > & buf ) {
2012-05-16 22:19:05 +04:00
const QString fastresume_path = QDir ( fsutils : : BTBackupLocation ( ) ) . absoluteFilePath ( hash + QString ( " .fastresume " ) ) ;
2010-10-17 18:46:01 +04:00
qDebug ( " Trying to load fastresume data: %s " , qPrintable ( fastresume_path ) ) ;
2011-01-23 22:31:48 +03:00
QFile fastresume_file ( fastresume_path ) ;
2012-08-24 20:19:54 +04:00
if ( fastresume_file . size ( ) < = 0 )
return false ;
if ( ! fastresume_file . open ( QIODevice : : ReadOnly ) )
return false ;
2011-01-23 22:31:48 +03:00
const QByteArray content = fastresume_file . readAll ( ) ;
const int content_size = content . size ( ) ;
2012-08-24 20:19:54 +04:00
Q_ASSERT ( content_size > 0 ) ;
2011-01-23 22:31:48 +03:00
buf . resize ( content_size ) ;
memcpy ( & buf [ 0 ] , content . data ( ) , content_size ) ;
2012-08-24 20:19:54 +04:00
fastresume_file . close ( ) ;
2011-01-23 22:31:48 +03:00
return true ;
2010-10-17 18:46:01 +04:00
}
2011-02-26 22:56:15 +03:00
void QBtSession : : loadTorrentSettings ( QTorrentHandle & h ) {
2010-11-16 23:34:31 +03:00
Preferences pref ;
2010-10-17 18:46:01 +04:00
// Connections limit per torrent
2010-11-16 23:34:31 +03:00
h . set_max_connections ( pref . getMaxConnecsPerTorrent ( ) ) ;
2010-10-17 18:46:01 +04:00
// Uploads limit per torrent
2010-11-16 23:34:31 +03:00
h . set_max_uploads ( pref . getMaxUploadsPerTorrent ( ) ) ;
2010-10-17 18:46:01 +04:00
# ifndef DISABLE_GUI
// Resolve countries
h . resolve_countries ( resolve_countries ) ;
# endif
}
2012-08-21 11:16:49 +04:00
QTorrentHandle QBtSession : : addMagnetUri ( QString magnet_uri , bool resumed , bool fromScanDir , const QString & filePath )
{
Q_UNUSED ( fromScanDir ) ;
Q_UNUSED ( filePath ) ;
2012-05-15 20:57:31 +04:00
Preferences pref ;
2009-08-17 09:14:03 +04:00
QTorrentHandle h ;
2013-10-22 23:29:25 +04:00
add_torrent_params p ;
libtorrent : : error_code ec ;
libtorrent : : parse_magnet_uri ( magnet_uri . toUtf8 ( ) . constData ( ) , p , ec ) ;
if ( ec ) {
2013-10-24 02:57:57 +04:00
addConsoleMessage ( tr ( " Couldn't parse this Magnet URI: '%1' " ) . arg ( magnet_uri ) ) ;
2013-10-22 23:29:25 +04:00
return h ;
}
const QString hash ( misc : : toQString ( p . info_hash ) ) ;
2012-02-20 21:30:53 +04:00
if ( hash . isEmpty ( ) ) {
2009-08-17 09:14:03 +04:00
addConsoleMessage ( tr ( " '%1' is not a valid magnet URI. " ) . arg ( magnet_uri ) ) ;
return h ;
}
2012-05-16 22:19:05 +04:00
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( resumed ) {
2010-01-20 00:47:53 +03:00
// Load metadata
2010-10-17 18:46:01 +04:00
const QString torrent_path = torrentBackup . absoluteFilePath ( hash + " .torrent " ) ;
2012-02-20 21:30:53 +04:00
if ( QFile : : exists ( torrent_path ) )
2010-10-17 18:46:01 +04:00
return addTorrent ( torrent_path , false , QString : : null , true ) ;
2009-08-17 09:14:03 +04:00
}
2010-10-17 18:46:01 +04:00
qDebug ( " Adding a magnet URI: %s " , qPrintable ( hash ) ) ;
Q_ASSERT ( magnet_uri . startsWith ( " magnet: " , Qt : : CaseInsensitive ) ) ;
2009-08-17 09:14:03 +04:00
2013-10-22 23:29:25 +04:00
// limit h_ex scope
{
// Check for duplicate torrent
QTorrentHandle h_ex = QTorrentHandle ( s - > find_torrent ( p . info_hash ) ) ;
if ( h_ex . is_valid ( ) ) {
qDebug ( " /! \\ Torrent is already in download list " ) ;
addConsoleMessage ( tr ( " '%1' is already in download list. " , " e.g: 'xxx.avi' is already in download list. " ) . arg ( magnet_uri ) ) ;
// Check if the torrent contains trackers or url seeds we don't know about
// and add them
mergeTorrents ( h_ex , magnet_uri ) ;
return h ;
}
2009-08-17 09:14:03 +04:00
}
2013-10-22 23:29:25 +04:00
initializeAddTorrentParams ( hash , p ) ;
2010-10-17 18:46:01 +04:00
// Get save path
2012-06-24 17:46:41 +04:00
QString savePath ;
if ( ! resumed & & savepathLabel_fromurl . contains ( magnet_uri ) ) {
QPair < QString , QString > savePath_label = savepathLabel_fromurl . take ( magnet_uri ) ;
if ( ! savePath_label . first . isEmpty ( ) )
savePath = savePath_label . first ;
// Remember label
if ( ! savePath_label . second . isEmpty ( ) )
TorrentTempData : : setLabel ( hash , savePath_label . second ) ;
}
if ( savePath . isEmpty ( ) )
savePath = getSavePath ( hash , false ) ;
2012-09-18 21:01:59 +04:00
if ( ! defaultTempPath . isEmpty ( ) & & ! TorrentPersistentData : : isSeed ( hash ) ) {
2010-01-05 00:16:33 +03:00
qDebug ( " addMagnetURI: Temp folder is enabled. " ) ;
2013-11-10 16:05:43 +04:00
QString torrent_tmp_path = defaultTempPath ;
p . save_path = fsutils : : toNativePath ( torrent_tmp_path ) . toUtf8 ( ) . constData ( ) ;
2010-07-16 23:53:47 +04:00
// Check if save path exists, creating it otherwise
2012-02-20 21:30:53 +04:00
if ( ! QDir ( torrent_tmp_path ) . exists ( ) )
2010-07-16 23:53:47 +04:00
QDir ( ) . mkpath ( torrent_tmp_path ) ;
2013-10-22 23:29:25 +04:00
qDebug ( " addTorrent: using save_path: %s " , qPrintable ( torrent_tmp_path ) ) ;
2010-01-05 00:16:33 +03:00
} else {
2013-11-10 16:05:43 +04:00
p . save_path = fsutils : : toNativePath ( savePath ) . toUtf8 ( ) . constData ( ) ;
2010-07-16 23:53:47 +04:00
// Check if save path exists, creating it otherwise
2012-02-20 21:30:53 +04:00
if ( ! QDir ( savePath ) . exists ( ) ) QDir ( ) . mkpath ( savePath ) ;
2013-10-22 23:29:25 +04:00
qDebug ( " addTorrent: using save_path: %s " , qPrintable ( savePath ) ) ;
2009-08-17 09:14:03 +04:00
}
2010-01-05 00:16:33 +03:00
2011-02-22 21:35:42 +03:00
qDebug ( " Adding magnet URI: %s " , qPrintable ( magnet_uri ) ) ;
2009-11-20 11:01:59 +03:00
// Adding torrent to Bittorrent session
2009-08-17 09:14:03 +04:00
try {
2013-10-22 23:29:25 +04:00
h = QTorrentHandle ( s - > add_torrent ( p ) ) ;
2014-01-03 21:24:32 +04:00
} catch ( std : : exception & e ) {
2009-08-17 09:14:03 +04:00
qDebug ( " Error: %s " , e . what ( ) ) ;
}
// Check if it worked
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) {
2009-08-17 09:14:03 +04:00
// No need to keep on, it failed.
qDebug ( " /! \\ Error: Invalid handle " ) ;
return h ;
}
Q_ASSERT ( h . hash ( ) = = hash ) ;
2010-01-05 00:16:33 +03:00
2010-10-17 18:46:01 +04:00
loadTorrentSettings ( h ) ;
2009-08-17 09:14:03 +04:00
// Load filtered files
2012-02-20 21:30:53 +04:00
if ( ! resumed ) {
2010-10-17 18:46:01 +04:00
loadTorrentTempData ( h , savePath , true ) ;
2013-09-18 01:44:18 +04:00
}
if ( HiddenData : : hasData ( hash ) & & pref . isQueueingSystemEnabled ( ) ) {
//Internally increase the queue limits to ensure that the magnet is started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
2013-10-10 00:34:00 +04:00
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
2013-09-18 01:44:18 +04:00
s - > set_settings ( sessionSettings ) ;
h . queue_position_top ( ) ;
}
if ( ! pref . addTorrentsInPause ( ) | | HiddenData : : hasData ( hash ) ) {
2009-08-17 09:14:03 +04:00
// Start torrent because it was added in paused state
h . resume ( ) ;
}
// Send torrent addition signal
2010-12-01 22:05:26 +03:00
addConsoleMessage ( tr ( " '%1' added to download list. " , " '/home/y/xxx.torrent' was added to download list. " ) . arg ( magnet_uri ) ) ;
2013-09-18 01:44:18 +04:00
if ( ! HiddenData : : hasData ( hash ) )
emit addedTorrent ( h ) ;
2009-08-17 09:14:03 +04:00
return h ;
}
2009-11-20 11:01:59 +03:00
// Add a torrent to the Bittorrent session
2010-10-17 18:46:01 +04:00
QTorrentHandle QBtSession : : addTorrent ( QString path , bool fromScanDir , QString from_url , bool resumed ) {
2007-08-20 10:29:18 +04:00
QTorrentHandle h ;
2012-05-15 20:57:31 +04:00
Preferences pref ;
2010-10-17 18:46:01 +04:00
// Check if BT_backup directory exists
2012-05-16 22:19:05 +04:00
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( ! torrentBackup . exists ( ) ) return h ;
2007-03-05 16:55:23 +03:00
2010-10-17 18:46:01 +04:00
// Fix the input path if necessary
2013-11-10 16:05:43 +04:00
path = fsutils : : fromNativePath ( path ) ;
2010-05-30 21:51:40 +04:00
# ifdef Q_WS_WIN
2010-06-04 00:08:19 +04:00
// Windows hack
2012-02-20 21:30:53 +04:00
if ( ! path . endsWith ( " .torrent " ) )
if ( QFile : : rename ( path , path + " .torrent " ) ) path + = " .torrent " ;
2010-05-30 21:51:40 +04:00
# endif
2012-02-20 21:30:53 +04:00
if ( path . startsWith ( " file: " , Qt : : CaseInsensitive ) )
2011-03-19 16:58:34 +03:00
path = QUrl : : fromEncoded ( path . toLocal8Bit ( ) ) . toLocalFile ( ) ;
2012-02-20 21:30:53 +04:00
if ( path . isEmpty ( ) ) return h ;
2010-10-17 18:46:01 +04:00
2010-12-30 22:12:03 +03:00
Q_ASSERT ( ! misc : : isUrl ( path ) ) ;
2009-08-16 07:09:20 +04:00
2010-12-30 22:12:03 +03:00
qDebug ( " Adding %s to download list " , qPrintable ( path ) ) ;
2010-10-17 18:46:01 +04:00
boost : : intrusive_ptr < torrent_info > t ;
2008-11-02 00:42:56 +03:00
try {
2011-04-09 13:03:04 +04:00
qDebug ( ) < < " Loading torrent at " < < path ;
2009-08-16 07:09:20 +04:00
// Getting torrent file informations
2013-11-10 16:05:43 +04:00
t = new torrent_info ( fsutils : : toNativePath ( path ) . toUtf8 ( ) . constData ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( ! t - > is_valid ( ) )
2010-01-03 16:00:16 +03:00
throw std : : exception ( ) ;
2011-10-04 23:18:59 +04:00
} catch ( std : : exception & e ) {
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) ) {
2009-08-16 07:09:20 +04:00
addConsoleMessage ( tr ( " Unable to decode torrent file: '%1' " , " e.g: Unable to decode torrent file: '/home/y/xxx.torrent' " ) . arg ( from_url ) , QString : : fromUtf8 ( " red " ) ) ;
2013-07-28 13:59:03 +04:00
addConsoleMessage ( misc : : toQString ( e . what ( ) ) , " red " ) ;
2009-08-16 07:09:20 +04:00
//emit invalidTorrent(from_url);
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2009-08-16 07:09:20 +04:00
} else {
2013-11-10 16:05:43 +04:00
addConsoleMessage ( tr ( " Unable to decode torrent file: '%1' " , " e.g: Unable to decode torrent file: '/home/y/xxx.torrent' " ) . arg ( fsutils : : toNativePath ( path ) ) , QString : : fromUtf8 ( " red " ) ) ;
2010-12-30 22:12:03 +03:00
//emit invalidTorrent(path);
2009-08-16 07:09:20 +04:00
}
addConsoleMessage ( tr ( " This file is either corrupted or this isn't a torrent. " ) , QString : : fromUtf8 ( " red " ) ) ;
2012-02-20 21:30:53 +04:00
if ( fromScanDir ) {
2009-08-16 07:09:20 +04:00
// Remove file
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2009-08-16 07:09:20 +04:00
}
return h ;
2008-11-02 00:42:56 +03:00
}
2010-10-17 18:46:01 +04:00
const QString hash = misc : : toQString ( t - > info_hash ( ) ) ;
2009-08-17 09:14:03 +04:00
2010-03-03 20:27:25 +03:00
qDebug ( " -> Hash: %s " , qPrintable ( hash ) ) ;
qDebug ( " -> Name: %s " , t - > name ( ) . c_str ( ) ) ;
2010-10-17 18:46:01 +04:00
// Check for duplicate
2012-02-20 21:30:53 +04:00
if ( s - > find_torrent ( t - > info_hash ( ) ) . is_valid ( ) ) {
2009-08-16 07:09:20 +04:00
qDebug ( " /! \\ Torrent is already in download list " ) ;
// Update info Bar
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) ) {
2010-03-11 19:37:49 +03:00
addConsoleMessage ( tr ( " '%1' is already in download list. " , " e.g: 'xxx.avi' is already in download list. " ) . arg ( from_url ) ) ;
} else {
2013-11-10 16:05:43 +04:00
addConsoleMessage ( tr ( " '%1' is already in download list. " , " e.g: 'xxx.avi' is already in download list. " ) . arg ( fsutils : : toNativePath ( path ) ) ) ;
2010-03-11 19:37:49 +03:00
}
// Check if the torrent contains trackers or url seeds we don't know about
// and add them
2011-02-26 22:56:15 +03:00
QTorrentHandle h_ex = getTorrentHandle ( hash ) ;
mergeTorrents ( h_ex , t ) ;
2010-10-17 16:18:34 +04:00
2010-10-17 18:46:01 +04:00
// Delete file if temporary
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) | | fromScanDir )
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2009-08-16 07:09:20 +04:00
return h ;
2008-11-02 00:42:56 +03:00
}
2010-10-17 18:46:01 +04:00
2010-06-23 19:14:38 +04:00
// Check number of files
2012-02-20 21:30:53 +04:00
if ( t - > num_files ( ) < 1 ) {
2010-06-23 19:14:38 +04:00
addConsoleMessage ( tr ( " Error: The torrent %1 does not contain any file. " ) . arg ( misc : : toQStringU ( t - > name ( ) ) ) ) ;
2010-10-17 18:46:01 +04:00
// Delete file if temporary
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) | | fromScanDir )
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2010-06-23 19:14:38 +04:00
return h ;
}
2010-10-17 18:46:01 +04:00
2010-06-23 19:14:38 +04:00
// Actually add the torrent
2013-10-22 23:29:25 +04:00
add_torrent_params p ;
initializeAddTorrentParams ( hash , p ) ;
2010-10-17 18:46:01 +04:00
p . ti = t ;
// Get fast resume data if existing
bool fastResume = false ;
2010-10-17 19:00:31 +04:00
std : : vector < char > buf ; // Needs to stay in the function scope
2012-02-20 21:30:53 +04:00
if ( resumed ) {
if ( loadFastResumeData ( hash , buf ) ) {
2008-11-02 00:42:56 +03:00
fastResume = true ;
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2008-11-02 00:42:56 +03:00
p . resume_data = & buf ;
2014-01-01 02:10:41 +04:00
# else
p . resume_data = buf ;
# endif
2010-10-17 18:46:01 +04:00
qDebug ( " Successfully loaded fast resume data " ) ;
2009-08-16 07:09:20 +04:00
}
2011-04-17 19:27:18 +04:00
}
2011-01-08 16:31:57 +03:00
2013-09-29 22:32:27 +04:00
recoverPersistentData ( hash , buf ) ;
2009-08-21 11:40:57 +04:00
QString savePath ;
2012-02-20 21:30:53 +04:00
if ( ! from_url . isEmpty ( ) & & savepathLabel_fromurl . contains ( QUrl : : fromEncoded ( from_url . toUtf8 ( ) ) ) ) {
2009-08-21 11:40:57 +04:00
// Enforcing the save path defined before URL download (from RSS for example)
2011-02-07 23:13:46 +03:00
QPair < QString , QString > savePath_label = savepathLabel_fromurl . take ( QUrl : : fromEncoded ( from_url . toUtf8 ( ) ) ) ;
2012-02-20 21:30:53 +04:00
if ( savePath_label . first . isEmpty ( ) )
2012-05-15 20:57:31 +04:00
savePath = getSavePath ( hash , fromScanDir , path ) ;
2010-11-13 13:49:22 +03:00
else
savePath = savePath_label . first ;
// Remember label
TorrentTempData : : setLabel ( hash , savePath_label . second ) ;
2009-08-21 11:40:57 +04:00
} else {
2012-05-15 20:57:31 +04:00
savePath = getSavePath ( hash , fromScanDir , path ) ;
2009-08-21 11:40:57 +04:00
}
2012-09-18 21:01:59 +04:00
if ( ! defaultTempPath . isEmpty ( ) & & ! TorrentPersistentData : : isSeed ( hash ) ) {
2010-01-05 00:16:33 +03:00
qDebug ( " addTorrent::Temp folder is enabled. " ) ;
2013-11-10 16:05:43 +04:00
QString torrent_tmp_path = defaultTempPath ;
p . save_path = fsutils : : toNativePath ( torrent_tmp_path ) . toUtf8 ( ) . constData ( ) ;
2010-07-16 23:53:47 +04:00
// Check if save path exists, creating it otherwise
2012-02-20 21:30:53 +04:00
if ( ! QDir ( torrent_tmp_path ) . exists ( ) ) QDir ( ) . mkpath ( torrent_tmp_path ) ;
2010-07-16 23:53:47 +04:00
qDebug ( " addTorrent: using save_path: %s " , qPrintable ( torrent_tmp_path ) ) ;
2010-01-05 00:16:33 +03:00
} else {
2013-11-10 16:05:43 +04:00
p . save_path = fsutils : : toNativePath ( savePath ) . toUtf8 ( ) . constData ( ) ;
2010-07-16 23:53:47 +04:00
// Check if save path exists, creating it otherwise
2012-02-20 21:30:53 +04:00
if ( ! QDir ( savePath ) . exists ( ) ) QDir ( ) . mkpath ( savePath ) ;
2010-03-03 20:27:25 +03:00
qDebug ( " addTorrent: using save_path: %s " , qPrintable ( savePath ) ) ;
2009-03-08 19:26:02 +03:00
}
2009-11-06 17:30:14 +03:00
2009-11-20 11:01:59 +03:00
// Adding torrent to Bittorrent session
2008-12-28 00:25:58 +03:00
try {
2009-08-16 07:09:20 +04:00
h = QTorrentHandle ( s - > add_torrent ( p ) ) ;
2014-01-03 21:24:32 +04:00
} catch ( std : : exception & e ) {
2008-12-28 00:25:58 +03:00
qDebug ( " Error: %s " , e . what ( ) ) ;
}
2008-11-02 00:42:56 +03:00
// Check if it worked
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) {
2009-08-16 07:09:20 +04:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) )
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2009-08-16 07:09:20 +04:00
return h ;
2008-11-02 00:42:56 +03:00
}
2009-12-08 20:20:28 +03:00
2010-10-17 18:46:01 +04:00
loadTorrentSettings ( h ) ;
2012-02-20 21:30:53 +04:00
if ( ! resumed ) {
2010-10-23 20:21:56 +04:00
qDebug ( " This is a NEW torrent (first time)... " ) ;
2010-10-17 18:46:01 +04:00
loadTorrentTempData ( h , savePath , false ) ;
2009-12-18 16:36:47 +03:00
// Append .!qB to incomplete files
2012-02-20 21:30:53 +04:00
if ( appendqBExtension )
2009-12-18 16:36:47 +03:00
appendqBextensionToTorrent ( h , true ) ;
2012-02-18 18:44:20 +04:00
2010-01-31 16:09:46 +03:00
// Backup torrent file
2010-07-23 18:05:53 +04:00
const QString newFile = torrentBackup . absoluteFilePath ( hash + " .torrent " ) ;
2012-02-20 21:30:53 +04:00
if ( path ! = newFile )
2010-12-30 22:12:03 +03:00
QFile : : copy ( path , newFile ) ;
2010-01-31 16:09:46 +03:00
// Copy the torrent file to the export folder
2012-08-21 11:16:49 +04:00
if ( m_torrentExportEnabled )
2010-10-17 18:46:01 +04:00
exportTorrentFile ( h ) ;
2008-11-02 00:42:56 +03:00
}
2010-10-17 18:46:01 +04:00
2012-05-15 20:57:31 +04:00
if ( ! fastResume & & ! pref . addTorrentsInPause ( ) ) {
2009-08-16 07:09:20 +04:00
// Start torrent because it was added in paused state
h . resume ( ) ;
2008-11-02 00:42:56 +03:00
}
2010-10-17 18:46:01 +04:00
// If temporary file, remove it
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) | | fromScanDir )
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( path ) ;
2010-10-17 18:46:01 +04:00
// Display console message
2012-02-20 21:30:53 +04:00
if ( ! from_url . isNull ( ) ) {
if ( fastResume )
2009-08-16 07:09:20 +04:00
addConsoleMessage ( tr ( " '%1' resumed. (fast resume) " , " '/home/y/xxx.torrent' was resumed. (fast resume) " ) . arg ( from_url ) ) ;
else
addConsoleMessage ( tr ( " '%1' added to download list. " , " '/home/y/xxx.torrent' was added to download list. " ) . arg ( from_url ) ) ;
2008-11-02 00:42:56 +03:00
} else {
2012-02-20 21:30:53 +04:00
if ( fastResume )
2013-11-05 22:33:04 +04:00
addConsoleMessage ( tr ( " '%1' resumed. (fast resume) " , " '/home/y/xxx.torrent' was resumed. (fast resume) " ) . arg ( fsutils : : toNativePath ( path ) ) ) ;
2011-02-07 20:10:06 +03:00
else
2013-11-05 22:33:04 +04:00
addConsoleMessage ( tr ( " '%1' added to download list. " , " '/home/y/xxx.torrent' was added to download list. " ) . arg ( fsutils : : toNativePath ( path ) ) ) ;
2008-01-04 23:43:28 +03:00
}
2010-10-17 18:46:01 +04:00
// Send torrent addition signal
2008-12-29 21:36:54 +03:00
emit addedTorrent ( h ) ;
2008-12-30 03:34:41 +03:00
return h ;
2007-03-05 16:55:23 +03:00
}
2012-08-21 11:16:49 +04:00
void QBtSession : : exportTorrentFile ( const QTorrentHandle & h , TorrentExportFolder folder ) {
Q_ASSERT ( ( folder = = RegularTorrentExportFolder & & m_torrentExportEnabled ) | |
( folder = = FinishedTorrentExportFolder & & m_finishedTorrentExportEnabled ) ) ;
2012-05-16 22:19:05 +04:00
QString torrent_path = QDir ( fsutils : : BTBackupLocation ( ) ) . absoluteFilePath ( h . hash ( ) + " .torrent " ) ;
2012-08-21 11:16:49 +04:00
QDir exportPath ( folder = = RegularTorrentExportFolder ? Preferences ( ) . getTorrentExportDir ( ) : Preferences ( ) . getFinishedTorrentExportDir ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( exportPath . exists ( ) | | exportPath . mkpath ( exportPath . absolutePath ( ) ) ) {
2010-10-17 18:46:01 +04:00
QString new_torrent_path = exportPath . absoluteFilePath ( h . name ( ) + " .torrent " ) ;
2012-05-16 22:19:05 +04:00
if ( QFile : : exists ( new_torrent_path ) & & fsutils : : sameFiles ( torrent_path , new_torrent_path ) ) {
2010-10-17 18:46:01 +04:00
// Append hash to torrent name to make it unique
new_torrent_path = exportPath . absoluteFilePath ( h . name ( ) + " - " + h . hash ( ) + " .torrent " ) ;
}
QFile : : copy ( torrent_path , new_torrent_path ) ;
}
}
2013-10-22 23:29:25 +04:00
void QBtSession : : initializeAddTorrentParams ( const QString & hash , add_torrent_params & p ) {
2010-10-17 18:46:01 +04:00
// Seeding mode
// Skip checking and directly start seeding (new in libtorrent v0.15)
2012-02-20 21:30:53 +04:00
if ( TorrentTempData : : isSeedingMode ( hash ) )
2014-01-01 04:49:16 +04:00
p . flags | = add_torrent_params : : flag_seed_mode ;
2010-10-17 18:46:01 +04:00
else
2014-01-01 04:49:16 +04:00
p . flags & = ~ add_torrent_params : : flag_seed_mode ;
2010-10-17 18:46:01 +04:00
// Preallocation mode
2012-02-20 21:30:53 +04:00
if ( preAllocateAll )
2010-10-17 18:46:01 +04:00
p . storage_mode = storage_mode_allocate ;
else
p . storage_mode = storage_mode_sparse ;
2011-04-17 19:27:18 +04:00
// Priorities
2013-10-23 23:16:23 +04:00
/*if (TorrentTempData::hasTempData(hash)) {
2011-04-17 19:27:18 +04:00
std : : vector < int > fp ;
TorrentTempData : : getFilesPriority ( hash , fp ) ;
2012-02-20 21:30:53 +04:00
if ( ! fp . empty ( ) ) {
2011-04-17 19:27:18 +04:00
std : : vector < boost : : uint8_t > * fp_conv = new std : : vector < boost : : uint8_t > ( ) ;
2012-02-20 21:30:53 +04:00
for ( uint i = 0 ; i < fp . size ( ) ; + + i ) {
2011-04-17 19:27:18 +04:00
fp_conv - > push_back ( fp [ i ] ) ;
}
p . file_priorities = fp_conv ;
}
2013-10-23 23:16:23 +04:00
} */
2011-04-17 19:27:18 +04:00
2010-10-17 18:46:01 +04:00
// Start in pause
2014-01-01 04:49:16 +04:00
p . flags | = add_torrent_params : : flag_paused ;
p . flags & = ~ add_torrent_params : : flag_duplicate_is_error ; // Already checked
p . flags & = ~ add_torrent_params : : flag_auto_managed ; // Because it is added in paused state
2010-10-17 18:46:01 +04:00
}
2011-02-26 22:56:15 +03:00
void QBtSession : : loadTorrentTempData ( QTorrentHandle & h , QString savePath , bool magnet ) {
2010-10-23 20:21:56 +04:00
qDebug ( " loadTorrentTempdata() - ENTER " ) ;
2010-10-17 18:46:01 +04:00
const QString hash = h . hash ( ) ;
// Sequential download
2012-02-20 21:30:53 +04:00
if ( TorrentTempData : : hasTempData ( hash ) ) {
2010-10-23 20:21:56 +04:00
// sequential download
h . set_sequential_download ( TorrentTempData : : isSequential ( hash ) ) ;
// The following is useless for newly added magnet
2012-02-20 21:30:53 +04:00
if ( ! magnet ) {
2010-10-23 20:21:56 +04:00
// Files priorities
vector < int > fp ;
TorrentTempData : : getFilesPriority ( hash , fp ) ;
h . prioritize_files ( fp ) ;
2011-01-12 19:53:11 +03:00
// Prioritize first/last piece
h . prioritize_first_last_piece ( TorrentTempData : : isSequential ( hash ) ) ;
2010-10-23 20:21:56 +04:00
// Update file names
const QStringList files_path = TorrentTempData : : getFilesPath ( hash ) ;
bool force_recheck = false ;
2012-12-26 21:31:02 +04:00
QDir base_dir ( h . save_path ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( files_path . size ( ) = = h . num_files ( ) ) {
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
2010-10-23 20:21:56 +04:00
const QString & path = files_path . at ( i ) ;
2012-12-26 21:31:02 +04:00
if ( ! force_recheck & & base_dir . exists ( path ) )
2010-10-23 20:21:56 +04:00
force_recheck = true ;
qDebug ( " Renaming file to %s " , qPrintable ( path ) ) ;
h . rename_file ( i , path ) ;
2010-10-17 18:46:01 +04:00
}
2010-10-23 20:21:56 +04:00
// Force recheck
2012-02-20 21:30:53 +04:00
if ( force_recheck ) h . force_recheck ( ) ;
2010-10-17 18:46:01 +04:00
}
}
}
// Save persistent data for new torrent
2010-10-23 20:21:56 +04:00
qDebug ( " Saving torrent persistant data " ) ;
2012-02-20 21:30:53 +04:00
if ( defaultTempPath . isEmpty ( ) )
2010-10-17 18:46:01 +04:00
TorrentPersistentData : : saveTorrentPersistentData ( h , QString : : null , magnet ) ;
else
2013-11-10 16:05:43 +04:00
TorrentPersistentData : : saveTorrentPersistentData ( h , fsutils : : fromNativePath ( savePath ) , magnet ) ;
2010-10-17 18:46:01 +04:00
}
2012-09-23 12:09:01 +04:00
void QBtSession : : mergeTorrents ( QTorrentHandle & h_ex , const QString & magnet_uri )
{
QList < QUrl > new_trackers = misc : : magnetUriToTrackers ( magnet_uri ) ;
bool trackers_added = false ;
foreach ( const QUrl & new_tracker , new_trackers ) {
bool found = false ;
std : : vector < announce_entry > existing_trackers = h_ex . trackers ( ) ;
foreach ( const announce_entry & existing_tracker , existing_trackers ) {
if ( new_tracker = = QUrl ( existing_tracker . url . c_str ( ) ) ) {
found = true ;
break ;
}
}
if ( ! found ) {
h_ex . add_tracker ( announce_entry ( new_tracker . toString ( ) . toStdString ( ) ) ) ;
trackers_added = true ;
}
}
if ( trackers_added )
addConsoleMessage ( tr ( " Note: new trackers were added to the existing torrent. " ) ) ;
}
2011-02-26 22:56:15 +03:00
void QBtSession : : mergeTorrents ( QTorrentHandle & h_ex , boost : : intrusive_ptr < torrent_info > t ) {
2010-10-17 16:18:34 +04:00
// Check if the torrent contains trackers or url seeds we don't know about
// and add them
2012-02-20 21:30:53 +04:00
if ( ! h_ex . is_valid ( ) ) return ;
2012-02-19 21:59:23 +04:00
std : : vector < announce_entry > existing_trackers = h_ex . trackers ( ) ;
2010-10-17 18:46:01 +04:00
std : : vector < announce_entry > new_trackers = t - > trackers ( ) ;
bool trackers_added = false ;
2012-02-19 21:59:23 +04:00
foreach ( const announce_entry & new_tracker , new_trackers ) {
std : : string new_tracker_url = new_tracker . url ;
// Check if existing torrent has this tracker
2010-10-17 18:46:01 +04:00
bool found = false ;
2012-02-19 21:59:23 +04:00
foreach ( const announce_entry & existing_tracker , existing_trackers ) {
2012-02-20 21:30:53 +04:00
if ( QUrl ( new_tracker_url . c_str ( ) ) = = QUrl ( existing_tracker . url . c_str ( ) ) ) {
2010-10-17 18:46:01 +04:00
found = true ;
break ;
2010-10-17 16:18:34 +04:00
}
}
2012-02-19 21:59:23 +04:00
if ( ! found ) {
h_ex . add_tracker ( announce_entry ( new_tracker_url ) ) ;
2010-10-17 18:46:01 +04:00
trackers_added = true ;
2010-10-17 16:18:34 +04:00
}
2010-10-17 18:46:01 +04:00
}
2012-02-19 21:59:23 +04:00
if ( trackers_added )
2010-10-17 18:46:01 +04:00
addConsoleMessage ( tr ( " Note: new trackers were added to the existing torrent. " ) ) ;
2012-02-19 21:59:23 +04:00
2010-10-17 18:46:01 +04:00
bool urlseeds_added = false ;
const QStringList old_urlseeds = h_ex . url_seeds ( ) ;
2011-04-17 14:29:44 +04:00
std : : vector < web_seed_entry > new_urlseeds = t - > web_seeds ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < web_seed_entry > : : iterator it = new_urlseeds . begin ( ) ;
std : : vector < web_seed_entry > : : iterator itend = new_urlseeds . end ( ) ;
for ( ; it ! = itend ; + + it ) {
2011-04-17 14:29:44 +04:00
const QString new_url = misc : : toQString ( it - > url . c_str ( ) ) ;
2012-02-19 21:59:23 +04:00
if ( ! old_urlseeds . contains ( new_url ) ) {
2011-04-17 14:29:44 +04:00
urlseeds_added = true ;
h_ex . add_url_seed ( new_url ) ;
}
}
2012-02-20 21:30:53 +04:00
if ( urlseeds_added )
2010-10-17 18:46:01 +04:00
addConsoleMessage ( tr ( " Note: new URL seeds were added to the existing torrent. " ) ) ;
2010-10-17 16:18:34 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : exportTorrentFiles ( QString path ) {
2012-08-21 11:16:49 +04:00
Q_ASSERT ( m_torrentExportEnabled ) ;
2010-01-31 16:09:46 +03:00
QDir exportDir ( path ) ;
2012-02-20 21:30:53 +04:00
if ( ! exportDir . exists ( ) ) {
if ( ! exportDir . mkpath ( exportDir . absolutePath ( ) ) ) {
2010-03-03 20:27:25 +03:00
std : : cerr < < " Error: Could not create torrent export directory: " < < qPrintable ( exportDir . absolutePath ( ) ) < < std : : endl ;
2010-01-31 16:09:46 +03:00
return ;
}
}
2012-05-16 22:19:05 +04:00
QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2010-01-31 16:09:46 +03:00
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator itr = handles . begin ( ) ;
std : : vector < torrent_handle > : : iterator itrend = handles . end ( ) ;
for ( ; itr ! = itrend ; + + itr ) {
2010-03-12 00:43:09 +03:00
const QTorrentHandle h ( * itr ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) {
2010-01-31 16:09:46 +03:00
std : : cerr < < " Torrent Export: torrent is invalid, skipping... " < < std : : endl ;
continue ;
}
2010-07-23 18:05:53 +04:00
const QString src_path ( torrentBackup . absoluteFilePath ( h . hash ( ) + " .torrent " ) ) ;
2012-02-20 21:30:53 +04:00
if ( QFile : : exists ( src_path ) ) {
2010-01-31 16:09:46 +03:00
QString dst_path = exportDir . absoluteFilePath ( h . name ( ) + " .torrent " ) ;
2012-02-20 21:30:53 +04:00
if ( QFile : : exists ( dst_path ) ) {
2012-05-16 22:19:05 +04:00
if ( ! fsutils : : sameFiles ( src_path , dst_path ) ) {
2010-01-31 16:09:46 +03:00
dst_path = exportDir . absoluteFilePath ( h . name ( ) + " - " + h . hash ( ) + " .torrent " ) ;
} else {
qDebug ( " Torrent Export: Destination file exists, skipping... " ) ;
continue ;
}
}
2010-03-03 20:27:25 +03:00
qDebug ( " Export Torrent: %s -> %s " , qPrintable ( src_path ) , qPrintable ( dst_path ) ) ;
2010-01-31 16:09:46 +03:00
QFile : : copy ( src_path , dst_path ) ;
} else {
2010-03-03 20:27:25 +03:00
std : : cerr < < " Error: could not export torrent " < < qPrintable ( h . hash ( ) ) < < " , maybe it has not metadata yet. " < < std : : endl ;
2010-01-31 16:09:46 +03:00
}
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setMaxConnectionsPerTorrent ( int max ) {
2010-12-02 20:10:34 +03:00
qDebug ( ) < < Q_FUNC_INFO < < max ;
2007-09-09 11:44:22 +04:00
// Apply this to all session torrents
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : const_iterator it = handles . begin ( ) ;
std : : vector < torrent_handle > : : const_iterator itend = handles . end ( ) ;
for ( ; it ! = itend ; + + it ) {
2012-02-20 21:30:53 +04:00
if ( ! it - > is_valid ( ) )
2007-09-09 11:44:22 +04:00
continue ;
2010-07-18 16:53:16 +04:00
try {
it - > set_max_connections ( max ) ;
} catch ( std : : exception ) { }
2007-09-09 11:44:22 +04:00
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setMaxUploadsPerTorrent ( int max ) {
2010-12-02 20:10:34 +03:00
qDebug ( ) < < Q_FUNC_INFO < < max ;
2007-09-09 11:44:22 +04:00
// Apply this to all session torrents
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : const_iterator it = handles . begin ( ) ;
std : : vector < torrent_handle > : : const_iterator itend = handles . end ( ) ;
for ( ; it ! = itend ; + + it ) {
2012-02-20 21:30:53 +04:00
if ( ! it - > is_valid ( ) )
2007-09-09 11:44:22 +04:00
continue ;
2010-07-18 16:53:16 +04:00
try {
it - > set_max_uploads ( max ) ;
} catch ( std : : exception ) { }
2007-09-09 11:44:22 +04:00
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : enableUPnP ( bool b ) {
2011-04-12 23:50:05 +04:00
Preferences pref ;
2012-02-20 21:30:53 +04:00
if ( b ) {
2014-01-01 02:10:41 +04:00
qDebug ( " Enabling UPnP / NAT-PMP " ) ;
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2014-01-01 02:10:41 +04:00
m_upnp = s - > start_upnp ( ) ;
m_natpmp = s - > start_natpmp ( ) ;
# else
s - > start_upnp ( ) ;
s - > start_natpmp ( ) ;
# endif
2011-04-12 23:50:05 +04:00
// Use UPnP/NAT-PMP for Web UI too
2012-02-20 21:30:53 +04:00
if ( pref . isWebUiEnabled ( ) & & pref . useUPnPForWebUIPort ( ) ) {
2011-04-12 23:50:05 +04:00
const qint16 port = pref . getWebUiPort ( ) ;
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2011-04-12 23:50:05 +04:00
m_upnp - > add_mapping ( upnp : : tcp , port , port ) ;
m_natpmp - > add_mapping ( natpmp : : tcp , port , port ) ;
2014-01-01 02:10:41 +04:00
# else
s - > add_port_mapping ( session : : tcp , port , port ) ;
# endif
2007-11-23 18:20:26 +03:00
}
2007-09-08 21:07:29 +04:00
} else {
2014-01-01 02:10:41 +04:00
qDebug ( " Disabling UPnP / NAT-PMP " ) ;
s - > stop_upnp ( ) ;
s - > stop_natpmp ( ) ;
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2014-01-01 02:10:41 +04:00
m_upnp = 0 ;
m_natpmp = 0 ;
# endif
2007-09-08 21:07:29 +04:00
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : enableLSD ( bool b ) {
2012-02-20 21:30:53 +04:00
if ( b ) {
if ( ! LSDEnabled ) {
2010-12-05 19:36:02 +03:00
qDebug ( " Enabling Local Peer Discovery " ) ;
2007-11-23 18:20:26 +03:00
s - > start_lsd ( ) ;
LSDEnabled = true ;
}
2007-09-08 21:07:29 +04:00
} else {
2012-02-20 21:30:53 +04:00
if ( LSDEnabled ) {
2010-12-05 19:36:02 +03:00
qDebug ( " Disabling Local Peer Discovery " ) ;
2007-11-23 18:20:26 +03:00
s - > stop_lsd ( ) ;
LSDEnabled = false ;
}
2007-09-08 21:07:29 +04:00
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : loadSessionState ( ) {
2013-11-10 16:05:43 +04:00
const QString state_path = fsutils : : cacheLocation ( ) + " / " + QString : : fromUtf8 ( " ses_state " ) ;
2012-02-20 21:30:53 +04:00
if ( ! QFile : : exists ( state_path ) ) return ;
if ( QFile ( state_path ) . size ( ) = = 0 ) {
2010-07-18 16:53:16 +04:00
// Remove empty invalid state file
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( state_path ) ;
2010-06-14 13:55:35 +04:00
return ;
}
2011-01-23 22:31:48 +03:00
QFile state_file ( state_path ) ;
2012-02-20 21:30:53 +04:00
if ( ! state_file . open ( QIODevice : : ReadOnly ) ) return ;
2010-04-06 20:52:17 +04:00
std : : vector < char > in ;
2011-03-10 20:36:11 +03:00
const qint64 content_size = state_file . bytesAvailable ( ) ;
2012-02-20 21:30:53 +04:00
if ( content_size < = 0 ) return ;
2011-01-23 22:31:48 +03:00
in . resize ( content_size ) ;
2011-03-10 20:36:11 +03:00
state_file . read ( & in [ 0 ] , content_size ) ;
2011-01-23 22:31:48 +03:00
// bdecode
lazy_entry e ;
2012-09-16 02:28:58 +04:00
libtorrent : : error_code ec ;
2011-04-17 14:29:44 +04:00
lazy_bdecode ( & in [ 0 ] , & in [ 0 ] + in . size ( ) , e , ec ) ;
2013-10-23 23:16:23 +04:00
if ( ! ec )
2011-01-23 22:31:48 +03:00
s - > load_state ( e ) ;
2008-11-02 16:19:27 +03:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : saveSessionState ( ) {
2009-08-16 07:09:20 +04:00
qDebug ( " Saving session state to disk... " ) ;
2013-11-10 16:05:43 +04:00
const QString state_path = fsutils : : cacheLocation ( ) + " / " + QString : : fromUtf8 ( " ses_state " ) ;
2010-04-06 20:52:17 +04:00
entry session_state ;
s - > save_state ( session_state ) ;
2011-03-10 20:36:11 +03:00
vector < char > out ;
bencode ( back_inserter ( out ) , session_state ) ;
QFile session_file ( state_path ) ;
if ( ! out . empty ( ) & & session_file . open ( QIODevice : : WriteOnly ) ) {
session_file . write ( & out [ 0 ] , out . size ( ) ) ;
session_file . close ( ) ;
}
2008-11-02 16:19:27 +03:00
}
2007-09-08 21:07:29 +04:00
// Enable DHT
2010-10-17 18:46:01 +04:00
bool QBtSession : : enableDHT ( bool b ) {
2012-02-20 21:30:53 +04:00
if ( b ) {
if ( ! DHTEnabled ) {
2007-10-28 00:53:09 +04:00
try {
2010-11-28 15:25:24 +03:00
qDebug ( ) < < " Starting DHT... " ;
Q_ASSERT ( ! s - > is_dht_running ( ) ) ;
2010-04-06 20:52:17 +04:00
s - > start_dht ( ) ;
2009-08-16 07:09:20 +04:00
s - > add_dht_router ( std : : make_pair ( std : : string ( " router.bittorrent.com " ) , 6881 ) ) ;
s - > add_dht_router ( std : : make_pair ( std : : string ( " router.utorrent.com " ) , 6881 ) ) ;
2010-07-18 16:53:16 +04:00
s - > add_dht_router ( std : : make_pair ( std : : string ( " dht.transmissionbt.com " ) , 6881 ) ) ;
2011-10-16 12:30:50 +04:00
s - > add_dht_router ( std : : make_pair ( std : : string ( " dht.aelitis.com " ) , 6881 ) ) ; // Vuze
2009-08-16 07:09:20 +04:00
DHTEnabled = true ;
qDebug ( " DHT enabled " ) ;
2014-01-03 21:24:32 +04:00
} catch ( std : : exception & e ) {
2009-08-16 07:09:20 +04:00
qDebug ( " Could not enable DHT, reason: %s " , e . what ( ) ) ;
return false ;
}
2007-09-08 21:07:29 +04:00
}
} else {
2012-02-20 21:30:53 +04:00
if ( DHTEnabled ) {
2007-09-08 21:07:29 +04:00
DHTEnabled = false ;
s - > stop_dht ( ) ;
qDebug ( " DHT disabled " ) ;
}
2007-03-05 16:55:23 +03:00
}
2007-10-28 00:53:09 +04:00
return true ;
2007-03-05 16:55:23 +03:00
}
2012-02-20 23:32:58 +04:00
qreal QBtSession : : getRealRatio ( const QString & hash ) const {
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) {
2010-03-03 20:27:25 +03:00
return 0. ;
}
2011-10-16 10:41:59 +04:00
libtorrent : : size_type all_time_upload = h . all_time_upload ( ) ;
libtorrent : : size_type all_time_download = h . all_time_download ( ) ;
if ( all_time_download = = 0 & & h . is_seed ( ) ) {
// Purely seeded torrent
all_time_download = h . total_done ( ) ;
}
2011-09-27 18:11:50 +04:00
2012-02-20 21:30:53 +04:00
if ( all_time_download = = 0 ) {
if ( all_time_upload = = 0 )
2009-07-12 12:21:06 +04:00
return 0 ;
2011-02-24 20:36:20 +03:00
return MAX_RATIO + 1 ;
2008-11-02 01:07:14 +03:00
}
2011-10-16 10:41:59 +04:00
2011-09-27 18:11:50 +04:00
qreal ratio = all_time_upload / ( float ) all_time_download ;
2007-08-20 10:29:18 +04:00
Q_ASSERT ( ratio > = 0. ) ;
2012-02-20 21:30:53 +04:00
if ( ratio > MAX_RATIO )
2011-02-24 20:36:20 +03:00
ratio = MAX_RATIO ;
2007-08-20 10:29:18 +04:00
return ratio ;
}
2011-04-17 18:54:47 +04:00
// Called periodically
2010-10-17 18:46:01 +04:00
void QBtSession : : saveTempFastResumeData ( ) {
2010-03-21 00:21:42 +03:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-03-21 00:21:42 +03:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2010-07-18 16:53:16 +04:00
try {
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) | | ! h . has_metadata ( ) /*|| h.is_seed() || h.is_paused()*/ ) continue ;
if ( ! h . need_save_resume_data ( ) ) continue ;
2013-10-01 01:37:34 +04:00
if ( h . state ( ) = = torrent_status : : checking_files | | h . state ( ) = = torrent_status : : queued_for_checking | | h . has_error ( ) ) continue ;
2010-07-18 16:53:16 +04:00
qDebug ( " Saving fastresume data for %s " , qPrintable ( h . name ( ) ) ) ;
h . save_resume_data ( ) ;
2014-01-03 21:24:32 +04:00
} catch ( std : : exception & e ) { }
2010-03-21 00:21:42 +03:00
}
}
2007-11-23 00:50:22 +03:00
// Only save fast resume data for unfinished and unpaused torrents (Optimization)
2011-04-17 18:54:47 +04:00
// Called on exit
2010-10-17 18:46:01 +04:00
void QBtSession : : saveFastResumeData ( ) {
2010-10-02 00:03:27 +04:00
qDebug ( " Saving fast resume data... " ) ;
2008-11-02 02:58:53 +03:00
// Stop listening for alerts
2010-03-21 00:21:42 +03:00
resumeDataTimer . stop ( ) ;
2008-11-02 02:58:53 +03:00
timerAlerts - > stop ( ) ;
int num_resume_data = 0 ;
2008-12-30 00:10:31 +03:00
// Pause session
2008-11-02 02:58:53 +03:00
s - > pause ( ) ;
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2008-12-30 00:10:31 +03:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-08-12 10:56:36 +04:00
if ( ! h . is_valid ( ) )
continue ;
2010-10-31 17:19:55 +03:00
try {
2012-02-20 21:30:53 +04:00
if ( isQueueingEnabled ( ) )
2010-10-31 17:19:55 +03:00
TorrentPersistentData : : savePriority ( h ) ;
2012-08-12 10:56:36 +04:00
if ( ! h . has_metadata ( ) )
continue ;
2010-10-31 17:19:55 +03:00
// Actually with should save fast resume data for paused files too
2012-02-20 21:30:53 +04:00
//if (h.is_paused()) continue;
2013-10-01 01:37:34 +04:00
if ( h . state ( ) = = torrent_status : : checking_files | | h . state ( ) = = torrent_status : : queued_for_checking | | h . has_error ( ) ) continue ;
2010-10-31 17:19:55 +03:00
h . save_resume_data ( ) ;
+ + num_resume_data ;
} catch ( libtorrent : : invalid_handle & ) { }
2008-11-02 02:58:53 +03:00
}
2008-12-30 00:10:31 +03:00
while ( num_resume_data > 0 ) {
2009-08-16 07:09:20 +04:00
alert const * a = s - > wait_for_alert ( seconds ( 30 ) ) ;
if ( a = = 0 ) {
std : : cerr < < " aborting with " < < num_resume_data < < " outstanding "
2010-10-17 15:45:53 +04:00
" torrents to save resume data for " < < std : : endl ;
2009-08-16 07:09:20 +04:00
break ;
}
// Saving fastresume data can fail
save_resume_data_failed_alert const * rda = dynamic_cast < save_resume_data_failed_alert const * > ( a ) ;
if ( rda ) {
2008-11-02 02:58:53 +03:00
- - num_resume_data ;
2009-08-16 07:09:20 +04:00
s - > pop_alert ( ) ;
2009-11-28 16:50:16 +03:00
try {
// Remove torrent from session
2012-02-20 21:30:53 +04:00
if ( rda - > handle . is_valid ( ) )
2010-10-31 17:19:55 +03:00
s - > remove_torrent ( rda - > handle ) ;
2012-02-20 21:56:07 +04:00
} catch ( libtorrent : : libtorrent_exception ) { }
2009-08-16 07:09:20 +04:00
continue ;
}
save_resume_data_alert const * rd = dynamic_cast < save_resume_data_alert const * > ( a ) ;
if ( ! rd ) {
2008-11-02 02:58:53 +03:00
s - > pop_alert ( ) ;
2009-08-16 07:09:20 +04:00
continue ;
}
// Saving fast resume data was successful
- - num_resume_data ;
if ( ! rd - > resume_data ) continue ;
2012-05-16 22:19:05 +04:00
QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2010-03-12 00:43:09 +03:00
const QTorrentHandle h ( rd - > handle ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) continue ;
2010-10-31 17:19:55 +03:00
try {
// Remove old fastresume file if it exists
2013-09-29 22:32:27 +04:00
backupPersistentData ( h . hash ( ) , rd - > resume_data ) ;
2011-03-10 20:36:11 +03:00
vector < char > out ;
bencode ( back_inserter ( out ) , * rd - > resume_data ) ;
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
2012-02-20 21:30:53 +04:00
if ( resume_file . exists ( ) )
2012-07-05 20:10:13 +04:00
fsutils : : forceRemove ( filepath ) ;
2012-02-20 21:30:53 +04:00
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
2011-03-10 20:36:11 +03:00
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
2010-10-31 17:19:55 +03:00
// Remove torrent from session
s - > remove_torrent ( rd - > handle ) ;
s - > pop_alert ( ) ;
2012-02-20 21:56:07 +04:00
} catch ( libtorrent : : invalid_handle & ) { }
2008-08-26 10:39:57 +04:00
}
2007-03-05 16:55:23 +03:00
}
2010-01-03 01:20:37 +03:00
# ifdef DISABLE_GUI
2010-10-17 18:46:01 +04:00
void QBtSession : : addConsoleMessage ( QString msg , QString ) {
2010-12-20 21:07:36 +03:00
emit newConsoleMessage ( QDateTime : : currentDateTime ( ) . toString ( " dd/MM/yyyy hh:mm:ss " ) + " - " + msg ) ;
2010-01-03 01:20:37 +03:00
# else
2010-10-17 18:46:01 +04:00
void QBtSession : : addConsoleMessage ( QString msg , QColor color ) {
2012-02-20 21:30:53 +04:00
if ( consoleMessages . size ( ) > MAX_LOG_MESSAGES ) {
2011-06-20 23:28:55 +04:00
consoleMessages . removeFirst ( ) ;
2010-10-17 15:45:53 +04:00
}
2013-11-23 15:30:24 +04:00
msg = " <font color='grey'> " + QDateTime : : currentDateTime ( ) . toString ( QString : : fromUtf8 ( " dd/MM/yyyy hh:mm:ss " ) ) + " </font> - <font color=' " + color . name ( ) + " '> " + msg + " </font> " ;
2011-06-20 23:28:55 +04:00
consoleMessages . append ( msg ) ;
2010-12-20 21:07:36 +03:00
emit newConsoleMessage ( msg ) ;
2010-01-03 01:20:37 +03:00
# endif
2010-10-17 15:45:53 +04:00
}
2008-09-07 15:31:29 +04:00
2010-10-17 18:46:01 +04:00
void QBtSession : : addPeerBanMessage ( QString ip , bool from_ipfilter ) {
2012-02-20 21:30:53 +04:00
if ( peerBanMessages . size ( ) > MAX_LOG_MESSAGES ) {
2011-06-20 23:28:55 +04:00
peerBanMessages . removeFirst ( ) ;
2008-09-07 15:31:29 +04:00
}
2010-12-20 21:07:36 +03:00
QString msg ;
2012-02-20 21:30:53 +04:00
if ( from_ipfilter )
2013-11-23 15:30:24 +04:00
msg = " <font color='grey'> " + QDateTime : : currentDateTime ( ) . toString ( QString : : fromUtf8 ( " dd/MM/yyyy hh:mm:ss " ) ) + " </font> - " + tr ( " <font color='red'>%1</font> was blocked " , " x.y.z.w was blocked " ) . arg ( ip ) ;
2010-10-17 15:45:53 +04:00
else
2013-11-23 15:30:24 +04:00
msg = " <font color='grey'> " + QDateTime : : currentDateTime ( ) . toString ( QString : : fromUtf8 ( " dd/MM/yyyy hh:mm:ss " ) ) + " </font> - " + tr ( " <font color='red'>%1</font> was banned " , " x.y.z.w was banned " ) . arg ( ip ) ;
2011-06-20 23:28:55 +04:00
peerBanMessages . append ( msg ) ;
2010-12-20 21:07:36 +03:00
emit newBanMessage ( msg ) ;
2010-10-17 15:45:53 +04:00
}
2008-09-07 15:31:29 +04:00
2012-02-20 23:32:58 +04:00
bool QBtSession : : isFilePreviewPossible ( const QString & hash ) const {
2010-10-17 15:45:53 +04:00
// See if there are supported files in the torrent
const QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) | | ! h . has_metadata ( ) ) {
2007-03-05 20:35:38 +03:00
return false ;
2007-03-05 16:55:23 +03:00
}
2010-10-17 15:45:53 +04:00
const unsigned int nbFiles = h . num_files ( ) ;
2012-02-20 21:30:53 +04:00
for ( unsigned int i = 0 ; i < nbFiles ; + + i ) {
2013-02-09 21:55:10 +04:00
QString filename = h . filename_at ( i ) ;
if ( filename . endsWith ( " .!qB " ) )
filename . chop ( 4 ) ;
const QString extension = fsutils : : fileExtension ( filename ) ;
2012-02-20 21:30:53 +04:00
if ( misc : : isPreviewable ( extension ) )
2010-10-17 15:45:53 +04:00
return true ;
}
return false ;
}
2007-03-05 16:55:23 +03:00
2010-10-17 18:46:01 +04:00
void QBtSession : : addTorrentsFromScanFolder ( QStringList & pathList ) {
2012-02-20 21:30:53 +04:00
foreach ( const QString & file , pathList ) {
2010-10-17 15:45:53 +04:00
qDebug ( " File %s added " , qPrintable ( file ) ) ;
2012-05-28 16:21:09 +04:00
if ( file . endsWith ( " .magnet " ) ) {
QFile f ( file ) ;
if ( ! f . open ( QIODevice : : ReadOnly ) ) {
qDebug ( " Failed to open magnet file: %s " , qPrintable ( f . errorString ( ) ) ) ;
} else {
const QString link = QString : : fromLocal8Bit ( f . readAll ( ) ) ;
addMagnetUri ( link , false , true , file ) ;
f . remove ( ) ;
}
continue ;
}
2010-10-17 15:45:53 +04:00
try {
2013-11-10 16:05:43 +04:00
torrent_info t ( fsutils : : toNativePath ( file ) . toUtf8 ( ) . constData ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( t . is_valid ( ) )
2010-10-17 15:45:53 +04:00
addTorrent ( file , true ) ;
} catch ( std : : exception & ) {
qDebug ( " Ignoring incomplete torrent file: %s " , qPrintable ( file ) ) ;
2009-08-16 07:09:20 +04:00
}
2007-03-05 16:55:23 +03:00
}
2010-10-17 15:45:53 +04:00
}
2007-03-05 16:55:23 +03:00
2012-12-01 16:48:08 +04:00
void QBtSession : : setDefaultSavePath ( const QString & savepath ) {
2012-12-01 19:48:18 +04:00
if ( savepath . isEmpty ( ) )
2010-10-17 15:45:53 +04:00
return ;
2012-12-01 17:40:18 +04:00
2013-11-10 16:05:43 +04:00
defaultSavePath = fsutils : : fromNativePath ( savepath ) ;
2012-12-01 16:48:08 +04:00
}
void QBtSession : : setDefaultTempPath ( const QString & temppath ) {
2012-12-01 17:40:18 +04:00
if ( QDir ( defaultTempPath ) = = QDir ( temppath ) )
2010-10-17 15:45:53 +04:00
return ;
2012-12-01 17:40:18 +04:00
2012-02-20 21:30:53 +04:00
if ( temppath . isEmpty ( ) ) {
2010-10-17 15:45:53 +04:00
// Disabling temp dir
// Moving all torrents to their destination folder
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-10-17 15:45:53 +04:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) continue ;
2010-10-17 15:45:53 +04:00
h . move_storage ( getSavePath ( h . hash ( ) ) ) ;
}
} else {
qDebug ( " Enabling default temp path... " ) ;
// Moving all downloading torrents to temporary save path
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-10-17 15:45:53 +04:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) continue ;
if ( ! h . is_seed ( ) ) {
2013-11-10 16:05:43 +04:00
qDebug ( " Moving torrent to its temp save path: %s " , qPrintable ( temppath ) ) ;
h . move_storage ( temppath ) ;
2010-01-03 02:03:46 +03:00
}
2009-03-08 19:26:02 +03:00
}
}
2013-11-10 16:05:43 +04:00
defaultTempPath = fsutils : : fromNativePath ( temppath ) ;
2010-10-17 15:45:53 +04:00
}
2009-03-08 19:26:02 +03:00
2010-11-24 23:31:14 +03:00
void QBtSession : : appendqBextensionToTorrent ( const QTorrentHandle & h , bool append ) {
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) | | ! h . has_metadata ( ) ) return ;
2010-10-17 15:45:53 +04:00
std : : vector < size_type > fp ;
h . file_progress ( fp ) ;
2012-02-20 21:30:53 +04:00
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
if ( append ) {
2010-10-17 15:45:53 +04:00
const qulonglong file_size = h . filesize_at ( i ) ;
2012-02-20 21:30:53 +04:00
if ( file_size > 0 & & ( fp [ i ] / ( double ) file_size ) < 1. ) {
2010-11-28 13:29:59 +03:00
const QString name = h . filepath_at ( i ) ;
2012-02-20 21:30:53 +04:00
if ( ! name . endsWith ( " .!qB " ) ) {
2010-10-17 15:45:53 +04:00
const QString new_name = name + " .!qB " ;
qDebug ( " Renaming %s to %s " , qPrintable ( name ) , qPrintable ( new_name ) ) ;
h . rename_file ( i , new_name ) ;
2009-12-18 16:36:47 +03:00
}
}
2010-10-17 15:45:53 +04:00
} else {
2010-11-28 13:29:59 +03:00
QString name = h . filepath_at ( i ) ;
2012-02-20 21:30:53 +04:00
if ( name . endsWith ( " .!qB " ) ) {
2010-10-17 15:45:53 +04:00
const QString old_name = name ;
name . chop ( 4 ) ;
qDebug ( " Renaming %s to %s " , qPrintable ( old_name ) , qPrintable ( name ) ) ;
h . rename_file ( i , name ) ;
}
2009-12-18 16:36:47 +03:00
}
}
2010-10-17 15:45:53 +04:00
}
2009-12-18 16:36:47 +03:00
2010-11-24 23:31:14 +03:00
void QBtSession : : changeLabelInTorrentSavePath ( const QTorrentHandle & h , QString old_label , QString new_label ) {
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) return ;
if ( ! appendLabelToSavePath ) return ;
2013-11-10 16:05:43 +04:00
QString old_save_path = fsutils : : fromNativePath ( TorrentPersistentData : : getSavePath ( h . hash ( ) ) ) ;
2012-02-20 21:30:53 +04:00
if ( ! old_save_path . startsWith ( defaultSavePath ) ) return ;
2012-05-16 22:19:05 +04:00
QString new_save_path = fsutils : : updateLabelInSavePath ( defaultSavePath , old_save_path , old_label , new_label ) ;
2012-02-20 21:30:53 +04:00
if ( new_save_path ! = old_save_path ) {
2010-10-17 15:45:53 +04:00
// Move storage
qDebug ( " Moving storage to %s " , qPrintable ( new_save_path ) ) ;
QDir ( ) . mkpath ( new_save_path ) ;
h . move_storage ( new_save_path ) ;
2009-12-17 23:28:30 +03:00
}
2010-10-17 15:45:53 +04:00
}
2009-12-17 23:28:30 +03:00
2010-11-24 23:31:14 +03:00
void QBtSession : : appendLabelToTorrentSavePath ( const QTorrentHandle & h ) {
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) return ;
2010-10-17 15:45:53 +04:00
const QString label = TorrentPersistentData : : getLabel ( h . hash ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( label . isEmpty ( ) ) return ;
2010-10-17 15:45:53 +04:00
// Current save path
2013-11-10 16:05:43 +04:00
QString old_save_path = fsutils : : fromNativePath ( TorrentPersistentData : : getSavePath ( h . hash ( ) ) ) ;
2012-05-16 22:19:05 +04:00
QString new_save_path = fsutils : : updateLabelInSavePath ( defaultSavePath , old_save_path , " " , label ) ;
2012-02-20 21:30:53 +04:00
if ( old_save_path ! = new_save_path ) {
2010-10-17 15:45:53 +04:00
// Move storage
QDir ( ) . mkpath ( new_save_path ) ;
h . move_storage ( new_save_path ) ;
}
}
2010-10-17 18:46:01 +04:00
void QBtSession : : setAppendLabelToSavePath ( bool append ) {
2012-02-20 21:30:53 +04:00
if ( appendLabelToSavePath ! = append ) {
2010-10-17 15:45:53 +04:00
appendLabelToSavePath = ! appendLabelToSavePath ;
2012-02-20 21:30:53 +04:00
if ( appendLabelToSavePath ) {
2010-10-17 15:45:53 +04:00
// Move torrents storage to sub folder with label name
2010-08-20 13:02:27 +04:00
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-01-03 02:03:46 +03:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
2010-10-17 15:45:53 +04:00
appendLabelToTorrentSavePath ( h ) ;
2010-01-03 02:03:46 +03:00
}
2009-12-18 16:36:47 +03:00
}
}
2010-10-17 15:45:53 +04:00
}
2009-12-18 16:36:47 +03:00
2010-10-17 18:46:01 +04:00
void QBtSession : : setAppendqBExtension ( bool append ) {
2012-02-20 21:30:53 +04:00
if ( appendqBExtension ! = append ) {
2010-10-17 15:45:53 +04:00
appendqBExtension = ! appendqBExtension ;
// append or remove .!qB extension for incomplete files
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
2012-07-14 02:28:23 +04:00
std : : vector < torrent_handle > : : iterator torrentIT = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator torrentITend = torrents . end ( ) ;
for ( ; torrentIT ! = torrentITend ; + + torrentIT ) {
2010-10-17 15:45:53 +04:00
QTorrentHandle h = QTorrentHandle ( * torrentIT ) ;
appendqBextensionToTorrent ( h , appendqBExtension ) ;
2010-05-11 19:53:14 +04:00
}
2010-01-03 02:03:46 +03:00
}
2010-10-17 15:45:53 +04:00
}
2007-03-05 16:55:23 +03:00
2010-10-17 15:45:53 +04:00
// Set the ports range in which is chosen the port the Bittorrent
// session will listen to
2010-10-17 18:46:01 +04:00
void QBtSession : : setListeningPort ( int port ) {
2011-05-01 16:00:23 +04:00
qDebug ( ) < < Q_FUNC_INFO < < port ;
2011-02-05 18:44:48 +03:00
Preferences pref ;
2010-10-17 15:45:53 +04:00
std : : pair < int , int > ports ( port , port ) ;
2012-09-16 02:28:58 +04:00
libtorrent : : error_code ec ;
2011-02-05 18:44:48 +03:00
const QString iface_name = pref . getNetworkInterface ( ) ;
2012-02-20 21:30:53 +04:00
if ( iface_name . isEmpty ( ) ) {
2014-01-08 14:03:26 +04:00
addConsoleMessage ( tr ( " qBittorrent is trying to listen on any interface port: %1 " , " e.g: qBittorrent is trying to listen on any interface port: TCP/6881 " ) . arg ( QString : : number ( port ) ) , " blue " ) ;
2013-09-20 22:23:26 +04:00
s - > listen_on ( ports , ec , 0 , session : : listen_no_system_port ) ;
2010-10-17 15:45:53 +04:00
return ;
2010-01-03 02:03:46 +03:00
}
2011-02-05 18:44:48 +03:00
// Attempt to listen on provided interface
2010-11-16 23:34:31 +03:00
const QNetworkInterface network_iface = QNetworkInterface : : interfaceFromName ( iface_name ) ;
2012-02-20 21:30:53 +04:00
if ( ! network_iface . isValid ( ) ) {
2010-10-31 02:40:28 +04:00
qDebug ( " Invalid network interface: %s " , qPrintable ( iface_name ) ) ;
addConsoleMessage ( tr ( " The network interface defined is invalid: %1 " ) . arg ( iface_name ) , " red " ) ;
2010-10-17 15:45:53 +04:00
return ;
2010-01-03 02:03:46 +03:00
}
2010-10-31 02:40:28 +04:00
QString ip ;
qDebug ( " This network interface has %d IP addresses " , network_iface . addressEntries ( ) . size ( ) ) ;
2012-02-20 21:30:53 +04:00
foreach ( const QNetworkAddressEntry & entry , network_iface . addressEntries ( ) ) {
2010-10-31 02:40:28 +04:00
qDebug ( " Trying to listen on IP %s (%s) " , qPrintable ( entry . ip ( ) . toString ( ) ) , qPrintable ( iface_name ) ) ;
2013-09-20 22:23:26 +04:00
s - > listen_on ( ports , ec , entry . ip ( ) . toString ( ) . toAscii ( ) . constData ( ) , session : : listen_no_system_port ) ;
2012-02-20 21:30:53 +04:00
if ( ! ec ) {
2010-10-31 02:40:28 +04:00
ip = entry . ip ( ) . toString ( ) ;
2014-01-08 14:03:26 +04:00
addConsoleMessage ( tr ( " qBittorrent is trying to listen on interface %1 port: %2 " , " e.g: qBittorrent is trying to listen on interface 192.168.0.1 port: TCP/6881 " ) . arg ( ip ) . arg ( QString : : number ( port ) ) , " blue " ) ;
2010-10-31 02:40:28 +04:00
break ;
}
2013-09-20 00:43:21 +04:00
}
2010-10-17 15:45:53 +04:00
}
2010-01-03 02:03:46 +03:00
2010-10-17 15:45:53 +04:00
// Set download rate limit
// -1 to disable
2010-10-17 18:46:01 +04:00
void QBtSession : : setDownloadRateLimit ( long rate ) {
2010-12-02 20:02:13 +03:00
qDebug ( ) < < Q_FUNC_INFO < < rate ;
2010-10-17 15:45:53 +04:00
Q_ASSERT ( rate = = - 1 | | rate > = 0 ) ;
2011-04-17 14:29:44 +04:00
session_settings settings = s - > settings ( ) ;
settings . download_rate_limit = rate ;
s - > set_settings ( settings ) ;
2010-10-17 15:45:53 +04:00
}
2007-09-09 13:09:24 +04:00
2010-10-17 15:45:53 +04:00
// Set upload rate limit
// -1 to disable
2010-10-17 18:46:01 +04:00
void QBtSession : : setUploadRateLimit ( long rate ) {
2010-11-27 11:56:24 +03:00
qDebug ( ) < < Q_FUNC_INFO < < rate ;
2010-10-17 15:45:53 +04:00
Q_ASSERT ( rate = = - 1 | | rate > = 0 ) ;
2011-04-17 14:29:44 +04:00
session_settings settings = s - > settings ( ) ;
settings . upload_rate_limit = rate ;
s - > set_settings ( settings ) ;
2010-10-17 15:45:53 +04:00
}
// Torrents will a ratio superior to the given value will
// be automatically deleted
2011-03-07 22:26:44 +03:00
void QBtSession : : setGlobalMaxRatio ( qreal ratio ) {
2012-02-20 21:30:53 +04:00
if ( ratio < 0 ) ratio = - 1. ;
if ( global_ratio_limit ! = ratio ) {
2011-03-07 22:26:44 +03:00
global_ratio_limit = ratio ;
qDebug ( " * Set global deleteRatio to %.1f " , global_ratio_limit ) ;
updateRatioTimer ( ) ;
}
}
void QBtSession : : setMaxRatioPerTorrent ( const QString & hash , qreal ratio )
{
if ( ratio < 0 )
ratio = - 1 ;
if ( ratio > MAX_RATIO )
ratio = MAX_RATIO ;
qDebug ( " * Set individual max ratio for torrent %s to %.1f. " ,
qPrintable ( hash ) , ratio ) ;
TorrentPersistentData : : setRatioLimit ( hash , ratio ) ;
updateRatioTimer ( ) ;
}
void QBtSession : : removeRatioPerTorrent ( const QString & hash )
{
qDebug ( " * Remove individual max ratio for torrent %s. " , qPrintable ( hash ) ) ;
TorrentPersistentData : : setRatioLimit ( hash , TorrentPersistentData : : USE_GLOBAL_RATIO ) ;
updateRatioTimer ( ) ;
}
qreal QBtSession : : getMaxRatioPerTorrent ( const QString & hash , bool * usesGlobalRatio ) const
{
qreal ratio_limit = TorrentPersistentData : : getRatioLimit ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ratio_limit = = TorrentPersistentData : : USE_GLOBAL_RATIO ) {
2011-03-07 22:26:44 +03:00
ratio_limit = global_ratio_limit ;
* usesGlobalRatio = true ;
2010-10-17 15:45:53 +04:00
} else {
2011-03-07 22:26:44 +03:00
* usesGlobalRatio = false ;
2008-05-18 00:32:03 +04:00
}
2011-03-07 22:26:44 +03:00
return ratio_limit ;
}
void QBtSession : : updateRatioTimer ( )
{
if ( global_ratio_limit = = - 1 & & ! TorrentPersistentData : : hasPerTorrentRatioLimit ( ) ) {
if ( BigRatioTimer - > isActive ( ) )
BigRatioTimer - > stop ( ) ;
} else if ( ! BigRatioTimer - > isActive ( ) ) {
BigRatioTimer - > start ( ) ;
2010-10-17 15:45:53 +04:00
}
}
2007-03-05 20:35:38 +03:00
2014-01-01 04:49:16 +04:00
# if LIBTORRENT_VERSION_NUM < 10000
2010-10-17 15:45:53 +04:00
// Set DHT port (>= 1 or 0 if same as BT)
2010-10-17 18:46:01 +04:00
void QBtSession : : setDHTPort ( int dht_port ) {
2012-02-20 21:30:53 +04:00
if ( dht_port > = 0 ) {
if ( dht_port = = current_dht_port ) return ;
2010-10-17 15:45:53 +04:00
struct dht_settings DHTSettings ;
DHTSettings . service_port = dht_port ;
s - > set_dht_settings ( DHTSettings ) ;
current_dht_port = dht_port ;
qDebug ( " Set DHT Port to %d " , dht_port ) ;
2008-05-18 00:32:03 +04:00
}
2010-10-17 15:45:53 +04:00
}
2014-01-01 04:49:16 +04:00
# endif
2007-03-05 20:35:38 +03:00
2010-10-17 15:45:53 +04:00
// Enable IP Filtering
2010-12-25 17:47:52 +03:00
void QBtSession : : enableIPFilter ( const QString & filter_path , bool force ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Enabling IPFiler " ) ;
2012-02-20 21:30:53 +04:00
if ( ! filterParser ) {
2010-10-17 15:45:53 +04:00
filterParser = new FilterParserThread ( this , s ) ;
2010-12-25 17:07:28 +03:00
connect ( filterParser . data ( ) , SIGNAL ( IPFilterParsed ( int ) ) , SLOT ( handleIPFilterParsed ( int ) ) ) ;
connect ( filterParser . data ( ) , SIGNAL ( IPFilterError ( ) ) , SLOT ( handleIPFilterError ( ) ) ) ;
2010-10-17 15:45:53 +04:00
}
2013-11-10 16:05:43 +04:00
if ( filterPath . isEmpty ( ) | | filterPath ! = fsutils : : fromNativePath ( filter_path ) | | force ) {
filterPath = fsutils : : fromNativePath ( filter_path ) ;
filterParser - > processFilterFile ( fsutils : : fromNativePath ( filter_path ) ) ;
2010-01-03 02:03:46 +03:00
}
2010-10-17 15:45:53 +04:00
}
2007-03-05 20:35:38 +03:00
2010-10-17 15:45:53 +04:00
// Disable IP Filtering
2010-10-17 18:46:01 +04:00
void QBtSession : : disableIPFilter ( ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Disabling IPFilter " ) ;
s - > set_ip_filter ( ip_filter ( ) ) ;
2012-02-20 21:30:53 +04:00
if ( filterParser ) {
2010-12-25 17:07:28 +03:00
disconnect ( filterParser . data ( ) , 0 , this , 0 ) ;
2010-10-17 15:45:53 +04:00
delete filterParser ;
2010-01-03 02:03:46 +03:00
}
2010-10-17 15:45:53 +04:00
filterPath = " " ;
}
2009-12-30 13:53:58 +03:00
2010-10-17 15:45:53 +04:00
// Set BT session settings (user_agent)
2010-10-17 18:46:01 +04:00
void QBtSession : : setSessionSettings ( const session_settings & sessionSettings ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Set session settings " ) ;
s - > set_settings ( sessionSettings ) ;
}
// Set Proxy
2011-05-01 15:22:17 +04:00
void QBtSession : : setProxySettings ( proxy_settings proxySettings ) {
2010-11-18 23:05:56 +03:00
qDebug ( ) < < Q_FUNC_INFO ;
2010-11-21 12:58:24 +03:00
2011-05-01 15:22:17 +04:00
proxySettings . proxy_peer_connections = Preferences ( ) . proxyPeerConnections ( ) ;
2010-11-18 23:05:56 +03:00
s - > set_proxy ( proxySettings ) ;
2011-05-01 15:22:17 +04:00
2010-11-18 23:05:56 +03:00
// Define environment variable
2010-10-17 15:45:53 +04:00
QString proxy_str ;
switch ( proxySettings . type ) {
case proxy_settings : : http_pw :
proxy_str = " http:// " + misc : : toQString ( proxySettings . username ) + " : " + misc : : toQString ( proxySettings . password ) + " @ " + misc : : toQString ( proxySettings . hostname ) + " : " + QString : : number ( proxySettings . port ) ;
break ;
case proxy_settings : : http :
proxy_str = " http:// " + misc : : toQString ( proxySettings . hostname ) + " : " + QString : : number ( proxySettings . port ) ;
break ;
case proxy_settings : : socks5 :
proxy_str = misc : : toQString ( proxySettings . hostname ) + " : " + QString : : number ( proxySettings . port ) ;
break ;
case proxy_settings : : socks5_pw :
proxy_str = misc : : toQString ( proxySettings . username ) + " : " + misc : : toQString ( proxySettings . password ) + " @ " + misc : : toQString ( proxySettings . hostname ) + " : " + QString : : number ( proxySettings . port ) ;
break ;
default :
qDebug ( " Disabling HTTP communications proxy " ) ;
2011-10-02 18:04:16 +04:00
qputenv ( " http_proxy " , QByteArray ( ) ) ;
qputenv ( " sock_proxy " , QByteArray ( ) ) ;
2010-10-17 15:45:53 +04:00
return ;
}
// We need this for urllib in search engine plugins
qDebug ( " HTTP communications proxy string: %s " , qPrintable ( proxy_str ) ) ;
2012-02-20 21:30:53 +04:00
if ( proxySettings . type = = proxy_settings : : socks5 | | proxySettings . type = = proxy_settings : : socks5_pw )
2011-10-02 18:04:16 +04:00
qputenv ( " sock_proxy " , proxy_str . toLocal8Bit ( ) ) ;
2010-10-17 15:45:53 +04:00
else
2011-10-02 18:04:16 +04:00
qputenv ( " http_proxy " , proxy_str . toLocal8Bit ( ) ) ;
2010-10-17 15:45:53 +04:00
}
2007-05-02 17:52:29 +04:00
2010-10-17 18:46:01 +04:00
void QBtSession : : recursiveTorrentDownload ( const QTorrentHandle & h ) {
2010-12-18 11:45:39 +03:00
try {
2012-02-20 21:30:53 +04:00
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
2011-04-17 14:29:44 +04:00
const QString torrent_relpath = h . filepath_at ( i ) ;
2012-02-20 21:30:53 +04:00
if ( torrent_relpath . endsWith ( " .torrent " ) ) {
2013-11-10 16:05:43 +04:00
addConsoleMessage ( tr ( " Recursive download of file %1 embedded in torrent %2 " , " Recursive download of test.torrent embedded in torrent test2 " ) . arg ( fsutils : : toNativePath ( torrent_relpath ) ) . arg ( h . name ( ) ) ) ;
const QString torrent_fullpath = h . save_path ( ) + " / " + torrent_relpath ;
2010-12-18 11:45:39 +03:00
2013-11-10 16:05:43 +04:00
boost : : intrusive_ptr < torrent_info > t = new torrent_info ( fsutils : : toNativePath ( torrent_fullpath ) . toUtf8 ( ) . constData ( ) ) ;
2010-10-17 15:45:53 +04:00
const QString sub_hash = misc : : toQString ( t - > info_hash ( ) ) ;
// Passing the save path along to the sub torrent file
TorrentTempData : : setSavePath ( sub_hash , h . save_path ( ) ) ;
addTorrent ( torrent_fullpath ) ;
2010-03-20 14:30:11 +03:00
}
}
2010-12-18 11:45:39 +03:00
} catch ( std : : exception & ) {
qDebug ( " Caught error loading torrent " ) ;
2010-03-20 14:30:11 +03:00
}
2010-10-17 15:45:53 +04:00
}
2010-08-20 17:20:23 +04:00
2010-10-17 18:46:01 +04:00
void QBtSession : : cleanUpAutoRunProcess ( int ) {
2010-10-17 15:45:53 +04:00
sender ( ) - > deleteLater ( ) ;
}
2010-08-20 17:20:23 +04:00
2011-02-26 22:56:15 +03:00
void QBtSession : : autoRunExternalProgram ( const QTorrentHandle & h , bool async ) {
2012-02-20 21:30:53 +04:00
if ( ! h . is_valid ( ) ) return ;
2010-11-16 23:34:31 +03:00
QString program = Preferences ( ) . getAutoRunProgram ( ) . trimmed ( ) ;
2012-02-20 21:30:53 +04:00
if ( program . isEmpty ( ) ) return ;
2010-10-17 15:45:53 +04:00
// Replace %f by torrent path
QString torrent_path ;
2012-02-20 21:30:53 +04:00
if ( h . num_files ( ) = = 1 )
2010-10-17 15:45:53 +04:00
torrent_path = h . firstFileSavePath ( ) ;
else
torrent_path = h . save_path ( ) ;
program . replace ( " %f " , torrent_path ) ;
2011-03-18 21:28:19 +03:00
// Replace %n by torrent name
program . replace ( " %n " , h . name ( ) ) ;
2010-10-17 15:45:53 +04:00
QProcess * process = new QProcess ;
2012-02-20 21:30:53 +04:00
if ( async ) {
2010-10-17 15:45:53 +04:00
connect ( process , SIGNAL ( finished ( int ) ) , this , SLOT ( cleanUpAutoRunProcess ( int ) ) ) ;
process - > start ( program ) ;
} else {
process - > execute ( program ) ;
delete process ;
2010-08-20 17:20:23 +04:00
}
2010-10-17 15:45:53 +04:00
}
2010-08-20 17:20:23 +04:00
2011-02-26 22:56:15 +03:00
void QBtSession : : sendNotificationEmail ( const QTorrentHandle & h ) {
2010-10-17 15:45:53 +04:00
// Prepare mail content
QString content = tr ( " Torrent name: %1 " ) . arg ( h . name ( ) ) + " \n " ;
content + = tr ( " Torrent size: %1 " ) . arg ( misc : : friendlyUnit ( h . actual_size ( ) ) ) + " \n " ;
content + = tr ( " Save path: %1 " ) . arg ( TorrentPersistentData : : getSavePath ( h . hash ( ) ) ) + " \n \n " ;
content + = tr ( " The torrent was downloaded in %1. " , " The torrent was downloaded in 1 hour and 20 seconds " ) . arg ( misc : : userFriendlyDuration ( h . active_time ( ) ) ) + " \n \n \n " ;
content + = tr ( " Thank you for using qBittorrent. " ) + " \n " ;
// Send the notification email
2011-04-09 21:39:51 +04:00
Smtp * sender = new Smtp ( this ) ;
sender - > sendMail ( " notification@qbittorrent.org " , Preferences ( ) . getMailNotificationEmail ( ) , tr ( " [qBittorrent] %1 has finished downloading " ) . arg ( h . name ( ) ) , content ) ;
2010-10-17 15:45:53 +04:00
}
2010-03-20 14:30:11 +03:00
2010-10-17 15:45:53 +04:00
// Read alerts sent by the Bittorrent session
2010-10-17 18:46:01 +04:00
void QBtSession : : readAlerts ( ) {
2010-10-17 15:45:53 +04:00
// look at session alerts and display some infos
std : : auto_ptr < alert > a = s - > pop_alert ( ) ;
while ( a . get ( ) ) {
2012-08-10 11:04:28 +04:00
try {
if ( torrent_finished_alert * p = dynamic_cast < torrent_finished_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " Got a torrent finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
// Remove .!qB extension if necessary
if ( appendqBExtension )
appendqBextensionToTorrent ( h , false ) ;
const bool was_already_seeded = TorrentPersistentData : : isSeed ( hash ) ;
qDebug ( " Was already seeded: %d " , was_already_seeded ) ;
if ( ! was_already_seeded ) {
h . save_resume_data ( ) ;
qDebug ( " Checking if the torrent contains torrent files to download " ) ;
// Check if there are torrent files inside
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
2013-11-10 16:05:43 +04:00
const QString torrent_relpath = h . filepath_at ( i ) ;
2012-08-10 11:04:28 +04:00
qDebug ( ) < < " File path: " < < torrent_relpath ;
if ( torrent_relpath . endsWith ( " .torrent " , Qt : : CaseInsensitive ) ) {
qDebug ( " Found possible recursive torrent download. " ) ;
const QString torrent_fullpath = h . save_path ( ) + " / " + torrent_relpath ;
qDebug ( " Full subtorrent path is %s " , qPrintable ( torrent_fullpath ) ) ;
try {
2013-11-10 16:05:43 +04:00
boost : : intrusive_ptr < torrent_info > t = new torrent_info ( fsutils : : toNativePath ( torrent_fullpath ) . toUtf8 ( ) . constData ( ) ) ;
2012-08-10 11:04:28 +04:00
if ( t - > is_valid ( ) ) {
qDebug ( " emitting recursiveTorrentDownloadPossible() " ) ;
emit recursiveTorrentDownloadPossible ( h ) ;
break ;
}
} catch ( std : : exception & ) {
qDebug ( " Caught error loading torrent " ) ;
2013-11-10 16:05:43 +04:00
addConsoleMessage ( tr ( " Unable to decode %1 torrent file. " ) . arg ( fsutils : : toNativePath ( torrent_fullpath ) ) , QString : : fromUtf8 ( " red " ) ) ;
2010-02-04 22:16:04 +03:00
}
2010-01-03 02:03:46 +03:00
}
2009-08-31 12:51:55 +04:00
}
2012-08-10 11:04:28 +04:00
// Move to download directory if necessary
if ( ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( hash ) ) ;
if ( current_dir ! = save_dir ) {
qDebug ( " Moving torrent from the temp folder " ) ;
h . move_storage ( save_dir . absolutePath ( ) ) ;
}
2010-10-02 16:52:06 +04:00
}
2012-08-10 11:04:28 +04:00
// Remember finished state
qDebug ( " Saving seed status " ) ;
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Recheck if the user asked to
Preferences pref ;
if ( pref . recheckTorrentsOnCompletion ( ) ) {
h . force_recheck ( ) ;
2011-02-05 17:51:31 +03:00
}
2012-08-10 11:04:28 +04:00
qDebug ( " Emitting finishedTorrent() signal " ) ;
emit finishedTorrent ( h ) ;
qDebug ( " Received finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
# ifndef DISABLE_GUI
bool will_shutdown = ( pref . shutdownWhenDownloadsComplete ( ) | |
pref . shutdownqBTWhenDownloadsComplete ( ) | |
pref . suspendWhenDownloadsComplete ( ) )
& & ! hasDownloadingTorrents ( ) ;
# else
bool will_shutdown = false ;
# endif
// AutoRun program
if ( pref . isAutoRunEnabled ( ) )
autoRunExternalProgram ( h , will_shutdown ) ;
2012-08-21 11:16:49 +04:00
// Move .torrent file to another folder
if ( pref . isFinishedTorrentExportEnabled ( ) )
exportTorrentFile ( h , FinishedTorrentExportFolder ) ;
2012-08-10 11:04:28 +04:00
// Mail notification
if ( pref . isMailNotificationEnabled ( ) )
sendNotificationEmail ( h ) ;
# ifndef DISABLE_GUI
// Auto-Shutdown
if ( will_shutdown ) {
bool suspend = pref . suspendWhenDownloadsComplete ( ) ;
bool shutdown = pref . shutdownWhenDownloadsComplete ( ) ;
// Confirm shutdown
QString confirm_msg ;
if ( suspend ) {
confirm_msg = tr ( " The computer will now go to sleep mode unless you cancel within the next 15 seconds... " ) ;
} else if ( shutdown ) {
confirm_msg = tr ( " The computer will now be switched off unless you cancel within the next 15 seconds... " ) ;
} else {
confirm_msg = tr ( " qBittorrent will now exit unless you cancel within the next 15 seconds... " ) ;
}
if ( ! ShutdownConfirmDlg : : askForConfirmation ( confirm_msg ) )
return ;
// Actually shut down
if ( suspend | | shutdown ) {
qDebug ( " Preparing for auto-shutdown because all downloads are complete! " ) ;
// Disabling it for next time
pref . setShutdownWhenDownloadsComplete ( false ) ;
pref . setSuspendWhenDownloadsComplete ( false ) ;
// Make sure preferences are synced before exiting
if ( suspend )
m_shutdownAct = SUSPEND_COMPUTER ;
else
m_shutdownAct = SHUTDOWN_COMPUTER ;
}
qDebug ( " Exiting the application " ) ;
qApp - > exit ( ) ;
2011-02-05 17:51:31 +03:00
return ;
2010-08-16 21:35:32 +04:00
}
2012-08-10 11:04:28 +04:00
# endif // DISABLE_GUI
2010-08-16 21:35:32 +04:00
}
2009-08-21 15:26:58 +04:00
}
2007-08-27 13:24:22 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( save_resume_data_alert * p = dynamic_cast < save_resume_data_alert * > ( a . get ( ) ) ) {
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) & & p - > resume_data ) {
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
if ( resume_file . exists ( ) )
fsutils : : forceRemove ( filepath ) ;
qDebug ( " Saving fastresume data in %s " , qPrintable ( filepath ) ) ;
2013-09-29 22:32:27 +04:00
backupPersistentData ( h . hash ( ) , p - > resume_data ) ;
2012-08-10 11:04:28 +04:00
vector < char > out ;
bencode ( back_inserter ( out ) , * p - > resume_data ) ;
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
2009-09-21 23:08:33 +04:00
}
2009-08-16 07:09:20 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( file_renamed_alert * p = dynamic_cast < file_renamed_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
if ( h . num_files ( ) > 1 ) {
// Check if folders were renamed
QStringList old_path_parts = h . orig_filepath_at ( p - > index ) . split ( " / " ) ;
old_path_parts . removeLast ( ) ;
QString old_path = old_path_parts . join ( " / " ) ;
2013-11-10 16:05:43 +04:00
QStringList new_path_parts = fsutils : : fromNativePath ( misc : : toQStringU ( p - > name ) ) . split ( " / " ) ;
2012-08-10 11:04:28 +04:00
new_path_parts . removeLast ( ) ;
if ( ! new_path_parts . isEmpty ( ) & & old_path ! = new_path_parts . join ( " / " ) ) {
qDebug ( " Old_path(%s) != new_path(%s) " , qPrintable ( old_path ) , qPrintable ( new_path_parts . join ( " / " ) ) ) ;
old_path = h . save_path ( ) + " / " + old_path ;
qDebug ( " Detected folder renaming, attempt to delete old folder: %s " , qPrintable ( old_path ) ) ;
QDir ( ) . rmpath ( old_path ) ;
}
} else {
// Single-file torrent
// Renaming a file corresponds to changing the save path
emit savePathChanged ( h ) ;
2010-06-04 00:08:19 +04:00
}
}
}
2012-08-10 11:04:28 +04:00
else if ( torrent_deleted_alert * p = dynamic_cast < torrent_deleted_alert * > ( a . get ( ) ) ) {
qDebug ( " A torrent was deleted from the hard disk, attempting to remove the root folder too... " ) ;
QString hash = misc : : toQString ( p - > info_hash ) ;
if ( ! hash . isEmpty ( ) ) {
if ( savePathsToRemove . contains ( hash ) ) {
const QString dirpath = savePathsToRemove . take ( hash ) ;
qDebug ( ) < < " Removing save path: " < < dirpath < < " ... " ;
bool ok = fsutils : : smartRemoveEmptyFolderTree ( dirpath ) ;
Q_UNUSED ( ok ) ;
qDebug ( ) < < " Folder was removed: " < < ok ;
}
} else {
// Fallback
qDebug ( ) < < " hash is empty, use fallback to remove save path " ;
foreach ( const QString & key , savePathsToRemove . keys ( ) ) {
// Attempt to delete
if ( QDir ( ) . rmdir ( savePathsToRemove [ key ] ) ) {
savePathsToRemove . remove ( key ) ;
}
2010-07-18 00:55:40 +04:00
}
}
}
2012-08-10 11:04:28 +04:00
else if ( storage_moved_alert * p = dynamic_cast < storage_moved_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Attempt to remove old folder if empty
2013-11-10 16:05:43 +04:00
const QString old_save_path = fsutils : : fromNativePath ( TorrentPersistentData : : getPreviousPath ( h . hash ( ) ) ) ;
const QString new_save_path = fsutils : : fromNativePath ( misc : : toQStringU ( p - > path . c_str ( ) ) ) ;
2012-08-10 11:04:28 +04:00
qDebug ( " Torrent moved from %s to %s " , qPrintable ( old_save_path ) , qPrintable ( new_save_path ) ) ;
QDir old_save_dir ( old_save_path ) ;
if ( old_save_dir ! = QDir ( defaultSavePath ) & & old_save_dir ! = QDir ( defaultTempPath ) ) {
qDebug ( " Attempting to remove %s " , qPrintable ( old_save_path ) ) ;
QDir ( ) . rmpath ( old_save_path ) ;
}
if ( defaultTempPath . isEmpty ( ) | | ! new_save_path . startsWith ( defaultTempPath ) ) {
qDebug ( " Storage has been moved, updating save path to %s " , qPrintable ( new_save_path ) ) ;
TorrentPersistentData : : saveSavePath ( h . hash ( ) , new_save_path ) ;
}
emit savePathChanged ( h ) ;
//h.force_recheck();
2010-04-10 18:50:11 +04:00
}
2010-01-05 00:16:33 +03:00
}
2012-08-10 11:04:28 +04:00
else if ( metadata_received_alert * p = dynamic_cast < metadata_received_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2013-09-18 01:44:18 +04:00
Preferences pref ;
2012-08-10 11:04:28 +04:00
if ( h . is_valid ( ) ) {
2013-09-18 01:44:18 +04:00
QString hash ( h . hash ( ) ) ;
if ( HiddenData : : hasData ( hash ) ) {
2013-10-10 00:34:00 +04:00
HiddenData : : gotMetadata ( hash ) ;
2013-09-18 01:44:18 +04:00
if ( pref . isQueueingSystemEnabled ( ) ) {
//Internally decrease the queue limits to ensure that that other queued items aren't started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
2013-10-10 00:34:00 +04:00
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
2013-09-18 01:44:18 +04:00
s - > set_settings ( sessionSettings ) ;
}
h . pause ( ) ;
}
2012-08-10 11:04:28 +04:00
qDebug ( " Received metadata for %s " , qPrintable ( h . hash ( ) ) ) ;
// Save metadata
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
if ( ! QFile : : exists ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) )
h . save_torrent_file ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) ;
// Copy the torrent file to the export folder
2012-08-21 11:16:49 +04:00
if ( m_torrentExportEnabled )
2012-08-10 11:04:28 +04:00
exportTorrentFile ( h ) ;
// Append .!qB to incomplete files
if ( appendqBExtension )
appendqBextensionToTorrent ( h , true ) ;
2013-09-18 01:44:18 +04:00
if ( ! HiddenData : : hasData ( hash ) )
emit metadataReceived ( h ) ;
else
emit metadataReceivedHidden ( h ) ;
if ( h . is_paused ( ) & & ! HiddenData : : hasData ( hash ) ) {
2012-08-10 11:04:28 +04:00
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
// and the torrent can be paused when metadata is received
emit pausedTorrent ( h ) ;
}
2010-10-17 15:45:53 +04:00
2012-08-10 11:04:28 +04:00
}
2009-08-17 12:08:51 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( file_error_alert * p = dynamic_cast < file_error_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) ) {
2012-08-10 11:04:28 +04:00
h . pause ( ) ;
std : : cerr < < " File Error: " < < p - > message ( ) . c_str ( ) < < std : : endl ;
2012-11-07 05:38:22 +04:00
addConsoleMessage ( tr ( " An I/O error occurred, '%1' paused. " ) . arg ( h . name ( ) ) ) ;
2013-07-28 13:59:03 +04:00
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
2012-08-10 11:04:28 +04:00
if ( h . is_valid ( ) ) {
2013-07-28 13:59:03 +04:00
emit fullDiskError ( h , misc : : toQStringU ( p - > message ( ) ) ) ;
2012-08-10 11:04:28 +04:00
//h.pause();
emit pausedTorrent ( h ) ;
}
2009-11-17 11:15:26 +03:00
}
2009-09-21 23:08:33 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( file_completed_alert * p = dynamic_cast < file_completed_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
qDebug ( " A file completed download in torrent %s " , qPrintable ( h . name ( ) ) ) ;
if ( appendqBExtension ) {
qDebug ( " appendqBTExtension is true " ) ;
QString name = h . filepath_at ( p - > index ) ;
if ( name . endsWith ( " .!qB " ) ) {
const QString old_name = name ;
name . chop ( 4 ) ;
qDebug ( " Renaming %s to %s " , qPrintable ( old_name ) , qPrintable ( name ) ) ;
h . rename_file ( p - > index , name ) ;
}
2009-12-18 16:36:47 +03:00
}
}
2012-08-10 11:04:28 +04:00
else if ( torrent_paused_alert * p = dynamic_cast < torrent_paused_alert * > ( a . get ( ) ) ) {
if ( p - > handle . is_valid ( ) ) {
QTorrentHandle h ( p - > handle ) ;
2013-09-18 01:44:18 +04:00
if ( ! HiddenData : : hasData ( h . hash ( ) ) ) {
if ( ! h . has_error ( ) )
h . save_resume_data ( ) ;
emit pausedTorrent ( h ) ;
}
2012-08-10 11:04:28 +04:00
}
}
else if ( tracker_error_alert * p = dynamic_cast < tracker_error_alert * > ( a . get ( ) ) ) {
// Level: fatal
2010-03-04 22:29:48 +03:00
QTorrentHandle h ( p - > handle ) ;
2012-08-10 11:04:28 +04:00
if ( h . is_valid ( ) ) {
// Authentication
if ( p - > status_code ! = 401 ) {
qDebug ( " Received a tracker error for %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
2013-07-28 13:59:03 +04:00
data . last_message = misc : : toQStringU ( p - > msg ) ;
2012-08-10 11:04:28 +04:00
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
} else {
emit trackerAuthenticationRequired ( h ) ;
}
}
2010-01-03 02:03:46 +03:00
}
2012-08-10 11:04:28 +04:00
else if ( tracker_reply_alert * p = dynamic_cast < tracker_reply_alert * > ( a . get ( ) ) ) {
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " Received a tracker reply from %s (Num_peers=%d) " , p - > url . c_str ( ) , p - > num_peers ) ;
// Connection was successful now. Remove possible old errors
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
2010-07-23 18:05:53 +04:00
const QString tracker_url = misc : : toQString ( p - > url ) ;
2012-08-10 11:04:28 +04:00
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = " " ; // Reset error/warning message
data . num_peers = p - > num_peers ;
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
}
2013-07-28 13:59:03 +04:00
}
else if ( tracker_warning_alert * p = dynamic_cast < tracker_warning_alert * > ( a . get ( ) ) ) {
2012-08-10 11:04:28 +04:00
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Connection was successful now but there is a warning message
2010-01-03 02:03:46 +03:00
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
2012-08-10 11:04:28 +04:00
const QString tracker_url = misc : : toQString ( p - > url ) ;
2010-01-03 02:03:46 +03:00
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
2013-07-28 13:59:03 +04:00
data . last_message = misc : : toQStringU ( p - > msg ) ; // Store warning message
2010-01-03 02:03:46 +03:00
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
2012-08-10 11:04:28 +04:00
qDebug ( " Received a tracker warning from %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
2010-01-03 02:03:46 +03:00
}
2009-11-19 11:14:04 +03:00
}
2012-08-10 11:04:28 +04:00
else if ( portmap_error_alert * p = dynamic_cast < portmap_error_alert * > ( a . get ( ) ) ) {
2013-07-28 13:59:03 +04:00
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping failure, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " red " ) ;
2012-08-10 11:04:28 +04:00
//emit UPnPError(QString(p->msg().c_str()));
2010-01-03 02:03:46 +03:00
}
2012-08-10 11:04:28 +04:00
else if ( portmap_alert * p = dynamic_cast < portmap_alert * > ( a . get ( ) ) ) {
qDebug ( " UPnP Success, msg: %s " , p - > message ( ) . c_str ( ) ) ;
2013-07-28 13:59:03 +04:00
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping successful, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " blue " ) ;
2012-08-10 11:04:28 +04:00
//emit UPnPSuccess(QString(p->msg().c_str()));
2010-01-03 02:03:46 +03:00
}
2012-08-10 11:04:28 +04:00
else if ( peer_blocked_alert * p = dynamic_cast < peer_blocked_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromAscii ( ip . c_str ( ) ) , true ) ;
//emit peerBlocked(QString::fromAscii(ip.c_str()));
}
2011-05-05 20:16:20 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( peer_ban_alert * p = dynamic_cast < peer_ban_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . address ( ) . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromAscii ( ip . c_str ( ) ) , false ) ;
//emit peerBlocked(QString::fromAscii(ip.c_str()));
}
2011-05-05 20:16:20 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( fastresume_rejected_alert * p = dynamic_cast < fastresume_rejected_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " /! \\ Fast resume failed for %s, reason: %s " , qPrintable ( h . name ( ) ) , p - > message ( ) . c_str ( ) ) ;
if ( p - > error . value ( ) = = 134 & & TorrentPersistentData : : isSeed ( h . hash ( ) ) & & h . has_missing_files ( ) ) {
const QString hash = h . hash ( ) ;
// Mismatching file size (files were probably moved
addConsoleMessage ( tr ( " File sizes mismatch for torrent %1, pausing it. " ) . arg ( h . name ( ) ) ) ;
TorrentPersistentData : : setErrorState ( hash , true ) ;
pauseTorrent ( hash ) ;
} else {
addConsoleMessage ( tr ( " Fast resume data was rejected for torrent %1, checking again... " ) . arg ( h . name ( ) ) , QString : : fromUtf8 ( " red " ) ) ;
2013-07-28 13:59:03 +04:00
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
2012-08-10 11:04:28 +04:00
}
2010-06-27 21:58:08 +04:00
}
2010-10-17 15:45:53 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( url_seed_alert * p = dynamic_cast < url_seed_alert * > ( a . get ( ) ) ) {
2013-07-28 13:59:03 +04:00
addConsoleMessage ( tr ( " Url seed lookup failed for url: %1, message: %2 " ) . arg ( misc : : toQString ( p - > url ) ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , QString : : fromUtf8 ( " red " ) ) ;
2012-08-10 11:04:28 +04:00
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
2011-04-13 21:18:56 +04:00
}
2012-08-10 11:04:28 +04:00
else if ( listen_succeeded_alert * p = dynamic_cast < listen_succeeded_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
2014-01-08 14:03:26 +04:00
QString proto = " TCP " ;
# if LIBTORRENT_VERSION_NUM >= 10000
if ( p - > sock_type = = listen_succeeded_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp_ssl )
proto = " TCP_SSL " ;
# endif
qDebug ( ) < < " Successfully listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent is successfully listening on interface %1 port: %2/%3 " , " e.g: qBittorrent is successfully listening on interface 192.168.0.1 port: TCP/6881 " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) , " blue " ) ;
2012-08-10 11:04:28 +04:00
// Force reannounce on all torrents because some trackers blacklist some ports
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
std : : vector < torrent_handle > : : iterator it = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator itend = torrents . end ( ) ;
for ( ; it ! = itend ; + + it ) {
it - > force_reannounce ( ) ;
2009-08-06 12:58:49 +04:00
}
2013-09-20 00:43:21 +04:00
}
else if ( listen_failed_alert * p = dynamic_cast < listen_failed_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
2014-01-08 14:03:26 +04:00
QString proto = " TCP " ;
# if LIBTORRENT_VERSION_NUM >= 10000
if ( p - > sock_type = = listen_failed_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp_ssl )
proto = " TCP_SSL " ;
else if ( p - > sock_type = = listen_failed_alert : : i2p )
proto = " I2P " ;
else if ( p - > sock_type = = listen_failed_alert : : socks5 )
proto = " SOCKS5 " ;
# endif
qDebug ( ) < < " Failed listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent failed listening on interface %1 port: %2/%3. Reason: %4 " , " e.g: qBittorrent failed listening on interface 192.168.0.1 port: TCP/6881. Reason: already in use " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) . arg ( misc : : toQStringU ( p - > error . message ( ) ) ) , " red " ) ;
2012-08-10 11:04:28 +04:00
}
else if ( torrent_checked_alert * p = dynamic_cast < torrent_checked_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " %s have just finished checking " , qPrintable ( hash ) ) ;
// Save seed status
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Move to temp directory if necessary
if ( ! h . is_seed ( ) & & ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( h . hash ( ) ) ) ;
if ( current_dir = = save_dir ) {
qDebug ( " Moving the torrent to the temp directory... " ) ;
2013-11-10 16:05:43 +04:00
QString torrent_tmp_path = defaultTempPath ;
2012-08-10 11:04:28 +04:00
h . move_storage ( torrent_tmp_path ) ;
}
}
emit torrentFinishedChecking ( h ) ;
if ( torrentsToPausedAfterChecking . contains ( hash ) ) {
torrentsToPausedAfterChecking . removeOne ( hash ) ;
h . pause ( ) ;
emit pausedTorrent ( h ) ;
}
2010-10-17 15:45:53 +04:00
}
2007-08-17 06:03:13 +04:00
}
2013-10-14 00:08:55 +04:00
else if ( external_ip_alert * p = dynamic_cast < external_ip_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
addConsoleMessage ( tr ( " External IP: %1 " , " e.g. External IP: 192.168.0.1 " ) . arg ( p - > external_address . to_string ( ec ) . c_str ( ) ) , " blue " ) ;
}
2012-08-10 11:04:28 +04:00
} catch ( const std : : exception & e ) {
qWarning ( ) < < " Caught exception in readAlerts(): " < < e . what ( ) ;
2007-08-17 06:03:13 +04:00
}
2012-08-10 11:04:28 +04:00
2010-10-17 15:45:53 +04:00
a = s - > pop_alert ( ) ;
}
}
2007-03-05 20:35:38 +03:00
2011-02-26 22:56:15 +03:00
void QBtSession : : recheckTorrent ( const QString & hash ) {
2010-10-17 15:45:53 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( h . is_valid ( ) & & h . has_metadata ( ) ) {
if ( h . is_paused ( ) ) {
if ( ! torrentsToPausedAfterChecking . contains ( h . hash ( ) ) ) {
2010-10-17 15:45:53 +04:00
torrentsToPausedAfterChecking < < h . hash ( ) ;
h . resume ( ) ;
2010-01-20 21:02:26 +03:00
}
}
2010-10-17 15:45:53 +04:00
h . force_recheck ( ) ;
}
}
2010-01-20 21:02:26 +03:00
2012-02-20 23:32:58 +04:00
QHash < QString , TrackerInfos > QBtSession : : getTrackersInfo ( const QString & hash ) const {
2010-10-17 15:45:53 +04:00
return trackersInfos . value ( hash , QHash < QString , TrackerInfos > ( ) ) ;
}
2007-07-27 17:58:12 +04:00
2012-02-20 23:32:58 +04:00
int QBtSession : : getListenPort ( ) const {
2010-12-02 20:36:08 +03:00
qDebug ( ) < < Q_FUNC_INFO < < s - > listen_port ( ) ;
2010-10-17 15:45:53 +04:00
return s - > listen_port ( ) ;
}
2007-03-08 01:36:01 +03:00
2012-02-20 23:32:58 +04:00
session_status QBtSession : : getSessionStatus ( ) const {
2010-10-17 15:45:53 +04:00
return s - > status ( ) ;
}
2007-03-08 01:36:01 +03:00
2012-05-15 20:57:31 +04:00
QString QBtSession : : getSavePath ( const QString & hash , bool fromScanDir , QString filePath ) {
2010-10-17 15:45:53 +04:00
QString savePath ;
2012-02-20 21:30:53 +04:00
if ( TorrentTempData : : hasTempData ( hash ) ) {
2013-11-10 16:05:43 +04:00
savePath = fsutils : : fromNativePath ( TorrentTempData : : getSavePath ( hash ) ) ;
2012-02-20 21:30:53 +04:00
if ( savePath . isEmpty ( ) ) {
2010-10-17 15:45:53 +04:00
savePath = defaultSavePath ;
}
2012-02-20 21:30:53 +04:00
if ( appendLabelToSavePath ) {
2010-10-17 15:45:53 +04:00
qDebug ( " appendLabelToSavePath is true " ) ;
const QString label = TorrentTempData : : getLabel ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! label . isEmpty ( ) ) {
2012-05-16 22:19:05 +04:00
savePath = fsutils : : updateLabelInSavePath ( defaultSavePath , savePath , " " , label ) ;
2009-12-17 23:28:30 +03:00
}
2010-06-27 21:58:08 +04:00
}
2010-10-17 15:45:53 +04:00
qDebug ( " getSavePath, got save_path from temp data: %s " , qPrintable ( savePath ) ) ;
} else {
2013-11-10 16:05:43 +04:00
savePath = fsutils : : fromNativePath ( TorrentPersistentData : : getSavePath ( hash ) ) ;
2010-10-17 15:45:53 +04:00
qDebug ( " SavePath got from persistant data is %s " , qPrintable ( savePath ) ) ;
2012-02-20 21:30:53 +04:00
if ( savePath . isEmpty ( ) ) {
if ( fromScanDir & & m_scanFolders - > downloadInTorrentFolder ( filePath ) ) {
2010-10-17 15:45:53 +04:00
savePath = QFileInfo ( filePath ) . dir ( ) . path ( ) ;
2011-03-10 20:46:56 +03:00
} else {
2010-10-17 15:45:53 +04:00
savePath = defaultSavePath ;
}
2010-01-03 02:03:46 +03:00
}
2012-02-20 21:30:53 +04:00
if ( ! fromScanDir & & appendLabelToSavePath ) {
2010-10-17 15:45:53 +04:00
const QString label = TorrentPersistentData : : getLabel ( hash ) ;
2012-02-20 21:30:53 +04:00
if ( ! label . isEmpty ( ) ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Torrent label is %s " , qPrintable ( label ) ) ;
2012-05-16 22:19:05 +04:00
savePath = fsutils : : updateLabelInSavePath ( defaultSavePath , savePath , " " , label ) ;
2010-10-17 15:45:53 +04:00
}
2010-06-27 21:58:08 +04:00
}
2010-10-17 15:45:53 +04:00
qDebug ( " getSavePath, got save_path from persistent data: %s " , qPrintable ( savePath ) ) ;
}
// Clean path
2013-11-10 16:05:43 +04:00
savePath = fsutils : : expandPathAbs ( savePath ) ;
2012-02-20 21:30:53 +04:00
if ( ! savePath . endsWith ( " / " ) )
2010-10-17 15:45:53 +04:00
savePath + = " / " ;
return savePath ;
}
2008-09-14 14:14:54 +04:00
2010-10-17 15:45:53 +04:00
// Take an url string to a torrent file,
// download the torrent file to a tmp location, then
// add it to download list
2012-05-20 17:03:10 +04:00
void QBtSession : : downloadFromUrl ( const QString & url , const QList < QNetworkCookie > & cookies )
{
2010-10-17 15:45:53 +04:00
addConsoleMessage ( tr ( " Downloading '%1', please wait... " , " e.g: Downloading 'xxx.torrent', please wait... " ) . arg ( url )
# ifndef DISABLE_GUI
, QPalette : : WindowText
# endif
) ;
//emit aboutToDownloadFromUrl(url);
// Launch downloader thread
2012-05-20 17:03:10 +04:00
downloader - > downloadTorrentUrl ( url , cookies ) ;
2010-10-17 15:45:53 +04:00
}
2010-10-17 18:46:01 +04:00
void QBtSession : : downloadFromURLList ( const QStringList & urls ) {
2012-02-20 21:30:53 +04:00
foreach ( const QString & url , urls ) {
2010-10-17 15:45:53 +04:00
downloadFromUrl ( url ) ;
}
}
2012-06-24 11:27:32 +04:00
void QBtSession : : addMagnetInteractive ( const QString & uri )
{
emit newMagnetLink ( uri ) ;
}
2012-06-24 17:46:41 +04:00
void QBtSession : : addMagnetSkipAddDlg ( const QString & uri , const QString & save_path , const QString & label ) {
if ( ! save_path . isEmpty ( ) | | ! label . isEmpty ( ) )
2013-11-10 16:05:43 +04:00
savepathLabel_fromurl [ uri ] = qMakePair ( fsutils : : fromNativePath ( save_path ) , label ) ;
2010-10-17 15:45:53 +04:00
addMagnetUri ( uri , false ) ;
2013-10-20 00:59:36 +04:00
emit newDownloadedTorrentFromRss ( uri ) ;
2010-10-17 15:45:53 +04:00
}
2013-03-01 23:25:38 +04:00
void QBtSession : : downloadUrlAndSkipDialog ( QString url , QString save_path , QString label , const QList < QNetworkCookie > & cookies ) {
2010-10-17 15:45:53 +04:00
//emit aboutToDownloadFromUrl(url);
2011-02-07 23:13:46 +03:00
const QUrl qurl = QUrl : : fromEncoded ( url . toUtf8 ( ) ) ;
2012-06-24 17:46:41 +04:00
if ( ! save_path . isEmpty ( ) | | ! label . isEmpty ( ) )
2013-11-10 16:05:43 +04:00
savepathLabel_fromurl [ qurl ] = qMakePair ( fsutils : : fromNativePath ( save_path ) , label ) ;
2010-10-17 15:45:53 +04:00
url_skippingDlg < < qurl ;
// Launch downloader thread
2013-03-01 23:25:38 +04:00
downloader - > downloadTorrentUrl ( url , cookies ) ;
2010-10-17 15:45:53 +04:00
}
// Add to Bittorrent session the downloaded torrent file
2010-10-17 18:46:01 +04:00
void QBtSession : : processDownloadedFile ( QString url , QString file_path ) {
2012-05-15 20:57:31 +04:00
Preferences pref ;
2011-02-07 23:13:46 +03:00
const int index = url_skippingDlg . indexOf ( QUrl : : fromEncoded ( url . toUtf8 ( ) ) ) ;
2012-02-20 21:30:53 +04:00
if ( index < 0 ) {
2010-10-17 15:45:53 +04:00
// Add file to torrent download list
2013-11-10 16:05:43 +04:00
file_path = fsutils : : fromNativePath ( file_path ) ;
2010-05-30 21:51:40 +04:00
# ifdef Q_WS_WIN
2010-10-17 15:45:53 +04:00
// Windows hack
2012-02-20 21:30:53 +04:00
if ( ! file_path . endsWith ( " .torrent " , Qt : : CaseInsensitive ) ) {
2010-10-17 15:45:53 +04:00
Q_ASSERT ( QFile : : exists ( file_path ) ) ;
2011-02-07 23:13:46 +03:00
qDebug ( " Torrent name does not end with .torrent, from %s " , qPrintable ( file_path ) ) ;
2012-02-20 21:30:53 +04:00
if ( QFile : : rename ( file_path , file_path + " .torrent " ) ) {
2010-10-17 15:45:53 +04:00
file_path + = " .torrent " ;
2010-06-27 21:58:08 +04:00
} else {
2010-10-17 15:45:53 +04:00
qDebug ( " Failed to rename torrent file! " ) ;
2010-06-27 21:58:08 +04:00
}
2010-01-03 02:03:46 +03:00
}
2010-10-17 15:45:53 +04:00
qDebug ( " Downloading torrent at path: %s " , qPrintable ( file_path ) ) ;
# endif
emit newDownloadedTorrent ( file_path , url ) ;
} else {
url_skippingDlg . removeAt ( index ) ;
2012-03-09 08:18:52 +04:00
QTorrentHandle h = addTorrent ( file_path , false , url , false ) ;
// Pause torrent if necessary
2012-05-15 20:57:31 +04:00
if ( h . is_valid ( ) & & pref . addTorrentsInPause ( ) & & Preferences ( ) . useAdditionDialog ( ) )
2012-03-09 08:18:52 +04:00
h . pause ( ) ;
2013-07-09 17:33:00 +04:00
emit newDownloadedTorrentFromRss ( url ) ;
2010-10-17 15:45:53 +04:00
}
2014-01-03 00:43:17 +04:00
fsutils : : forceRemove ( file_path ) ;
2010-10-17 15:45:53 +04:00
}
2007-03-08 01:36:01 +03:00
2010-10-17 15:45:53 +04:00
// Return current download rate for the BT
// session. Payload means that it only take into
// account "useful" part of the rate
2012-02-20 23:32:58 +04:00
qreal QBtSession : : getPayloadDownloadRate ( ) const {
2010-10-17 15:45:53 +04:00
return s - > status ( ) . payload_download_rate ;
}
2007-03-08 01:36:01 +03:00
2010-10-17 15:45:53 +04:00
// Return current upload rate for the BT
// session. Payload means that it only take into
// account "useful" part of the rate
2012-02-20 23:32:58 +04:00
qreal QBtSession : : getPayloadUploadRate ( ) const {
2010-10-17 15:45:53 +04:00
return s - > status ( ) . payload_upload_rate ;
}
2007-03-08 01:36:01 +03:00
2010-10-17 18:46:01 +04:00
void QBtSession : : applyEncryptionSettings ( pe_settings se ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Applying encryption settings " ) ;
s - > set_pe_settings ( se ) ;
}
2010-06-27 21:58:08 +04:00
2010-10-17 15:45:53 +04:00
// Will fast resume torrents in
// backup directory
2010-10-17 18:46:01 +04:00
void QBtSession : : startUpTorrents ( ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Resuming unfinished torrents " ) ;
2012-05-16 22:19:05 +04:00
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
2010-10-17 15:45:53 +04:00
const QStringList known_torrents = TorrentPersistentData : : knownTorrents ( ) ;
// Safety measure because some people reported torrent loss since
// we switch the v1.5 way of resuming torrents on startup
QStringList filters ;
filters < < " *.torrent " ;
const QStringList torrents_on_hd = torrentBackup . entryList ( filters , QDir : : Files , QDir : : Unsorted ) ;
2012-02-20 21:30:53 +04:00
foreach ( QString hash , torrents_on_hd ) {
2010-10-17 15:45:53 +04:00
hash . chop ( 8 ) ; // remove trailing .torrent
2012-02-20 21:30:53 +04:00
if ( ! known_torrents . contains ( hash ) ) {
2010-10-17 15:45:53 +04:00
qDebug ( " found torrent with hash: %s on hard disk " , qPrintable ( hash ) ) ;
std : : cerr < < " ERROR Detected!!! Adding back torrent " < < qPrintable ( hash ) < < " which got lost for some reason. " < < std : : endl ;
2013-11-10 16:05:43 +04:00
addTorrent ( torrentBackup . path ( ) + " / " + hash + " .torrent " , false , QString ( ) , true ) ;
2010-10-17 15:45:53 +04:00
}
}
// End of safety measure
qDebug ( " Starting up torrents " ) ;
2012-02-20 21:30:53 +04:00
if ( isQueueingEnabled ( ) ) {
2010-10-17 15:45:53 +04:00
priority_queue < QPair < int , QString > , vector < QPair < int , QString > > , std : : greater < QPair < int , QString > > > torrent_queue ;
2012-02-20 21:30:53 +04:00
foreach ( const QString & hash , known_torrents ) {
2010-10-17 15:45:53 +04:00
const int prio = TorrentPersistentData : : getPriority ( hash ) ;
torrent_queue . push ( qMakePair ( prio , hash ) ) ;
}
qDebug ( " Priority_queue size: %ld " , ( long ) torrent_queue . size ( ) ) ;
// Resume downloads
while ( ! torrent_queue . empty ( ) ) {
const QString hash = torrent_queue . top ( ) . second ;
torrent_queue . pop ( ) ;
qDebug ( " Starting up torrent %s " , qPrintable ( hash ) ) ;
2012-02-20 21:30:53 +04:00
if ( TorrentPersistentData : : isMagnet ( hash ) ) {
2010-10-17 15:45:53 +04:00
addMagnetUri ( TorrentPersistentData : : getMagnetUri ( hash ) , true ) ;
2010-06-27 21:58:08 +04:00
} else {
2013-11-10 16:05:43 +04:00
addTorrent ( torrentBackup . path ( ) + " / " + hash + " .torrent " , false , QString ( ) , true ) ;
2009-08-27 12:43:19 +04:00
}
}
2010-10-17 15:45:53 +04:00
} else {
// Resume downloads
2012-02-20 21:30:53 +04:00
foreach ( const QString & hash , known_torrents ) {
2010-10-17 15:45:53 +04:00
qDebug ( " Starting up torrent %s " , qPrintable ( hash ) ) ;
2012-02-20 21:30:53 +04:00
if ( TorrentPersistentData : : isMagnet ( hash ) )
2010-10-17 15:45:53 +04:00
addMagnetUri ( TorrentPersistentData : : getMagnetUri ( hash ) , true ) ;
else
2013-11-10 16:05:43 +04:00
addTorrent ( torrentBackup . path ( ) + " / " + hash + " .torrent " , false , QString ( ) , true ) ;
2010-10-17 15:45:53 +04:00
}
}
2013-02-16 22:04:48 +04:00
QIniSettings settings ;
2010-10-17 15:45:53 +04:00
settings . setValue ( " ported_to_new_savepath_system " , true ) ;
qDebug ( " Unfinished torrents resumed " ) ;
}
2010-11-13 22:36:46 +03:00
QBtSession * QBtSession : : instance ( )
{
2012-02-20 21:30:53 +04:00
if ( ! m_instance ) {
2010-11-13 22:36:46 +03:00
m_instance = new QBtSession ;
}
return m_instance ;
}
void QBtSession : : drop ( )
{
2012-02-20 21:30:53 +04:00
if ( m_instance ) {
2010-11-13 22:36:46 +03:00
delete m_instance ;
2010-11-13 23:14:59 +03:00
m_instance = 0 ;
}
2010-11-13 22:36:46 +03:00
}
2010-12-18 18:34:38 +03:00
qlonglong QBtSession : : getETA ( const QString & hash ) const
{
return m_speedMonitor - > getETA ( hash ) ;
}
2010-12-25 17:07:28 +03:00
2013-11-14 23:56:13 +04:00
quint64 QBtSession : : getAlltimeDL ( ) const {
return m_speedMonitor - > getAlltimeDL ( ) ;
}
quint64 QBtSession : : getAlltimeUL ( ) const {
return m_speedMonitor - > getAlltimeUL ( ) ;
}
2010-12-25 17:07:28 +03:00
void QBtSession : : handleIPFilterParsed ( int ruleCount )
{
2012-02-20 23:46:02 +04:00
addConsoleMessage ( tr ( " Successfully parsed the provided IP filter: %1 rules were applied. " , " %1 is a number " ) . arg ( ruleCount ) ) ;
2010-12-25 17:47:52 +03:00
emit ipFilterParsed ( false , ruleCount ) ;
2010-12-25 17:07:28 +03:00
}
void QBtSession : : handleIPFilterError ( )
{
addConsoleMessage ( tr ( " Error: Failed to parse the provided IP filter. " ) , " red " ) ;
2010-12-25 17:47:52 +03:00
emit ipFilterParsed ( true , 0 ) ;
2010-12-25 17:07:28 +03:00
}
2011-01-08 16:31:57 +03:00
2013-09-29 22:32:27 +04:00
void QBtSession : : recoverPersistentData ( const QString & hash , const std : : vector < char > & buf ) {
if ( TorrentPersistentData : : isKnownTorrent ( hash ) | | TorrentTempData : : hasTempData ( hash ) | | buf . empty ( ) )
return ;
libtorrent : : lazy_entry fast ;
libtorrent : : error_code ec ;
libtorrent : : lazy_bdecode ( & ( buf . front ( ) ) , & ( buf . back ( ) ) , fast , ec ) ;
if ( fast . type ( ) ! = libtorrent : : lazy_entry : : dict_t & & ! ec )
return ;
2013-11-10 16:05:43 +04:00
QString savePath = fsutils : : fromNativePath ( QString : : fromUtf8 ( fast . dict_find_string_value ( " qBt-savePath " ) . c_str ( ) ) ) ;
2013-09-29 22:32:27 +04:00
qreal ratioLimit = QString : : fromUtf8 ( fast . dict_find_string_value ( " qBt-ratioLimit " ) . c_str ( ) ) . toDouble ( ) ;
QDateTime addedDate = QDateTime : : fromTime_t ( fast . dict_find_int_value ( " added_time " ) ) ;
QString previousSavePath = QString : : fromUtf8 ( fast . dict_find_string_value ( " qBt-previousSavePath " ) . c_str ( ) ) ;
QDateTime seedDate = QDateTime : : fromTime_t ( fast . dict_find_int_value ( " qBt-seedDate " ) ) ;
QString label = QString : : fromUtf8 ( fast . dict_find_string_value ( " qBt-label " ) . c_str ( ) ) ;
int priority = fast . dict_find_int_value ( " qBt-queuePosition " ) ;
bool seedStatus = fast . dict_find_int_value ( " qBt-seedStatus " ) ;
TorrentPersistentData : : saveSavePath ( hash , savePath ) ;
TorrentPersistentData : : setRatioLimit ( hash , ratioLimit ) ;
TorrentPersistentData : : setAddedDate ( hash , addedDate ) ;
TorrentPersistentData : : setPreviousSavePath ( hash , previousSavePath ) ;
TorrentPersistentData : : saveSeedDate ( hash , seedDate ) ;
TorrentPersistentData : : saveLabel ( hash , label ) ;
TorrentPersistentData : : savePriority ( hash , priority ) ;
TorrentPersistentData : : saveSeedStatus ( hash , seedStatus ) ;
}
void QBtSession : : backupPersistentData ( const QString & hash , boost : : shared_ptr < libtorrent : : entry > data ) {
2013-11-10 16:05:43 +04:00
( * data ) [ " qBt-savePath " ] = fsutils : : fromNativePath ( TorrentPersistentData : : getSavePath ( hash ) ) . toUtf8 ( ) . constData ( ) ;
2013-09-29 22:32:27 +04:00
( * data ) [ " qBt-ratioLimit " ] = QString : : number ( TorrentPersistentData : : getRatioLimit ( hash ) ) . toUtf8 ( ) . constData ( ) ;
2013-11-10 16:05:43 +04:00
( * data ) [ " qBt-previousSavePath " ] = fsutils : : fromNativePath ( TorrentPersistentData : : getPreviousPath ( hash ) ) . toUtf8 ( ) . constData ( ) ;
2013-09-29 22:32:27 +04:00
( * data ) [ " qBt-seedDate " ] = TorrentPersistentData : : getSeedDate ( hash ) . toTime_t ( ) ;
( * data ) [ " qBt-label " ] = TorrentPersistentData : : getLabel ( hash ) . toUtf8 ( ) . constData ( ) ;
( * data ) [ " qBt-queuePosition " ] = TorrentPersistentData : : getPriority ( hash ) ;
( * data ) [ " qBt-seedStatus " ] = ( int ) TorrentPersistentData : : isSeed ( hash ) ;
}
2013-09-18 01:44:18 +04:00
void QBtSession : : unhideMagnet ( const QString & hash ) {
Preferences pref ;
2013-10-10 00:34:00 +04:00
HiddenData : : deleteData ( hash ) ;
2013-10-24 00:58:17 +04:00
QString save_path = getSavePath ( hash , false ) ; //appends label if necessary
2013-09-18 01:44:18 +04:00
QTorrentHandle h ( getTorrentHandle ( hash ) ) ;
2013-10-10 00:34:00 +04:00
2013-09-18 01:44:18 +04:00
if ( ! h . is_valid ( ) ) {
if ( pref . isQueueingSystemEnabled ( ) ) {
//Internally decrease the queue limits to ensure that other queued items aren't started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
2013-10-10 00:34:00 +04:00
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
2013-09-18 01:44:18 +04:00
s - > set_settings ( sessionSettings ) ;
2013-10-10 00:34:00 +04:00
}
2013-09-18 01:44:18 +04:00
TorrentTempData : : deleteTempData ( hash ) ;
return ;
}
if ( ! h . has_metadata ( ) ) {
if ( pref . isQueueingSystemEnabled ( ) ) {
//Internally decrease the queue limits to ensure that other queued items aren't started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
2013-10-10 00:34:00 +04:00
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
2013-09-18 01:44:18 +04:00
s - > set_settings ( sessionSettings ) ;
}
if ( pref . addTorrentsInPause ( ) )
h . pause ( ) ;
}
h . queue_position_bottom ( ) ;
2013-10-10 00:34:00 +04:00
loadTorrentTempData ( h , h . save_path ( ) , ! h . has_metadata ( ) ) ; //TempData are deleted by a call to TorrentPersistentData::saveTorrentPersistentData()
2013-09-18 01:44:18 +04:00
if ( ! pref . addTorrentsInPause ( ) )
h . resume ( ) ;
2013-10-10 00:34:00 +04:00
h . move_storage ( save_path ) ;
2013-09-18 01:44:18 +04:00
emit addedTorrent ( h ) ;
}