diff --git a/Changelog b/Changelog index 46b33c189..b1ede14b9 100644 --- a/Changelog +++ b/Changelog @@ -5,8 +5,11 @@ - FEATURE: Allow to open torrent destination folder - FEATURE: Real progress bar in torrent properties that displays downloaded pieces - FEATURE: Allow to buy downloads using ShareMonkey + - FEATURE: Display if UPnP/NAT-PMP was successful or not + - FEATURE: Threadified torrent creation - BUGFIX: Do not display seeds number in seeding list (always 0) - COSMETIC: Do not display progress bar in seeding list (always 100%) + - COSMETIC: Added a progress bar for torrent creation * Unknown - Christophe Dumez - v1.0.0 - FEATURE: Based on new libtorrent v0.13 diff --git a/src/bittorrent.cpp b/src/bittorrent.cpp index 19a5aa4f2..f28c2c4a5 100644 --- a/src/bittorrent.cpp +++ b/src/bittorrent.cpp @@ -1158,6 +1158,13 @@ void bittorrent::readAlerts() { } } } + else if (portmap_error_alert* p = dynamic_cast(a.get())) { + emit UPnPError(QString(p->msg().c_str())); + } + else if (portmap_alert* p = dynamic_cast(a.get())) { + qDebug("UPnP Success, msg: %s", p->msg().c_str()); + emit UPnPSuccess(); + } else if (peer_blocked_alert* p = dynamic_cast(a.get())) { emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str())); } diff --git a/src/bittorrent.h b/src/bittorrent.h index 01896a421..dd2453f9e 100644 --- a/src/bittorrent.h +++ b/src/bittorrent.h @@ -168,6 +168,8 @@ class bittorrent : public QObject{ void urlSeedProblem(QString url, QString msg); void torrentFinishedChecking(QString hash); void torrent_deleted(QString hash, QString fileName, bool finished); + void UPnPError(QString msg); + void UPnPSuccess(); }; #endif diff --git a/src/createtorrent.ui b/src/createtorrent.ui index 1e1cdf12f..349a33aad 100644 --- a/src/createtorrent.ui +++ b/src/createtorrent.ui @@ -6,7 +6,7 @@ 0 0 592 - 590 + 655 @@ -477,6 +477,20 @@ + + + + Progress: + + + + + + + 0 + + + diff --git a/src/createtorrent_imp.cpp b/src/createtorrent_imp.cpp index 6dfae9ef2..eb3e2f40c 100644 --- a/src/createtorrent_imp.cpp +++ b/src/createtorrent_imp.cpp @@ -44,9 +44,17 @@ using namespace boost::filesystem; createtorrent::createtorrent(QWidget *parent): QDialog(parent){ setupUi(this); setAttribute(Qt::WA_DeleteOnClose); + creatorThread = new torrentCreatorThread(); + connect(creatorThread, SIGNAL(creationSuccess(QString)), this, SLOT(handleCreationSucess(QString))); + connect(creatorThread, SIGNAL(creationFailure(QString)), this, SLOT(handleCreationFailure(QString))); + connect(creatorThread, SIGNAL(updateProgress(int)), this, SLOT(updateProgressBar(int))); show(); } +createtorrent::~createtorrent() { + delete creatorThread; +} + void createtorrent::on_addFolder_button_clicked(){ QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly); if(!dir.isEmpty()) @@ -162,26 +170,70 @@ void createtorrent::on_createButton_clicked(){ } else { return; } + QStringList url_seeds = allItems(URLSeeds_list); + QString comment = txt_comment->toPlainText(); + creatorThread->create(input, destination, trackers, url_seeds, comment, check_private->isChecked(), getPieceSize()); +} + +void createtorrent::handleCreationFailure(QString msg) { + QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(msg)); + hide(); +} + +void createtorrent::handleCreationSuccess(QString path, const char* branch_path, QString hash) { + if(checkStartSeeding->isChecked()) { + // Create save path file + QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+hash+QString::fromUtf8(".savepath")); + savepath_file.open(QIODevice::WriteOnly | QIODevice::Text); + savepath_file.write(branch_path); + savepath_file.close(); + emit torrent_to_seed(path); + } + QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+path); + hide(); +} + +void createtorrent::updateProgressBar(int progress) { + progressBar->setValue(progress); +} + +// +// Torrent Creator Thread +// + +void torrentCreatorThread::create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size) { + input_path = _input_path; + save_path = _save_path; + trackers = _trackers; + url_seeds = _url_seeds; + comment = _comment; + is_private = _is_private; + piece_size = _piece_size; + abort = false; + start(); +} + +void torrentCreatorThread::run() { + emit updateProgress(0); char const* creator_str = "qBittorrent "VERSION; try { boost::intrusive_ptr t(new torrent_info); - ofstream out(complete(path((const char*)destination.toUtf8())), std::ios_base::binary); + ofstream out(complete(path((const char*)save_path.toUtf8())), std::ios_base::binary); // Adding files to the torrent - path full_path = complete(path(input.toUtf8().data())); + path full_path = complete(path(input_path.toUtf8().data())); add_files(*t, full_path.branch_path(), full_path.leaf()); + if(abort) return; // Set piece size - int piece_size = getPieceSize(); t->set_piece_size(piece_size); // Add url seeds - QStringList urlSeeds = allItems(URLSeeds_list); QString seed; - foreach(seed, urlSeeds){ + foreach(seed, url_seeds){ t->add_url_seed(seed.toUtf8().data()); } for(int i=0; iadd_tracker(trackers.at(i).toUtf8().data()); } - + if(abort) return; // calculate the hash for all pieces file_pool fp; boost::scoped_ptr st(default_storage_constructor(t, full_path.branch_path(), fp)); @@ -191,34 +243,26 @@ void createtorrent::on_createButton_clicked(){ st->read(&buf[0], i, 0, t->piece_size(i)); hasher h(&buf[0], t->piece_size(i)); t->set_hash(i, h.final()); + emit updateProgress((int)(i*100./(float)num)); + if(abort) return; } // Set qBittorrent as creator and add user comment to // torrent_info structure t->set_creator(creator_str); - t->set_comment((const char*)txt_comment->toPlainText().toUtf8()); + t->set_comment((const char*)comment.toUtf8()); // Is private ? - if(check_private->isChecked()){ + if(is_private){ t->set_priv(true); } + if(abort) return; // create the torrent and print it to out entry e = t->create_torrent(); libtorrent::bencode(std::ostream_iterator(out), e); out.flush(); - if(checkStartSeeding->isChecked()) { - // Create save path file - QFile savepath_file(misc::qBittorrentPath()+QString::fromUtf8("BT_backup")+QDir::separator()+misc::toQString(t->info_hash())+QString::fromUtf8(".savepath")); - savepath_file.open(QIODevice::WriteOnly | QIODevice::Text); - savepath_file.write(full_path.branch_path().string().c_str()); - savepath_file.close(); - emit torrent_to_seed(destination); - } + emit updateProgress(100); + emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash())); } catch (std::exception& e){ - std::cerr << e.what() << "\n"; - QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(QString::fromUtf8(e.what()))); - hide(); - return; + emit creationFailure(QString::fromUtf8(e.what())); } - hide(); - QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+destination); } diff --git a/src/createtorrent_imp.h b/src/createtorrent_imp.h index d8ff04157..15a19c228 100644 --- a/src/createtorrent_imp.h +++ b/src/createtorrent_imp.h @@ -22,13 +22,48 @@ #ifndef CREATE_TORRENT_IMP_H #define CREATE_TORRENT_IMP_H +#include + #include "ui_createtorrent.h" +class torrentCreatorThread : public QThread { + Q_OBJECT + + QString input_path; + QString save_path; + QStringList trackers; + QStringList url_seeds; + QString comment; + bool is_private; + int piece_size; + bool abort; + + public: + torrentCreatorThread() {} + ~torrentCreatorThread() { + abort = true; + wait(); + } + void create(QString _input_path, QString _save_path, QStringList _trackers, QStringList _url_seeds, QString _comment, bool _is_private, int _piece_size); + + protected: + void run(); + + signals: + void creationFailure(QString msg); + void creationSuccess(QString path, const char* branch_path, QString hash); + void updateProgress(int progress); +}; + class createtorrent : public QDialog, private Ui::createTorrentDialog{ Q_OBJECT + private: + torrentCreatorThread *creatorThread; + public: createtorrent(QWidget *parent = 0); + ~createtorrent(); QStringList allItems(QListWidget *list); int getPieceSize() const; @@ -43,6 +78,9 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{ void on_removeTracker_button_clicked(); void on_addURLSeed_button_clicked(); void on_removeURLSeed_button_clicked(); + void handleCreationFailure(QString msg); + void handleCreationSuccess(QString path, const char* branch_path, QString hash); + void updateProgressBar(int progress); }; #endif diff --git a/src/downloadingTorrents.cpp b/src/downloadingTorrents.cpp index c9ff8fcfb..2ec5a67a9 100644 --- a/src/downloadingTorrents.cpp +++ b/src/downloadingTorrents.cpp @@ -75,6 +75,8 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession) connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString))); connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString))); connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, QString))); + connect(BTSession, SIGNAL(UPnPError(QString)), this, SLOT(displayUPnPError(QString))); + connect(BTSession, SIGNAL(UPnPSucess(QString)), this, SLOT(displayUPnPSucess(QString))); // Load last columns width for download list if(!loadColWidthDLList()) { @@ -200,6 +202,14 @@ void DownloadingTorrents::deleteTorrent(QString hash) { emit unfinishedTorrentsNumberChanged(nbTorrents); } +void DownloadingTorrents::displayUPnPError(QString msg) { + setInfoBar(tr("UPnP/NAT-PMP: Port mapping failure, message: %1").arg(msg), QColor("red")); +} + +void DownloadingTorrents::displayUPnPSucess() { + DownloadingTorrents::setInfoBar(tr("UPnP/NAT-PMP: Port mapping successful"), QColor("blue")); +} + // Update Info Bar information void DownloadingTorrents::setInfoBar(QString info, QColor color) { static unsigned int nbLines = 0; diff --git a/src/downloadingTorrents.h b/src/downloadingTorrents.h index e2346a1d6..0fa76e8f6 100644 --- a/src/downloadingTorrents.h +++ b/src/downloadingTorrents.h @@ -92,6 +92,8 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{ void hideOrShowColumnSeedersLeechers(); void hideOrShowColumnRatio(); void hideOrShowColumnEta(); + void displayUPnPError(QString msg); + void displayUPnPSucess(); public slots: void updateDlList(); diff --git a/src/src.pro b/src/src.pro index 967e6d54f..12ad44f15 100644 --- a/src/src.pro +++ b/src/src.pro @@ -11,7 +11,7 @@ TARGET = qbittorrent CONFIG += qt thread x11 network # Update this VERSION for each release -DEFINES += VERSION=\\\"v1.1.0alpha2\\\" +DEFINES += VERSION=\\\"v1.1.0alpha3\\\" DEFINES += VERSION_MAJOR=1 DEFINES += VERSION_MINOR=1 DEFINES += VERSION_BUGFIX=0