mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-25 18:56:34 +03:00
- Threadified torrent creation
- Added a progress bar in torrent creation - Display if UPnP/NAT-PMP was successful or not
This commit is contained in:
parent
fa00d745b2
commit
c6abdacadd
9 changed files with 144 additions and 24 deletions
|
@ -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 <chris@qbittorrent.org> - v1.0.0
|
||||
- FEATURE: Based on new libtorrent v0.13
|
||||
|
|
|
@ -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())) {
|
||||
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>592</width>
|
||||
<height>590</height>
|
||||
<height>655</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
|
@ -477,6 +477,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
|
|
|
@ -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<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
|
||||
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; i<trackers.size(); ++i){
|
||||
t->add_tracker(trackers.at(i).toUtf8().data());
|
||||
}
|
||||
|
||||
if(abort) return;
|
||||
// calculate the hash for all pieces
|
||||
file_pool 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));
|
||||
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<char>(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);
|
||||
}
|
||||
|
|
|
@ -22,13 +22,48 @@
|
|||
#ifndef CREATE_TORRENT_IMP_H
|
||||
#define CREATE_TORRENT_IMP_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue