Skip to content

Commit

Permalink
Add options to adjust behavior of merging trackers to existing torrent
Browse files Browse the repository at this point in the history
PR #19278.
Closes #19251.
  • Loading branch information
glassez authored Jul 6, 2023
1 parent fff7b1d commit 4ef9a64
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/base/bittorrent/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,8 @@ namespace BitTorrent
virtual void setBannedIPs(const QStringList &newList) = 0;
virtual ResumeDataStorageType resumeDataStorageType() const = 0;
virtual void setResumeDataStorageType(ResumeDataStorageType type) = 0;
virtual bool isMergeTrackersEnabled() const = 0;
virtual void setMergeTrackersEnabled(bool enabled) = 0;

virtual bool isRestored() const = 0;

Expand Down
32 changes: 32 additions & 0 deletions src/base/bittorrent/sessionimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ SessionImpl::SessionImpl(QObject *parent)
, m_excludedFileNames(BITTORRENT_SESSION_KEY(u"ExcludedFileNames"_s))
, m_bannedIPs(u"State/BannedIPs"_s, QStringList(), Algorithm::sorted<QStringList>)
, m_resumeDataStorageType(BITTORRENT_SESSION_KEY(u"ResumeDataStorageType"_s), ResumeDataStorageType::Legacy)
, m_isMergeTrackersEnabled(BITTORRENT_KEY(u"MergeTrackersEnabled"_s), false)
, m_isI2PEnabled {BITTORRENT_SESSION_KEY(u"I2P/Enabled"_s), false}
, m_I2PAddress {BITTORRENT_SESSION_KEY(u"I2P/Address"_s), u"127.0.0.1"_s}
, m_I2PPort {BITTORRENT_SESSION_KEY(u"I2P/Port"_s), 7656}
Expand Down Expand Up @@ -2677,10 +2678,31 @@ bool SessionImpl::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &so

if (Torrent *torrent = findTorrent(infoHash); torrent)
{
// a duplicate torrent is being added
if (torrent->isPrivate())
return false;

if (hasMetadata)
{
// Trying to set metadata to existing torrent in case if it has none
torrent->setMetadata(std::get<TorrentInfo>(source));

const TorrentInfo &torrentInfo = std::get<TorrentInfo>(source);

if (torrentInfo.isPrivate())
return false;

// merge trackers and web seeds
torrent->addTrackers(torrentInfo.trackers());
torrent->addUrlSeeds(torrentInfo.urlSeeds());
}
else
{
const MagnetUri &magnetUri = std::get<MagnetUri>(source);

// merge trackers and web seeds
torrent->addTrackers(magnetUri.trackers());
torrent->addUrlSeeds(magnetUri.urlSeeds());
}

return false;
Expand Down Expand Up @@ -3904,6 +3926,16 @@ void SessionImpl::setResumeDataStorageType(const ResumeDataStorageType type)
m_resumeDataStorageType = type;
}

bool SessionImpl::isMergeTrackersEnabled() const
{
return m_isMergeTrackersEnabled;
}

void SessionImpl::setMergeTrackersEnabled(const bool enabled)
{
m_isMergeTrackersEnabled = enabled;
}

QStringList SessionImpl::bannedIPs() const
{
return m_bannedIPs;
Expand Down
3 changes: 3 additions & 0 deletions src/base/bittorrent/sessionimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ namespace BitTorrent
void setBannedIPs(const QStringList &newList) override;
ResumeDataStorageType resumeDataStorageType() const override;
void setResumeDataStorageType(ResumeDataStorageType type) override;
bool isMergeTrackersEnabled() const override;
void setMergeTrackersEnabled(bool enabled) override;

bool isRestored() const override;

Expand Down Expand Up @@ -704,6 +706,7 @@ namespace BitTorrent
CachedSettingValue<QStringList> m_excludedFileNames;
CachedSettingValue<QStringList> m_bannedIPs;
CachedSettingValue<ResumeDataStorageType> m_resumeDataStorageType;
CachedSettingValue<bool> m_isMergeTrackersEnabled;
CachedSettingValue<bool> m_isI2PEnabled;
CachedSettingValue<QString> m_I2PAddress;
CachedSettingValue<int> m_I2PPort;
Expand Down
13 changes: 13 additions & 0 deletions src/base/preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,19 @@ void Preferences::setConfirmPauseAndResumeAll(const bool enabled)
setValue(u"GUI/ConfirmActions/PauseAndResumeAllTorrents"_s, enabled);
}

bool Preferences::confirmMergeTrackers() const
{
return value(u"GUI/ConfirmActions/MergeTrackers"_s, true);
}

void Preferences::setConfirmMergeTrackers(const bool enabled)
{
if (enabled == confirmMergeTrackers())
return;

setValue(u"GUI/ConfirmActions/MergeTrackers"_s, enabled);
}

#ifndef Q_OS_MACOS
TrayIcon::Style Preferences::trayIconStyle() const
{
Expand Down
2 changes: 2 additions & 0 deletions src/base/preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ class Preferences final : public QObject
void setConfirmRemoveAllTags(bool enabled);
bool confirmPauseAndResumeAll() const;
void setConfirmPauseAndResumeAll(bool enabled);
bool confirmMergeTrackers() const;
void setConfirmMergeTrackers(bool enabled);
#ifndef Q_OS_MACOS
bool systemTrayEnabled() const;
void setSystemTrayEnabled(bool enabled);
Expand Down
42 changes: 28 additions & 14 deletions src/gui/addnewtorrentdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,10 @@ bool AddNewTorrentDialog::loadTorrentImpl()
const BitTorrent::InfoHash infoHash = m_torrentInfo.infoHash();

// Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
const auto *btSession = BitTorrent::Session::instance();
if (btSession->isKnownTorrent(infoHash))
{
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
BitTorrent::Torrent *const torrent = btSession->findTorrent(infoHash);
if (torrent)
{
// Trying to set metadata to existing torrent in case if it has none
Expand All @@ -553,10 +554,16 @@ bool AddNewTorrentDialog::loadTorrentImpl()
}
else
{
const QMessageBox::StandardButton btn = RaisedMessageBox::question(this, tr("Torrent is already present")
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
if (btn == QMessageBox::Yes)
bool mergeTrackers = btSession->isMergeTrackersEnabled();
if (Preferences::instance()->confirmMergeTrackers())
{
const QMessageBox::StandardButton btn = RaisedMessageBox::question(this, tr("Torrent is already present")
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
mergeTrackers = (btn == QMessageBox::Yes);
}

if (mergeTrackers)
{
torrent->addTrackers(m_torrentInfo.trackers());
torrent->addUrlSeeds(m_torrentInfo.urlSeeds());
Expand Down Expand Up @@ -592,9 +599,10 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
const BitTorrent::InfoHash infoHash = magnetUri.infoHash();

// Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
auto *btSession = BitTorrent::Session::instance();
if (btSession->isKnownTorrent(infoHash))
{
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
BitTorrent::Torrent *const torrent = btSession->findTorrent(infoHash);
if (torrent)
{
if (torrent->isPrivate())
Expand All @@ -603,10 +611,16 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
}
else
{
const QMessageBox::StandardButton btn = RaisedMessageBox::question(this, tr("Torrent is already present")
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
if (btn == QMessageBox::Yes)
bool mergeTrackers = btSession->isMergeTrackersEnabled();
if (Preferences::instance()->confirmMergeTrackers())
{
const QMessageBox::StandardButton btn = RaisedMessageBox::question(this, tr("Torrent is already present")
, tr("Torrent '%1' is already in the transfer list. Do you want to merge trackers from new source?").arg(torrent->name())
, (QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes);
mergeTrackers = (btn == QMessageBox::Yes);
}

if (mergeTrackers)
{
torrent->addTrackers(magnetUri.trackers());
torrent->addUrlSeeds(magnetUri.urlSeeds());
Expand All @@ -621,7 +635,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
return false;
}

connect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata);
connect(btSession, &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata);

// Set dialog title
const QString torrentName = magnetUri.name();
Expand All @@ -630,7 +644,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
updateDiskSpaceLabel();
TMMChanged(m_ui->comboTTM->currentIndex());

BitTorrent::Session::instance()->downloadMetadata(magnetUri);
btSession->downloadMetadata(magnetUri);
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
m_ui->labelInfohash1Data->setText(magnetUri.infoHash().v1().isValid() ? magnetUri.infoHash().v1().toString() : tr("N/A"));
m_ui->labelInfohash2Data->setText(magnetUri.infoHash().v2().isValid() ? magnetUri.infoHash().v2().toString() : tr("N/A"));
Expand Down
7 changes: 7 additions & 0 deletions src/gui/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,9 @@ void OptionsDialog::loadDownloadsTabOptions()
m_ui->stopConditionLabel->setEnabled(!m_ui->checkStartPaused->isChecked());
m_ui->stopConditionComboBox->setEnabled(!m_ui->checkStartPaused->isChecked());

m_ui->checkMergeTrackers->setChecked(session->isMergeTrackersEnabled());
m_ui->checkConfirmMergeTrackers->setChecked(pref->confirmMergeTrackers());

const TorrentFileGuard::AutoDeleteMode autoDeleteMode = TorrentFileGuard::autoDeleteMode();
m_ui->deleteTorrentBox->setChecked(autoDeleteMode != TorrentFileGuard::Never);
m_ui->deleteCancelledTorrentBox->setChecked(autoDeleteMode == TorrentFileGuard::Always);
Expand Down Expand Up @@ -619,6 +622,8 @@ void OptionsDialog::loadDownloadsTabOptions()
m_ui->stopConditionComboBox->setEnabled(!checked);
});
connect(m_ui->stopConditionComboBox, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
connect(m_ui->checkMergeTrackers, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->checkConfirmMergeTrackers, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->deleteTorrentBox, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->deleteCancelledTorrentBox, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);

Expand Down Expand Up @@ -684,6 +689,8 @@ void OptionsDialog::saveDownloadsTabOptions() const
TorrentFileGuard::setAutoDeleteMode(!m_ui->deleteTorrentBox->isChecked() ? TorrentFileGuard::Never
: !m_ui->deleteCancelledTorrentBox->isChecked() ? TorrentFileGuard::IfAdded
: TorrentFileGuard::Always);
session->setMergeTrackersEnabled(m_ui->checkMergeTrackers->isChecked());
pref->setConfirmMergeTrackers(m_ui->checkConfirmMergeTrackers->isChecked());

session->setPreallocationEnabled(preAllocateAllFiles());
session->setAppendExtensionEnabled(m_ui->checkAppendqB->isChecked());
Expand Down
35 changes: 35 additions & 0 deletions src/gui/optionsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,41 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="duplicateTorrentGroup">
<property name="title">
<string>When duplicate torrent is being added</string>
</property>
<layout class="QVBoxLayout" name="deleteTorrentBoxLayout">
<item>
<widget class="QCheckBox" name="checkMergeTrackers">
<property name="toolTip">
<string>Whether trackers should be merged to existing torrent</string>
</property>
<property name="text">
<string>Merge trackers to existing torrent</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkConfirmMergeTrackers">
<property name="toolTip">
<string>Shows a confirmation dialog upon merging trackers to existing torrent</string>
</property>
<property name="text">
<string>Confirm merging trackers</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="deleteTorrentBox">
<property name="toolTip">
Expand Down
3 changes: 3 additions & 0 deletions src/webui/api/appcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void AppController::preferencesAction()
data[u"add_to_top_of_queue"_s] = session->isAddTorrentToQueueTop();
data[u"start_paused_enabled"_s] = session->isAddTorrentPaused();
data[u"torrent_stop_condition"_s] = Utils::String::fromEnum(session->torrentStopCondition());
data[u"merge_trackers"_s] = session->isMergeTrackersEnabled();
data[u"auto_delete_mode"_s] = static_cast<int>(TorrentFileGuard::autoDeleteMode());
data[u"preallocate_all"_s] = session->isPreallocationEnabled();
data[u"incomplete_files_ext"_s] = session->isAppendExtensionEnabled();
Expand Down Expand Up @@ -477,6 +478,8 @@ void AppController::setPreferencesAction()
session->setAddTorrentPaused(it.value().toBool());
if (hasKey(u"torrent_stop_condition"_s))
session->setTorrentStopCondition(Utils::String::toEnum(it.value().toString(), BitTorrent::Torrent::StopCondition::None));
if (hasKey(u"merge_trackers"_s))
session->setMergeTrackersEnabled(it.value().toBool());
if (hasKey(u"auto_delete_mode"_s))
TorrentFileGuard::setAutoDeleteMode(static_cast<TorrentFileGuard::AutoDeleteMode>(it.value().toInt()));

Expand Down

0 comments on commit 4ef9a64

Please sign in to comment.