Add struct TorrentCreatorParams for passing parameters

Filter out continuous newlines in Trackers field
Avoid adding empty url seed entries

Cleanup:
  Replace boost::bind
  Add const
  Use nullptr
  Use QString::SkipEmptyParts
  Rename variables
  Throw proper exception type
This commit is contained in:
Chocobo1 2017-12-05 23:17:29 +08:00
parent c9720cad81
commit c405cb2f1c
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
3 changed files with 53 additions and 64 deletions

View File

@ -59,8 +59,6 @@ using namespace BitTorrent;
TorrentCreatorThread::TorrentCreatorThread(QObject *parent) TorrentCreatorThread::TorrentCreatorThread(QObject *parent)
: QThread(parent) : QThread(parent)
, m_private(false)
, m_pieceSize(0)
{ {
} }
@ -70,97 +68,83 @@ TorrentCreatorThread::~TorrentCreatorThread()
wait(); wait();
} }
void TorrentCreatorThread::create(const QString &inputPath, const QString &savePath, const QStringList &trackers, void TorrentCreatorThread::create(const TorrentCreatorParams &params)
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize)
{ {
m_inputPath = Utils::Fs::fromNativePath(inputPath); m_params = params;
m_savePath = Utils::Fs::fromNativePath(savePath);
if (QFile(m_savePath).exists())
Utils::Fs::forceRemove(m_savePath);
m_trackers = trackers;
m_urlSeeds = urlSeeds;
m_comment = comment;
m_private = isPrivate;
m_pieceSize = pieceSize;
start(); start();
} }
void TorrentCreatorThread::sendProgressSignal(int numHashes, int numPieces) void TorrentCreatorThread::sendProgressSignal(int currentPieceIdx, int totalPieces)
{ {
emit updateProgress(static_cast<int>((numHashes * 100.) / numPieces)); emit updateProgress(static_cast<int>((currentPieceIdx * 100.) / totalPieces));
} }
void TorrentCreatorThread::run() void TorrentCreatorThread::run()
{ {
const QString creatorStr("qBittorrent " QBT_VERSION);
emit updateProgress(0); emit updateProgress(0);
QString creator_str("qBittorrent " QBT_VERSION);
try { try {
libt::file_storage fs; libt::file_storage fs;
// Adding files to the torrent // Adding files to the torrent
libt::add_files(fs, Utils::Fs::toNativePath(m_inputPath).toStdString(), fileFilter); libt::add_files(fs, Utils::Fs::toNativePath(m_params.inputPath).toStdString(), fileFilter);
if (isInterruptionRequested()) return; if (isInterruptionRequested()) return;
libt::create_torrent t(fs, m_pieceSize); libt::create_torrent newTorrent(fs, m_params.pieceSize);
// Add url seeds // Add url seeds
foreach (const QString &seed, m_urlSeeds) foreach (QString seed, m_params.urlSeeds) {
t.add_url_seed(seed.trimmed().toStdString()); seed = seed.trimmed();
if (!seed.isEmpty())
newTorrent.add_url_seed(seed.toStdString());
}
int tier = 0; int tier = 0;
bool newline = false; foreach (const QString &tracker, m_params.trackers) {
foreach (const QString &tracker, m_trackers) { if (tracker.isEmpty())
if (tracker.isEmpty()) {
if (newline)
continue;
++tier; ++tier;
newline = true; else
continue; newTorrent.add_tracker(tracker.trimmed().toStdString(), tier);
}
t.add_tracker(tracker.trimmed().toStdString(), tier);
newline = false;
} }
if (isInterruptionRequested()) return; if (isInterruptionRequested()) return;
// calculate the hash for all pieces // calculate the hash for all pieces
const QString parentPath = Utils::Fs::branchPath(m_inputPath) + "/"; const QString parentPath = Utils::Fs::branchPath(m_params.inputPath) + "/";
libt::set_piece_hashes(t, Utils::Fs::toNativePath(parentPath).toStdString(), boost::bind(&TorrentCreatorThread::sendProgressSignal, this, _1, t.num_pieces())); libt::set_piece_hashes(newTorrent, Utils::Fs::toNativePath(parentPath).toStdString()
, [this, &newTorrent](const int n) { sendProgressSignal(n, newTorrent.num_pieces()); });
// 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.toUtf8().constData()); newTorrent.set_creator(creatorStr.toUtf8().constData());
t.set_comment(m_comment.toUtf8().constData()); newTorrent.set_comment(m_params.comment.toUtf8().constData());
// Is private ? // Is private ?
t.set_priv(m_private); newTorrent.set_priv(m_params.isPrivate);
if (isInterruptionRequested()) return; if (isInterruptionRequested()) return;
// create the torrent and print it to out // create the torrent
qDebug("Saving to %s", qUtf8Printable(m_savePath)); std::ofstream outfile(
#ifdef _MSC_VER #ifdef _MSC_VER
wchar_t *savePathW = new wchar_t[m_savePath.length() + 1]; Utils::Fs::toNativePath(m_params.savePath).toStdWString().c_str()
int len = Utils::Fs::toNativePath(m_savePath).toWCharArray(savePathW);
savePathW[len] = L'\0';
std::ofstream outfile(savePathW, std::ios_base::out | std::ios_base::binary);
delete[] savePathW;
#else #else
std::ofstream outfile(Utils::Fs::toNativePath(m_savePath).toLocal8Bit().constData(), std::ios_base::out | std::ios_base::binary); Utils::Fs::toNativePath(m_params.savePath).toUtf8().constData()
#endif #endif
, (std::ios_base::out | std::ios_base::binary | std::ios_base::trunc));
if (outfile.fail()) if (outfile.fail())
throw std::exception(); throw std::runtime_error(tr("create new torrent file failed").toStdString());
if (isInterruptionRequested()) return; if (isInterruptionRequested()) return;
libt::bencode(std::ostream_iterator<char>(outfile), t.generate()); libt::bencode(std::ostream_iterator<char>(outfile), newTorrent.generate());
outfile.close(); outfile.close();
emit updateProgress(100); emit updateProgress(100);
emit creationSuccess(m_savePath, parentPath); emit creationSuccess(m_params.savePath, parentPath);
} }
catch (std::exception& e) { catch (const std::exception &e) {
emit creationFailure(QString::fromStdString(e.what())); emit creationFailure(e.what());
} }
} }

View File

@ -36,16 +36,26 @@
namespace BitTorrent namespace BitTorrent
{ {
struct TorrentCreatorParams
{
bool isPrivate;
int pieceSize;
QString inputPath;
QString savePath;
QString comment;
QStringList trackers;
QStringList urlSeeds;
};
class TorrentCreatorThread : public QThread class TorrentCreatorThread : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
TorrentCreatorThread(QObject *parent = 0); TorrentCreatorThread(QObject *parent = nullptr);
~TorrentCreatorThread(); ~TorrentCreatorThread();
void create(const QString &inputPath, const QString &savePath, const QStringList &trackers, void create(const TorrentCreatorParams &params);
const QStringList &urlSeeds, const QString &comment, bool isPrivate, int pieceSize);
static int calculateTotalPieces(const QString &inputPath, const int pieceSize); static int calculateTotalPieces(const QString &inputPath, const int pieceSize);
@ -58,15 +68,9 @@ namespace BitTorrent
void updateProgress(int progress); void updateProgress(int progress);
private: private:
void sendProgressSignal(int numHashes, int numPieces); void sendProgressSignal(int currentPieceIdx, int totalPieces);
QString m_inputPath; TorrentCreatorParams m_params;
QString m_savePath;
QStringList m_trackers;
QStringList m_urlSeeds;
QString m_comment;
bool m_private;
int m_pieceSize;
}; };
} }

View File

@ -161,12 +161,13 @@ void TorrentCreatorDlg::onCreateButtonClicked()
setInteractionEnabled(false); setInteractionEnabled(false);
setCursor(QCursor(Qt::WaitCursor)); setCursor(QCursor(Qt::WaitCursor));
QStringList trackers = m_ui->trackersList->toPlainText().split("\n"); const QStringList trackers = m_ui->trackersList->toPlainText().trimmed()
QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split("\n"); .replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n');
QString comment = m_ui->txtComment->toPlainText(); const QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split('\n', QString::SkipEmptyParts);
const QString comment = m_ui->txtComment->toPlainText();
// run the creator thread // run the creator thread
m_creatorThread->create(input, destination, trackers, urlSeeds, comment, m_ui->checkPrivate->isChecked(), getPieceSize()); m_creatorThread->create({ m_ui->checkPrivate->isChecked(), getPieceSize(), input, destination, comment, trackers, urlSeeds });
} }
void TorrentCreatorDlg::handleCreationFailure(const QString &msg) void TorrentCreatorDlg::handleCreationFailure(const QString &msg)