From edcc74c1ae14ae36d08a750db3d3fedf6268ca94 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Tue, 10 Sep 2019 00:59:43 +0800 Subject: [PATCH] Add option to align file to piece boundary when creating new torrent Alignment is achieved by adding dummy pad files between files which is handled by libtorrent. Closes #10460. --- src/base/bittorrent/torrentcreatorthread.cpp | 12 ++--- src/base/bittorrent/torrentcreatorthread.h | 4 +- src/gui/torrentcreatordialog.cpp | 36 +++++++++---- src/gui/torrentcreatordialog.h | 5 +- src/gui/torrentcreatordialog.ui | 53 ++++++++++++++++++-- 5 files changed, 89 insertions(+), 21 deletions(-) diff --git a/src/base/bittorrent/torrentcreatorthread.cpp b/src/base/bittorrent/torrentcreatorthread.cpp index b8acc4f08..a48173d7c 100644 --- a/src/base/bittorrent/torrentcreatorthread.cpp +++ b/src/base/bittorrent/torrentcreatorthread.cpp @@ -54,7 +54,7 @@ namespace #else using LTCreateFlags = lt::create_flags_t; using LTPieceIndex = lt::piece_index_t; -#endif +#endif // do not include files and folders whose // name starts with a . @@ -138,8 +138,8 @@ void TorrentCreatorThread::run() if (isInterruptionRequested()) return; - lt::create_torrent newTorrent(fs, m_params.pieceSize, -1 - , (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})); + lt::create_torrent newTorrent(fs, m_params.pieceSize, m_params.paddedFileSizeLimit + , (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})); // Add url seeds for (QString seed : asConst(m_params.urlSeeds)) { @@ -205,7 +205,7 @@ void TorrentCreatorThread::run() } } -int TorrentCreatorThread::calculateTotalPieces(const QString &inputPath, const int pieceSize, const bool isAlignmentOptimized) +int TorrentCreatorThread::calculateTotalPieces(const QString &inputPath, const int pieceSize, const bool isAlignmentOptimized, const int paddedFileSizeLimit) { if (inputPath.isEmpty()) return 0; @@ -213,6 +213,6 @@ int TorrentCreatorThread::calculateTotalPieces(const QString &inputPath, const i lt::file_storage fs; lt::add_files(fs, Utils::Fs::toNativePath(inputPath).toStdString(), fileFilter); - return lt::create_torrent(fs, pieceSize, -1 - , (isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})).num_pieces(); + return lt::create_torrent(fs, pieceSize, paddedFileSizeLimit + , (isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})).num_pieces(); } diff --git a/src/base/bittorrent/torrentcreatorthread.h b/src/base/bittorrent/torrentcreatorthread.h index f772d9ecf..523e3a42d 100644 --- a/src/base/bittorrent/torrentcreatorthread.h +++ b/src/base/bittorrent/torrentcreatorthread.h @@ -39,6 +39,7 @@ namespace BitTorrent bool isPrivate; bool isAlignmentOptimized; int pieceSize; + int paddedFileSizeLimit; QString inputPath; QString savePath; QString comment; @@ -57,7 +58,8 @@ namespace BitTorrent void create(const TorrentCreatorParams ¶ms); - static int calculateTotalPieces(const QString &inputPath, int pieceSize, bool isAlignmentOptimized); + static int calculateTotalPieces(const QString &inputPath + , const int pieceSize, const bool isAlignmentOptimized, int paddedFileSizeLimit); protected: void run() override; diff --git a/src/gui/torrentcreatordialog.cpp b/src/gui/torrentcreatordialog.cpp index 0135f49ae..252301857 100644 --- a/src/gui/torrentcreatordialog.cpp +++ b/src/gui/torrentcreatordialog.cpp @@ -55,6 +55,7 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const QString &defau , m_storeStartSeeding(SETTINGS_KEY("StartSeeding")) , m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio")) , m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"), true) + , m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit"), -1) , m_storeLastAddPath(SETTINGS_KEY("LastAddPath"), QDir::homePath()) , m_storeTrackerList(SETTINGS_KEY("TrackerList")) , m_storeWebSeedList(SETTINGS_KEY("WebSeedList")) @@ -117,6 +118,12 @@ int TorrentCreatorDialog::getPieceSize() const return pieceSizes[m_ui->comboPieceSize->currentIndex()] * 1024; } +int TorrentCreatorDialog::getPaddedFileSizeLimit() const +{ + const int value = m_ui->spinPaddedFileSizeLimit->value(); + return ((value >= 0) ? (value * 1024) : -1); +} + void TorrentCreatorDialog::dropEvent(QDropEvent *event) { event->acceptProposedAction(); @@ -164,14 +171,19 @@ void TorrentCreatorDialog::onCreateButtonClicked() const QStringList trackers = m_ui->trackersList->toPlainText().trimmed() .replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n'); - const QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split('\n', QString::SkipEmptyParts); - const QString comment = m_ui->txtComment->toPlainText(); - const QString source = m_ui->lineEditSource->text(); + const BitTorrent::TorrentCreatorParams params { + m_ui->checkPrivate->isChecked() + , m_ui->checkOptimizeAlignment->isChecked() + , getPieceSize(), getPaddedFileSizeLimit() + , input, destination + , m_ui->txtComment->toPlainText() + , m_ui->lineEditSource->text() + , trackers + , m_ui->URLSeedsList->toPlainText().split('\n', QString::SkipEmptyParts) + }; // run the creator thread - m_creatorThread->create({ m_ui->checkPrivate->isChecked() - , m_ui->checkOptimizeAlignment->isChecked(), getPieceSize() - , input, destination, comment, source, trackers, urlSeeds }); + m_creatorThread->create(params); } void TorrentCreatorDialog::handleCreationFailure(const QString &msg) @@ -216,11 +228,12 @@ void TorrentCreatorDialog::updatePiecesCount() const QString path = m_ui->textInputPath->text().trimmed(); const bool isAlignmentOptimized = m_ui->checkOptimizeAlignment->isChecked(); - const int count = BitTorrent::TorrentCreatorThread::calculateTotalPieces(path, getPieceSize(), isAlignmentOptimized); + const int count = BitTorrent::TorrentCreatorThread::calculateTotalPieces(path + , getPieceSize(), isAlignmentOptimized, getPaddedFileSizeLimit()); m_ui->labelTotalPieces->setText(QString::number(count)); } -void TorrentCreatorDialog::setInteractionEnabled(bool enabled) +void TorrentCreatorDialog::setInteractionEnabled(const bool enabled) const { m_ui->textInputPath->setEnabled(enabled); m_ui->addFileButton->setEnabled(enabled); @@ -229,10 +242,13 @@ void TorrentCreatorDialog::setInteractionEnabled(bool enabled) m_ui->URLSeedsList->setEnabled(enabled); m_ui->txtComment->setEnabled(enabled); m_ui->comboPieceSize->setEnabled(enabled); + m_ui->buttonCalcTotalPieces->setEnabled(enabled); m_ui->checkPrivate->setEnabled(enabled); m_ui->checkStartSeeding->setEnabled(enabled); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); m_ui->checkIgnoreShareLimits->setEnabled(enabled && m_ui->checkStartSeeding->isChecked()); + m_ui->checkOptimizeAlignment->setEnabled(enabled); + m_ui->spinPaddedFileSizeLimit->setEnabled(enabled); } void TorrentCreatorDialog::saveSettings() @@ -244,6 +260,7 @@ void TorrentCreatorDialog::saveSettings() m_storeStartSeeding = m_ui->checkStartSeeding->isChecked(); m_storeIgnoreRatio = m_ui->checkIgnoreShareLimits->isChecked(); m_storeOptimizeAlignment = m_ui->checkOptimizeAlignment->isChecked(); + m_paddedFileSizeLimit = m_ui->spinPaddedFileSizeLimit->value(); m_storeTrackerList = m_ui->trackersList->toPlainText(); m_storeWebSeedList = m_ui->URLSeedsList->toPlainText(); @@ -261,8 +278,9 @@ void TorrentCreatorDialog::loadSettings() m_ui->checkPrivate->setChecked(m_storePrivateTorrent); m_ui->checkStartSeeding->setChecked(m_storeStartSeeding); m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio); - m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment); m_ui->checkIgnoreShareLimits->setEnabled(m_ui->checkStartSeeding->isChecked()); + m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment); + m_ui->spinPaddedFileSizeLimit->setValue(m_paddedFileSizeLimit); m_ui->trackersList->setPlainText(m_storeTrackerList); m_ui->URLSeedsList->setPlainText(m_storeWebSeedList); diff --git a/src/gui/torrentcreatordialog.h b/src/gui/torrentcreatordialog.h index 94e0efdb4..3a7f145fd 100644 --- a/src/gui/torrentcreatordialog.h +++ b/src/gui/torrentcreatordialog.h @@ -68,8 +68,10 @@ private: void saveSettings(); void loadSettings(); + void setInteractionEnabled(bool enabled) const; + int getPieceSize() const; - void setInteractionEnabled(bool enabled); + int getPaddedFileSizeLimit() const; Ui::TorrentCreatorDialog *m_ui; BitTorrent::TorrentCreatorThread *m_creatorThread; @@ -81,6 +83,7 @@ private: CachedSettingValue m_storeStartSeeding; CachedSettingValue m_storeIgnoreRatio; CachedSettingValue m_storeOptimizeAlignment; + CachedSettingValue m_paddedFileSizeLimit; CachedSettingValue m_storeLastAddPath; CachedSettingValue m_storeTrackerList; CachedSettingValue m_storeWebSeedList; diff --git a/src/gui/torrentcreatordialog.ui b/src/gui/torrentcreatordialog.ui index 02e416945..23b2861c0 100644 --- a/src/gui/torrentcreatordialog.ui +++ b/src/gui/torrentcreatordialog.ui @@ -7,7 +7,7 @@ 0 0 592 - 658 + 731 @@ -225,13 +225,58 @@ - - + + Optimize alignment - + true + + + + + + + Align to piece boundary for files larger than: + + + + + + + Disabled + + + KiB + + + -1 + + + 2147483647 + + + -1 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + +