- Threadified torrent creation

- Added a progress bar in torrent creation
- Display if UPnP/NAT-PMP was successful or not
This commit is contained in:
Christophe Dumez 2007-12-31 16:57:35 +00:00
parent fa00d745b2
commit c6abdacadd
9 changed files with 144 additions and 24 deletions

View file

@ -5,8 +5,11 @@
- FEATURE: Allow to open torrent destination folder - FEATURE: Allow to open torrent destination folder
- FEATURE: Real progress bar in torrent properties that displays downloaded pieces - FEATURE: Real progress bar in torrent properties that displays downloaded pieces
- FEATURE: Allow to buy downloads using ShareMonkey - 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) - BUGFIX: Do not display seeds number in seeding list (always 0)
- COSMETIC: Do not display progress bar in seeding list (always 100%) - COSMETIC: Do not display progress bar in seeding list (always 100%)
- COSMETIC: Added a progress bar for torrent creation
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0 * Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.0.0
- FEATURE: Based on new libtorrent v0.13 - FEATURE: Based on new libtorrent v0.13

View file

@ -1158,6 +1158,13 @@ void bittorrent::readAlerts() {
} }
} }
} }
else if (portmap_error_alert* p = dynamic_cast<portmap_error_alert*>(a.get())) {
emit UPnPError(QString(p->msg().c_str()));
}
else if (portmap_alert* p = dynamic_cast<portmap_alert*>(a.get())) {
qDebug("UPnP Success, msg: %s", p->msg().c_str());
emit UPnPSuccess();
}
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) { else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str())); emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
} }

View file

@ -168,6 +168,8 @@ class bittorrent : public QObject{
void urlSeedProblem(QString url, QString msg); void urlSeedProblem(QString url, QString msg);
void torrentFinishedChecking(QString hash); void torrentFinishedChecking(QString hash);
void torrent_deleted(QString hash, QString fileName, bool finished); void torrent_deleted(QString hash, QString fileName, bool finished);
void UPnPError(QString msg);
void UPnPSuccess();
}; };
#endif #endif

View file

@ -6,7 +6,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>592</width> <width>592</width>
<height>590</height> <height>655</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle" >
@ -477,6 +477,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="progressLbl" >
<property name="text" >
<string>Progress:</string>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar" >
<property name="value" >
<number>0</number>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" > <layout class="QHBoxLayout" >
<property name="spacing" > <property name="spacing" >

View file

@ -44,9 +44,17 @@ using namespace boost::filesystem;
createtorrent::createtorrent(QWidget *parent): QDialog(parent){ createtorrent::createtorrent(QWidget *parent): QDialog(parent){
setupUi(this); setupUi(this);
setAttribute(Qt::WA_DeleteOnClose); 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(); show();
} }
createtorrent::~createtorrent() {
delete creatorThread;
}
void createtorrent::on_addFolder_button_clicked(){ void createtorrent::on_addFolder_button_clicked(){
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly); QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder to add to the torrent"), QDir::homePath(), QFileDialog::ShowDirsOnly);
if(!dir.isEmpty()) if(!dir.isEmpty())
@ -162,26 +170,70 @@ void createtorrent::on_createButton_clicked(){
} else { } else {
return; 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; char const* creator_str = "qBittorrent "VERSION;
try { try {
boost::intrusive_ptr<torrent_info> t(new torrent_info); boost::intrusive_ptr<torrent_info> 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 // 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()); add_files(*t, full_path.branch_path(), full_path.leaf());
if(abort) return;
// Set piece size // Set piece size
int piece_size = getPieceSize();
t->set_piece_size(piece_size); t->set_piece_size(piece_size);
// Add url seeds // Add url seeds
QStringList urlSeeds = allItems(URLSeeds_list);
QString seed; QString seed;
foreach(seed, urlSeeds){ foreach(seed, url_seeds){
t->add_url_seed(seed.toUtf8().data()); t->add_url_seed(seed.toUtf8().data());
} }
for(int i=0; i<trackers.size(); ++i){ for(int i=0; i<trackers.size(); ++i){
t->add_tracker(trackers.at(i).toUtf8().data()); t->add_tracker(trackers.at(i).toUtf8().data());
} }
if(abort) return;
// calculate the hash for all pieces // calculate the hash for all pieces
file_pool fp; file_pool fp;
boost::scoped_ptr<storage_interface> st(default_storage_constructor(t, full_path.branch_path(), fp)); boost::scoped_ptr<storage_interface> 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)); st->read(&buf[0], i, 0, t->piece_size(i));
hasher h(&buf[0], t->piece_size(i)); hasher h(&buf[0], t->piece_size(i));
t->set_hash(i, h.final()); 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 // Set qBittorrent as creator and add user comment to
// torrent_info structure // torrent_info structure
t->set_creator(creator_str); t->set_creator(creator_str);
t->set_comment((const char*)txt_comment->toPlainText().toUtf8()); t->set_comment((const char*)comment.toUtf8());
// Is private ? // Is private ?
if(check_private->isChecked()){ if(is_private){
t->set_priv(true); t->set_priv(true);
} }
if(abort) return;
// create the torrent and print it to out // create the torrent and print it to out
entry e = t->create_torrent(); entry e = t->create_torrent();
libtorrent::bencode(std::ostream_iterator<char>(out), e); libtorrent::bencode(std::ostream_iterator<char>(out), e);
out.flush(); out.flush();
if(checkStartSeeding->isChecked()) { emit updateProgress(100);
// Create save path file emit creationSuccess(save_path, full_path.branch_path().string().c_str(), misc::toQString(t->info_hash()));
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);
}
} }
catch (std::exception& e){ catch (std::exception& e){
std::cerr << e.what() << "\n"; emit creationFailure(QString::fromUtf8(e.what()));
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent creation was unsuccessful, reason: %1").arg(QString::fromUtf8(e.what())));
hide();
return;
} }
hide();
QMessageBox::information(0, tr("Torrent creation"), tr("Torrent was created successfully:")+" "+destination);
} }

View file

@ -22,13 +22,48 @@
#ifndef CREATE_TORRENT_IMP_H #ifndef CREATE_TORRENT_IMP_H
#define CREATE_TORRENT_IMP_H #define CREATE_TORRENT_IMP_H
#include <QThread>
#include "ui_createtorrent.h" #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{ class createtorrent : public QDialog, private Ui::createTorrentDialog{
Q_OBJECT Q_OBJECT
private:
torrentCreatorThread *creatorThread;
public: public:
createtorrent(QWidget *parent = 0); createtorrent(QWidget *parent = 0);
~createtorrent();
QStringList allItems(QListWidget *list); QStringList allItems(QListWidget *list);
int getPieceSize() const; int getPieceSize() const;
@ -43,6 +78,9 @@ class createtorrent : public QDialog, private Ui::createTorrentDialog{
void on_removeTracker_button_clicked(); void on_removeTracker_button_clicked();
void on_addURLSeed_button_clicked(); void on_addURLSeed_button_clicked();
void on_removeURLSeed_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 #endif

View file

@ -75,6 +75,8 @@ DownloadingTorrents::DownloadingTorrents(QObject *parent, bittorrent *BTSession)
connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString))); connect(BTSession, SIGNAL(fastResumeDataRejected(QString)), this, SLOT(addFastResumeRejectedAlert(QString)));
connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString))); connect(BTSession, SIGNAL(aboutToDownloadFromUrl(QString)), this, SLOT(displayDownloadingUrlInfos(QString)));
connect(BTSession, SIGNAL(urlSeedProblem(QString, QString)), this, SLOT(addUrlSeedError(QString, 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 // Load last columns width for download list
if(!loadColWidthDLList()) { if(!loadColWidthDLList()) {
@ -200,6 +202,14 @@ void DownloadingTorrents::deleteTorrent(QString hash) {
emit unfinishedTorrentsNumberChanged(nbTorrents); 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 // Update Info Bar information
void DownloadingTorrents::setInfoBar(QString info, QColor color) { void DownloadingTorrents::setInfoBar(QString info, QColor color) {
static unsigned int nbLines = 0; static unsigned int nbLines = 0;

View file

@ -92,6 +92,8 @@ class DownloadingTorrents : public QWidget, public Ui::downloading{
void hideOrShowColumnSeedersLeechers(); void hideOrShowColumnSeedersLeechers();
void hideOrShowColumnRatio(); void hideOrShowColumnRatio();
void hideOrShowColumnEta(); void hideOrShowColumnEta();
void displayUPnPError(QString msg);
void displayUPnPSucess();
public slots: public slots:
void updateDlList(); void updateDlList();

View file

@ -11,7 +11,7 @@ TARGET = qbittorrent
CONFIG += qt thread x11 network CONFIG += qt thread x11 network
# Update this VERSION for each release # Update this VERSION for each release
DEFINES += VERSION=\\\"v1.1.0alpha2\\\" DEFINES += VERSION=\\\"v1.1.0alpha3\\\"
DEFINES += VERSION_MAJOR=1 DEFINES += VERSION_MAJOR=1
DEFINES += VERSION_MINOR=1 DEFINES += VERSION_MINOR=1
DEFINES += VERSION_BUGFIX=0 DEFINES += VERSION_BUGFIX=0