1
0
mirror of https://github.com/d47081/qBittorrent.git synced 2025-02-02 09:55:55 +00:00

Handle exceptions in readAlerts()

This commit is contained in:
Christophe Dumez 2012-08-10 10:04:28 +03:00
parent e73bff817c
commit 81b0a7f785

View File

@ -2159,388 +2159,393 @@ void QBtSession::readAlerts() {
// look at session alerts and display some infos // look at session alerts and display some infos
std::auto_ptr<alert> a = s->pop_alert(); std::auto_ptr<alert> a = s->pop_alert();
while (a.get()) { while (a.get()) {
if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get())) { try {
QTorrentHandle h(p->handle); if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get())) {
if (h.is_valid()) { QTorrentHandle h(p->handle);
const QString hash = h.hash(); if (h.is_valid()) {
qDebug("Got a torrent finished alert for %s", qPrintable(h.name())); const QString hash = h.hash();
// Remove .!qB extension if necessary qDebug("Got a torrent finished alert for %s", qPrintable(h.name()));
if (appendqBExtension) // Remove .!qB extension if necessary
appendqBextensionToTorrent(h, false); if (appendqBExtension)
appendqBextensionToTorrent(h, false);
const bool was_already_seeded = TorrentPersistentData::isSeed(hash); const bool was_already_seeded = TorrentPersistentData::isSeed(hash);
qDebug("Was already seeded: %d", was_already_seeded); qDebug("Was already seeded: %d", was_already_seeded);
if (!was_already_seeded) { if (!was_already_seeded) {
h.save_resume_data(); h.save_resume_data();
qDebug("Checking if the torrent contains torrent files to download"); qDebug("Checking if the torrent contains torrent files to download");
// Check if there are torrent files inside // Check if there are torrent files inside
for (int i=0; i<h.num_files(); ++i) { for (int i=0; i<h.num_files(); ++i) {
const QString torrent_relpath = h.filepath_at(i).replace("\\", "/"); const QString torrent_relpath = h.filepath_at(i).replace("\\", "/");
qDebug() << "File path:" << torrent_relpath; qDebug() << "File path:" << torrent_relpath;
if (torrent_relpath.endsWith(".torrent", Qt::CaseInsensitive)) { if (torrent_relpath.endsWith(".torrent", Qt::CaseInsensitive)) {
qDebug("Found possible recursive torrent download."); qDebug("Found possible recursive torrent download.");
const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath; const QString torrent_fullpath = h.save_path()+"/"+torrent_relpath;
qDebug("Full subtorrent path is %s", qPrintable(torrent_fullpath)); qDebug("Full subtorrent path is %s", qPrintable(torrent_fullpath));
try { try {
boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_fullpath.toUtf8().constData()); boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_fullpath.toUtf8().constData());
if (t->is_valid()) { if (t->is_valid()) {
qDebug("emitting recursiveTorrentDownloadPossible()"); qDebug("emitting recursiveTorrentDownloadPossible()");
emit recursiveTorrentDownloadPossible(h); emit recursiveTorrentDownloadPossible(h);
break; break;
}
} catch(std::exception&) {
qDebug("Caught error loading torrent");
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
QString displayed_path = torrent_fullpath;
displayed_path.replace("/", "\\");
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(displayed_path), QString::fromUtf8("red"));
#else
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red"));
#endif
} }
} catch(std::exception&) {
qDebug("Caught error loading torrent");
#if defined(Q_WS_WIN) || defined(Q_OS_OS2)
QString displayed_path = torrent_fullpath;
displayed_path.replace("/", "\\");
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(displayed_path), QString::fromUtf8("red"));
#else
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red"));
#endif
} }
} }
} // Move to download directory if necessary
// Move to download directory if necessary if (!defaultTempPath.isEmpty()) {
if (!defaultTempPath.isEmpty()) { // Check if directory is different
// Check if directory is different const QDir current_dir(h.save_path());
const QDir current_dir(h.save_path()); const QDir save_dir(getSavePath(hash));
const QDir save_dir(getSavePath(hash)); if (current_dir != save_dir) {
if (current_dir != save_dir) { qDebug("Moving torrent from the temp folder");
qDebug("Moving torrent from the temp folder"); h.move_storage(save_dir.absolutePath());
h.move_storage(save_dir.absolutePath()); }
} }
} // Remember finished state
// Remember finished state qDebug("Saving seed status");
qDebug("Saving seed status"); TorrentPersistentData::saveSeedStatus(h);
TorrentPersistentData::saveSeedStatus(h); // Recheck if the user asked to
// Recheck if the user asked to Preferences pref;
Preferences pref; if (pref.recheckTorrentsOnCompletion()) {
if (pref.recheckTorrentsOnCompletion()) { h.force_recheck();
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, will_shutdown);
// 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)) qDebug("Emitting finishedTorrent() signal");
emit finishedTorrent(h);
qDebug("Received finished alert for %s", qPrintable(h.name()));
#ifndef DISABLE_GUI
bool will_shutdown = (pref.shutdownWhenDownloadsComplete() ||
pref.shutdownqBTWhenDownloadsComplete() ||
pref.suspendWhenDownloadsComplete())
&& !hasDownloadingTorrents();
#else
bool will_shutdown = false;
#endif
// AutoRun program
if (pref.isAutoRunEnabled())
autoRunExternalProgram(h, will_shutdown);
// 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();
return; 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"); #endif // DISABLE_GUI
qApp->exit();
return;
} }
#endif // DISABLE_GUI
} }
} }
} else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) {
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get())) { const QDir torrentBackup(fsutils::BTBackupLocation());
const QDir torrentBackup(fsutils::BTBackupLocation()); const QTorrentHandle h(p->handle);
const QTorrentHandle h(p->handle); if (h.is_valid() && p->resume_data) {
if (h.is_valid() && p->resume_data) { const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume");
const QString filepath = torrentBackup.absoluteFilePath(h.hash()+".fastresume"); QFile resume_file(filepath);
QFile resume_file(filepath); if (resume_file.exists())
if (resume_file.exists()) fsutils::forceRemove(filepath);
fsutils::forceRemove(filepath); qDebug("Saving fastresume data in %s", qPrintable(filepath));
qDebug("Saving fastresume data in %s", qPrintable(filepath)); vector<char> out;
vector<char> out; bencode(back_inserter(out), *p->resume_data);
bencode(back_inserter(out), *p->resume_data); if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) {
if (!out.empty() && resume_file.open(QIODevice::WriteOnly)) { resume_file.write(&out[0], out.size());
resume_file.write(&out[0], out.size()); resume_file.close();
resume_file.close(); }
} }
} }
} else if (file_renamed_alert* p = dynamic_cast<file_renamed_alert*>(a.get())) {
else if (file_renamed_alert* p = dynamic_cast<file_renamed_alert*>(a.get())) { QTorrentHandle h(p->handle);
QTorrentHandle h(p->handle); if (h.is_valid()) {
if (h.is_valid()) { if (h.num_files() > 1) {
if (h.num_files() > 1) { // Check if folders were renamed
// Check if folders were renamed QStringList old_path_parts = h.orig_filepath_at(p->index).split("/");
QStringList old_path_parts = h.orig_filepath_at(p->index).split("/"); old_path_parts.removeLast();
old_path_parts.removeLast(); QString old_path = old_path_parts.join("/");
QString old_path = old_path_parts.join("/"); QStringList new_path_parts = misc::toQStringU(p->name).split("/");
QStringList new_path_parts = misc::toQStringU(p->name).split("/"); new_path_parts.removeLast();
new_path_parts.removeLast(); if (!new_path_parts.isEmpty() && old_path != new_path_parts.join("/")) {
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("/")));
qDebug("Old_path(%s) != new_path(%s)", qPrintable(old_path), qPrintable(new_path_parts.join("/"))); old_path = h.save_path()+"/"+old_path;
old_path = h.save_path()+"/"+old_path; qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(old_path));
qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(old_path)); QDir().rmpath(old_path);
QDir().rmpath(old_path); }
} else {
// Single-file torrent
// Renaming a file corresponds to changing the save path
emit savePathChanged(h);
}
}
}
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 { } else {
// Single-file torrent // Fallback
// Renaming a file corresponds to changing the save path qDebug() << "hash is empty, use fallback to remove save path";
emit savePathChanged(h); foreach (const QString& key, savePathsToRemove.keys()) {
} // Attempt to delete
} if (QDir().rmdir(savePathsToRemove[key])) {
} savePathsToRemove.remove(key);
else if (torrent_deleted_alert* p = dynamic_cast<torrent_deleted_alert*>(a.get())) { }
qDebug("A torrent was deleted from the hard disk, attempting to remove the root folder too...");
QString hash = misc::toQString(p->info_hash);
if (!hash.isEmpty()) {
if (savePathsToRemove.contains(hash)) {
const QString dirpath = savePathsToRemove.take(hash);
qDebug() << "Removing save path: " << dirpath << "...";
bool ok = fsutils::smartRemoveEmptyFolderTree(dirpath);
Q_UNUSED(ok);
qDebug() << "Folder was removed: " << ok;
}
} else {
// Fallback
qDebug() << "hash is empty, use fallback to remove save path";
foreach (const QString& key, savePathsToRemove.keys()) {
// Attempt to delete
if (QDir().rmdir(savePathsToRemove[key])) {
savePathsToRemove.remove(key);
} }
} }
} }
} else if (storage_moved_alert* p = dynamic_cast<storage_moved_alert*>(a.get())) {
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 = TorrentPersistentData::getPreviousPath(h.hash());
const QString new_save_path = 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 (metadata_received_alert* p = dynamic_cast<metadata_received_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if (h.is_valid()) {
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 (torrentExport)
exportTorrentFile(h);
// Append .!qB to incomplete files
if (appendqBExtension)
appendqBextensionToTorrent(h, true);
emit metadataReceived(h);
if (h.is_paused()) {
// 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_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 occured, '%1' paused.").arg(h.name()));
addConsoleMessage(tr("Reason: %1").arg(misc::toQString(p->message())));
if (h.is_valid()) {
emit fullDiskError(h, misc::toQString(p->message()));
//h.pause();
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 (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
if (p->handle.is_valid()) {
QTorrentHandle h(p->handle); QTorrentHandle h(p->handle);
if (!h.has_error()) if (h.is_valid()) {
h.save_resume_data(); // Attempt to remove old folder if empty
emit pausedTorrent(h); const QString old_save_path = TorrentPersistentData::getPreviousPath(h.hash());
const QString new_save_path = 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 (metadata_received_alert* p = dynamic_cast<metadata_received_alert*>(a.get())) {
else if (tracker_error_alert* p = dynamic_cast<tracker_error_alert*>(a.get())) { QTorrentHandle h(p->handle);
// Level: fatal if (h.is_valid()) {
QTorrentHandle h(p->handle); qDebug("Received metadata for %s", qPrintable(h.hash()));
if (h.is_valid()) { // Save metadata
// Authentication const QDir torrentBackup(fsutils::BTBackupLocation());
if (p->status_code != 401) { if (!QFile::exists(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent"))))
qDebug("Received a tracker error for %s: %s", p->url.c_str(), p->msg.c_str()); h.save_torrent_file(torrentBackup.absoluteFilePath(h.hash()+QString(".torrent")));
const QString tracker_url = misc::toQString(p->url); // Copy the torrent file to the export folder
if (torrentExport)
exportTorrentFile(h);
// Append .!qB to incomplete files
if (appendqBExtension)
appendqBextensionToTorrent(h, true);
emit metadataReceived(h);
if (h.is_paused()) {
// 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_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 occured, '%1' paused.").arg(h.name()));
addConsoleMessage(tr("Reason: %1").arg(misc::toQString(p->message())));
if (h.is_valid()) {
emit fullDiskError(h, misc::toQString(p->message()));
//h.pause();
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 (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
if (p->handle.is_valid()) {
QTorrentHandle h(p->handle);
if (!h.has_error())
h.save_resume_data();
emit pausedTorrent(h);
}
}
else if (tracker_error_alert* p = dynamic_cast<tracker_error_alert*>(a.get())) {
// 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);
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::toQString(p->msg);
trackers_data.insert(tracker_url, data);
trackersInfos[h.hash()] = trackers_data;
} else {
emit trackerAuthenticationRequired(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>()); 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)); TrackerInfos data = trackers_data.value(tracker_url, TrackerInfos(tracker_url));
data.last_message = misc::toQString(p->msg); data.last_message = ""; // Reset error/warning message
data.num_peers = p->num_peers;
trackers_data.insert(tracker_url, data); trackers_data.insert(tracker_url, data);
trackersInfos[h.hash()] = trackers_data; trackersInfos[h.hash()] = trackers_data;
} else { }
emit trackerAuthenticationRequired(h); } 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::toQString(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 (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get())) { addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(misc::toQString(p->message())), "red");
const QTorrentHandle h(p->handle); //emit UPnPError(QString(p->msg().c_str()));
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 (tracker_warning_alert* p = dynamic_cast<tracker_warning_alert*>(a.get())) { else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
const QTorrentHandle h(p->handle); qDebug("UPnP Success, msg: %s", p->message().c_str());
if (h.is_valid()) { addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(misc::toQString(p->message())), "blue");
// Connection was successful now but there is a warning message //emit UPnPSuccess(QString(p->msg().c_str()));
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::toQString(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())) {
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) { boost::system::error_code ec;
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(misc::toQString(p->message())), "red"); string ip = p->ip.to_string(ec);
//emit UPnPError(QString(p->msg().c_str())); if (!ec) {
} addPeerBanMessage(QString::fromAscii(ip.c_str()), true);
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) { //emit peerBlocked(QString::fromAscii(ip.c_str()));
qDebug("UPnP Success, msg: %s", p->message().c_str());
addConsoleMessage(tr("UPnP/NAT-PMP: Port mapping successful, message: %1").arg(misc::toQString(p->message())), "blue");
//emit UPnPSuccess(QString(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::fromAscii(ip.c_str()), true);
//emit peerBlocked(QString::fromAscii(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::fromAscii(ip.c_str()), false);
//emit peerBlocked(QString::fromAscii(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::toQString(p->message())));
} }
} }
} else if (peer_ban_alert* p = dynamic_cast<peer_ban_alert*>(a.get())) {
else if (url_seed_alert* p = dynamic_cast<url_seed_alert*>(a.get())) { boost::system::error_code ec;
addConsoleMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(misc::toQString(p->url)).arg(misc::toQString(p->message())), QString::fromUtf8("red")); string ip = p->ip.address().to_string(ec);
//emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str())); if (!ec) {
} addPeerBanMessage(QString::fromAscii(ip.c_str()), false);
else if (listen_succeeded_alert *p = dynamic_cast<listen_succeeded_alert*>(a.get())) { //emit peerBlocked(QString::fromAscii(ip.c_str()));
boost::system::error_code ec; }
qDebug() << "Sucessfully listening on" << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port();
// 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();
} }
emit listenSucceeded(); else if (fastresume_rejected_alert* p = dynamic_cast<fastresume_rejected_alert*>(a.get())) {
} QTorrentHandle h(p->handle);
else if (torrent_checked_alert* p = dynamic_cast<torrent_checked_alert*>(a.get())) { if (h.is_valid()) {
QTorrentHandle h(p->handle); qDebug("/!\\ Fast resume failed for %s, reason: %s", qPrintable(h.name()), p->message().c_str());
if (h.is_valid()) { if (p->error.value() == 134 && TorrentPersistentData::isSeed(h.hash()) && h.has_missing_files()) {
const QString hash = h.hash(); const QString hash = h.hash();
qDebug("%s have just finished checking", qPrintable(hash)); // Mismatching file size (files were probably moved
// Save seed status addConsoleMessage(tr("File sizes mismatch for torrent %1, pausing it.").arg(h.name()));
TorrentPersistentData::saveSeedStatus(h); TorrentPersistentData::setErrorState(hash, true);
// Move to temp directory if necessary pauseTorrent(hash);
if (!h.is_seed() && !defaultTempPath.isEmpty()) { } else {
// Check if directory is different addConsoleMessage(tr("Fast resume data was rejected for torrent %1, checking again...").arg(h.name()), QString::fromUtf8("red"));
const QDir current_dir(h.save_path()); addConsoleMessage(tr("Reason: %1").arg(misc::toQString(p->message())));
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.replace("\\", "/");
h.move_storage(torrent_tmp_path);
} }
} }
emit torrentFinishedChecking(h); }
if (torrentsToPausedAfterChecking.contains(hash)) { else if (url_seed_alert* p = dynamic_cast<url_seed_alert*>(a.get())) {
torrentsToPausedAfterChecking.removeOne(hash); addConsoleMessage(tr("Url seed lookup failed for url: %1, message: %2").arg(misc::toQString(p->url)).arg(misc::toQString(p->message())), QString::fromUtf8("red"));
h.pause(); //emit urlSeedProblem(QString::fromUtf8(p->url.c_str()), QString::fromUtf8(p->msg().c_str()));
emit pausedTorrent(h); }
else if (listen_succeeded_alert *p = dynamic_cast<listen_succeeded_alert*>(a.get())) {
boost::system::error_code ec;
qDebug() << "Sucessfully listening on" << p->endpoint.address().to_string(ec).c_str() << "/" << p->endpoint.port();
// 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();
}
emit listenSucceeded();
}
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.replace("\\", "/");
h.move_storage(torrent_tmp_path);
}
}
emit torrentFinishedChecking(h);
if (torrentsToPausedAfterChecking.contains(hash)) {
torrentsToPausedAfterChecking.removeOne(hash);
h.pause();
emit pausedTorrent(h);
}
} }
} }
} catch (const std::exception& e) {
qWarning() << "Caught exception in readAlerts(): " << e.what();
} }
a = s->pop_alert(); a = s->pop_alert();
} }
} }