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 .
*
* Contact : chris @ qbittorrent . org
2007-03-05 16:55:23 +03:00
*/
2007-03-27 22:49:29 +04:00
# include <QDir>
# include <QTime>
# include <QString>
2007-07-30 17:56:31 +04:00
# include <QTimer>
2008-05-18 13:50:35 +04:00
# include <QSettings>
2007-03-27 22:49:29 +04:00
2007-09-29 12:00:14 +04:00
# include "bittorrent.h"
# include "misc.h"
# include "downloadThread.h"
2007-10-19 20:00:42 +04:00
# include "deleteThread.h"
2008-05-18 00:32:03 +04:00
# include "filterParserThread.h"
2007-09-29 12:00:14 +04:00
2007-07-23 16:46:36 +04:00
# include <libtorrent/extensions/metadata_transfer.hpp>
# include <libtorrent/extensions/ut_pex.hpp>
# include <libtorrent/entry.hpp>
# include <libtorrent/bencode.hpp>
# include <libtorrent/identify_client.hpp>
# include <libtorrent/alert_types.hpp>
2007-08-26 20:25:22 +04:00
# include <libtorrent/torrent_info.hpp>
2007-08-02 00:01:06 +04:00
# include <boost/filesystem/exception.hpp>
2007-07-23 16:46:36 +04:00
2007-08-29 19:13:20 +04:00
# define MAX_TRACKER_ERRORS 2
2007-06-29 19:23:15 +04:00
2007-03-05 16:55:23 +03:00
// Main constructor
2008-07-27 19:41:46 +04:00
bittorrent : : bittorrent ( ) : timerScan ( 0 ) , DHTEnabled ( false ) , preAllocateAll ( false ) , addInPause ( false ) , maxConnecsPerTorrent ( 500 ) , maxUploadsPerTorrent ( 4 ) , max_ratio ( - 1 ) , UPnPEnabled ( false ) , NATPMPEnabled ( false ) , LSDEnabled ( false ) , folderScanInterval ( 5 ) , queueingEnabled ( false ) , calculateETA ( true ) {
2007-04-07 11:43:57 +04:00
// To avoid some exceptions
fs : : path : : default_name_check ( fs : : no_check ) ;
2007-03-05 16:55:23 +03:00
// Creating bittorrent session
2008-05-18 13:50:35 +04:00
// Check if we should spoof azureus
QSettings settings ( QString : : fromUtf8 ( " qBittorrent " ) , QString : : fromUtf8 ( " qBittorrent " ) ) ;
if ( settings . value ( QString : : fromUtf8 ( " AzureusSpoof " ) , false ) . toBool ( ) ) {
2008-07-10 02:42:04 +04:00
s = new session ( fingerprint ( " AZ " , 3 , 0 , 5 , 2 ) ) ;
2008-05-18 13:50:35 +04:00
} else {
s = new session ( fingerprint ( " qB " , VERSION_MAJOR , VERSION_MINOR , VERSION_BUGFIX , 0 ) ) ;
}
2007-03-05 16:55:23 +03:00
// Set severity level of libtorrent session
s - > set_severity_level ( alert : : info ) ;
// Enabling metadata plugin
s - > add_extension ( & create_metadata_plugin ) ;
2007-07-30 17:56:31 +04:00
timerAlerts = new QTimer ( ) ;
connect ( timerAlerts , SIGNAL ( timeout ( ) ) , this , SLOT ( readAlerts ( ) ) ) ;
timerAlerts - > start ( 3000 ) ;
2007-11-19 23:33:31 +03:00
fastResumeSaver = new QTimer ( ) ;
2007-11-23 00:50:22 +03:00
connect ( fastResumeSaver , SIGNAL ( timeout ( ) ) , this , SLOT ( saveFastResumeAndRatioData ( ) ) ) ;
2007-11-21 19:50:26 +03:00
fastResumeSaver - > start ( 60000 ) ;
2007-03-08 01:36:01 +03:00
// To download from urls
downloader = new downloadThread ( this ) ;
2007-07-22 13:47:27 +04:00
connect ( downloader , SIGNAL ( downloadFinished ( QString , QString ) ) , this , SLOT ( processDownloadedFile ( QString , QString ) ) ) ;
2007-08-26 20:25:22 +04:00
connect ( downloader , SIGNAL ( downloadFailure ( QString , QString ) ) , this , SLOT ( handleDownloadFailure ( QString , QString ) ) ) ;
2007-10-19 20:00:42 +04:00
// File deleter (thread)
deleter = new deleteThread ( this ) ;
2008-05-18 00:32:03 +04:00
BigRatioTimer = 0 ;
filterParser = 0 ;
2008-07-14 23:20:18 +04:00
downloadQueue = 0 ;
2008-07-15 22:10:10 +04:00
queuedDownloads = 0 ;
uploadQueue = 0 ;
queuedUploads = 0 ;
2007-08-26 20:25:22 +04:00
qDebug ( " * BTSession constructed " ) ;
2007-03-08 01:36:01 +03:00
}
2007-03-05 16:55:23 +03:00
// Main destructor
2007-08-20 10:29:18 +04:00
bittorrent : : ~ bittorrent ( ) {
2008-05-18 16:01:42 +04:00
qDebug ( " BTSession deletion " ) ;
2007-11-24 15:11:12 +03:00
// Set Session settings
session_settings ss ;
ss . tracker_receive_timeout = 1 ;
ss . stop_tracker_timeout = 1 ;
ss . tracker_completion_timeout = 1 ;
ss . piece_timeout = 1 ;
ss . peer_timeout = 1 ;
ss . urlseed_timeout = 1 ;
s - > set_settings ( ss ) ;
2007-07-29 18:54:39 +04:00
// Disable directory scanning
2007-03-05 16:55:23 +03:00
disableDirectoryScanning ( ) ;
2007-07-29 18:54:39 +04:00
// Delete our objects
2007-10-19 20:00:42 +04:00
delete deleter ;
2007-11-19 23:33:31 +03:00
delete fastResumeSaver ;
2007-07-30 17:56:31 +04:00
delete timerAlerts ;
2008-09-13 11:33:41 +04:00
if ( BigRatioTimer )
2007-11-25 00:55:19 +03:00
delete BigRatioTimer ;
2008-09-13 11:33:41 +04:00
if ( filterParser )
2008-05-18 00:32:03 +04:00
delete filterParser ;
2007-03-08 01:36:01 +03:00
delete downloader ;
2008-07-15 02:01:05 +04:00
if ( queueingEnabled ) {
2008-07-14 23:20:18 +04:00
Q_ASSERT ( downloadQueue ) ;
delete downloadQueue ;
Q_ASSERT ( queuedDownloads ) ;
delete queuedDownloads ;
2008-07-15 02:01:05 +04:00
Q_ASSERT ( uploadQueue ) ;
delete uploadQueue ;
Q_ASSERT ( queuedUploads ) ;
delete queuedUploads ;
2008-07-14 23:20:18 +04:00
}
2007-08-08 03:15:46 +04:00
// Delete BT session
2007-11-24 15:11:12 +03:00
qDebug ( " Deleting session " ) ;
2007-03-05 16:55:23 +03:00
delete s ;
2007-11-24 15:11:12 +03:00
qDebug ( " Session deleted " ) ;
2007-03-05 16:55:23 +03:00
}
2007-09-08 21:07:29 +04:00
void bittorrent : : preAllocateAllFiles ( bool b ) {
2007-11-03 01:56:07 +03:00
bool change = ( preAllocateAll ! = b ) ;
if ( change ) {
qDebug ( " PreAllocateAll changed, reloading all torrents! " ) ;
preAllocateAll = b ;
2007-11-03 03:19:24 +03:00
// Reload All unfinished torrents
QString hash ;
foreach ( hash , unfinishedTorrents ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-11-03 01:56:07 +03:00
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
2007-11-19 23:33:31 +03:00
reloadTorrent ( h , b ) ;
2007-09-08 21:07:29 +04:00
}
}
}
2007-09-09 13:09:24 +04:00
void bittorrent : : deleteBigRatios ( ) {
if ( max_ratio = = - 1 ) return ;
2007-09-13 23:50:14 +04:00
QString hash ;
foreach ( hash , finishedTorrents ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-09-09 13:09:24 +04:00
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
QString hash = h . hash ( ) ;
if ( getRealRatio ( hash ) > max_ratio ) {
QString fileName = h . name ( ) ;
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " %1 reached the maximum ratio you set. " ) . arg ( fileName ) ) ;
2007-09-09 13:09:24 +04:00
deleteTorrent ( hash ) ;
2008-09-07 15:31:29 +04:00
//emit torrent_ratio_deleted(fileName);
2007-09-09 13:09:24 +04:00
}
}
}
2008-07-27 19:41:46 +04:00
void bittorrent : : setETACalculation ( bool enable ) {
if ( calculateETA ! = enable ) {
calculateETA = enable ;
if ( calculateETA ) {
foreach ( QString hash , unfinishedTorrents ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_paused ( ) ) {
TorrentsStartData [ hash ] = h . total_payload_download ( ) ;
TorrentsStartTime [ hash ] = QDateTime : : currentDateTime ( ) ;
}
}
} else {
TorrentsStartData . clear ( ) ;
TorrentsStartTime . clear ( ) ;
}
}
}
2007-08-20 10:29:18 +04:00
void bittorrent : : setDownloadLimit ( QString hash , long val ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-07-30 20:57:28 +04:00
if ( h . is_valid ( ) )
h . set_download_limit ( val ) ;
2007-07-14 17:38:29 +04:00
saveTorrentSpeedLimits ( hash ) ;
}
2008-07-15 02:01:05 +04:00
bool bittorrent : : isQueueingEnabled ( ) const {
return queueingEnabled ;
2008-07-14 23:20:18 +04:00
}
2008-07-15 02:01:05 +04:00
void bittorrent : : setMaxActiveDownloads ( int val ) {
2008-07-15 22:34:28 +04:00
if ( val ! = maxActiveDownloads ) {
maxActiveDownloads = val ;
if ( queueingEnabled ) {
updateDownloadQueue ( ) ;
updateUploadQueue ( ) ;
}
}
2008-07-15 02:01:05 +04:00
}
void bittorrent : : setMaxActiveTorrents ( int val ) {
2008-07-15 22:34:28 +04:00
if ( val ! = maxActiveTorrents ) {
maxActiveTorrents = val ;
if ( queueingEnabled ) {
updateDownloadQueue ( ) ;
updateUploadQueue ( ) ;
}
}
2008-07-14 23:20:18 +04:00
}
2008-07-15 00:01:21 +04:00
void bittorrent : : increaseDlTorrentPriority ( QString hash ) {
2008-08-02 23:46:02 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-14 23:20:18 +04:00
int index = downloadQueue - > indexOf ( hash ) ;
Q_ASSERT ( index ! = - 1 ) ;
if ( index > 0 ) {
downloadQueue - > swap ( index - 1 , index ) ;
2008-07-15 02:01:05 +04:00
saveTorrentPriority ( hash , index - 1 ) ;
saveTorrentPriority ( downloadQueue - > at ( index ) , index ) ;
2008-07-14 23:20:18 +04:00
updateDownloadQueue ( ) ;
}
}
2008-07-15 02:01:05 +04:00
void bittorrent : : increaseUpTorrentPriority ( QString hash ) {
2008-08-02 23:46:02 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-15 02:01:05 +04:00
int index = uploadQueue - > indexOf ( hash ) ;
Q_ASSERT ( index ! = - 1 ) ;
if ( index > 0 ) {
uploadQueue - > swap ( index - 1 , index ) ;
saveTorrentPriority ( hash , index - 1 ) ;
saveTorrentPriority ( uploadQueue - > at ( index ) , index ) ;
updateUploadQueue ( ) ;
}
}
2008-07-15 00:01:21 +04:00
void bittorrent : : decreaseDlTorrentPriority ( QString hash ) {
2008-08-02 23:46:02 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-14 23:20:18 +04:00
int index = downloadQueue - > indexOf ( hash ) ;
Q_ASSERT ( index ! = - 1 ) ;
if ( index > = 0 & & index < ( downloadQueue - > size ( ) - 1 ) ) {
downloadQueue - > swap ( index + 1 , index ) ;
2008-07-15 02:01:05 +04:00
saveTorrentPriority ( hash , index + 1 ) ;
saveTorrentPriority ( downloadQueue - > at ( index ) , index ) ;
2008-07-14 23:20:18 +04:00
updateDownloadQueue ( ) ;
}
}
2008-07-15 02:01:05 +04:00
void bittorrent : : decreaseUpTorrentPriority ( QString hash ) {
2008-08-02 23:46:02 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-15 02:01:05 +04:00
int index = uploadQueue - > indexOf ( hash ) ;
Q_ASSERT ( index ! = - 1 ) ;
if ( index > = 0 & & index < ( uploadQueue - > size ( ) - 1 ) ) {
uploadQueue - > swap ( index + 1 , index ) ;
saveTorrentPriority ( hash , index + 1 ) ;
saveTorrentPriority ( uploadQueue - > at ( index ) , index ) ;
updateUploadQueue ( ) ;
}
}
void bittorrent : : saveTorrentPriority ( QString hash , int prio ) {
2008-07-14 23:20:18 +04:00
// Write .queued file
QFile prio_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
prio_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
prio_file . write ( QByteArray : : number ( prio ) ) ;
prio_file . close ( ) ;
}
2008-07-15 02:01:05 +04:00
int bittorrent : : loadTorrentPriority ( QString hash ) {
2008-07-14 23:20:18 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ) {
// Read .queued file
QFile prio_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
if ( ! prio_file . exists ( ) ) {
return - 1 ;
}
prio_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ;
bool ok = false ;
int prio = prio_file . readAll ( ) . toInt ( & ok ) ;
prio_file . close ( ) ;
if ( ! ok ) {
return - 1 ;
}
return prio ;
}
return - 1 ;
}
bool bittorrent : : isDownloadQueued ( QString hash ) const {
2008-07-15 02:01:05 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-14 23:20:18 +04:00
return queuedDownloads - > contains ( hash ) ;
}
2008-07-15 02:01:05 +04:00
bool bittorrent : : isUploadQueued ( QString hash ) const {
Q_ASSERT ( queueingEnabled ) ;
return queuedUploads - > contains ( hash ) ;
}
2007-08-20 10:29:18 +04:00
void bittorrent : : 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 ) ;
2007-07-30 20:57:28 +04:00
if ( h . is_valid ( ) )
h . set_upload_limit ( val ) ;
2007-07-14 17:38:29 +04:00
saveTorrentSpeedLimits ( hash ) ;
}
2008-07-15 22:34:28 +04:00
int bittorrent : : getMaximumActiveDownloads ( ) const {
return maxActiveDownloads ;
}
int bittorrent : : getMaximumActiveTorrents ( ) const {
return maxActiveTorrents ;
}
2007-08-26 20:25:22 +04:00
void bittorrent : : handleDownloadFailure ( QString url , QString reason ) {
2007-07-21 00:18:18 +04:00
emit downloadFromUrlFailure ( url , reason ) ;
}
2007-09-08 21:07:29 +04:00
void bittorrent : : startTorrentsInPause ( bool b ) {
addInPause = b ;
}
2008-07-15 02:01:05 +04:00
void bittorrent : : setQueueingEnabled ( bool enable ) {
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
if ( enable ) {
// Load priorities
QList < QPair < int , QString > > tmp_list ;
QStringList noprio ;
2008-07-15 02:01:05 +04:00
QStringList unfinished = getUnfinishedTorrents ( ) ;
foreach ( QString hash , unfinished ) {
int prio = loadTorrentPriority ( hash ) ;
2008-07-14 23:20:18 +04:00
if ( prio ! = - 1 ) {
misc : : insertSort2 < QString > ( tmp_list , QPair < int , QString > ( prio , hash ) , Qt : : AscendingOrder ) ;
} else {
noprio < < hash ;
}
}
downloadQueue = new QStringList ( ) ;
QPair < int , QString > couple ;
foreach ( couple , tmp_list ) {
downloadQueue - > append ( couple . second ) ;
}
( * downloadQueue ) < < noprio ;
// save priorities
int i = 0 ;
foreach ( QString hash , * downloadQueue ) {
2008-07-15 02:01:05 +04:00
saveTorrentPriority ( hash , i ) ;
2008-07-14 23:20:18 +04:00
+ + i ;
}
queuedDownloads = new QStringList ( ) ;
updateDownloadQueue ( ) ;
2008-07-15 02:01:05 +04:00
QList < QPair < int , QString > > tmp_list2 ;
QStringList noprio2 ;
QStringList finished = getFinishedTorrents ( ) ;
foreach ( QString hash , finished ) {
int prio = loadTorrentPriority ( hash ) ;
if ( prio ! = - 1 ) {
misc : : insertSort2 < QString > ( tmp_list2 , QPair < int , QString > ( prio , hash ) , Qt : : AscendingOrder ) ;
} else {
noprio2 < < hash ;
}
}
uploadQueue = new QStringList ( ) ;
QPair < int , QString > couple2 ;
foreach ( couple2 , tmp_list2 ) {
uploadQueue - > append ( couple2 . second ) ;
}
2008-08-19 04:28:44 +04:00
( * uploadQueue ) < < noprio2 ;
2008-07-15 02:01:05 +04:00
// save priorities
int j = 0 ;
foreach ( QString hash , * uploadQueue ) {
saveTorrentPriority ( hash , j ) ;
+ + j ;
}
queuedUploads = new QStringList ( ) ;
updateUploadQueue ( ) ;
2008-07-14 23:20:18 +04:00
} else {
2008-07-17 02:06:37 +04:00
// Unqueue torrents
foreach ( QString hash , * queuedDownloads ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ) {
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
}
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ) {
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
}
}
foreach ( QString hash , * queuedUploads ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ) {
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
}
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ) {
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
}
}
2008-07-14 23:20:18 +04:00
delete downloadQueue ;
downloadQueue = 0 ;
delete queuedDownloads ;
queuedDownloads = 0 ;
2008-07-15 02:01:05 +04:00
delete uploadQueue ;
uploadQueue = 0 ;
delete queuedUploads ;
queuedUploads = 0 ;
2008-07-14 23:20:18 +04:00
}
}
}
int bittorrent : : getDlTorrentPriority ( QString hash ) const {
Q_ASSERT ( downloadQueue ! = 0 ) ;
return downloadQueue - > indexOf ( hash ) ;
}
2008-07-15 02:01:05 +04:00
int bittorrent : : getUpTorrentPriority ( QString hash ) const {
Q_ASSERT ( uploadQueue ! = 0 ) ;
return uploadQueue - > indexOf ( hash ) ;
}
void bittorrent : : updateUploadQueue ( ) {
Q_ASSERT ( queueingEnabled ) ;
2008-07-16 00:19:41 +04:00
bool change = false ;
2008-07-15 02:01:05 +04:00
int maxActiveUploads = maxActiveTorrents - currentActiveDownloads ;
int currentActiveUploads = 0 ;
// Check if it is necessary to queue uploads
foreach ( QString hash , * uploadQueue ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_paused ( ) ) {
if ( currentActiveUploads < maxActiveUploads ) {
+ + currentActiveUploads ;
} else {
// Queue it
h . pause ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-15 02:01:05 +04:00
if ( ! queuedUploads - > contains ( hash ) ) {
queuedUploads - > append ( hash ) ;
// Create .queued file
if ( ! QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ) {
QFile queued_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
queued_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
queued_file . close ( ) ;
}
}
}
} else {
if ( currentActiveUploads < maxActiveUploads & & isUploadQueued ( hash ) ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-15 02:01:05 +04:00
queuedUploads - > removeAll ( hash ) ;
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
+ + currentActiveUploads ;
}
}
}
if ( currentActiveUploads < maxActiveUploads ) {
// Could not fill download slots, unqueue torrents
foreach ( QString hash , * uploadQueue ) {
if ( uploadQueue - > size ( ) ! = 0 & & currentActiveUploads < maxActiveUploads ) {
2008-07-18 01:12:10 +04:00
if ( queuedUploads - > contains ( hash ) ) {
2008-07-15 02:01:05 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-15 02:01:05 +04:00
queuedUploads - > removeAll ( hash ) ;
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
+ + currentActiveUploads ;
}
} else {
break ;
}
}
}
2008-08-08 17:17:26 +04:00
if ( change ) {
emit updateFinishedTorrentNumber ( ) ;
emit forceFinishedListUpdate ( ) ;
}
2008-07-15 02:01:05 +04:00
}
2008-07-14 23:20:18 +04:00
void bittorrent : : updateDownloadQueue ( ) {
2008-07-15 02:01:05 +04:00
Q_ASSERT ( queueingEnabled ) ;
2008-07-16 00:19:41 +04:00
bool change = false ;
2008-07-15 02:01:05 +04:00
currentActiveDownloads = 0 ;
2008-07-14 23:20:18 +04:00
// Check if it is necessary to queue torrents
foreach ( QString hash , * downloadQueue ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_paused ( ) ) {
2008-07-15 02:01:05 +04:00
if ( currentActiveDownloads < maxActiveDownloads ) {
+ + currentActiveDownloads ;
2008-07-14 23:20:18 +04:00
} else {
// Queue it
h . pause ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-14 23:20:18 +04:00
if ( ! queuedDownloads - > contains ( hash ) ) {
queuedDownloads - > append ( hash ) ;
// Create .queued file
if ( ! QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ) {
QFile queued_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
queued_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
queued_file . close ( ) ;
}
}
}
2008-07-15 00:08:24 +04:00
} else {
2008-07-15 02:01:05 +04:00
if ( currentActiveDownloads < maxActiveDownloads & & isDownloadQueued ( hash ) ) {
2008-07-15 00:08:24 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-15 00:08:24 +04:00
queuedDownloads - > removeAll ( hash ) ;
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
2008-07-15 02:01:05 +04:00
+ + currentActiveDownloads ;
2008-07-15 00:08:24 +04:00
}
2008-07-14 23:20:18 +04:00
}
}
2008-07-15 02:01:05 +04:00
if ( currentActiveDownloads < maxActiveDownloads ) {
2008-07-14 23:20:18 +04:00
// Could not fill download slots, unqueue torrents
foreach ( QString hash , * downloadQueue ) {
2008-07-15 02:01:05 +04:00
if ( downloadQueue - > size ( ) ! = 0 & & currentActiveDownloads < maxActiveDownloads ) {
2008-07-18 01:12:10 +04:00
if ( queuedDownloads - > contains ( hash ) ) {
2008-07-14 23:20:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
h . resume ( ) ;
2008-07-16 00:19:41 +04:00
change = true ;
2008-07-14 23:20:18 +04:00
queuedDownloads - > removeAll ( hash ) ;
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
2008-07-15 02:01:05 +04:00
+ + currentActiveDownloads ;
2008-07-14 23:20:18 +04:00
}
} else {
break ;
}
}
}
2008-08-08 17:17:26 +04:00
if ( change ) {
2008-07-16 00:19:41 +04:00
emit updateUnfinishedTorrentNumber ( ) ;
2008-08-08 17:17:26 +04:00
emit forceUnfinishedListUpdate ( ) ;
}
2008-07-14 23:20:18 +04:00
}
2007-11-25 00:55:19 +03:00
// Calculate the ETA using GASA
// GASA: global Average Speed Algorithm
qlonglong bittorrent : : getETA ( QString hash ) const {
2008-07-27 19:41:46 +04:00
Q_ASSERT ( calculateETA ) ;
2007-11-25 00:55:19 +03:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_valid ( ) ) return - 1 ;
switch ( h . state ( ) ) {
case torrent_status : : downloading :
case torrent_status : : connecting_to_tracker : {
if ( ! TorrentsStartTime . contains ( hash ) ) return - 1 ;
int timeElapsed = TorrentsStartTime . value ( hash ) . secsTo ( QDateTime : : currentDateTime ( ) ) ;
double avg_speed ;
if ( timeElapsed ) {
size_type data_origin = TorrentsStartData . value ( hash , 0 ) ;
avg_speed = ( double ) ( h . total_payload_download ( ) - data_origin ) / ( double ) timeElapsed ;
2007-10-10 23:57:24 +04:00
} else {
2007-11-25 00:55:19 +03:00
return - 1 ;
}
if ( avg_speed ) {
return ( qlonglong ) floor ( ( double ) ( h . actual_size ( ) - h . total_wanted_done ( ) ) / avg_speed ) ;
} else {
return - 1 ;
2007-06-29 19:23:15 +04:00
}
2007-11-25 00:55:19 +03:00
2007-06-29 19:23:15 +04:00
}
2007-11-25 00:55:19 +03:00
default :
return - 1 ;
2007-06-29 19:23:15 +04:00
}
2007-11-25 00:55:19 +03:00
2007-06-29 19:23:15 +04:00
}
2007-03-05 16:55:23 +03:00
// Return the torrent handle, given its hash
2007-08-20 10:29:18 +04:00
QTorrentHandle bittorrent : : getTorrentHandle ( QString hash ) const {
return QTorrentHandle ( s - > find_torrent ( misc : : fromString < sha1_hash > ( ( hash . toStdString ( ) ) ) ) ) ;
2007-03-05 16:55:23 +03:00
}
2007-03-08 01:36:01 +03:00
// Return true if the torrent corresponding to the
// hash is paused
2007-07-22 13:47:27 +04:00
bool bittorrent : : isPaused ( QString hash ) const {
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_valid ( ) ) {
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
2007-03-08 01:36:01 +03:00
return true ;
}
return h . is_paused ( ) ;
}
2008-05-18 13:26:02 +04:00
unsigned int bittorrent : : getFinishedPausedTorrentsNb ( ) const {
unsigned int nbPaused = 0 ;
foreach ( QString hash , finishedTorrents ) {
if ( isPaused ( hash ) ) {
+ + nbPaused ;
}
}
return nbPaused ;
}
unsigned int bittorrent : : getUnfinishedPausedTorrentsNb ( ) const {
unsigned int nbPaused = 0 ;
foreach ( QString hash , unfinishedTorrents ) {
if ( isPaused ( hash ) ) {
+ + nbPaused ;
}
}
return nbPaused ;
}
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
2007-08-20 10:29:18 +04:00
void bittorrent : : deleteTorrent ( QString hash , bool permanent ) {
qDebug ( " Deleting torrent with hash: %s " , hash . toUtf8 ( ) . data ( ) ) ;
QTorrentHandle h = getTorrentHandle ( hash ) ;
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 ;
}
2007-08-20 10:29:18 +04:00
QString savePath = h . save_path ( ) ;
QString fileName = h . name ( ) ;
2007-10-19 20:00:42 +04:00
arborescence * files_arb = 0 ;
if ( permanent ) {
files_arb = new arborescence ( h . get_torrent_info ( ) ) ;
2007-10-13 12:54:46 +04:00
}
2007-10-19 20:00:42 +04:00
// Remove it from session
s - > remove_torrent ( h . get_torrent_handle ( ) ) ;
2007-03-05 16:55:23 +03:00
// Remove it from torrent backup directory
2007-03-05 20:35:38 +03:00
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
2007-07-31 12:13:38 +04:00
QStringList filters ;
filters < < hash + " .* " ;
QStringList files = torrentBackup . entryList ( filters , QDir : : Files , QDir : : Unsorted ) ;
QString file ;
2007-08-20 10:29:18 +04:00
foreach ( file , files ) {
2007-07-31 12:13:38 +04:00
torrentBackup . remove ( file ) ;
}
2007-11-25 00:55:19 +03:00
// Remove it from TorrentsStartTime hash table
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartTime . remove ( hash ) ;
TorrentsStartData . remove ( hash ) ;
}
2007-07-27 17:58:12 +04:00
// Remove tracker errors
2007-07-30 20:57:28 +04:00
trackersErrors . remove ( hash ) ;
2007-07-18 11:44:52 +04:00
// Remove it from ratio table
2007-07-30 20:57:28 +04:00
ratioData . remove ( hash ) ;
2007-08-29 18:54:03 +04:00
int index = finishedTorrents . indexOf ( hash ) ;
2007-08-20 10:29:18 +04:00
if ( index ! = - 1 ) {
2007-08-19 18:20:54 +04:00
finishedTorrents . removeAt ( index ) ;
} else {
index = unfinishedTorrents . indexOf ( hash ) ;
2007-08-20 10:29:18 +04:00
if ( index ! = - 1 ) {
2007-08-19 18:20:54 +04:00
unfinishedTorrents . removeAt ( index ) ;
} else {
std : : cerr < < " Error: Torrent " < < hash . toStdString ( ) < < " is neither in finished or unfinished list \n " ;
}
}
2008-07-15 02:01:05 +04:00
// Remove it from downloadQueue or UploadQueue
if ( queueingEnabled ) {
if ( downloadQueue - > contains ( hash ) ) {
downloadQueue - > removeAll ( hash ) ;
queuedDownloads - > removeAll ( hash ) ;
updateDownloadQueue ( ) ;
}
if ( uploadQueue - > contains ( hash ) ) {
uploadQueue - > removeAll ( hash ) ;
queuedUploads - > removeAll ( hash ) ;
updateUploadQueue ( ) ;
}
2008-07-14 23:20:18 +04:00
}
2008-07-15 02:01:05 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
2007-10-19 20:00:42 +04:00
if ( permanent & & files_arb ! = 0 ) {
// Remove from Hard drive
qDebug ( " Removing this on hard drive: %s " , qPrintable ( savePath + QDir : : separator ( ) + fileName ) ) ;
// Deleting in a thread to avoid GUI freeze
deleter - > deleteTorrent ( savePath , files_arb ) ;
}
2008-09-07 15:31:29 +04:00
if ( permanent )
addConsoleMessage ( tr ( " '%1' was removed permanently. " , " 'xxx.avi' was removed permanently. " ) . arg ( fileName ) ) ;
else
addConsoleMessage ( tr ( " '%1' was removed. " , " 'xxx.avi' was removed. " ) . arg ( fileName ) ) ;
2008-05-16 11:10:50 +04:00
emit deletedTorrent ( hash ) ;
2007-03-05 16:55:23 +03:00
}
2007-08-19 18:20:54 +04:00
// Return a list of hashes for the finished torrents
QStringList bittorrent : : getFinishedTorrents ( ) const {
return finishedTorrents ;
}
QStringList bittorrent : : getUnfinishedTorrents ( ) const {
return unfinishedTorrents ;
}
bool bittorrent : : isFinished ( QString hash ) const {
return finishedTorrents . contains ( hash ) ;
}
// Remove the given hash from the list of finished torrents
void bittorrent : : setUnfinishedTorrent ( QString hash ) {
2007-08-26 23:17:50 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .finished " ) ) {
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .finished " ) ;
}
2007-08-19 18:20:54 +04:00
int index = finishedTorrents . indexOf ( hash ) ;
2007-08-20 10:29:18 +04:00
if ( index ! = - 1 ) {
2007-08-19 18:20:54 +04:00
finishedTorrents . removeAt ( index ) ;
}
2007-08-20 10:29:18 +04:00
if ( ! unfinishedTorrents . contains ( hash ) ) {
2007-08-19 18:20:54 +04:00
unfinishedTorrents < < hash ;
2007-11-25 00:55:19 +03:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartData [ hash ] = h . total_payload_download ( ) ;
TorrentsStartTime [ hash ] = QDateTime : : currentDateTime ( ) ;
}
2007-08-19 18:20:54 +04:00
}
2008-07-15 02:01:05 +04:00
if ( queueingEnabled ) {
2008-07-15 02:15:25 +04:00
// Remove it from uploadQueue
if ( uploadQueue - > contains ( hash ) ) {
uploadQueue - > removeAll ( hash ) ;
queuedDownloads - > removeAll ( hash ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
updateUploadQueue ( ) ;
}
// Add it to downloadQueue
2008-07-14 23:20:18 +04:00
if ( ! downloadQueue - > contains ( hash ) ) {
downloadQueue - > append ( hash ) ;
2008-07-15 02:01:05 +04:00
saveTorrentPriority ( hash , downloadQueue - > size ( ) - 1 ) ;
2008-07-14 23:20:18 +04:00
updateDownloadQueue ( ) ;
}
}
2007-08-19 18:20:54 +04:00
}
// Add the given hash to the list of finished torrents
2007-08-20 10:29:18 +04:00
void bittorrent : : setFinishedTorrent ( QString hash ) {
2007-08-26 23:17:50 +04:00
if ( ! QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .finished " ) ) {
QFile finished_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .finished " ) ;
finished_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
finished_file . close ( ) ;
}
2007-08-20 10:29:18 +04:00
if ( ! finishedTorrents . contains ( hash ) ) {
2007-08-19 18:20:54 +04:00
finishedTorrents < < hash ;
}
int index = unfinishedTorrents . indexOf ( hash ) ;
2007-08-20 10:29:18 +04:00
if ( index ! = - 1 ) {
2007-08-19 18:20:54 +04:00
unfinishedTorrents . removeAt ( index ) ;
}
2007-11-25 00:55:19 +03:00
// Remove it from TorrentsStartTime hash table
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartTime . remove ( hash ) ;
TorrentsStartData . remove ( hash ) ;
}
2008-07-15 22:10:10 +04:00
// Remove it from
2008-07-15 02:01:05 +04:00
if ( queueingEnabled ) {
2008-07-14 23:20:18 +04:00
downloadQueue - > removeAll ( hash ) ;
queuedDownloads - > removeAll ( hash ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .prio " ) ;
2008-07-15 02:01:05 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
2008-07-14 23:20:18 +04:00
updateDownloadQueue ( ) ;
2008-07-15 22:10:10 +04:00
if ( ! uploadQueue - > contains ( hash ) ) {
uploadQueue - > append ( hash ) ;
updateUploadQueue ( ) ;
}
2008-07-14 23:20:18 +04:00
}
2007-11-21 23:33:30 +03:00
// Save fast resume data
saveFastResumeAndRatioData ( hash ) ;
2007-08-19 18:20:54 +04:00
}
2007-03-05 16:55:23 +03:00
// Pause a running torrent
2007-08-20 10:29:18 +04:00
bool bittorrent : : pauseTorrent ( QString hash ) {
2007-07-29 18:14:57 +04:00
bool change = false ;
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( h . is_valid ( ) & & ! h . is_paused ( ) ) {
2007-03-05 16:55:23 +03:00
h . pause ( ) ;
2007-07-29 18:14:57 +04:00
change = true ;
2007-11-23 00:50:22 +03:00
// Save fast resume data
saveFastResumeAndRatioData ( hash ) ;
2008-08-02 23:49:37 +04:00
if ( queueingEnabled ) {
updateDownloadQueue ( ) ;
updateUploadQueue ( ) ;
}
2007-07-29 05:46:31 +04:00
qDebug ( " Torrent paused successfully " ) ;
2008-05-16 11:10:50 +04:00
emit pausedTorrent ( hash ) ;
2007-07-29 05:46:31 +04:00
} else {
2007-08-20 10:29:18 +04:00
if ( ! h . is_valid ( ) ) {
qDebug ( " Could not pause torrent %s, reason: invalid " , hash . toUtf8 ( ) . data ( ) ) ;
2007-07-31 18:28:17 +04:00
} else {
2008-07-18 01:12:10 +04:00
if ( queueingEnabled & & ( isDownloadQueued ( hash ) | | isUploadQueued ( hash ) ) ) {
// Remove it from queued list if present
if ( queuedDownloads - > contains ( hash ) )
queuedDownloads - > removeAll ( hash ) ;
if ( queuedUploads - > contains ( hash ) )
queuedUploads - > removeAll ( hash ) ;
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) )
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .queued " ) ;
updateDownloadQueue ( ) ;
updateUploadQueue ( ) ;
change = true ;
} else {
qDebug ( " Could not pause torrent %s, reason: already paused " , hash . toUtf8 ( ) . data ( ) ) ;
}
2007-07-31 18:28:17 +04:00
}
2007-07-29 05:44:49 +04:00
}
2007-07-29 18:14:57 +04:00
// Create .paused file if necessary
2007-08-20 10:29:18 +04:00
if ( ! QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) ) {
2007-07-29 18:14:57 +04:00
QFile paused_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) ;
paused_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
paused_file . close ( ) ;
}
2007-11-25 00:55:19 +03:00
// Remove it from TorrentsStartTime hash table
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartTime . remove ( hash ) ;
TorrentsStartData . remove ( hash ) ;
}
2008-09-07 15:31:29 +04:00
if ( change ) {
addConsoleMessage ( tr ( " '%1' paused. " , " e.g: xxx.avi paused. " ) . arg ( h . name ( ) ) ) ;
}
2007-07-29 18:14:57 +04:00
return change ;
2007-03-05 16:55:23 +03:00
}
// Resume a torrent in paused state
2007-08-20 10:29:18 +04:00
bool bittorrent : : resumeTorrent ( QString hash ) {
2008-09-07 15:31:29 +04:00
bool change = false ;
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( h . is_valid ( ) & & h . is_paused ( ) ) {
2008-07-18 01:12:10 +04:00
if ( ! ( queueingEnabled & & ( isDownloadQueued ( hash ) | | isUploadQueued ( hash ) ) ) ) {
// Save Addition DateTime
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartData [ hash ] = h . total_payload_download ( ) ;
TorrentsStartTime [ hash ] = QDateTime : : currentDateTime ( ) ;
}
2008-07-18 01:12:10 +04:00
h . resume ( ) ;
2008-09-07 15:31:29 +04:00
change = true ;
2008-07-18 01:12:10 +04:00
emit resumedTorrent ( hash ) ;
}
2007-07-29 18:14:57 +04:00
}
// Delete .paused file
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) )
2007-03-08 01:36:01 +03:00
QFile : : remove ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) ;
2008-08-02 23:46:02 +04:00
if ( queueingEnabled ) {
updateDownloadQueue ( ) ;
updateUploadQueue ( ) ;
}
2008-09-07 15:31:29 +04:00
if ( change ) {
addConsoleMessage ( tr ( " '%1' resumed. " , " e.g: xxx.avi resumed. " ) . arg ( h . name ( ) ) ) ;
}
return change ;
2007-03-05 16:55:23 +03:00
}
2008-05-16 11:10:50 +04:00
void bittorrent : : pauseAllTorrents ( ) {
QStringList list = getUnfinishedTorrents ( ) + getFinishedTorrents ( ) ;
foreach ( QString hash , list )
pauseTorrent ( hash ) ;
}
void bittorrent : : resumeAllTorrents ( ) {
QStringList list = getUnfinishedTorrents ( ) + getFinishedTorrents ( ) ;
foreach ( QString hash , list )
resumeTorrent ( hash ) ;
}
2007-08-20 10:29:18 +04:00
void bittorrent : : loadWebSeeds ( QString hash ) {
QFile urlseeds_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .urlseeds " ) ;
2007-07-27 13:53:55 +04:00
if ( ! urlseeds_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) return ;
QByteArray urlseeds_lines = urlseeds_file . readAll ( ) ;
urlseeds_file . close ( ) ;
QList < QByteArray > url_seeds = urlseeds_lines . split ( ' \n ' ) ;
QByteArray url_seed ;
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-08-18 09:55:09 +04:00
// First remove from the torrent the url seeds that were deleted
// in a previous session
QStringList seeds_to_delete ;
2007-08-20 10:29:18 +04:00
QStringList existing_seeds = h . url_seeds ( ) ;
2007-08-18 09:55:09 +04:00
QString existing_seed ;
2007-08-20 10:29:18 +04:00
foreach ( existing_seed , existing_seeds ) {
if ( ! url_seeds . contains ( existing_seed . toUtf8 ( ) ) ) {
2007-08-18 09:55:09 +04:00
seeds_to_delete < < existing_seed ;
}
}
2007-08-20 10:29:18 +04:00
foreach ( existing_seed , seeds_to_delete ) {
h . remove_url_seed ( existing_seed ) ;
2007-08-18 09:55:09 +04:00
}
// Add the ones that were added in a previous session
2007-08-20 10:29:18 +04:00
foreach ( url_seed , url_seeds ) {
if ( ! url_seed . isEmpty ( ) ) {
2007-08-18 09:55:09 +04:00
// XXX: Should we check if it is already in the list before adding it
// or is libtorrent clever enough to know
2007-08-20 10:29:18 +04:00
h . add_url_seed ( url_seed ) ;
2007-08-18 09:55:09 +04:00
}
2007-07-27 13:53:55 +04:00
}
}
2007-03-05 16:55:23 +03:00
// Add a torrent to the bittorrent session
2008-09-13 22:53:58 +04:00
void bittorrent : : addTorrent ( QString path , bool fromScanDir , QString from_url , bool ) {
2007-08-20 10:29:18 +04:00
QTorrentHandle h ;
2007-03-05 16:55:23 +03:00
entry resume_data ;
bool fastResume = false ;
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
QString file , dest_file , scan_dir ;
// Checking if BT_backup Dir exists
// create it if it is not
2007-08-20 10:29:18 +04:00
if ( ! torrentBackup . exists ( ) ) {
if ( ! torrentBackup . mkpath ( torrentBackup . path ( ) ) ) {
std : : cerr < < " Couldn't create the directory: ' " < < torrentBackup . path ( ) . toUtf8 ( ) . data ( ) < < " ' \n " ;
2007-03-05 20:35:38 +03:00
exit ( 1 ) ;
2007-03-05 16:55:23 +03:00
}
}
// Processing torrents
2007-09-08 21:07:29 +04:00
file = path . trimmed ( ) . replace ( " file:// " , " " , Qt : : CaseInsensitive ) ;
2007-08-20 10:29:18 +04:00
if ( file . isEmpty ( ) ) {
2007-03-05 16:55:23 +03:00
return ;
}
2007-09-09 11:44:22 +04:00
Q_ASSERT ( ! file . startsWith ( " http:// " , Qt : : CaseInsensitive ) & & ! file . startsWith ( " https:// " , Qt : : CaseInsensitive ) & & ! file . startsWith ( " ftp:// " , Qt : : CaseInsensitive ) ) ;
2007-08-20 10:29:18 +04:00
qDebug ( " Adding %s to download list " , file . toUtf8 ( ) . data ( ) ) ;
std : : ifstream in ( file . toUtf8 ( ) . data ( ) , std : : ios_base : : binary ) ;
2007-03-05 16:55:23 +03:00
in . unsetf ( std : : ios_base : : skipws ) ;
try {
// Decode torrent file
entry e = bdecode ( std : : istream_iterator < char > ( in ) , std : : istream_iterator < char > ( ) ) ;
// Getting torrent file informations
2007-09-04 08:18:51 +04:00
boost : : intrusive_ptr < torrent_info > t ( new torrent_info ( e ) ) ;
qDebug ( " -> Hash: %s " , misc : : toString ( t - > info_hash ( ) ) . c_str ( ) ) ;
qDebug ( " -> Name: %s " , t - > name ( ) . c_str ( ) ) ;
QString hash = misc : : toQString ( t - > info_hash ( ) ) ;
2007-08-26 22:50:51 +04:00
if ( file . startsWith ( torrentBackup . path ( ) ) ) {
QFileInfo fi ( file ) ;
QString old_hash = fi . baseName ( ) ;
if ( old_hash ! = hash ) {
qDebug ( " * ERROR: Strange, hash changed from %s to %s " , old_hash . toUtf8 ( ) . data ( ) , hash . toUtf8 ( ) . data ( ) ) ;
}
}
2007-09-04 08:18:51 +04:00
if ( s - > find_torrent ( t - > info_hash ( ) ) . is_valid ( ) ) {
2007-08-26 22:41:45 +04:00
qDebug ( " /! \\ Torrent is already in download list " ) ;
2007-03-05 16:55:23 +03:00
// Update info Bar
2007-08-20 10:29:18 +04:00
if ( ! fromScanDir ) {
if ( ! from_url . isNull ( ) ) {
2007-07-22 13:47:27 +04:00
// If download from url, remove temp file
2008-09-07 15:31:29 +04:00
QFile : : remove ( file ) ;
addConsoleMessage ( tr ( " '%1' is already in download list. " , " e.g: 'xxx.avi' is already in download list. " ) . arg ( from_url ) ) ;
//emit duplicateTorrent(from_url);
2007-03-05 16:55:23 +03:00
} else {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " '%1' is already in download list. " , " e.g: 'xxx.avi' is already in download list. " ) . arg ( file ) ) ;
//emit duplicateTorrent(file);
2007-03-05 16:55:23 +03:00
}
} else {
// Delete torrent from scan dir
QFile : : remove ( file ) ;
}
return ;
}
//Getting fast resume data if existing
2007-08-20 10:29:18 +04:00
if ( torrentBackup . exists ( hash + " .fastresume " ) ) {
2007-03-05 16:55:23 +03:00
try {
std : : stringstream strStream ;
strStream < < hash . toStdString ( ) < < " .fastresume " ;
2007-08-20 10:29:18 +04:00
boost : : filesystem : : ifstream resume_file ( fs : : path ( torrentBackup . path ( ) . toUtf8 ( ) . data ( ) ) / strStream . str ( ) , std : : ios_base : : binary ) ;
2007-03-05 16:55:23 +03:00
resume_file . unsetf ( std : : ios_base : : skipws ) ;
resume_data = bdecode ( std : : istream_iterator < char > ( resume_file ) , std : : istream_iterator < char > ( ) ) ;
fastResume = true ;
} catch ( invalid_encoding & ) { }
catch ( fs : : filesystem_error & ) { }
}
QString savePath = getSavePath ( hash ) ;
// Adding files to bittorrent session
2007-10-10 21:34:52 +04:00
if ( preAllocateAll ) {
h = s - > add_torrent ( t , fs : : path ( savePath . toUtf8 ( ) . data ( ) ) , resume_data , storage_mode_allocate , true ) ;
2007-08-26 22:41:45 +04:00
qDebug ( " -> Full allocation mode " ) ;
2007-03-05 16:55:23 +03:00
} else {
2007-10-10 21:34:52 +04:00
h = s - > add_torrent ( t , fs : : path ( savePath . toUtf8 ( ) . data ( ) ) , resume_data , storage_mode_sparse , true ) ;
qDebug ( " -> Sparse allocation mode " ) ;
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
if ( ! h . is_valid ( ) ) {
2007-03-05 16:55:23 +03:00
// No need to keep on, it failed.
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
2007-07-22 13:47:27 +04:00
// If download from url, remove temp file
if ( ! from_url . isNull ( ) ) QFile : : remove ( file ) ;
2007-03-05 16:55:23 +03:00
return ;
}
2007-09-09 11:44:22 +04:00
// Connections limit per torrent
h . set_max_connections ( maxConnecsPerTorrent ) ;
// Uploads limit per torrent
h . set_max_uploads ( maxUploadsPerTorrent ) ;
2007-03-05 16:55:23 +03:00
// Load filtered files
2007-07-04 14:06:22 +04:00
loadFilesPriorities ( h ) ;
2007-07-27 13:53:55 +04:00
// Load custom url seeds
loadWebSeeds ( hash ) ;
2007-07-14 17:38:29 +04:00
// Load speed limit from hard drive
loadTorrentSpeedLimits ( hash ) ;
2007-07-18 11:44:52 +04:00
// Load ratio data
loadDownloadUploadForTorrent ( hash ) ;
2007-03-25 20:18:57 +04:00
// Load trackers
2007-03-25 22:39:27 +04:00
bool loaded_trackers = loadTrackerFile ( hash ) ;
// Doing this to order trackers well
2007-08-20 10:29:18 +04:00
if ( ! loaded_trackers ) {
2007-03-25 22:39:27 +04:00
saveTrackerFile ( hash ) ;
loadTrackerFile ( hash ) ;
}
2007-03-05 16:55:23 +03:00
QString newFile = torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .torrent " ;
2007-08-20 10:29:18 +04:00
if ( file ! = newFile ) {
2007-03-05 16:55:23 +03:00
// Delete file from torrentBackup directory in case it exists because
// QFile::copy() do not overwrite
QFile : : remove ( newFile ) ;
// Copy it to torrentBackup directory
QFile : : copy ( file , newFile ) ;
}
// Incremental download
2007-08-20 10:29:18 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .incremental " ) ) {
2007-09-04 08:18:51 +04:00
qDebug ( " Incremental download enabled for %s " , t - > name ( ) . c_str ( ) ) ;
2007-08-17 06:22:04 +04:00
h . set_sequenced_download_threshold ( 1 ) ;
2007-03-05 16:55:23 +03:00
}
2008-09-13 22:53:58 +04:00
if ( ! addInPause & & ! QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) ) {
// Start torrent because it was added in paused state
h . resume ( ) ;
}
2007-08-20 10:29:18 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .finished " ) ) {
2007-08-19 18:20:54 +04:00
finishedTorrents < < hash ;
2008-07-15 02:01:05 +04:00
if ( queueingEnabled ) {
uploadQueue - > append ( hash ) ;
saveTorrentPriority ( hash , uploadQueue - > size ( ) - 1 ) ;
updateUploadQueue ( ) ;
}
2007-08-19 18:20:54 +04:00
} else {
unfinishedTorrents < < hash ;
2008-07-14 23:20:18 +04:00
// Add it to downloadQueue
2008-07-15 02:01:05 +04:00
if ( queueingEnabled ) {
2008-07-14 23:20:18 +04:00
downloadQueue - > append ( hash ) ;
2008-07-15 02:01:05 +04:00
saveTorrentPriority ( hash , downloadQueue - > size ( ) - 1 ) ;
2008-07-14 23:20:18 +04:00
updateDownloadQueue ( ) ;
}
2007-08-19 18:20:54 +04:00
}
2007-07-22 13:47:27 +04:00
// If download from url, remove temp file
if ( ! from_url . isNull ( ) ) QFile : : remove ( file ) ;
2007-03-05 16:55:23 +03:00
// Delete from scan dir to avoid trying to download it again
2007-08-20 10:29:18 +04:00
if ( fromScanDir ) {
2007-03-05 16:55:23 +03:00
QFile : : remove ( file ) ;
}
// Send torrent addition signal
2007-08-20 10:29:18 +04:00
if ( ! from_url . isNull ( ) ) {
2008-09-07 15:31:29 +04:00
emit addedTorrent ( h ) ;
if ( fastResume )
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 ) ) ;
2007-03-05 16:55:23 +03:00
} else {
2008-09-07 15:31:29 +04:00
emit addedTorrent ( h ) ;
if ( fastResume )
addConsoleMessage ( tr ( " '%1' resumed. (fast resume) " , " '/home/y/xxx.torrent' was resumed. (fast resume) " ) . arg ( file ) ) ;
else
addConsoleMessage ( tr ( " '%1' added to download list. " , " '/home/y/xxx.torrent' was added to download list. " ) . arg ( file ) ) ;
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
} catch ( invalid_encoding & e ) { // Raised by bdecode()
2007-03-05 16:55:23 +03:00
std : : cerr < < " Could not decode file, reason: " < < e . what ( ) < < ' \n ' ;
// Display warning to tell user we can't decode the torrent file
2007-08-20 10:29:18 +04:00
if ( ! from_url . isNull ( ) ) {
2008-09-07 15:31:29 +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 " ) ) ;
//emit invalidTorrent(from_url);
2007-12-11 23:00:43 +03:00
QFile : : remove ( file ) ;
2007-03-05 16:55:23 +03:00
} else {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Unable to decode torrent file: '%1' " , " e.g: Unable to decode torrent file: '/home/y/xxx.torrent' " ) . arg ( file ) , QString : : fromUtf8 ( " red " ) ) ;
//emit invalidTorrent(file);
2007-03-05 16:55:23 +03:00
}
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " This file is either corrupted or this isn't a torrent. " ) , QString : : fromUtf8 ( " red " ) ) ;
2007-08-20 10:29:18 +04:00
if ( fromScanDir ) {
2007-03-05 16:55:23 +03:00
// Remove .corrupt file in case it already exists
QFile : : remove ( file + " .corrupt " ) ;
//Rename file extension so that it won't display error message more than once
QFile : : rename ( file , file + " .corrupt " ) ;
}
}
2007-08-20 10:29:18 +04:00
catch ( invalid_torrent_file & ) { // Raised by torrent_info constructor
2007-03-05 16:55:23 +03:00
// Display warning to tell user we can't decode the torrent file
2007-08-20 10:29:18 +04:00
if ( ! from_url . isNull ( ) ) {
2008-09-07 15:31:29 +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 " ) ) ;
//emit invalidTorrent(from_url);
2007-12-11 23:00:43 +03:00
qDebug ( " File path is: %s " , file . toUtf8 ( ) . data ( ) ) ;
QFile : : remove ( file ) ;
2007-03-05 16:55:23 +03:00
} else {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Unable to decode torrent file: '%1' " , " e.g: Unable to decode torrent file: '/home/y/xxx.torrent' " ) . arg ( file ) , QString : : fromUtf8 ( " red " ) ) ;
//emit invalidTorrent(file);
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
if ( fromScanDir ) {
2007-03-05 16:55:23 +03:00
// Remove .corrupt file in case it already exists
QFile : : remove ( file + " .corrupt " ) ;
//Rename file extension so that it won't display error message more than once
QFile : : rename ( file , file + " .corrupt " ) ;
}
}
2008-01-04 23:43:28 +03:00
catch ( std : : exception & e ) {
std : : cerr < < " Could not decode file, reason: " < < e . what ( ) < < ' \n ' ;
// Display warning to tell user we can't decode the torrent file
if ( ! from_url . isNull ( ) ) {
2008-09-07 15:31:29 +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 " ) ) ;
//emit invalidTorrent(from_url);
2008-01-04 23:43:28 +03:00
QFile : : remove ( file ) ;
} else {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Unable to decode torrent file: '%1' " , " e.g: Unable to decode torrent file: '/home/y/xxx.torrent' " ) . arg ( file ) , QString : : fromUtf8 ( " red " ) ) ;
//emit invalidTorrent(file);
2008-01-04 23:43:28 +03:00
}
if ( fromScanDir ) {
// Remove .corrupt file in case it already exists
QFile : : remove ( file + " .corrupt " ) ;
//Rename file extension so that it won't display error message more than once
QFile : : rename ( file , file + " .corrupt " ) ;
}
}
2007-03-05 16:55:23 +03:00
}
2007-04-12 23:51:39 +04:00
// Check in .priorities file if the user filtered files
2007-03-05 16:55:23 +03:00
// in this torrent.
2007-08-20 10:29:18 +04:00
bool bittorrent : : has_filtered_files ( QString hash ) const {
QFile pieces_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .priorities " ) ;
2007-03-05 16:55:23 +03:00
// Read saved file
2007-08-20 10:29:18 +04:00
if ( ! pieces_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
2007-03-05 16:55:23 +03:00
return false ;
}
2007-04-12 23:51:39 +04:00
QByteArray pieces_text = pieces_file . readAll ( ) ;
2007-03-05 16:55:23 +03:00
pieces_file . close ( ) ;
2007-04-12 23:51:39 +04:00
QList < QByteArray > pieces_priorities_list = pieces_text . split ( ' \n ' ) ;
unsigned int listSize = pieces_priorities_list . size ( ) ;
2007-08-20 10:29:18 +04:00
for ( unsigned int i = 0 ; i < listSize - 1 ; + + i ) {
2007-04-12 23:51:39 +04:00
int priority = pieces_priorities_list . at ( i ) . toInt ( ) ;
2007-08-20 10:29:18 +04:00
if ( priority < 0 | | priority > 7 ) {
2007-04-12 23:51:39 +04:00
priority = 1 ;
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
if ( ! priority ) {
2007-03-05 16:55:23 +03:00
return true ;
}
}
return false ;
}
2007-08-20 10:29:18 +04:00
// Set the maximum number of opened connections
void bittorrent : : setMaxConnections ( int maxConnec ) {
s - > set_max_connections ( maxConnec ) ;
}
2007-09-09 11:44:22 +04:00
void bittorrent : : setMaxConnectionsPerTorrent ( int max ) {
maxConnecsPerTorrent = max ;
// Apply this to all session torrents
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
unsigned int nbHandles = handles . size ( ) ;
for ( unsigned int i = 0 ; i < nbHandles ; + + i ) {
QTorrentHandle h = handles [ i ] ;
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
h . set_max_connections ( max ) ;
}
}
void bittorrent : : setMaxUploadsPerTorrent ( int max ) {
maxUploadsPerTorrent = max ;
// Apply this to all session torrents
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
unsigned int nbHandles = handles . size ( ) ;
for ( unsigned int i = 0 ; i < nbHandles ; + + i ) {
QTorrentHandle h = handles [ i ] ;
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
h . set_max_uploads ( max ) ;
}
}
2007-03-05 16:55:23 +03:00
// Return DHT state
bool bittorrent : : isDHTEnabled ( ) const {
return DHTEnabled ;
}
2007-09-08 21:07:29 +04:00
void bittorrent : : enableUPnP ( bool b ) {
if ( b ) {
2007-11-23 18:20:26 +03:00
if ( ! UPnPEnabled ) {
qDebug ( " Enabling UPnP " ) ;
s - > start_upnp ( ) ;
UPnPEnabled = true ;
}
2007-09-08 21:07:29 +04:00
} else {
2007-11-23 18:20:26 +03:00
if ( UPnPEnabled ) {
qDebug ( " Disabling UPnP " ) ;
s - > stop_upnp ( ) ;
UPnPEnabled = false ;
}
2007-03-05 16:55:23 +03:00
}
}
2007-09-08 21:07:29 +04:00
void bittorrent : : enableNATPMP ( bool b ) {
if ( b ) {
2007-11-23 18:20:26 +03:00
if ( ! NATPMPEnabled ) {
qDebug ( " Enabling NAT-PMP " ) ;
s - > start_natpmp ( ) ;
NATPMPEnabled = true ;
}
2007-09-08 21:07:29 +04:00
} else {
2007-11-23 18:20:26 +03:00
if ( NATPMPEnabled ) {
qDebug ( " Disabling NAT-PMP " ) ;
s - > stop_natpmp ( ) ;
NATPMPEnabled = false ;
}
2007-09-08 21:07:29 +04:00
}
}
void bittorrent : : enableLSD ( bool b ) {
if ( b ) {
2007-11-23 18:20:26 +03:00
if ( ! LSDEnabled ) {
qDebug ( " Enabling LSD " ) ;
s - > start_lsd ( ) ;
LSDEnabled = true ;
}
2007-09-08 21:07:29 +04:00
} else {
2007-11-23 18:20:26 +03:00
if ( LSDEnabled ) {
qDebug ( " Disabling LSD " ) ;
s - > stop_lsd ( ) ;
LSDEnabled = false ;
}
2007-09-08 21:07:29 +04:00
}
}
// Enable DHT
2007-10-28 00:53:09 +04:00
bool bittorrent : : enableDHT ( bool b ) {
2007-09-08 21:07:29 +04:00
if ( b ) {
if ( ! DHTEnabled ) {
boost : : filesystem : : ifstream dht_state_file ( ( misc : : qBittorrentPath ( ) + QString : : fromUtf8 ( " dht_state " ) ) . toUtf8 ( ) . data ( ) , std : : ios_base : : binary ) ;
dht_state_file . unsetf ( std : : ios_base : : skipws ) ;
entry dht_state ;
try {
dht_state = bdecode ( std : : istream_iterator < char > ( dht_state_file ) , std : : istream_iterator < char > ( ) ) ;
} catch ( std : : exception & ) { }
2007-10-28 00:53:09 +04:00
try {
2008-05-16 11:10:50 +04:00
s - > start_dht ( dht_state ) ;
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 ) ) ;
s - > add_dht_router ( std : : make_pair ( std : : string ( " router.bitcomet.com " ) , 6881 ) ) ;
DHTEnabled = true ;
qDebug ( " DHT enabled " ) ;
2007-10-28 00:53:09 +04:00
} catch ( std : : exception e ) {
qDebug ( " Could not enable DHT, reason: %s " , e . what ( ) ) ;
return false ;
}
2007-09-08 21:07:29 +04:00
}
} else {
if ( DHTEnabled ) {
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
}
2007-08-20 10:29:18 +04:00
void bittorrent : : saveTorrentSpeedLimits ( QString hash ) {
qDebug ( " Saving speedLimits file for %s " , hash . toUtf8 ( ) . data ( ) ) ;
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-07-14 17:38:29 +04:00
int download_limit = h . download_limit ( ) ;
int upload_limit = h . upload_limit ( ) ;
QFile speeds_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .speedLimits " ) ;
2007-08-20 10:29:18 +04:00
if ( ! speeds_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ) {
qDebug ( " * Error: Couldn't open speed limits file for torrent: %s " , hash . toUtf8 ( ) . data ( ) ) ;
2007-07-14 17:38:29 +04:00
return ;
}
2007-08-20 10:29:18 +04:00
speeds_file . write ( misc : : toQByteArray ( download_limit ) + QByteArray ( " " ) + misc : : toQByteArray ( upload_limit ) ) ;
2007-07-14 17:38:29 +04:00
speeds_file . close ( ) ;
}
2007-08-20 10:29:18 +04:00
void bittorrent : : loadTorrentSpeedLimits ( QString hash ) {
2007-08-26 22:41:45 +04:00
// qDebug("Loading speedLimits file for %s", hash.toUtf8().data());
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-07-14 17:38:29 +04:00
QFile speeds_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .speedLimits " ) ;
2007-08-20 10:29:18 +04:00
if ( ! speeds_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
2007-07-14 17:38:29 +04:00
return ;
}
QByteArray speed_limits = speeds_file . readAll ( ) ;
speeds_file . close ( ) ;
QList < QByteArray > speeds = speed_limits . split ( ' ' ) ;
2007-08-20 10:29:18 +04:00
if ( speeds . size ( ) ! = 2 ) {
2007-07-14 17:38:29 +04:00
std : : cerr < < " Invalid .speedLimits file for " < < hash . toStdString ( ) < < ' \n ' ;
return ;
}
h . set_download_limit ( speeds . at ( 0 ) . toInt ( ) ) ;
h . set_upload_limit ( speeds . at ( 1 ) . toInt ( ) ) ;
}
2007-04-12 23:51:39 +04:00
// Read pieces priorities from .priorities file
2007-08-20 10:29:18 +04:00
// and ask QTorrentHandle to consider them
void bittorrent : : loadFilesPriorities ( QTorrentHandle & h ) {
2007-11-06 23:55:23 +03:00
qDebug ( " Applying pieces priorities " ) ;
2007-08-20 10:29:18 +04:00
if ( ! h . is_valid ( ) ) {
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
2007-03-05 16:55:23 +03:00
return ;
}
2007-08-20 10:29:18 +04:00
unsigned int nbFiles = h . num_files ( ) ;
QString hash = h . hash ( ) ;
QFile pieces_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .priorities " ) ;
2007-08-26 21:48:38 +04:00
if ( ! pieces_file . exists ( ) ) {
return ;
}
2007-03-05 16:55:23 +03:00
// Read saved file
2007-08-20 10:29:18 +04:00
if ( ! pieces_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
2007-08-26 22:41:45 +04:00
qDebug ( " * Error: Couldn't open priorities file: %s " , hash . toUtf8 ( ) . data ( ) ) ;
2007-03-05 16:55:23 +03:00
return ;
}
2007-04-12 23:51:39 +04:00
QByteArray pieces_priorities = pieces_file . readAll ( ) ;
2007-03-05 16:55:23 +03:00
pieces_file . close ( ) ;
2007-04-12 23:51:39 +04:00
QList < QByteArray > pieces_priorities_list = pieces_priorities . split ( ' \n ' ) ;
2007-08-20 10:29:18 +04:00
if ( ( unsigned int ) pieces_priorities_list . size ( ) ! = nbFiles + 1 ) {
2007-07-03 13:04:04 +04:00
std : : cerr < < " * Error: Corrupted priorities file \n " ;
2007-03-05 16:55:23 +03:00
return ;
}
2007-07-04 02:39:49 +04:00
std : : vector < int > v ;
2007-08-20 10:29:18 +04:00
for ( unsigned int i = 0 ; i < nbFiles ; + + i ) {
2007-04-12 23:51:39 +04:00
int priority = pieces_priorities_list . at ( i ) . toInt ( ) ;
2007-08-20 10:29:18 +04:00
if ( priority < 0 | | priority > 7 ) {
2007-04-12 23:51:39 +04:00
priority = 1 ;
2007-03-05 16:55:23 +03:00
}
2007-12-30 21:06:51 +03:00
qDebug ( " Setting piece piority to %d " , priority ) ;
2007-07-04 02:39:49 +04:00
v . push_back ( priority ) ;
2007-03-05 16:55:23 +03:00
}
2007-07-04 02:39:49 +04:00
h . prioritize_files ( v ) ;
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
void bittorrent : : loadDownloadUploadForTorrent ( QString hash ) {
2007-07-18 11:44:52 +04:00
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
// Checking if torrentBackup Dir exists
// create it if it is not
2007-08-20 10:29:18 +04:00
if ( ! torrentBackup . exists ( ) ) {
2007-07-18 11:44:52 +04:00
torrentBackup . mkpath ( torrentBackup . path ( ) ) ;
}
2007-08-26 22:41:45 +04:00
// qDebug("Loading ratio data for %s", hash.toUtf8().data());
2007-07-18 11:44:52 +04:00
QFile ratio_file ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .ratio " ) ;
2007-08-26 22:41:45 +04:00
if ( ! ratio_file . exists ( ) | | ! ratio_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
2007-07-18 11:44:52 +04:00
return ;
}
QByteArray data = ratio_file . readAll ( ) ;
QList < QByteArray > data_list = data . split ( ' ' ) ;
2007-08-20 10:29:18 +04:00
if ( data_list . size ( ) ! = 2 ) {
2007-07-18 11:44:52 +04:00
std : : cerr < < " Corrupted ratio file for torrent: " < < hash . toStdString ( ) < < ' \n ' ;
return ;
}
QPair < size_type , size_type > downUp ;
2007-08-09 09:03:06 +04:00
downUp . first = ( size_type ) data_list . at ( 0 ) . toLongLong ( ) ;
downUp . second = ( size_type ) data_list . at ( 1 ) . toLongLong ( ) ;
2007-09-21 11:45:28 +04:00
if ( downUp . first < 0 | | downUp . second < 0 ) {
qDebug ( " ** Overflow in ratio!!! fixing... " ) ;
downUp . first = 0 ;
downUp . second = 0 ;
}
2007-07-18 11:44:52 +04:00
ratioData [ hash ] = downUp ;
}
2008-09-13 22:53:58 +04:00
float bittorrent : : getUncheckedTorrentProgress ( QString hash ) const {
/*if(QFile::exists(misc::qBittorrentPath()+"BT_backup"+QDir::separator()+hash+".finished"))
return 1. ; */
QTorrentHandle h = getTorrentHandle ( hash ) ;
QPair < size_type , size_type > downUpInfo = ratioData . value ( hash , QPair < size_type , size_type > ( 0 , 0 ) ) ;
return ( float ) downUpInfo . first / ( float ) h . actual_size ( ) ;
}
2007-08-20 10:29:18 +04:00
float bittorrent : : getRealRatio ( QString hash ) const {
QPair < size_type , size_type > downUpInfo = ratioData . value ( hash , QPair < size_type , size_type > ( 0 , 0 ) ) ;
size_type download = downUpInfo . first ;
size_type upload = downUpInfo . second ;
QTorrentHandle h = getTorrentHandle ( hash ) ;
download + = h . total_payload_download ( ) ;
2007-08-29 10:33:27 +04:00
Q_ASSERT ( download > = 0 ) ;
2007-08-20 10:29:18 +04:00
upload + = h . total_payload_upload ( ) ;
2007-08-29 10:33:27 +04:00
Q_ASSERT ( upload > = 0 ) ;
2007-08-20 10:29:18 +04:00
if ( download = = 0 ) {
if ( upload = = 0 )
return 1. ;
return 10. ;
}
float ratio = ( double ) upload / ( double ) download ;
Q_ASSERT ( ratio > = 0. ) ;
if ( ratio > 10. )
ratio = 10. ;
return ratio ;
}
2007-07-18 11:44:52 +04:00
// To remember share ratio or a torrent, we must save current
// total_upload and total_upload and reload them on startup
2007-08-20 10:29:18 +04:00
void bittorrent : : saveDownloadUploadForTorrent ( QString hash ) {
qDebug ( " Saving ratio data for torrent %s " , hash . toUtf8 ( ) . data ( ) ) ;
QDir torrentBackup ( misc : : qBittorrentPath ( ) + QString : : fromUtf8 ( " BT_backup " ) ) ;
2007-07-18 11:44:52 +04:00
// Checking if torrentBackup Dir exists
// create it if it is not
2007-08-20 10:29:18 +04:00
if ( ! torrentBackup . exists ( ) ) {
2007-07-18 11:44:52 +04:00
torrentBackup . mkpath ( torrentBackup . path ( ) ) ;
}
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_valid ( ) ) {
2007-07-18 11:44:52 +04:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
return ;
}
2007-08-20 10:29:18 +04:00
QPair < size_type , size_type > ratioInfo = ratioData . value ( hash , QPair < size_type , size_type > ( 0 , 0 ) ) ;
size_type download = h . total_payload_download ( ) ;
2007-07-18 11:44:52 +04:00
download + = ratioInfo . first ;
2007-08-20 10:29:18 +04:00
size_type upload = h . total_payload_upload ( ) ;
2007-07-18 11:44:52 +04:00
upload + = ratioInfo . second ;
2007-08-09 09:03:06 +04:00
Q_ASSERT ( download > = 0 & & upload > = 0 ) ;
2007-08-20 10:29:18 +04:00
QFile ratio_file ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + QString : : fromUtf8 ( " .ratio " ) ) ;
if ( ! ratio_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ) {
std : : cerr < < " Couldn't save ratio data for torrent: " < < hash . toStdString ( ) < < ' \n ' ;
2007-07-18 11:44:52 +04:00
return ;
}
2007-08-20 10:29:18 +04:00
ratio_file . write ( misc : : toQByteArray ( download ) + QByteArray ( " " ) + misc : : toQByteArray ( upload ) ) ;
2007-07-18 11:44:52 +04:00
ratio_file . close ( ) ;
}
2007-11-23 00:50:22 +03:00
// Only save fast resume data for unfinished and unpaused torrents (Optimization)
// Called periodically and on exit
void bittorrent : : saveFastResumeAndRatioData ( ) {
2007-11-21 23:33:30 +03:00
QString hash ;
QStringList hashes = getUnfinishedTorrents ( ) ;
foreach ( hash , hashes ) {
2007-11-23 00:50:22 +03:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-11-23 00:53:42 +03:00
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
2007-11-23 00:50:22 +03:00
if ( h . is_paused ( ) ) {
// Do not need to save fast resume data for paused torrents
2007-08-19 12:45:24 +04:00
continue ;
}
2007-11-21 23:33:30 +03:00
saveFastResumeAndRatioData ( hash ) ;
2007-03-05 16:55:23 +03:00
}
2008-08-26 10:39:57 +04:00
hashes = getFinishedTorrents ( ) ;
foreach ( hash , hashes ) {
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
if ( h . is_paused ( ) ) {
2008-08-26 11:14:38 +04:00
// Do not need to save ratio data for paused torrents
2008-08-26 10:39:57 +04:00
continue ;
}
saveDownloadUploadForTorrent ( hash ) ;
}
2007-03-05 16:55:23 +03:00
}
2008-09-07 15:31:29 +04:00
QStringList bittorrent : : getConsoleMessages ( ) const {
return consoleMessages ;
}
QStringList bittorrent : : getPeerBanMessages ( ) const {
return peerBanMessages ;
}
void bittorrent : : addConsoleMessage ( QString msg , QColor color ) {
if ( consoleMessages . size ( ) > 100 ) {
consoleMessages . removeFirst ( ) ;
}
consoleMessages . append ( QString : : fromUtf8 ( " <font color='grey'> " ) + QTime : : currentTime ( ) . toString ( QString : : fromUtf8 ( " hh:mm:ss " ) ) + QString : : fromUtf8 ( " </font> - <font color=' " ) + color . name ( ) + QString : : fromUtf8 ( " '><i> " ) + msg + QString : : fromUtf8 ( " </i></font> " ) ) ;
}
void bittorrent : : addPeerBanMessage ( QString ip , bool from_ipfilter ) {
if ( peerBanMessages . size ( ) > 100 ) {
peerBanMessages . removeFirst ( ) ;
}
if ( from_ipfilter )
peerBanMessages . append ( QString : : fromUtf8 ( " <font color='grey'> " ) + QTime : : currentTime ( ) . toString ( QString : : fromUtf8 ( " hh:mm:ss " ) ) + QString : : fromUtf8 ( " </font> - " ) + tr ( " <font color='red'>%1</font> <i>was blocked due to your IP filter</i> " , " x.y.z.w was blocked " ) . arg ( ip ) ) ;
else
peerBanMessages . append ( QString : : fromUtf8 ( " <font color='grey'> " ) + QTime : : currentTime ( ) . toString ( QString : : fromUtf8 ( " hh:mm:ss " ) ) + QString : : fromUtf8 ( " </font> - " ) + tr ( " <font color='red'>%1</font> <i>was banned due to corrupt pieces</i> " , " x.y.z.w was banned " ) . arg ( ip ) ) ;
}
2007-11-21 23:33:30 +03:00
void bittorrent : : saveFastResumeAndRatioData ( QString hash ) {
QString file ;
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
// Checking if torrentBackup Dir exists
// create it if it is not
if ( ! torrentBackup . exists ( ) ) {
torrentBackup . mkpath ( torrentBackup . path ( ) ) ;
}
// Extracting resume data
QTorrentHandle h = getTorrentHandle ( hash ) ;
if ( ! h . is_valid ( ) ) {
qDebug ( " /! \\ Error: Invalid handle " ) ;
return ;
}
if ( h . has_metadata ( ) & & h . state ( ) ! = torrent_status : : checking_files & & h . state ( ) ! = torrent_status : : queued_for_checking ) {
if ( QFile : : exists ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .torrent " ) ) {
// Remove old .fastresume data in case it exists
QFile : : remove ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .fastresume " ) ;
// Write fast resume data
entry resumeData = h . write_resume_data ( ) ;
file = hash + " .fastresume " ;
boost : : filesystem : : ofstream out ( fs : : path ( torrentBackup . path ( ) . toUtf8 ( ) . data ( ) ) / file . toUtf8 ( ) . data ( ) , std : : ios_base : : binary ) ;
out . unsetf ( std : : ios_base : : skipws ) ;
bencode ( std : : ostream_iterator < char > ( out ) , resumeData ) ;
}
// Save ratio data
saveDownloadUploadForTorrent ( hash ) ;
}
}
2007-07-22 13:47:27 +04:00
bool bittorrent : : isFilePreviewPossible ( QString hash ) const {
2007-03-05 16:55:23 +03:00
// See if there are supported files in the torrent
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
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 false ;
2007-03-05 16:55:23 +03:00
}
2007-08-20 10:29:18 +04:00
unsigned int nbFiles = h . num_files ( ) ;
for ( unsigned int i = 0 ; i < nbFiles ; + + i ) {
QString fileName = h . file_at ( i ) ;
2007-08-29 20:07:37 +04:00
QString extension = fileName . split ( ' . ' ) . last ( ) ;
if ( misc : : isPreviewable ( extension ) )
2007-03-05 16:55:23 +03:00
return true ;
}
return false ;
}
// Scan the first level of the directory for torrent files
// and add them to download list
2007-08-20 10:29:18 +04:00
void bittorrent : : scanDirectory ( ) {
2007-03-05 16:55:23 +03:00
QString file ;
2007-08-20 10:29:18 +04:00
if ( ! scan_dir . isNull ( ) ) {
2007-03-05 16:55:23 +03:00
QStringList to_add ;
QDir dir ( scan_dir ) ;
2007-07-31 12:13:38 +04:00
QStringList filters ;
filters < < " *.torrent " ;
QStringList files = dir . entryList ( filters , QDir : : Files , QDir : : Unsorted ) ;
2007-08-20 10:29:18 +04:00
foreach ( file , files ) {
2007-03-05 16:55:23 +03:00
QString fullPath = dir . path ( ) + QDir : : separator ( ) + file ;
2007-08-20 10:29:18 +04:00
QFile : : rename ( fullPath , fullPath + QString : : fromUtf8 ( " .old " ) ) ;
to_add < < fullPath + QString : : fromUtf8 ( " .old " ) ;
2007-03-05 16:55:23 +03:00
}
2007-03-08 01:36:01 +03:00
emit scanDirFoundTorrents ( to_add ) ;
2007-03-05 16:55:23 +03:00
}
}
2007-08-20 10:29:18 +04:00
void bittorrent : : setDefaultSavePath ( QString savepath ) {
2007-03-08 01:36:01 +03:00
defaultSavePath = savepath ;
}
2008-05-18 12:40:39 +04:00
void bittorrent : : setTimerScanInterval ( int secs ) {
if ( folderScanInterval ! = secs ) {
folderScanInterval = secs ;
if ( ! scan_dir . isNull ( ) ) {
timerScan - > start ( folderScanInterval * 1000 ) ;
}
}
}
2007-03-05 16:55:23 +03:00
// Enable directory scanning
2007-08-20 10:29:18 +04:00
void bittorrent : : enableDirectoryScanning ( QString _scan_dir ) {
if ( ! _scan_dir . isEmpty ( ) ) {
2007-03-05 20:35:38 +03:00
scan_dir = _scan_dir ;
2007-03-05 16:55:23 +03:00
timerScan = new QTimer ( this ) ;
connect ( timerScan , SIGNAL ( timeout ( ) ) , this , SLOT ( scanDirectory ( ) ) ) ;
2008-05-18 12:40:39 +04:00
timerScan - > start ( folderScanInterval * 1000 ) ;
2007-03-05 16:55:23 +03:00
}
}
// Disable directory scanning
2007-08-20 10:29:18 +04:00
void bittorrent : : disableDirectoryScanning ( ) {
if ( ! scan_dir . isNull ( ) ) {
2007-03-05 16:55:23 +03:00
scan_dir = QString : : null ;
2007-08-20 10:29:18 +04:00
if ( timerScan - > isActive ( ) ) {
2007-03-05 20:35:38 +03:00
timerScan - > stop ( ) ;
}
2007-03-05 16:55:23 +03:00
}
2008-09-13 11:33:41 +04:00
if ( timerScan )
2007-07-30 17:56:31 +04:00
delete timerScan ;
2007-03-05 16:55:23 +03:00
}
// Set the ports range in which is chosen the port the bittorrent
// session will listen to
2007-08-20 10:29:18 +04:00
void bittorrent : : setListeningPortsRange ( std : : pair < unsigned short , unsigned short > ports ) {
2007-03-05 16:55:23 +03:00
s - > listen_on ( ports ) ;
}
// Set download rate limit
// -1 to disable
2007-08-20 10:29:18 +04:00
void bittorrent : : setDownloadRateLimit ( long rate ) {
2007-08-04 10:23:44 +04:00
qDebug ( " Setting a global download rate limit at %ld " , rate ) ;
2007-03-05 16:55:23 +03:00
s - > set_download_rate_limit ( rate ) ;
}
2007-07-14 14:50:38 +04:00
session * bittorrent : : getSession ( ) const {
return s ;
}
2007-03-05 16:55:23 +03:00
// Set upload rate limit
// -1 to disable
2007-08-20 10:29:18 +04:00
void bittorrent : : setUploadRateLimit ( long rate ) {
2007-08-08 11:35:57 +04:00
qDebug ( " set upload_limit to %fkb/s " , rate / 1024. ) ;
2007-03-05 16:55:23 +03:00
s - > set_upload_rate_limit ( rate ) ;
}
// libtorrent allow to adjust ratio for each torrent
// This function will apply to same ratio to all torrents
2007-08-20 10:29:18 +04:00
void bittorrent : : setGlobalRatio ( float ratio ) {
2007-09-09 13:09:24 +04:00
if ( ratio ! = - 1 & & ratio < 1. ) ratio = 1. ;
2007-09-16 18:16:42 +04:00
if ( ratio = = - 1 ) {
// 0 means unlimited for libtorrent
ratio = 0 ;
}
2007-03-05 16:55:23 +03:00
std : : vector < torrent_handle > handles = s - > get_torrents ( ) ;
2007-07-31 13:17:59 +04:00
unsigned int nbHandles = handles . size ( ) ;
2007-08-20 10:29:18 +04:00
for ( unsigned int i = 0 ; i < nbHandles ; + + i ) {
QTorrentHandle h = handles [ i ] ;
if ( ! h . is_valid ( ) ) {
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
continue ;
}
h . set_ratio ( ratio ) ;
2007-03-05 16:55:23 +03:00
}
}
2007-03-05 20:35:38 +03:00
2007-09-09 13:09:24 +04:00
// Torrents will a ratio superior to the given value will
// be automatically deleted
void bittorrent : : setDeleteRatio ( float ratio ) {
if ( ratio ! = - 1 & & ratio < 1. ) ratio = 1. ;
2007-11-25 00:55:19 +03:00
if ( max_ratio = = - 1 & & ratio ! = - 1 ) {
Q_ASSERT ( ! BigRatioTimer ) ;
BigRatioTimer = new QTimer ( this ) ;
connect ( BigRatioTimer , SIGNAL ( timeout ( ) ) , this , SLOT ( deleteBigRatios ( ) ) ) ;
BigRatioTimer - > start ( 5000 ) ;
} else {
if ( max_ratio ! = - 1 & & ratio = = - 1 ) {
delete BigRatioTimer ;
}
}
if ( max_ratio ! = ratio ) {
max_ratio = ratio ;
qDebug ( " * Set deleteRatio to %.1f " , max_ratio ) ;
deleteBigRatios ( ) ;
}
2007-09-09 13:09:24 +04:00
}
2007-08-20 10:29:18 +04:00
bool bittorrent : : loadTrackerFile ( QString hash ) {
2007-03-25 20:18:57 +04:00
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
QFile tracker_file ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .trackers " ) ;
2007-03-25 22:39:27 +04:00
if ( ! tracker_file . exists ( ) ) return false ;
2007-03-25 20:18:57 +04:00
tracker_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ;
2007-08-20 10:29:18 +04:00
QStringList lines = QString : : fromUtf8 ( tracker_file . readAll ( ) . data ( ) ) . split ( " \n " ) ;
2007-03-25 20:18:57 +04:00
std : : vector < announce_entry > trackers ;
QString line ;
2007-08-20 10:29:18 +04:00
foreach ( line , lines ) {
2007-03-25 20:18:57 +04:00
QStringList parts = line . split ( " | " ) ;
if ( parts . size ( ) ! = 2 ) continue ;
announce_entry t ( parts [ 0 ] . toStdString ( ) ) ;
t . tier = parts [ 1 ] . toInt ( ) ;
trackers . push_back ( t ) ;
}
2008-09-13 11:33:41 +04:00
if ( ! trackers . empty ( ) ) {
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-03-25 20:18:57 +04:00
h . replace_trackers ( trackers ) ;
2008-04-13 18:15:19 +04:00
h . force_reannounce ( ) ;
2007-03-25 22:39:27 +04:00
return true ;
} else {
return false ;
2007-03-25 20:18:57 +04:00
}
}
2007-08-20 10:29:18 +04:00
void bittorrent : : saveTrackerFile ( QString hash ) {
2007-11-20 00:10:57 +03:00
qDebug ( " Saving tracker file for %s " , hash . toUtf8 ( ) . data ( ) ) ;
2007-03-25 20:18:57 +04:00
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
QFile tracker_file ( torrentBackup . path ( ) + QDir : : separator ( ) + hash + " .trackers " ) ;
2007-08-20 10:29:18 +04:00
if ( tracker_file . exists ( ) ) {
2007-03-25 20:18:57 +04:00
tracker_file . remove ( ) ;
}
tracker_file . open ( QIODevice : : WriteOnly | QIODevice : : Text ) ;
2007-08-20 10:29:18 +04:00
QTorrentHandle h = getTorrentHandle ( hash ) ;
2007-03-25 20:18:57 +04:00
std : : vector < announce_entry > trackers = h . trackers ( ) ;
2007-08-20 10:29:18 +04:00
for ( unsigned int i = 0 ; i < trackers . size ( ) ; + + i ) {
2007-03-25 22:39:27 +04:00
tracker_file . write ( QByteArray ( trackers [ i ] . url . c_str ( ) ) + QByteArray ( " | " ) + QByteArray ( misc : : toString ( i ) . c_str ( ) ) + QByteArray ( " \n " ) ) ;
2007-03-25 20:18:57 +04:00
}
tracker_file . close ( ) ;
}
2007-03-05 20:35:38 +03:00
// Add uT PeX extension to bittorrent session
2007-08-20 10:29:18 +04:00
void bittorrent : : enablePeerExchange ( ) {
2007-06-16 03:02:35 +04:00
qDebug ( " Enabling Peer eXchange " ) ;
2007-03-05 20:35:38 +03:00
s - > add_extension ( & create_ut_pex_plugin ) ;
}
// Set DHT port (>= 1000)
2007-08-20 10:29:18 +04:00
void bittorrent : : setDHTPort ( int dht_port ) {
if ( dht_port > = 1000 ) {
2007-03-05 20:35:38 +03:00
struct dht_settings DHTSettings ;
DHTSettings . service_port = dht_port ;
s - > set_dht_settings ( DHTSettings ) ;
qDebug ( " Set DHT Port to %d " , dht_port ) ;
}
}
// Enable IP Filtering
2008-05-18 00:32:03 +04:00
void bittorrent : : enableIPFilter ( QString filter ) {
2007-06-16 03:02:35 +04:00
qDebug ( " Enabling IPFiler " ) ;
2008-05-18 00:32:03 +04:00
if ( ! filterParser ) {
filterParser = new FilterParserThread ( this , s ) ;
}
if ( filterPath . isEmpty ( ) | | filterPath ! = filter ) {
filterPath = filter ;
filterParser - > processFilterFile ( filter ) ;
}
2007-03-05 20:35:38 +03:00
}
// Disable IP Filtering
2007-08-20 10:29:18 +04:00
void bittorrent : : disableIPFilter ( ) {
qDebug ( " Disabling IPFilter " ) ;
2007-03-05 20:35:38 +03:00
s - > set_ip_filter ( ip_filter ( ) ) ;
2008-05-18 00:32:03 +04:00
if ( filterParser ) {
delete filterParser ;
}
filterPath = " " ;
2007-03-05 20:35:38 +03:00
}
2007-05-02 17:52:29 +04:00
// Set BT session settings (user_agent)
2007-08-20 10:29:18 +04:00
void bittorrent : : setSessionSettings ( session_settings sessionSettings ) {
2007-06-16 03:02:35 +04:00
qDebug ( " Set session settings " ) ;
2007-03-05 20:35:38 +03:00
s - > set_settings ( sessionSettings ) ;
}
2007-05-02 17:52:29 +04:00
// Set Proxy
2007-08-20 10:29:18 +04:00
void bittorrent : : setProxySettings ( proxy_settings proxySettings , bool trackers , bool peers , bool web_seeds , bool dht ) {
2007-06-16 03:02:35 +04:00
qDebug ( " Set Proxy settings " ) ;
2007-05-14 00:02:30 +04:00
if ( trackers )
s - > set_tracker_proxy ( proxySettings ) ;
if ( peers )
s - > set_peer_proxy ( proxySettings ) ;
if ( web_seeds )
s - > set_web_seed_proxy ( proxySettings ) ;
2007-08-20 10:29:18 +04:00
if ( DHTEnabled & & dht ) {
2007-05-14 00:02:30 +04:00
s - > set_dht_proxy ( proxySettings ) ;
}
2007-05-02 17:52:29 +04:00
}
2007-03-05 20:35:38 +03:00
// Read alerts sent by the bittorrent session
2007-08-20 10:29:18 +04:00
void bittorrent : : readAlerts ( ) {
2007-03-05 20:35:38 +03:00
// look at session alerts and display some infos
std : : auto_ptr < alert > a = s - > pop_alert ( ) ;
2007-08-20 10:29:18 +04:00
while ( a . get ( ) ) {
if ( torrent_finished_alert * p = dynamic_cast < torrent_finished_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2007-08-27 13:24:22 +04:00
if ( h . is_valid ( ) ) {
QString hash = h . hash ( ) ;
qDebug ( " Received finished alert for %s " , h . name ( ) . toUtf8 ( ) . data ( ) ) ;
setFinishedTorrent ( hash ) ;
emit finishedTorrent ( h ) ;
}
2007-03-05 20:35:38 +03:00
}
2007-08-20 10:29:18 +04:00
else if ( file_error_alert * p = dynamic_cast < file_error_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2007-09-19 02:41:23 +04:00
qDebug ( " File Error: %s " , p - > msg ( ) . c_str ( ) ) ;
2007-08-27 13:24:22 +04:00
if ( h . is_valid ( ) )
emit fullDiskError ( h ) ;
2007-03-05 20:35:38 +03:00
}
2007-08-20 10:29:18 +04:00
else if ( dynamic_cast < listen_failed_alert * > ( a . get ( ) ) ) {
2007-03-05 20:35:38 +03:00
// Level: fatal
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Couldn't listen on any of the given ports. " ) , QString : : fromUtf8 ( " red " ) ) ;
//emit portListeningFailure();
2007-03-05 20:35:38 +03:00
}
2007-08-20 10:29:18 +04:00
else if ( tracker_alert * p = dynamic_cast < tracker_alert * > ( a . get ( ) ) ) {
2007-03-05 20:35:38 +03:00
// Level: fatal
2007-08-20 10:29:18 +04:00
QTorrentHandle h ( p - > handle ) ;
2007-08-27 13:24:22 +04:00
if ( h . is_valid ( ) ) {
// Authentication
2008-05-15 23:48:15 +04:00
if ( p - > status_code ! = 401 ) {
QString hash = h . hash ( ) ;
2008-05-17 02:27:36 +04:00
qDebug ( " Received a tracker error for %s " , p - > url . c_str ( ) ) ;
2008-05-15 23:48:15 +04:00
QHash < QString , QString > errors = trackersErrors . value ( hash , QHash < QString , QString > ( ) ) ;
// p->url requires at least libtorrent v0.13.1
errors [ misc : : toQString ( p - > url ) ] = QString : : fromUtf8 ( a - > msg ( ) . c_str ( ) ) ;
trackersErrors [ hash ] = errors ;
} else {
2007-08-27 13:24:22 +04:00
emit trackerAuthenticationRequired ( h ) ;
}
2007-03-05 20:35:38 +03:00
}
}
2008-05-15 23:48:15 +04:00
else if ( tracker_reply_alert * p = dynamic_cast < tracker_reply_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " Received a tracker reply from %s " , ( const char * ) h . current_tracker ( ) . toUtf8 ( ) ) ;
QString hash = h . hash ( ) ;
QHash < QString , QString > errors = trackersErrors . value ( hash , QHash < QString , QString > ( ) ) ;
// p->url requires at least libtorrent v0.13.1
errors . remove ( h . current_tracker ( ) ) ;
trackersErrors [ hash ] = errors ;
}
}
2007-12-31 19:57:35 +03:00
else if ( portmap_error_alert * p = dynamic_cast < portmap_error_alert * > ( a . get ( ) ) ) {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping failure, message: %1 " ) . arg ( QString ( p - > msg ( ) . c_str ( ) ) ) , QColor ( " red " ) ) ;
//emit UPnPError(QString(p->msg().c_str()));
2007-12-31 19:57:35 +03:00
}
else if ( portmap_alert * p = dynamic_cast < portmap_alert * > ( a . get ( ) ) ) {
qDebug ( " UPnP Success, msg: %s " , p - > msg ( ) . c_str ( ) ) ;
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping successful, message: %1 " ) . arg ( QString ( p - > msg ( ) . c_str ( ) ) ) , QColor ( " blue " ) ) ;
//emit UPnPSuccess(QString(p->msg().c_str()));
2007-12-31 19:57:35 +03:00
}
2007-08-20 10:29:18 +04:00
else if ( peer_blocked_alert * p = dynamic_cast < peer_blocked_alert * > ( a . get ( ) ) ) {
2008-09-07 15:31:29 +04:00
addPeerBanMessage ( QString ( p - > ip . to_string ( ) . c_str ( ) ) , true ) ;
//emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
}
else if ( peer_ban_alert * p = dynamic_cast < peer_ban_alert * > ( a . get ( ) ) ) {
addPeerBanMessage ( QString ( p - > ip . address ( ) . to_string ( ) . c_str ( ) ) , false ) ;
//emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
2007-07-04 10:42:36 +04:00
}
2007-08-20 10:29:18 +04:00
else if ( fastresume_rejected_alert * p = dynamic_cast < fastresume_rejected_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2007-08-27 13:24:22 +04:00
if ( h . is_valid ( ) ) {
qDebug ( " /! \\ Fast resume failed for %s, reason: %s " , h . name ( ) . toUtf8 ( ) . data ( ) , p - > msg ( ) . c_str ( ) ) ;
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Fast resume data was rejected for torrent %1, checking again... " ) . arg ( h . name ( ) ) , QString : : fromUtf8 ( " red " ) ) ;
//emit fastResumeDataRejected(h.name());
2007-08-27 13:24:22 +04:00
}
2007-07-24 11:13:40 +04:00
}
2007-08-20 10:29:18 +04:00
else if ( url_seed_alert * p = dynamic_cast < url_seed_alert * > ( a . get ( ) ) ) {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Url seed lookup failed for url: %1, message: %2 " ) . arg ( QString : : fromUtf8 ( p - > url . c_str ( ) ) ) . arg ( QString : : fromUtf8 ( p - > msg ( ) . c_str ( ) ) ) , QString : : fromUtf8 ( " red " ) ) ;
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
2007-07-27 13:53:55 +04:00
}
2007-08-20 10:29:18 +04:00
else if ( torrent_checked_alert * p = dynamic_cast < torrent_checked_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
2007-08-27 13:24:22 +04:00
if ( h . is_valid ( ) ) {
QString hash = h . hash ( ) ;
qDebug ( " %s have just finished checking " , hash . toUtf8 ( ) . data ( ) ) ;
2008-09-13 22:53:58 +04:00
if ( ! h . is_paused ( ) ) {
2007-11-25 00:55:19 +03:00
// Save Addition DateTime
2008-07-27 19:41:46 +04:00
if ( calculateETA ) {
TorrentsStartTime [ hash ] = QDateTime : : currentDateTime ( ) ;
TorrentsStartData [ hash ] = h . total_payload_download ( ) ;
}
2008-09-13 22:53:58 +04:00
}
//emit torrentFinishedChecking(hash);
2007-08-17 06:03:13 +04:00
}
}
2007-03-05 20:35:38 +03:00
a = s - > pop_alert ( ) ;
}
}
2008-05-15 23:48:15 +04:00
QHash < QString , QString > bittorrent : : getTrackersErrors ( QString hash ) const {
return trackersErrors . value ( hash , QHash < QString , QString > ( ) ) ;
2007-07-27 17:58:12 +04:00
}
2007-07-04 14:06:22 +04:00
// Reload a torrent with full allocation mode
2007-10-10 21:34:52 +04:00
void bittorrent : : reloadTorrent ( const QTorrentHandle & h , bool full_alloc ) {
2007-04-13 01:28:15 +04:00
qDebug ( " ** Reloading a torrent " ) ;
2007-08-20 10:29:18 +04:00
if ( ! h . is_valid ( ) ) {
2007-03-11 21:01:34 +03:00
qDebug ( " /! \\ Error: Invalid handle " ) ;
return ;
}
2007-03-08 01:36:01 +03:00
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
2007-08-20 10:29:18 +04:00
fs : : path saveDir = h . save_path_boost ( ) ;
QString fileName = h . name ( ) ;
QString hash = h . hash ( ) ;
2007-09-04 08:18:51 +04:00
boost : : intrusive_ptr < torrent_info > t ( new torrent_info ( h . get_torrent_info ( ) ) ) ;
2007-08-20 10:29:18 +04:00
qDebug ( " Reloading torrent: %s " , fileName . toUtf8 ( ) . data ( ) ) ;
entry resumeData ;
2007-03-08 01:36:01 +03:00
// Checking if torrentBackup Dir exists
// create it if it is not
2007-08-20 10:29:18 +04:00
if ( ! torrentBackup . exists ( ) ) {
2007-03-08 01:36:01 +03:00
torrentBackup . mkpath ( torrentBackup . path ( ) ) ;
}
// Extracting resume data
2007-08-20 10:29:18 +04:00
if ( h . has_metadata ( ) ) {
2007-03-08 01:36:01 +03:00
// get fast resume data
resumeData = h . write_resume_data ( ) ;
}
// Remove torrent
2007-08-20 10:29:18 +04:00
s - > remove_torrent ( h . get_torrent_handle ( ) ) ;
2007-03-08 01:36:01 +03:00
// Add torrent again to session
2007-08-28 20:55:14 +04:00
unsigned int timeout = 0 ;
2007-08-20 10:29:18 +04:00
while ( h . is_valid ( ) & & timeout < 6 ) {
2007-11-03 03:19:24 +03:00
qDebug ( " Waiting for the torrent to be removed... " ) ;
2007-03-08 01:36:01 +03:00
SleeperThread : : msleep ( 1000 ) ;
+ + timeout ;
}
2007-10-10 21:34:52 +04:00
QTorrentHandle new_h ;
2007-11-03 01:56:07 +03:00
if ( full_alloc ) {
2007-10-10 21:34:52 +04:00
new_h = s - > add_torrent ( t , saveDir , resumeData , storage_mode_allocate ) ;
2007-11-03 01:56:07 +03:00
qDebug ( " Using full allocation mode " ) ;
} else {
2007-10-10 21:34:52 +04:00
new_h = s - > add_torrent ( t , saveDir , resumeData , storage_mode_sparse ) ;
2007-11-03 01:56:07 +03:00
qDebug ( " Using sparse mode " ) ;
}
2007-09-09 11:44:22 +04:00
// Connections limit per torrent
new_h . set_max_connections ( maxConnecsPerTorrent ) ;
// Uploads limit per torrent
new_h . set_max_uploads ( maxUploadsPerTorrent ) ;
2007-03-08 01:36:01 +03:00
// Load filtered Files
2007-07-04 14:06:22 +04:00
loadFilesPriorities ( new_h ) ;
2007-07-14 17:38:29 +04:00
// Load speed limit from hard drive
2007-08-20 10:29:18 +04:00
loadTorrentSpeedLimits ( hash ) ;
2007-07-27 13:53:55 +04:00
// Load custom url seeds
2007-08-20 10:29:18 +04:00
loadWebSeeds ( hash ) ;
2007-07-18 11:44:52 +04:00
// Load ratio data
2007-08-20 10:29:18 +04:00
loadDownloadUploadForTorrent ( hash ) ;
2007-03-08 01:36:01 +03:00
// Pause torrent if it was paused last time
2007-08-20 10:29:18 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .paused " ) ) {
2007-03-08 01:36:01 +03:00
new_h . pause ( ) ;
}
// Incremental download
2007-08-20 10:29:18 +04:00
if ( QFile : : exists ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .incremental " ) ) {
qDebug ( " Incremental download enabled for %s " , fileName . toUtf8 ( ) . data ( ) ) ;
2007-08-17 06:22:04 +04:00
new_h . set_sequenced_download_threshold ( 1 ) ;
2007-03-08 01:36:01 +03:00
}
}
2007-08-15 23:41:12 +04:00
2007-03-08 01:36:01 +03:00
int bittorrent : : getListenPort ( ) const {
return s - > listen_port ( ) ;
}
session_status bittorrent : : getSessionStatus ( ) const {
return s - > status ( ) ;
}
2007-08-20 10:29:18 +04:00
QString bittorrent : : getSavePath ( QString hash ) {
2007-03-05 20:35:38 +03:00
QFile savepath_file ( misc : : qBittorrentPath ( ) + " BT_backup " + QDir : : separator ( ) + hash + " .savepath " ) ;
QByteArray line ;
QString savePath ;
2007-08-20 10:29:18 +04:00
if ( savepath_file . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) {
2007-03-05 20:35:38 +03:00
line = savepath_file . readAll ( ) ;
savepath_file . close ( ) ;
2007-08-26 22:41:45 +04:00
qDebug ( " -> Save path: %s " , line . data ( ) ) ;
2007-03-05 20:35:38 +03:00
savePath = QString : : fromUtf8 ( line . data ( ) ) ;
} else {
2007-03-08 01:36:01 +03:00
// use default save path
2007-11-06 20:40:44 +03:00
qDebug ( " Using default save path because none was set " ) ;
2007-03-08 01:36:01 +03:00
savePath = defaultSavePath ;
2007-03-05 20:35:38 +03:00
}
// Checking if savePath Dir exists
// create it if it is not
QDir saveDir ( savePath ) ;
2007-08-20 10:29:18 +04:00
if ( ! saveDir . exists ( ) ) {
if ( ! saveDir . mkpath ( saveDir . path ( ) ) ) {
std : : cerr < < " Couldn't create the save directory: " < < saveDir . path ( ) . toUtf8 ( ) . data ( ) < < " \n " ;
2007-03-08 01:36:01 +03:00
// XXX: handle this better
2007-03-05 20:35:38 +03:00
return QDir : : homePath ( ) ;
}
}
return savePath ;
}
2007-03-08 01:36:01 +03:00
// Take an url string to a torrent file,
// download the torrent file to a tmp location, then
// add it to download list
2007-08-20 10:29:18 +04:00
void bittorrent : : downloadFromUrl ( QString url ) {
2008-09-07 15:31:29 +04:00
addConsoleMessage ( tr ( " Downloading '%1', please wait... " , " e.g: Downloading 'xxx.torrent', please wait... " ) . arg ( url ) , QPalette : : WindowText ) ;
//emit aboutToDownloadFromUrl(url);
2007-03-08 01:36:01 +03:00
// Launch downloader thread
downloader - > downloadUrl ( url ) ;
}
2008-09-14 14:14:54 +04:00
void bittorrent : : downloadUrlAndSkipDialog ( QString url ) {
//emit aboutToDownloadFromUrl(url);
url_skippingDlg < < url ;
// Launch downloader thread
downloader - > downloadUrl ( url ) ;
}
2007-03-08 01:36:01 +03:00
// Add to bittorrent session the downloaded torrent file
2007-08-20 10:29:18 +04:00
void bittorrent : : processDownloadedFile ( QString url , QString file_path ) {
2008-09-14 14:14:54 +04:00
int index = url_skippingDlg . indexOf ( url ) ;
if ( index < 0 ) {
// Add file to torrent download list
emit newDownloadedTorrent ( file_path , url ) ;
} else {
url_skippingDlg . removeAt ( index ) ;
addTorrent ( file_path , false , url , false ) ;
}
2007-03-08 01:36:01 +03:00
}
2007-08-20 10:29:18 +04:00
void bittorrent : : downloadFromURLList ( const QStringList & url_list ) {
2007-03-08 01:36:01 +03:00
QString url ;
2007-07-03 13:04:04 +04:00
qDebug ( " DownloadFromUrlList " ) ;
2007-08-20 10:29:18 +04:00
foreach ( url , url_list ) {
2007-03-08 01:36:01 +03:00
downloadFromUrl ( url ) ;
}
}
// Return current download rate for the BT
// session. Payload means that it only take into
// account "useful" part of the rate
float bittorrent : : getPayloadDownloadRate ( ) const {
session_status sessionStatus = s - > status ( ) ;
return sessionStatus . payload_download_rate ;
}
// Return current upload rate for the BT
// session. Payload means that it only take into
// account "useful" part of the rate
float bittorrent : : getPayloadUploadRate ( ) const {
session_status sessionStatus = s - > status ( ) ;
return sessionStatus . payload_upload_rate ;
}
// Save DHT entry to hard drive
2007-08-20 10:29:18 +04:00
void bittorrent : : saveDHTEntry ( ) {
2007-03-08 01:36:01 +03:00
// Save DHT entry
2007-08-20 10:29:18 +04:00
if ( DHTEnabled ) {
2007-03-08 01:36:01 +03:00
try {
entry dht_state = s - > dht_state ( ) ;
2007-08-20 10:29:18 +04:00
boost : : filesystem : : ofstream out ( ( misc : : qBittorrentPath ( ) + QString : : fromUtf8 ( " dht_state " ) ) . toUtf8 ( ) . data ( ) , std : : ios_base : : binary ) ;
2007-03-08 01:36:01 +03:00
out . unsetf ( std : : ios_base : : skipws ) ;
bencode ( std : : ostream_iterator < char > ( out ) , dht_state ) ;
2007-07-29 18:54:39 +04:00
qDebug ( " DHT entry saved " ) ;
2007-08-20 10:29:18 +04:00
} catch ( std : : exception & e ) {
2007-03-08 01:36:01 +03:00
std : : cerr < < e . what ( ) < < " \n " ;
}
}
}
2007-08-20 10:29:18 +04:00
void bittorrent : : applyEncryptionSettings ( pe_settings se ) {
2007-06-16 03:02:35 +04:00
qDebug ( " Applying encryption settings " ) ;
2007-06-16 00:35:07 +04:00
s - > set_pe_settings ( se ) ;
}
2007-10-10 21:34:52 +04:00
// Will fast resume torrents in
2007-03-08 01:36:01 +03:00
// backup directory
2007-08-20 10:29:18 +04:00
void bittorrent : : resumeUnfinishedTorrents ( ) {
2007-03-08 01:36:01 +03:00
qDebug ( " Resuming unfinished torrents " ) ;
QDir torrentBackup ( misc : : qBittorrentPath ( ) + " BT_backup " ) ;
QStringList fileNames , filePaths ;
// Scan torrentBackup directory
2007-07-31 12:21:51 +04:00
QStringList filters ;
filters < < " *.torrent " ;
fileNames = torrentBackup . entryList ( filters , QDir : : Files , QDir : : Unsorted ) ;
2007-03-08 01:36:01 +03:00
QString fileName ;
2007-08-20 10:29:18 +04:00
foreach ( fileName , fileNames ) {
2007-07-31 12:21:51 +04:00
filePaths . append ( torrentBackup . path ( ) + QDir : : separator ( ) + fileName ) ;
2007-03-08 01:36:01 +03:00
}
// Resume downloads
2007-08-20 10:29:18 +04:00
foreach ( fileName , filePaths ) {
2007-10-10 21:34:52 +04:00
addTorrent ( fileName , false , QString ( ) , true ) ;
2007-03-08 01:36:01 +03:00
}
qDebug ( " Unfinished torrents resumed " ) ;
}