@ -114,6 +114,7 @@ QBtSession::QBtSession()
@@ -114,6 +114,7 @@ QBtSession::QBtSession()
, m_upnp ( 0 ) , m_natpmp ( 0 )
# endif
, m_dynDNSUpdater ( 0 )
, m_alertDispatcher ( 0 )
{
BigRatioTimer = new QTimer ( this ) ;
BigRatioTimer - > setInterval ( 10000 ) ;
@ -147,9 +148,8 @@ QBtSession::QBtSession()
@@ -147,9 +148,8 @@ QBtSession::QBtSession()
PeXEnabled = false ;
}
s - > add_extension ( & create_smart_ban_plugin ) ;
timerAlerts = new QTimer ( this ) ;
connect ( timerAlerts , SIGNAL ( timeout ( ) ) , SLOT ( readAlerts ( ) ) ) ;
timerAlerts - > start ( 1000 ) ;
m_alertDispatcher = new QAlertDispatcher ( s , this ) ;
connect ( m_alertDispatcher , SIGNAL ( alertsReceived ( ) ) , SLOT ( readAlerts ( ) ) ) ;
appendLabelToSavePath = pref . appendTorrentLabel ( ) ;
appendqBExtension = pref . useIncompleteFilesExtension ( ) ;
connect ( m_scanFolders , SIGNAL ( torrentsAdded ( QStringList & ) ) , SLOT ( addTorrentsFromScanFolder ( QStringList & ) ) ) ;
@ -179,7 +179,6 @@ QBtSession::~QBtSession() {
@@ -179,7 +179,6 @@ QBtSession::~QBtSession() {
// Delete our objects
if ( m_tracker )
delete m_tracker ;
delete timerAlerts ;
if ( BigRatioTimer )
delete BigRatioTimer ;
if ( filterParser )
@ -190,6 +189,7 @@ QBtSession::~QBtSession() {
@@ -190,6 +189,7 @@ QBtSession::~QBtSession() {
// HTTP Server
if ( httpServer )
delete httpServer ;
delete m_alertDispatcher ;
qDebug ( " Deleting the session " ) ;
delete s ;
qDebug ( " BTSession destructor OUT " ) ;
@ -1608,7 +1608,6 @@ void QBtSession::saveFastResumeData() {
@@ -1608,7 +1608,6 @@ void QBtSession::saveFastResumeData() {
qDebug ( " Saving fast resume data... " ) ;
// Stop listening for alerts
resumeDataTimer . stop ( ) ;
timerAlerts - > stop ( ) ;
int num_resume_data = 0 ;
// Pause session
s - > pause ( ) ;
@ -1633,52 +1632,52 @@ void QBtSession::saveFastResumeData() {
@@ -1633,52 +1632,52 @@ void QBtSession::saveFastResumeData() {
} catch ( libtorrent : : invalid_handle & ) { }
}
while ( num_resume_data > 0 ) {
alert const * a = s - > wait_for_alert ( seconds ( 30 ) ) ;
if ( a = = 0 ) {
std : : cerr < < " aborting with " < < num_resume_data < < " outstanding "
" torrents to save resume data for " < < std : : endl ;
break ;
}
// Saving fastresume data can fail
save_resume_data_failed_alert const * rda = dynamic_cast < save_resume_data_failed_alert const * > ( a ) ;
if ( rda ) {
std : : deque < alert * > alerts ;
m_alertDispatcher - > getPendingAlerts ( alerts ) ;
for ( std : : deque < alert * > : : const_iterator i = alerts . begin ( ) , end = alerts . end ( ) ; i ! = end ; + + i )
{
alert const * a = * i ;
// Saving fastresume data can fail
save_resume_data_failed_alert const * rda = dynamic_cast < save_resume_data_failed_alert const * > ( a ) ;
if ( rda ) {
- - num_resume_data ;
try {
// Remove torrent from session
if ( rda - > handle . is_valid ( ) )
s - > remove_torrent ( rda - > handle ) ;
} catch ( libtorrent : : libtorrent_exception ) { }
continue ;
}
save_resume_data_alert const * rd = dynamic_cast < save_resume_data_alert const * > ( a ) ;
if ( ! rd ) {
continue ;
}
// Saving fast resume data was successful
- - num_resume_data ;
s - > pop_alert ( ) ;
if ( ! rd - > resume_data ) continue ;
QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
const QTorrentHandle h ( rd - > handle ) ;
if ( ! h . is_valid ( ) ) continue ;
try {
// Remove old fastresume file if it exists
backupPersistentData ( h . hash ( ) , rd - > resume_data ) ;
vector < char > out ;
bencode ( back_inserter ( out ) , * rd - > resume_data ) ;
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
if ( resume_file . exists ( ) )
fsutils : : forceRemove ( filepath ) ;
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
// Remove torrent from session
if ( rda - > handle . is_valid ( ) )
s - > remove_torrent ( rda - > handle ) ;
} catch ( libtorrent : : libtorrent_exception ) { }
continue ;
}
save_resume_data_alert const * rd = dynamic_cast < save_resume_data_alert const * > ( a ) ;
if ( ! rd ) {
s - > pop_alert ( ) ;
continue ;
s - > remove_torrent ( rd - > handle ) ;
} catch ( libtorrent : : invalid_handle & ) { }
delete a ;
}
// Saving fast resume data was successful
- - num_resume_data ;
if ( ! rd - > resume_data ) continue ;
QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
const QTorrentHandle h ( rd - > handle ) ;
if ( ! h . is_valid ( ) ) continue ;
try {
// Remove old fastresume file if it exists
backupPersistentData ( h . hash ( ) , rd - > resume_data ) ;
vector < char > out ;
bencode ( back_inserter ( out ) , * rd - > resume_data ) ;
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
if ( resume_file . exists ( ) )
fsutils : : forceRemove ( filepath ) ;
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
// Remove torrent from session
s - > remove_torrent ( rd - > handle ) ;
s - > pop_alert ( ) ;
} catch ( libtorrent : : invalid_handle & ) { }
}
}
@ -2117,454 +2116,460 @@ void QBtSession::sendNotificationEmail(const QTorrentHandle &h) {
@@ -2117,454 +2116,460 @@ void QBtSession::sendNotificationEmail(const QTorrentHandle &h) {
// Read alerts sent by the Bittorrent session
void QBtSession : : readAlerts ( ) {
// look at session alerts and display some infos
std : : auto_ptr < alert > a = s - > pop_alert ( ) ;
while ( a . get ( ) ) {
try {
if ( torrent_finished_alert * p = dynamic_cast < torrent_finished_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " Got a torrent finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
// Remove .!qB extension if necessary
if ( appendqBExtension )
appendqBextensionToTorrent ( h , false ) ;
const bool was_already_seeded = TorrentPersistentData : : isSeed ( hash ) ;
qDebug ( " Was already seeded: %d " , was_already_seeded ) ;
if ( ! was_already_seeded ) {
h . save_resume_data ( ) ;
qDebug ( " Checking if the torrent contains torrent files to download " ) ;
// Check if there are torrent files inside
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
const QString torrent_relpath = h . filepath_at ( i ) ;
qDebug ( ) < < " File path: " < < torrent_relpath ;
if ( torrent_relpath . endsWith ( " .torrent " , Qt : : CaseInsensitive ) ) {
qDebug ( " Found possible recursive torrent download. " ) ;
const QString torrent_fullpath = h . save_path ( ) + " / " + torrent_relpath ;
qDebug ( " Full subtorrent path is %s " , qPrintable ( torrent_fullpath ) ) ;
try {
boost : : intrusive_ptr < torrent_info > t = new torrent_info ( fsutils : : toNativePath ( torrent_fullpath ) . toUtf8 ( ) . constData ( ) ) ;
if ( t - > is_valid ( ) ) {
qDebug ( " emitting recursiveTorrentDownloadPossible() " ) ;
emit recursiveTorrentDownloadPossible ( h ) ;
break ;
}
} catch ( std : : exception & ) {
qDebug ( " Caught error loading torrent " ) ;
addConsoleMessage ( tr ( " Unable to decode %1 torrent file. " ) . arg ( fsutils : : toNativePath ( torrent_fullpath ) ) , QString : : fromUtf8 ( " red " ) ) ;
typedef std : : deque < alert * > alerts_t ;
alerts_t alerts ;
m_alertDispatcher - > getPendingAlertsNoWait ( alerts ) ;
for ( alerts_t : : const_iterator i = alerts . begin ( ) , end = alerts . end ( ) ; i ! = end ; + + i ) {
handleAlert ( * i ) ;
delete * i ;
}
}
void QBtSession : : handleAlert ( libtorrent : : alert * a ) {
try {
if ( torrent_finished_alert * p = dynamic_cast < torrent_finished_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " Got a torrent finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
// Remove .!qB extension if necessary
if ( appendqBExtension )
appendqBextensionToTorrent ( h , false ) ;
const bool was_already_seeded = TorrentPersistentData : : isSeed ( hash ) ;
qDebug ( " Was already seeded: %d " , was_already_seeded ) ;
if ( ! was_already_seeded ) {
h . save_resume_data ( ) ;
qDebug ( " Checking if the torrent contains torrent files to download " ) ;
// Check if there are torrent files inside
for ( int i = 0 ; i < h . num_files ( ) ; + + i ) {
const QString torrent_relpath = h . filepath_at ( i ) ;
qDebug ( ) < < " File path: " < < torrent_relpath ;
if ( torrent_relpath . endsWith ( " .torrent " , Qt : : CaseInsensitive ) ) {
qDebug ( " Found possible recursive torrent download. " ) ;
const QString torrent_fullpath = h . save_path ( ) + " / " + torrent_relpath ;
qDebug ( " Full subtorrent path is %s " , qPrintable ( torrent_fullpath ) ) ;
try {
boost : : intrusive_ptr < torrent_info > t = new torrent_info ( fsutils : : toNativePath ( torrent_fullpath ) . toUtf8 ( ) . constData ( ) ) ;
if ( t - > is_valid ( ) ) {
qDebug ( " emitting recursiveTorrentDownloadPossible() " ) ;
emit recursiveTorrentDownloadPossible ( h ) ;
break ;
}
} catch ( std : : exception & ) {
qDebug ( " Caught error loading torrent " ) ;
addConsoleMessage ( tr ( " Unable to decode %1 torrent file. " ) . arg ( fsutils : : toNativePath ( torrent_fullpath ) ) , QString : : fromUtf8 ( " red " ) ) ;
}
}
// Move to download directory if necessary
if ( ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( hash ) ) ;
if ( current_dir ! = save_dir ) {
qDebug ( " Moving torrent from the temp folder " ) ;
h . move_storage ( save_dir . absolutePath ( ) ) ;
}
}
// Move to download directory if necessary
if ( ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( hash ) ) ;
if ( current_dir ! = save_dir ) {
qDebug ( " Moving torrent from the temp folder " ) ;
h . move_storage ( save_dir . absolutePath ( ) ) ;
}
// Remember finished state
qDebug ( " Saving seed status " ) ;
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Recheck if the user asked to
Preferences pref ;
if ( pref . recheckTorrentsOnCompletion ( ) ) {
h . force_recheck ( ) ;
}
// Remember finished state
qDebug ( " Saving seed status " ) ;
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Recheck if the user asked to
Preferences pref ;
if ( pref . recheckTorrentsOnCompletion ( ) ) {
h . force_recheck ( ) ;
}
qDebug ( " Emitting finishedTorrent() signal " ) ;
emit finishedTorrent ( h ) ;
qDebug ( " Received finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
# ifndef DISABLE_GUI
bool will_shutdown = ( pref . shutdownWhenDownloadsComplete ( ) | |
pref . shutdownqBTWhenDownloadsComplete ( ) | |
pref . suspendWhenDownloadsComplete ( ) )
& & ! hasDownloadingTorrents ( ) ;
# else
bool will_shutdown = false ;
# endif
// AutoRun program
if ( pref . isAutoRunEnabled ( ) )
autoRunExternalProgram ( h ) ;
// Move .torrent file to another folder
if ( pref . isFinishedTorrentExportEnabled ( ) )
exportTorrentFile ( h , FinishedTorrentExportFolder ) ;
// Mail notification
if ( pref . isMailNotificationEnabled ( ) )
sendNotificationEmail ( h ) ;
# ifndef DISABLE_GUI
// Auto-Shutdown
if ( will_shutdown ) {
bool suspend = pref . suspendWhenDownloadsComplete ( ) ;
bool shutdown = pref . shutdownWhenDownloadsComplete ( ) ;
// Confirm shutdown
QString confirm_msg ;
if ( suspend ) {
confirm_msg = tr ( " The computer will now go to sleep mode unless you cancel within the next 15 seconds... " ) ;
} else if ( shutdown ) {
confirm_msg = tr ( " The computer will now be switched off unless you cancel within the next 15 seconds... " ) ;
} else {
confirm_msg = tr ( " qBittorrent will now exit unless you cancel within the next 15 seconds... " ) ;
}
qDebug ( " Emitting finishedTorrent() signal " ) ;
emit finishedTorrent ( h ) ;
qDebug ( " Received finished alert for %s " , qPrintable ( h . name ( ) ) ) ;
# ifndef DISABLE_GUI
bool will_shutdown = ( pref . shutdownWhenDownloadsComplete ( ) | |
pref . shutdownqBTWhenDownloadsComplete ( ) | |
pref . suspendWhenDownloadsComplete ( ) )
& & ! hasDownloadingTorrents ( ) ;
# else
bool will_shutdown = false ;
# endif
// AutoRun program
if ( pref . isAutoRunEnabled ( ) )
autoRunExternalProgram ( h ) ;
// Move .torrent file to another folder
if ( pref . isFinishedTorrentExportEnabled ( ) )
exportTorrentFile ( h , FinishedTorrentExportFolder ) ;
// Mail notification
if ( pref . isMailNotificationEnabled ( ) )
sendNotificationEmail ( h ) ;
# ifndef DISABLE_GUI
// Auto-Shutdown
if ( will_shutdown ) {
bool suspend = pref . suspendWhenDownloadsComplete ( ) ;
bool shutdown = pref . shutdownWhenDownloadsComplete ( ) ;
// Confirm shutdown
QString confirm_msg ;
if ( suspend ) {
confirm_msg = tr ( " The computer will now go to sleep mode unless you cancel within the next 15 seconds... " ) ;
} else if ( shutdown ) {
confirm_msg = tr ( " The computer will now be switched off unless you cancel within the next 15 seconds... " ) ;
} else {
confirm_msg = tr ( " qBittorrent will now exit unless you cancel within the next 15 seconds... " ) ;
}
if ( ! ShutdownConfirmDlg : : askForConfirmation ( confirm_msg ) )
return ;
// Actually shut down
if ( suspend | | shutdown ) {
qDebug ( " Preparing for auto-shutdown because all downloads are complete! " ) ;
// Disabling it for next time
pref . setShutdownWhenDownloadsComplete ( false ) ;
pref . setSuspendWhenDownloadsComplete ( false ) ;
// Make sure preferences are synced before exiting
if ( suspend )
m_shutdownAct = SUSPEND_COMPUTER ;
else
m_shutdownAct = SHUTDOWN_COMPUTER ;
}
qDebug ( " Exiting the application " ) ;
qApp - > exit ( ) ;
if ( ! ShutdownConfirmDlg : : askForConfirmation ( confirm_msg ) )
return ;
// Actually shut down
if ( suspend | | shutdown ) {
qDebug ( " Preparing for auto-shutdown because all downloads are complete! " ) ;
// Disabling it for next time
pref . setShutdownWhenDownloadsComplete ( false ) ;
pref . setSuspendWhenDownloadsComplete ( false ) ;
// Make sure preferences are synced before exiting
if ( suspend )
m_shutdownAct = SUSPEND_COMPUTER ;
else
m_shutdownAct = SHUTDOWN_COMPUTER ;
}
# endif // DISABLE_GUI
qDebug ( " Exiting the application " ) ;
qApp - > exit ( ) ;
return ;
}
# endif // DISABLE_GUI
}
}
else if ( save_resume_data_alert * p = dynamic_cast < save_resume_data_alert * > ( a . get ( ) ) ) {
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) & & p - > resume_data ) {
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
if ( resume_file . exists ( ) )
fsutils : : forceRemove ( filepath ) ;
qDebug ( " Saving fastresume data in %s " , qPrintable ( filepath ) ) ;
backupPersistentData ( h . hash ( ) , p - > resume_data ) ;
vector < char > out ;
bencode ( back_inserter ( out ) , * p - > resume_data ) ;
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
}
}
else if ( file_renamed_alert * p = dynamic_cast < file_renamed_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
if ( h . num_files ( ) > 1 ) {
// Check if folders were renamed
QStringList old_path_parts = h . orig_filepath_at ( p - > index ) . split ( " / " ) ;
old_path_parts . removeLast ( ) ;
QString old_path = old_path_parts . join ( " / " ) ;
QStringList new_path_parts = fsutils : : fromNativePath ( misc : : toQStringU ( p - > name ) ) . split ( " / " ) ;
new_path_parts . removeLast ( ) ;
if ( ! new_path_parts . isEmpty ( ) & & old_path ! = new_path_parts . join ( " / " ) ) {
qDebug ( " Old_path(%s) != new_path(%s) " , qPrintable ( old_path ) , qPrintable ( new_path_parts . join ( " / " ) ) ) ;
old_path = h . save_path ( ) + " / " + old_path ;
qDebug ( " Detected folder renaming, attempt to delete old folder: %s " , qPrintable ( old_path ) ) ;
QDir ( ) . rmpath ( old_path ) ;
}
} else {
// Single-file torrent
// Renaming a file corresponds to changing the save path
emit savePathChanged ( h ) ;
}
}
else if ( save_resume_data_alert * p = dynamic_cast < save_resume_data_alert * > ( a ) ) {
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) & & p - > resume_data ) {
const QString filepath = torrentBackup . absoluteFilePath ( h . hash ( ) + " .fastresume " ) ;
QFile resume_file ( filepath ) ;
if ( resume_file . exists ( ) )
fsutils : : forceRemove ( filepath ) ;
qDebug ( " Saving fastresume data in %s " , qPrintable ( filepath ) ) ;
backupPersistentData ( h . hash ( ) , p - > resume_data ) ;
vector < char > out ;
bencode ( back_inserter ( out ) , * p - > resume_data ) ;
if ( ! out . empty ( ) & & resume_file . open ( QIODevice : : WriteOnly ) ) {
resume_file . write ( & out [ 0 ] , out . size ( ) ) ;
resume_file . close ( ) ;
}
}
else if ( torrent_deleted_alert * p = dynamic_cast < torrent_deleted_alert * > ( a . get ( ) ) ) {
qDebug ( " A torrent was deleted from the hard disk, attempting to remove the root folder too... " ) ;
QString hash = misc : : toQString ( p - > info_hash ) ;
if ( ! hash . isEmpty ( ) ) {
if ( savePathsToRemove . contains ( hash ) ) {
const QString dirpath = savePathsToRemove . take ( hash ) ;
qDebug ( ) < < " Removing save path: " < < dirpath < < " ... " ;
bool ok = fsutils : : smartRemoveEmptyFolderTree ( dirpath ) ;
Q_UNUSED ( ok ) ;
qDebug ( ) < < " Folder was removed: " < < ok ;
}
else if ( file_renamed_alert * p = dynamic_cast < file_renamed_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
if ( h . num_files ( ) > 1 ) {
// Check if folders were renamed
QStringList old_path_parts = h . orig_filepath_at ( p - > index ) . split ( " / " ) ;
old_path_parts . removeLast ( ) ;
QString old_path = old_path_parts . join ( " / " ) ;
QStringList new_path_parts = fsutils : : fromNativePath ( misc : : toQStringU ( p - > name ) ) . split ( " / " ) ;
new_path_parts . removeLast ( ) ;
if ( ! new_path_parts . isEmpty ( ) & & old_path ! = new_path_parts . join ( " / " ) ) {
qDebug ( " Old_path(%s) != new_path(%s) " , qPrintable ( old_path ) , qPrintable ( new_path_parts . join ( " / " ) ) ) ;
old_path = h . save_path ( ) + " / " + old_path ;
qDebug ( " Detected folder renaming, attempt to delete old folder: %s " , qPrintable ( old_path ) ) ;
QDir ( ) . rmpath ( old_path ) ;
}
} else {
// Fallback
qDebug ( ) < < " hash is empty, use fallback to remove save path " ;
foreach ( const QString & key , savePathsToRemove . keys ( ) ) {
// Attempt to delete
if ( QDir ( ) . rmdir ( savePathsToRemove [ key ] ) ) {
savePathsToRemove . remove ( key ) ;
}
}
// Single-file torrent
// Renaming a file corresponds to changing the save path
emit savePathChanged ( h ) ;
}
}
else if ( storage_moved_alert * p = dynamic_cast < storage_moved_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Attempt to remove old folder if empty
const QString old_save_path = fsutils : : fromNativePath ( TorrentPersistentData : : getPreviousPath ( h . hash ( ) ) ) ;
const QString new_save_path = fsutils : : fromNativePath ( misc : : toQStringU ( p - > path . c_str ( ) ) ) ;
qDebug ( " Torrent moved from %s to %s " , qPrintable ( old_save_path ) , qPrintable ( new_save_path ) ) ;
QDir old_save_dir ( old_save_path ) ;
if ( old_save_dir ! = QDir ( defaultSavePath ) & & old_save_dir ! = QDir ( defaultTempPath ) ) {
qDebug ( " Attempting to remove %s " , qPrintable ( old_save_path ) ) ;
QDir ( ) . rmpath ( old_save_path ) ;
}
if ( defaultTempPath . isEmpty ( ) | | ! new_save_path . startsWith ( defaultTempPath ) ) {
qDebug ( " Storage has been moved, updating save path to %s " , qPrintable ( new_save_path ) ) ;
TorrentPersistentData : : saveSavePath ( h . hash ( ) , new_save_path ) ;
}
else if ( torrent_deleted_alert * p = dynamic_cast < torrent_deleted_alert * > ( a ) ) {
qDebug ( " A torrent was deleted from the hard disk, attempting to remove the root folder too... " ) ;
QString hash = misc : : toQString ( p - > info_hash ) ;
if ( ! hash . isEmpty ( ) ) {
if ( savePathsToRemove . contains ( hash ) ) {
const QString dirpath = savePathsToRemove . take ( hash ) ;
qDebug ( ) < < " Removing save path: " < < dirpath < < " ... " ;
bool ok = fsutils : : smartRemoveEmptyFolderTree ( dirpath ) ;
Q_UNUSED ( ok ) ;
qDebug ( ) < < " Folder was removed: " < < ok ;
}
} else {
// Fallback
qDebug ( ) < < " hash is empty, use fallback to remove save path " ;
foreach ( const QString & key , savePathsToRemove . keys ( ) ) {
// Attempt to delete
if ( QDir ( ) . rmdir ( savePathsToRemove [ key ] ) ) {
savePathsToRemove . remove ( key ) ;
}
emit savePathChanged ( h ) ;
//h.force_recheck();
}
}
else if ( metadata_received_alert * p = dynamic_cast < metadata_received_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
Preferences pref ;
if ( h . is_valid ( ) ) {
QString hash ( h . hash ( ) ) ;
if ( HiddenData : : hasData ( hash ) ) {
HiddenData : : gotMetadata ( hash ) ;
if ( pref . isQueueingSystemEnabled ( ) ) {
//Internally decrease the queue limits to ensure that that other queued items aren't started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
s - > set_settings ( sessionSettings ) ;
}
h . pause ( ) ;
}
qDebug ( " Received metadata for %s " , qPrintable ( h . hash ( ) ) ) ;
// Save metadata
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
if ( ! QFile : : exists ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) )
h . save_torrent_file ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) ;
// Copy the torrent file to the export folder
if ( m_torrentExportEnabled )
exportTorrentFile ( h ) ;
// Append .!qB to incomplete files
if ( appendqBExtension )
appendqBextensionToTorrent ( h , true ) ;
if ( ! HiddenData : : hasData ( hash ) )
emit metadataReceived ( h ) ;
else
emit metadataReceivedHidden ( h ) ;
if ( h . is_paused ( ) & & ! HiddenData : : hasData ( hash ) ) {
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
// and the torrent can be paused when metadata is received
emit pausedTorrent ( h ) ;
}
}
else if ( storage_moved_alert * p = dynamic_cast < storage_moved_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Attempt to remove old folder if empty
const QString old_save_path = fsutils : : fromNativePath ( TorrentPersistentData : : getPreviousPath ( h . hash ( ) ) ) ;
const QString new_save_path = fsutils : : fromNativePath ( misc : : toQStringU ( p - > path . c_str ( ) ) ) ;
qDebug ( " Torrent moved from %s to %s " , qPrintable ( old_save_path ) , qPrintable ( new_save_path ) ) ;
QDir old_save_dir ( old_save_path ) ;
if ( old_save_dir ! = QDir ( defaultSavePath ) & & old_save_dir ! = QDir ( defaultTempPath ) ) {
qDebug ( " Attempting to remove %s " , qPrintable ( old_save_path ) ) ;
QDir ( ) . rmpath ( old_save_path ) ;
}
if ( defaultTempPath . isEmpty ( ) | | ! new_save_path . startsWith ( defaultTempPath ) ) {
qDebug ( " Storage has been moved, updating save path to %s " , qPrintable ( new_save_path ) ) ;
TorrentPersistentData : : saveSavePath ( h . hash ( ) , new_save_path ) ;
}
emit savePathChanged ( h ) ;
//h.force_recheck();
}
else if ( file_error_alert * p = dynamic_cast < file_error_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
h . pause ( ) ;
std : : cerr < < " File Error: " < < p - > message ( ) . c_str ( ) < < std : : endl ;
addConsoleMessage ( tr ( " An I/O error occurred, '%1' paused. " ) . arg ( h . name ( ) ) ) ;
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
if ( h . is_valid ( ) ) {
emit fullDiskError ( h , misc : : toQStringU ( p - > message ( ) ) ) ;
//h.pause();
emit pausedTorrent ( h ) ;
}
else if ( metadata_received_alert * p = dynamic_cast < metadata_received_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
Preferences pref ;
if ( h . is_valid ( ) ) {
QString hash ( h . hash ( ) ) ;
if ( HiddenData : : hasData ( hash ) ) {
HiddenData : : gotMetadata ( hash ) ;
if ( pref . isQueueingSystemEnabled ( ) ) {
//Internally decrease the queue limits to ensure that that other queued items aren't started
libtorrent : : session_settings sessionSettings ( s - > settings ( ) ) ;
int max_downloading = pref . getMaxActiveDownloads ( ) ;
int max_active = pref . getMaxActiveTorrents ( ) ;
if ( max_downloading > - 1 )
sessionSettings . active_downloads = max_downloading + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_downloads = max_downloading ;
if ( max_active > - 1 )
sessionSettings . active_limit = max_active + HiddenData : : getDownloadingSize ( ) ;
else
sessionSettings . active_limit = max_active ;
s - > set_settings ( sessionSettings ) ;
}
h . pause ( ) ;
}
qDebug ( " Received metadata for %s " , qPrintable ( h . hash ( ) ) ) ;
// Save metadata
const QDir torrentBackup ( fsutils : : BTBackupLocation ( ) ) ;
if ( ! QFile : : exists ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) )
h . save_torrent_file ( torrentBackup . absoluteFilePath ( h . hash ( ) + QString ( " .torrent " ) ) ) ;
// Copy the torrent file to the export folder
if ( m_torrentExportEnabled )
exportTorrentFile ( h ) ;
// Append .!qB to incomplete files
if ( appendqBExtension )
appendqBextensionToTorrent ( h , true ) ;
if ( ! HiddenData : : hasData ( hash ) )
emit metadataReceived ( h ) ;
else
emit metadataReceivedHidden ( h ) ;
if ( h . is_paused ( ) & & ! HiddenData : : hasData ( hash ) ) {
// XXX: Unfortunately libtorrent-rasterbar does not send a torrent_paused_alert
// and the torrent can be paused when metadata is received
emit pausedTorrent ( h ) ;
}
}
else if ( file_completed_alert * p = dynamic_cast < file_completed_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
qDebug ( " A file completed download in torrent %s " , qPrintable ( h . name ( ) ) ) ;
if ( appendqBExtension ) {
qDebug ( " appendqBTExtension is true " ) ;
QString name = h . filepath_at ( p - > index ) ;
if ( name . endsWith ( " .!qB " ) ) {
const QString old_name = name ;
name . chop ( 4 ) ;
qDebug ( " Renaming %s to %s " , qPrintable ( old_name ) , qPrintable ( name ) ) ;
h . rename_file ( p - > index , name ) ;
}
}
else if ( file_error_alert * p = dynamic_cast < file_error_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
h . pause ( ) ;
std : : cerr < < " File Error: " < < p - > message ( ) . c_str ( ) < < std : : endl ;
addConsoleMessage ( tr ( " An I/O error occurred, '%1' paused. " ) . arg ( h . name ( ) ) ) ;
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
if ( h . is_valid ( ) ) {
emit fullDiskError ( h , misc : : toQStringU ( p - > message ( ) ) ) ;
//h.pause();
emit pausedTorrent ( h ) ;
}
}
else if ( torrent_paused_alert * p = dynamic_cast < torrent_paused_alert * > ( a . get ( ) ) ) {
if ( p - > handle . is_valid ( ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( ! HiddenData : : hasData ( h . hash ( ) ) ) {
if ( ! h . has_error ( ) )
h . save_resume_data ( ) ;
emit pausedTorrent ( h ) ;
}
}
else if ( file_completed_alert * p = dynamic_cast < file_completed_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
qDebug ( " A file completed download in torrent %s " , qPrintable ( h . name ( ) ) ) ;
if ( appendqBExtension ) {
qDebug ( " appendqBTExtension is true " ) ;
QString name = h . filepath_at ( p - > index ) ;
if ( name . endsWith ( " .!qB " ) ) {
const QString old_name = name ;
name . chop ( 4 ) ;
qDebug ( " Renaming %s to %s " , qPrintable ( old_name ) , qPrintable ( name ) ) ;
h . rename_file ( p - > index , name ) ;
}
}
else if ( tracker_error_alert * p = dynamic_cast < tracker_error_alert * > ( a . get ( ) ) ) {
// Level: fatal
}
else if ( torrent_paused_alert * p = dynamic_cast < torrent_paused_alert * > ( a ) ) {
if ( p - > handle . is_valid ( ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Authentication
if ( p - > status_code ! = 401 ) {
qDebug ( " Received a tracker error for %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = misc : : toQStringU ( p - > msg ) ;
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
} else {
emit trackerAuthenticationRequired ( h ) ;
}
if ( ! HiddenData : : hasData ( h . hash ( ) ) ) {
if ( ! h . has_error ( ) )
h . save_resume_data ( ) ;
emit pausedTorrent ( h ) ;
}
}
else if ( tracker_reply_alert * p = dynamic_cast < tracker_reply_alert * > ( a . get ( ) ) ) {
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " Received a tracker reply from %s (Num_peers=%d) " , p - > url . c_str ( ) , p - > num_peers ) ;
// Connection was successful now. Remove possible old errors
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
}
else if ( tracker_error_alert * p = dynamic_cast < tracker_error_alert * > ( a ) ) {
// Level: fatal
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Authentication
if ( p - > status_code ! = 401 ) {
qDebug ( " Received a tracker error for %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = " " ; // Reset error/warning message
data . num_peers = p - > num_peers ;
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
}
}
else if ( tracker_warning_alert * p = dynamic_cast < tracker_warning_alert * > ( a . get ( ) ) ) {
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Connection was successful now but there is a warning message
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = misc : : toQStringU ( p - > msg ) ; // Store warning message
data . last_message = misc : : toQStringU ( p - > msg ) ;
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
qDebug ( " Received a tracker warning from %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
} else {
emit trackerAuthenticationRequired ( h ) ;
}
}
else if ( portmap_error_alert * p = dynamic_cast < portmap_error_alert * > ( a . get ( ) ) ) {
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping failure, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " red " ) ;
//emit UPnPError(QString(p->msg().c_str()));
}
else if ( tracker_reply_alert * p = dynamic_cast < tracker_reply_alert * > ( a ) ) {
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " Received a tracker reply from %s (Num_peers=%d) " , p - > url . c_str ( ) , p - > num_peers ) ;
// Connection was successful now. Remove possible old errors
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = " " ; // Reset error/warning message
data . num_peers = p - > num_peers ;
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
}
else if ( portmap_alert * p = dynamic_cast < portmap_alert * > ( a . get ( ) ) ) {
qDebug ( " UPnP Success, msg: %s " , p - > message ( ) . c_str ( ) ) ;
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping successful, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " blue " ) ;
//emit UPnPSuccess(QString(p->msg().c_str()));
}
else if ( tracker_warning_alert * p = dynamic_cast < tracker_warning_alert * > ( a ) ) {
const QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
// Connection was successful now but there is a warning message
QHash < QString , TrackerInfos > trackers_data = trackersInfos . value ( h . hash ( ) , QHash < QString , TrackerInfos > ( ) ) ;
const QString tracker_url = misc : : toQString ( p - > url ) ;
TrackerInfos data = trackers_data . value ( tracker_url , TrackerInfos ( tracker_url ) ) ;
data . last_message = misc : : toQStringU ( p - > msg ) ; // Store warning message
trackers_data . insert ( tracker_url , data ) ;
trackersInfos [ h . hash ( ) ] = trackers_data ;
qDebug ( " Received a tracker warning from %s: %s " , p - > url . c_str ( ) , p - > msg . c_str ( ) ) ;
}
else if ( peer_blocked_alert * p = dynamic_cast < peer_blocked_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromLatin1 ( ip . c_str ( ) ) , true ) ;
//emit peerBlocked(QString::fromLatin1(ip.c_str()));
}
}
else if ( portmap_error_alert * p = dynamic_cast < portmap_error_alert * > ( a ) ) {
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping failure, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " red " ) ;
//emit UPnPError(QString(p->msg().c_str()));
}
else if ( portmap_alert * p = dynamic_cast < portmap_alert * > ( a ) ) {
qDebug ( " UPnP Success, msg: %s " , p - > message ( ) . c_str ( ) ) ;
addConsoleMessage ( tr ( " UPnP/NAT-PMP: Port mapping successful, message: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , " blue " ) ;
//emit UPnPSuccess(QString(p->msg().c_str()));
}
else if ( peer_blocked_alert * p = dynamic_cast < peer_blocked_alert * > ( a ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromLatin1 ( ip . c_str ( ) ) , true ) ;
//emit peerBlocked(QString::fromLatin1(ip.c_str()));
}
else if ( peer_ban_alert * p = dynamic_cast < peer_ban_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . address ( ) . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromLatin1 ( ip . c_str ( ) ) , false ) ;
//emit peerBlocked(QString::fromLatin1(ip.c_str()));
}
}
else if ( peer_ban_alert * p = dynamic_cast < peer_ban_alert * > ( a ) ) {
boost : : system : : error_code ec ;
string ip = p - > ip . address ( ) . to_string ( ec ) ;
if ( ! ec ) {
addPeerBanMessage ( QString : : fromLatin1 ( ip . c_str ( ) ) , false ) ;
//emit peerBlocked(QString::fromLatin1(ip.c_str()));
}
else if ( fastresume_rejected_alert * p = dynamic_cast < fastresume_rejected_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " /! \\ Fast resume failed for %s, reason: %s " , qPrintable ( h . name ( ) ) , p - > message ( ) . c_str ( ) ) ;
if ( p - > error . value ( ) = = 134 & & TorrentPersistentData : : isSeed ( h . hash ( ) ) & & h . has_missing_files ( ) ) {
const QString hash = h . hash ( ) ;
// Mismatching file size (files were probably moved
addConsoleMessage ( tr ( " File sizes mismatch for torrent %1, pausing it. " ) . arg ( h . name ( ) ) ) ;
TorrentPersistentData : : setErrorState ( hash , true ) ;
pauseTorrent ( hash ) ;
} else {
addConsoleMessage ( tr ( " Fast resume data was rejected for torrent %1, checking again... " ) . arg ( h . name ( ) ) , QString : : fromUtf8 ( " red " ) ) ;
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
}
}
else if ( fastresume_rejected_alert * p = dynamic_cast < fastresume_rejected_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
qDebug ( " /! \\ Fast resume failed for %s, reason: %s " , qPrintable ( h . name ( ) ) , p - > message ( ) . c_str ( ) ) ;
if ( p - > error . value ( ) = = 134 & & TorrentPersistentData : : isSeed ( h . hash ( ) ) & & h . has_missing_files ( ) ) {
const QString hash = h . hash ( ) ;
// Mismatching file size (files were probably moved
addConsoleMessage ( tr ( " File sizes mismatch for torrent %1, pausing it. " ) . arg ( h . name ( ) ) ) ;
TorrentPersistentData : : setErrorState ( hash , true ) ;
pauseTorrent ( hash ) ;
} else {
addConsoleMessage ( tr ( " Fast resume data was rejected for torrent %1, checking again... " ) . arg ( h . name ( ) ) , QString : : fromUtf8 ( " red " ) ) ;
addConsoleMessage ( tr ( " Reason: %1 " ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) ) ;
}
}
else if ( url_seed_alert * p = dynamic_cast < url_seed_alert * > ( a . get ( ) ) ) {
addConsoleMessage ( tr ( " Url seed lookup failed for url: %1, message: %2 " ) . arg ( misc : : toQString ( p - > url ) ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , QString : : fromUtf8 ( " red " ) ) ;
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
}
else if ( listen_succeeded_alert * p = dynamic_cast < listen_succeeded_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
QString proto = " TCP " ;
}
else if ( url_seed_alert * p = dynamic_cast < url_seed_alert * > ( a ) ) {
addConsoleMessage ( tr ( " Url seed lookup failed for url: %1, message: %2 " ) . arg ( misc : : toQString ( p - > url ) ) . arg ( misc : : toQStringU ( p - > message ( ) ) ) , QString : : fromUtf8 ( " red " ) ) ;
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
}
else if ( listen_succeeded_alert * p = dynamic_cast < listen_succeeded_alert * > ( a ) ) {
boost : : system : : error_code ec ;
QString proto = " TCP " ;
# if LIBTORRENT_VERSION_NUM >= 10000
if ( p - > sock_type = = listen_succeeded_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp_ssl )
proto = " TCP_SSL " ;
if ( p - > sock_type = = listen_succeeded_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_succeeded_alert : : tcp_ssl )
proto = " TCP_SSL " ;
# endif
qDebug ( ) < < " Successfully listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent is successfully listening on interface %1 port: %2/%3 " , " e.g: qBittorrent is successfully listening on interface 192.168.0.1 port: TCP/6881 " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) , " blue " ) ;
// Force reannounce on all torrents because some trackers blacklist some ports
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
std : : vector < torrent_handle > : : iterator it = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator itend = torrents . end ( ) ;
for ( ; it ! = itend ; + + it ) {
it - > force_reannounce ( ) ;
}
qDebug ( ) < < " Successfully listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent is successfully listening on interface %1 port: %2/%3 " , " e.g: qBittorrent is successfully listening on interface 192.168.0.1 port: TCP/6881 " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) , " blue " ) ;
// Force reannounce on all torrents because some trackers blacklist some ports
std : : vector < torrent_handle > torrents = s - > get_torrents ( ) ;
std : : vector < torrent_handle > : : iterator it = torrents . begin ( ) ;
std : : vector < torrent_handle > : : iterator itend = torrents . end ( ) ;
for ( ; it ! = itend ; + + it ) {
it - > force_reannounce ( ) ;
}
else if ( listen_failed_alert * p = dynamic_cast < listen_failed_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
QString proto = " TCP " ;
}
else if ( listen_failed_alert * p = dynamic_cast < listen_failed_alert * > ( a ) ) {
boost : : system : : error_code ec ;
QString proto = " TCP " ;
# if LIBTORRENT_VERSION_NUM >= 10000
if ( p - > sock_type = = listen_failed_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp_ssl )
proto = " TCP_SSL " ;
else if ( p - > sock_type = = listen_failed_alert : : i2p )
proto = " I2P " ;
else if ( p - > sock_type = = listen_failed_alert : : socks5 )
proto = " SOCKS5 " ;
if ( p - > sock_type = = listen_failed_alert : : udp )
proto = " UDP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp )
proto = " TCP " ;
else if ( p - > sock_type = = listen_failed_alert : : tcp_ssl )
proto = " TCP_SSL " ;
else if ( p - > sock_type = = listen_failed_alert : : i2p )
proto = " I2P " ;
else if ( p - > sock_type = = listen_failed_alert : : socks5 )
proto = " SOCKS5 " ;
# endif
qDebug ( ) < < " Failed listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent failed listening on interface %1 port: %2/%3. Reason: %4 " , " e.g: qBittorrent failed listening on interface 192.168.0.1 port: TCP/6881. Reason: already in use " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) . arg ( misc : : toQStringU ( p - > error . message ( ) ) ) , " red " ) ;
}
else if ( torrent_checked_alert * p = dynamic_cast < torrent_checked_alert * > ( a . get ( ) ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " %s have just finished checking " , qPrintable ( hash ) ) ;
// Save seed status
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Move to temp directory if necessary
if ( ! h . is_seed ( ) & & ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( h . hash ( ) ) ) ;
if ( current_dir = = save_dir ) {
qDebug ( " Moving the torrent to the temp directory... " ) ;
QString torrent_tmp_path = defaultTempPath ;
h . move_storage ( torrent_tmp_path ) ;
}
}
emit torrentFinishedChecking ( h ) ;
if ( torrentsToPausedAfterChecking . contains ( hash ) ) {
torrentsToPausedAfterChecking . removeOne ( hash ) ;
h . pause ( ) ;
emit pausedTorrent ( h ) ;
qDebug ( ) < < " Failed listening on " < < proto < < p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) < < " / " < < p - > endpoint . port ( ) ;
addConsoleMessage ( tr ( " qBittorrent failed listening on interface %1 port: %2/%3. Reason: %4 " , " e.g: qBittorrent failed listening on interface 192.168.0.1 port: TCP/6881. Reason: already in use " ) . arg ( p - > endpoint . address ( ) . to_string ( ec ) . c_str ( ) ) . arg ( proto ) . arg ( QString : : number ( p - > endpoint . port ( ) ) ) . arg ( misc : : toQStringU ( p - > error . message ( ) ) ) , " red " ) ;
}
else if ( torrent_checked_alert * p = dynamic_cast < torrent_checked_alert * > ( a ) ) {
QTorrentHandle h ( p - > handle ) ;
if ( h . is_valid ( ) ) {
const QString hash = h . hash ( ) ;
qDebug ( " %s have just finished checking " , qPrintable ( hash ) ) ;
// Save seed status
TorrentPersistentData : : saveSeedStatus ( h ) ;
// Move to temp directory if necessary
if ( ! h . is_seed ( ) & & ! defaultTempPath . isEmpty ( ) ) {
// Check if directory is different
const QDir current_dir ( h . save_path ( ) ) ;
const QDir save_dir ( getSavePath ( h . hash ( ) ) ) ;
if ( current_dir = = save_dir ) {
qDebug ( " Moving the torrent to the temp directory... " ) ;
QString torrent_tmp_path = defaultTempPath ;
h . move_storage ( torrent_tmp_path ) ;
}
}
emit torrentFinishedChecking ( h ) ;
if ( torrentsToPausedAfterChecking . contains ( hash ) ) {
torrentsToPausedAfterChecking . removeOne ( hash ) ;
h . pause ( ) ;
emit pausedTorrent ( h ) ;
}
}
else if ( external_ip_alert * p = dynamic_cast < external_ip_alert * > ( a . get ( ) ) ) {
boost : : system : : error_code ec ;
addConsoleMessage ( tr ( " External IP: %1 " , " e.g. External IP: 192.168.0.1 " ) . arg ( p - > external_address . to_string ( ec ) . c_str ( ) ) , " blue " ) ;
}
} catch ( const std : : exception & e ) {
qWarning ( ) < < " Caught exception in readAlerts(): " < < e . what ( ) ;
}
a = s - > pop_alert ( ) ;
else if ( external_ip_alert * p = dynamic_cast < external_ip_alert * > ( a ) ) {
boost : : system : : error_code ec ;
addConsoleMessage ( tr ( " External IP: %1 " , " e.g. External IP: 192.168.0.1 " ) . arg ( p - > external_address . to_string ( ec ) . c_str ( ) ) , " blue " ) ;
}
} catch ( const std : : exception & e ) {
qWarning ( ) < < " Caught exception in readAlerts(): " < < e . what ( ) ;
}
}