Browse Source

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.
adaptive-webui-19844
Chocobo1 5 years ago
parent
commit
edcc74c1ae
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 12
      src/base/bittorrent/torrentcreatorthread.cpp
  2. 4
      src/base/bittorrent/torrentcreatorthread.h
  3. 36
      src/gui/torrentcreatordialog.cpp
  4. 5
      src/gui/torrentcreatordialog.h
  5. 53
      src/gui/torrentcreatordialog.ui

12
src/base/bittorrent/torrentcreatorthread.cpp

@ -54,7 +54,7 @@ namespace
#else #else
using LTCreateFlags = lt::create_flags_t; using LTCreateFlags = lt::create_flags_t;
using LTPieceIndex = lt::piece_index_t; using LTPieceIndex = lt::piece_index_t;
#endif #endif
// do not include files and folders whose // do not include files and folders whose
// name starts with a . // name starts with a .
@ -138,8 +138,8 @@ void TorrentCreatorThread::run()
if (isInterruptionRequested()) return; if (isInterruptionRequested()) return;
lt::create_torrent newTorrent(fs, m_params.pieceSize, -1 lt::create_torrent newTorrent(fs, m_params.pieceSize, m_params.paddedFileSizeLimit
, (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})); , (m_params.isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {}));
// Add url seeds // Add url seeds
for (QString seed : asConst(m_params.urlSeeds)) { 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()) if (inputPath.isEmpty())
return 0; return 0;
@ -213,6 +213,6 @@ int TorrentCreatorThread::calculateTotalPieces(const QString &inputPath, const i
lt::file_storage fs; lt::file_storage fs;
lt::add_files(fs, Utils::Fs::toNativePath(inputPath).toStdString(), fileFilter); lt::add_files(fs, Utils::Fs::toNativePath(inputPath).toStdString(), fileFilter);
return lt::create_torrent(fs, pieceSize, -1 return lt::create_torrent(fs, pieceSize, paddedFileSizeLimit
, (isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})).num_pieces(); , (isAlignmentOptimized ? lt::create_torrent::optimize_alignment : LTCreateFlags {})).num_pieces();
} }

4
src/base/bittorrent/torrentcreatorthread.h

@ -39,6 +39,7 @@ namespace BitTorrent
bool isPrivate; bool isPrivate;
bool isAlignmentOptimized; bool isAlignmentOptimized;
int pieceSize; int pieceSize;
int paddedFileSizeLimit;
QString inputPath; QString inputPath;
QString savePath; QString savePath;
QString comment; QString comment;
@ -57,7 +58,8 @@ namespace BitTorrent
void create(const TorrentCreatorParams &params); void create(const TorrentCreatorParams &params);
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: protected:
void run() override; void run() override;

36
src/gui/torrentcreatordialog.cpp

@ -55,6 +55,7 @@ TorrentCreatorDialog::TorrentCreatorDialog(QWidget *parent, const QString &defau
, m_storeStartSeeding(SETTINGS_KEY("StartSeeding")) , m_storeStartSeeding(SETTINGS_KEY("StartSeeding"))
, m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio")) , m_storeIgnoreRatio(SETTINGS_KEY("IgnoreRatio"))
, m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"), true) , m_storeOptimizeAlignment(SETTINGS_KEY("OptimizeAlignment"), true)
, m_paddedFileSizeLimit(SETTINGS_KEY("PaddedFileSizeLimit"), -1)
, m_storeLastAddPath(SETTINGS_KEY("LastAddPath"), QDir::homePath()) , m_storeLastAddPath(SETTINGS_KEY("LastAddPath"), QDir::homePath())
, m_storeTrackerList(SETTINGS_KEY("TrackerList")) , m_storeTrackerList(SETTINGS_KEY("TrackerList"))
, m_storeWebSeedList(SETTINGS_KEY("WebSeedList")) , m_storeWebSeedList(SETTINGS_KEY("WebSeedList"))
@ -117,6 +118,12 @@ int TorrentCreatorDialog::getPieceSize() const
return pieceSizes[m_ui->comboPieceSize->currentIndex()] * 1024; 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) void TorrentCreatorDialog::dropEvent(QDropEvent *event)
{ {
event->acceptProposedAction(); event->acceptProposedAction();
@ -164,14 +171,19 @@ void TorrentCreatorDialog::onCreateButtonClicked()
const QStringList trackers = m_ui->trackersList->toPlainText().trimmed() const QStringList trackers = m_ui->trackersList->toPlainText().trimmed()
.replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n'); .replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n');
const QStringList urlSeeds = m_ui->URLSeedsList->toPlainText().split('\n', QString::SkipEmptyParts); const BitTorrent::TorrentCreatorParams params {
const QString comment = m_ui->txtComment->toPlainText(); m_ui->checkPrivate->isChecked()
const QString source = m_ui->lineEditSource->text(); , 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 // run the creator thread
m_creatorThread->create({ m_ui->checkPrivate->isChecked() m_creatorThread->create(params);
, m_ui->checkOptimizeAlignment->isChecked(), getPieceSize()
, input, destination, comment, source, trackers, urlSeeds });
} }
void TorrentCreatorDialog::handleCreationFailure(const QString &msg) void TorrentCreatorDialog::handleCreationFailure(const QString &msg)
@ -216,11 +228,12 @@ void TorrentCreatorDialog::updatePiecesCount()
const QString path = m_ui->textInputPath->text().trimmed(); const QString path = m_ui->textInputPath->text().trimmed();
const bool isAlignmentOptimized = m_ui->checkOptimizeAlignment->isChecked(); 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)); 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->textInputPath->setEnabled(enabled);
m_ui->addFileButton->setEnabled(enabled); m_ui->addFileButton->setEnabled(enabled);
@ -229,10 +242,13 @@ void TorrentCreatorDialog::setInteractionEnabled(bool enabled)
m_ui->URLSeedsList->setEnabled(enabled); m_ui->URLSeedsList->setEnabled(enabled);
m_ui->txtComment->setEnabled(enabled); m_ui->txtComment->setEnabled(enabled);
m_ui->comboPieceSize->setEnabled(enabled); m_ui->comboPieceSize->setEnabled(enabled);
m_ui->buttonCalcTotalPieces->setEnabled(enabled);
m_ui->checkPrivate->setEnabled(enabled); m_ui->checkPrivate->setEnabled(enabled);
m_ui->checkStartSeeding->setEnabled(enabled); m_ui->checkStartSeeding->setEnabled(enabled);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled);
m_ui->checkIgnoreShareLimits->setEnabled(enabled && m_ui->checkStartSeeding->isChecked()); m_ui->checkIgnoreShareLimits->setEnabled(enabled && m_ui->checkStartSeeding->isChecked());
m_ui->checkOptimizeAlignment->setEnabled(enabled);
m_ui->spinPaddedFileSizeLimit->setEnabled(enabled);
} }
void TorrentCreatorDialog::saveSettings() void TorrentCreatorDialog::saveSettings()
@ -244,6 +260,7 @@ void TorrentCreatorDialog::saveSettings()
m_storeStartSeeding = m_ui->checkStartSeeding->isChecked(); m_storeStartSeeding = m_ui->checkStartSeeding->isChecked();
m_storeIgnoreRatio = m_ui->checkIgnoreShareLimits->isChecked(); m_storeIgnoreRatio = m_ui->checkIgnoreShareLimits->isChecked();
m_storeOptimizeAlignment = m_ui->checkOptimizeAlignment->isChecked(); m_storeOptimizeAlignment = m_ui->checkOptimizeAlignment->isChecked();
m_paddedFileSizeLimit = m_ui->spinPaddedFileSizeLimit->value();
m_storeTrackerList = m_ui->trackersList->toPlainText(); m_storeTrackerList = m_ui->trackersList->toPlainText();
m_storeWebSeedList = m_ui->URLSeedsList->toPlainText(); m_storeWebSeedList = m_ui->URLSeedsList->toPlainText();
@ -261,8 +278,9 @@ void TorrentCreatorDialog::loadSettings()
m_ui->checkPrivate->setChecked(m_storePrivateTorrent); m_ui->checkPrivate->setChecked(m_storePrivateTorrent);
m_ui->checkStartSeeding->setChecked(m_storeStartSeeding); m_ui->checkStartSeeding->setChecked(m_storeStartSeeding);
m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio); m_ui->checkIgnoreShareLimits->setChecked(m_storeIgnoreRatio);
m_ui->checkOptimizeAlignment->setChecked(m_storeOptimizeAlignment);
m_ui->checkIgnoreShareLimits->setEnabled(m_ui->checkStartSeeding->isChecked()); 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->trackersList->setPlainText(m_storeTrackerList);
m_ui->URLSeedsList->setPlainText(m_storeWebSeedList); m_ui->URLSeedsList->setPlainText(m_storeWebSeedList);

5
src/gui/torrentcreatordialog.h

@ -68,8 +68,10 @@ private:
void saveSettings(); void saveSettings();
void loadSettings(); void loadSettings();
void setInteractionEnabled(bool enabled) const;
int getPieceSize() const; int getPieceSize() const;
void setInteractionEnabled(bool enabled); int getPaddedFileSizeLimit() const;
Ui::TorrentCreatorDialog *m_ui; Ui::TorrentCreatorDialog *m_ui;
BitTorrent::TorrentCreatorThread *m_creatorThread; BitTorrent::TorrentCreatorThread *m_creatorThread;
@ -81,6 +83,7 @@ private:
CachedSettingValue<bool> m_storeStartSeeding; CachedSettingValue<bool> m_storeStartSeeding;
CachedSettingValue<bool> m_storeIgnoreRatio; CachedSettingValue<bool> m_storeIgnoreRatio;
CachedSettingValue<bool> m_storeOptimizeAlignment; CachedSettingValue<bool> m_storeOptimizeAlignment;
CachedSettingValue<int> m_paddedFileSizeLimit;
CachedSettingValue<QString> m_storeLastAddPath; CachedSettingValue<QString> m_storeLastAddPath;
CachedSettingValue<QString> m_storeTrackerList; CachedSettingValue<QString> m_storeTrackerList;
CachedSettingValue<QString> m_storeWebSeedList; CachedSettingValue<QString> m_storeWebSeedList;

53
src/gui/torrentcreatordialog.ui

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>592</width> <width>592</width>
<height>658</height> <height>731</height>
</rect> </rect>
</property> </property>
<property name="acceptDrops"> <property name="acceptDrops">
@ -225,13 +225,58 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="checkOptimizeAlignment"> <widget class="QGroupBox" name="checkOptimizeAlignment">
<property name="text"> <property name="title">
<string>Optimize alignment</string> <string>Optimize alignment</string>
</property> </property>
<property name="checked"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="lblPaddedFileSizeLimit">
<property name="text">
<string>Align to piece boundary for files larger than:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinPaddedFileSizeLimit">
<property name="specialValueText">
<string>Disabled</string>
</property>
<property name="suffix">
<string> KiB</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>2147483647</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>

Loading…
Cancel
Save