mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-10-22 02:36:15 +03:00
parent
773cb1e55d
commit
d5e41bf679
23 changed files with 477 additions and 256 deletions
|
@ -32,6 +32,7 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include "base/bittorrent/sharelimitaction.h"
|
||||
#include "base/bittorrent/torrentcontentlayout.h"
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
|
@ -45,7 +46,7 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
const int MIGRATION_VERSION = 6;
|
||||
const int MIGRATION_VERSION = 7;
|
||||
const QString MIGRATION_VERSION_KEY = u"Meta/MigrationVersion"_s;
|
||||
|
||||
void exportWebUIHttpsFiles()
|
||||
|
@ -437,6 +438,36 @@ namespace
|
|||
settingsStorage->storeValue(key, u"zh_CN"_s);
|
||||
}
|
||||
}
|
||||
|
||||
void migrateShareLimitActionSettings()
|
||||
{
|
||||
auto *settingsStorage = SettingsStorage::instance();
|
||||
const auto oldKey = u"BitTorrent/Session/MaxRatioAction"_s;
|
||||
const auto newKey = u"BitTorrent/Session/ShareLimitAction"_s;
|
||||
const auto value = settingsStorage->loadValue<int>(oldKey);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
settingsStorage->storeValue(newKey, BitTorrent::ShareLimitAction::Stop);
|
||||
break;
|
||||
case 1:
|
||||
settingsStorage->storeValue(newKey, BitTorrent::ShareLimitAction::Remove);
|
||||
break;
|
||||
case 2:
|
||||
settingsStorage->storeValue(newKey, BitTorrent::ShareLimitAction::EnableSuperSeeding);
|
||||
break;
|
||||
case 3:
|
||||
settingsStorage->storeValue(newKey, BitTorrent::ShareLimitAction::RemoveWithContent);
|
||||
break;
|
||||
default:
|
||||
LogMsg(QCoreApplication::translate("Upgrade", "Invalid value found in configuration file, reverting it to default. Key: \"%1\". Invalid value: \"%2\".")
|
||||
.arg(oldKey, QString::number(value)), Log::WARNING);
|
||||
break;
|
||||
}
|
||||
|
||||
settingsStorage->removeValue(oldKey);
|
||||
}
|
||||
}
|
||||
|
||||
bool upgrade()
|
||||
|
@ -475,6 +506,9 @@ bool upgrade()
|
|||
if (version < 6)
|
||||
migrateProxySettings();
|
||||
|
||||
if (version < 7)
|
||||
migrateShareLimitActionSettings();
|
||||
|
||||
version = MIGRATION_VERSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ add_library(qbt_base STATIC
|
|||
bittorrent/session.h
|
||||
bittorrent/sessionimpl.h
|
||||
bittorrent/sessionstatus.h
|
||||
bittorrent/sharelimitaction.h
|
||||
bittorrent/speedmonitor.h
|
||||
bittorrent/sslparameters.h
|
||||
bittorrent/torrent.h
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -51,6 +51,7 @@ const QString PARAM_UPLOADLIMIT = u"upload_limit"_s;
|
|||
const QString PARAM_DOWNLOADLIMIT = u"download_limit"_s;
|
||||
const QString PARAM_SEEDINGTIMELIMIT = u"seeding_time_limit"_s;
|
||||
const QString PARAM_INACTIVESEEDINGTIMELIMIT = u"inactive_seeding_time_limit"_s;
|
||||
const QString PARAM_SHARELIMITACTION = u"share_limit_action"_s;
|
||||
const QString PARAM_RATIOLIMIT = u"ratio_limit"_s;
|
||||
const QString PARAM_SSL_CERTIFICATE = u"ssl_certificate"_s;
|
||||
const QString PARAM_SSL_PRIVATEKEY = u"ssl_private_key"_s;
|
||||
|
@ -96,10 +97,10 @@ namespace
|
|||
}
|
||||
|
||||
template <typename Enum>
|
||||
Enum getEnum(const QJsonObject &jsonObj, const QString &key)
|
||||
Enum getEnum(const QJsonObject &jsonObj, const QString &key, const Enum defaultValue = {})
|
||||
{
|
||||
const QJsonValue jsonVal = jsonObj.value(key);
|
||||
return Utils::String::toEnum<Enum>(jsonVal.toString(), {});
|
||||
return Utils::String::toEnum<Enum>(jsonVal.toString(), defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +128,7 @@ BitTorrent::AddTorrentParams BitTorrent::parseAddTorrentParams(const QJsonObject
|
|||
.seedingTimeLimit = jsonObj.value(PARAM_SEEDINGTIMELIMIT).toInt(Torrent::USE_GLOBAL_SEEDING_TIME),
|
||||
.inactiveSeedingTimeLimit = jsonObj.value(PARAM_INACTIVESEEDINGTIMELIMIT).toInt(Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME),
|
||||
.ratioLimit = jsonObj.value(PARAM_RATIOLIMIT).toDouble(Torrent::USE_GLOBAL_RATIO),
|
||||
.shareLimitAction = getEnum<ShareLimitAction>(jsonObj, PARAM_SHARELIMITACTION, ShareLimitAction::Default),
|
||||
.sslParameters =
|
||||
{
|
||||
.certificate = QSslCertificate(jsonObj.value(PARAM_SSL_CERTIFICATE).toString().toLatin1()),
|
||||
|
@ -152,6 +154,7 @@ QJsonObject BitTorrent::serializeAddTorrentParams(const AddTorrentParams ¶ms
|
|||
{PARAM_DOWNLOADLIMIT, params.downloadLimit},
|
||||
{PARAM_SEEDINGTIMELIMIT, params.seedingTimeLimit},
|
||||
{PARAM_INACTIVESEEDINGTIMELIMIT, params.inactiveSeedingTimeLimit},
|
||||
{PARAM_SHARELIMITACTION, Utils::String::fromEnum(params.shareLimitAction)},
|
||||
{PARAM_RATIOLIMIT, params.ratioLimit},
|
||||
{PARAM_SSL_CERTIFICATE, QString::fromLatin1(params.sslParameters.certificate.toPem())},
|
||||
{PARAM_SSL_PRIVATEKEY, QString::fromLatin1(params.sslParameters.privateKey.toPem())},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "base/path.h"
|
||||
#include "base/tagset.h"
|
||||
#include "sharelimitaction.h"
|
||||
#include "sslparameters.h"
|
||||
#include "torrent.h"
|
||||
#include "torrentcontentlayout.h"
|
||||
|
@ -70,6 +71,7 @@ namespace BitTorrent
|
|||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
||||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
||||
SSLParameters sslParameters;
|
||||
|
||||
friend bool operator==(const AddTorrentParams &lhs, const AddTorrentParams &rhs) = default;
|
||||
|
|
|
@ -231,6 +231,8 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::loadTorre
|
|||
torrentParams.firstLastPiecePriority = resumeDataRoot.dict_find_int_value("qBt-firstLastPiecePriority");
|
||||
torrentParams.seedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-seedingTimeLimit", Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||
torrentParams.inactiveSeedingTimeLimit = resumeDataRoot.dict_find_int_value("qBt-inactiveSeedingTimeLimit", Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
||||
torrentParams.shareLimitAction = Utils::String::toEnum(
|
||||
fromLTString(resumeDataRoot.dict_find_string_value("qBt-shareLimitAction")), ShareLimitAction::Default);
|
||||
|
||||
torrentParams.savePath = Profile::instance()->fromPortablePath(
|
||||
Path(fromLTString(resumeDataRoot.dict_find_string_value("qBt-savePath"))));
|
||||
|
@ -418,6 +420,8 @@ void BitTorrent::BencodeResumeDataStorage::Worker::store(const TorrentID &id, co
|
|||
data["qBt-ratioLimit"] = static_cast<int>(resumeData.ratioLimit * 1000);
|
||||
data["qBt-seedingTimeLimit"] = resumeData.seedingTimeLimit;
|
||||
data["qBt-inactiveSeedingTimeLimit"] = resumeData.inactiveSeedingTimeLimit;
|
||||
data["qBt-shareLimitAction"] = Utils::String::fromEnum(resumeData.shareLimitAction).toStdString();
|
||||
|
||||
data["qBt-category"] = resumeData.category.toStdString();
|
||||
data["qBt-tags"] = setToEntryList(resumeData.tags);
|
||||
data["qBt-name"] = resumeData.name.toStdString();
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace
|
|||
{
|
||||
const QString DB_CONNECTION_NAME = u"ResumeDataStorage"_s;
|
||||
|
||||
const int DB_VERSION = 6;
|
||||
const int DB_VERSION = 7;
|
||||
|
||||
const QString DB_TABLE_META = u"meta"_s;
|
||||
const QString DB_TABLE_TORRENTS = u"torrents"_s;
|
||||
|
@ -138,6 +138,7 @@ namespace
|
|||
const Column DB_COLUMN_RATIO_LIMIT = makeColumn("ratio_limit");
|
||||
const Column DB_COLUMN_SEEDING_TIME_LIMIT = makeColumn("seeding_time_limit");
|
||||
const Column DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT = makeColumn("inactive_seeding_time_limit");
|
||||
const Column DB_COLUMN_SHARE_LIMIT_ACTION = makeColumn("share_limit_action");
|
||||
const Column DB_COLUMN_HAS_OUTER_PIECES_PRIORITY = makeColumn("has_outer_pieces_priority");
|
||||
const Column DB_COLUMN_HAS_SEED_STATUS = makeColumn("has_seed_status");
|
||||
const Column DB_COLUMN_OPERATING_MODE = makeColumn("operating_mode");
|
||||
|
@ -234,6 +235,8 @@ namespace
|
|||
resumeData.ratioLimit = query.value(DB_COLUMN_RATIO_LIMIT.name).toInt() / 1000.0;
|
||||
resumeData.seedingTimeLimit = query.value(DB_COLUMN_SEEDING_TIME_LIMIT.name).toInt();
|
||||
resumeData.inactiveSeedingTimeLimit = query.value(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT.name).toInt();
|
||||
resumeData.shareLimitAction = Utils::String::toEnum<ShareLimitAction>(
|
||||
query.value(DB_COLUMN_SHARE_LIMIT_ACTION.name).toString(), ShareLimitAction::Default);
|
||||
resumeData.contentLayout = Utils::String::toEnum<TorrentContentLayout>(
|
||||
query.value(DB_COLUMN_CONTENT_LAYOUT.name).toString(), TorrentContentLayout::Original);
|
||||
resumeData.operatingMode = Utils::String::toEnum<TorrentOperatingMode>(
|
||||
|
@ -540,6 +543,7 @@ void BitTorrent::DBResumeDataStorage::createDB() const
|
|||
makeColumnDefinition(DB_COLUMN_RATIO_LIMIT, "INTEGER NOT NULL"),
|
||||
makeColumnDefinition(DB_COLUMN_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"),
|
||||
makeColumnDefinition(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT, "INTEGER NOT NULL"),
|
||||
makeColumnDefinition(DB_COLUMN_SHARE_LIMIT_ACTION, "TEXT NOT NULL DEFAULT `Default`"),
|
||||
makeColumnDefinition(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY, "INTEGER NOT NULL"),
|
||||
makeColumnDefinition(DB_COLUMN_HAS_SEED_STATUS, "INTEGER NOT NULL"),
|
||||
makeColumnDefinition(DB_COLUMN_OPERATING_MODE, "TEXT NOT NULL"),
|
||||
|
@ -623,6 +627,9 @@ void BitTorrent::DBResumeDataStorage::updateDB(const int fromVersion) const
|
|||
addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SSL_DH_PARAMS, "TEXT");
|
||||
}
|
||||
|
||||
if (fromVersion <= 6)
|
||||
addColumn(DB_TABLE_TORRENTS, DB_COLUMN_SHARE_LIMIT_ACTION, "TEXTNOT NULL DEFAULT `Default`");
|
||||
|
||||
const QString updateMetaVersionQuery = makeUpdateStatement(DB_TABLE_META, {DB_COLUMN_NAME, DB_COLUMN_VALUE});
|
||||
if (!query.prepare(updateMetaVersionQuery))
|
||||
throw RuntimeError(query.lastError().text());
|
||||
|
@ -801,6 +808,7 @@ namespace
|
|||
DB_COLUMN_RATIO_LIMIT,
|
||||
DB_COLUMN_SEEDING_TIME_LIMIT,
|
||||
DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT,
|
||||
DB_COLUMN_SHARE_LIMIT_ACTION,
|
||||
DB_COLUMN_HAS_OUTER_PIECES_PRIORITY,
|
||||
DB_COLUMN_HAS_SEED_STATUS,
|
||||
DB_COLUMN_OPERATING_MODE,
|
||||
|
@ -863,6 +871,7 @@ namespace
|
|||
query.bindValue(DB_COLUMN_RATIO_LIMIT.placeholder, static_cast<int>(m_resumeData.ratioLimit * 1000));
|
||||
query.bindValue(DB_COLUMN_SEEDING_TIME_LIMIT.placeholder, m_resumeData.seedingTimeLimit);
|
||||
query.bindValue(DB_COLUMN_INACTIVE_SEEDING_TIME_LIMIT.placeholder, m_resumeData.inactiveSeedingTimeLimit);
|
||||
query.bindValue(DB_COLUMN_SHARE_LIMIT_ACTION.placeholder, Utils::String::fromEnum(m_resumeData.shareLimitAction));
|
||||
query.bindValue(DB_COLUMN_HAS_OUTER_PIECES_PRIORITY.placeholder, m_resumeData.firstLastPiecePriority);
|
||||
query.bindValue(DB_COLUMN_HAS_SEED_STATUS.placeholder, m_resumeData.hasFinishedStatus);
|
||||
query.bindValue(DB_COLUMN_OPERATING_MODE.placeholder, Utils::String::fromEnum(m_resumeData.operatingMode));
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2021 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2021-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "base/path.h"
|
||||
#include "base/tagset.h"
|
||||
#include "sharelimitaction.h"
|
||||
#include "sslparameters.h"
|
||||
#include "torrent.h"
|
||||
#include "torrentcontentlayout.h"
|
||||
|
@ -62,6 +63,8 @@ namespace BitTorrent
|
|||
qreal ratioLimit = Torrent::USE_GLOBAL_RATIO;
|
||||
int seedingTimeLimit = Torrent::USE_GLOBAL_SEEDING_TIME;
|
||||
int inactiveSeedingTimeLimit = Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME;
|
||||
ShareLimitAction shareLimitAction = ShareLimitAction::Default;
|
||||
|
||||
SSLParameters sslParameters;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -36,20 +36,11 @@
|
|||
#include "base/tagset.h"
|
||||
#include "addtorrentparams.h"
|
||||
#include "categoryoptions.h"
|
||||
#include "sharelimitaction.h"
|
||||
#include "trackerentry.h"
|
||||
|
||||
class QString;
|
||||
|
||||
// These values should remain unchanged when adding new items
|
||||
// so as not to break the existing user settings.
|
||||
enum MaxRatioAction
|
||||
{
|
||||
Pause = 0,
|
||||
Remove = 1,
|
||||
DeleteFiles = 3,
|
||||
EnableSuperSeeding = 2
|
||||
};
|
||||
|
||||
enum DeleteOption
|
||||
{
|
||||
DeleteTorrent,
|
||||
|
@ -209,6 +200,9 @@ namespace BitTorrent
|
|||
virtual void setGlobalMaxSeedingMinutes(int minutes) = 0;
|
||||
virtual int globalMaxInactiveSeedingMinutes() const = 0;
|
||||
virtual void setGlobalMaxInactiveSeedingMinutes(int minutes) = 0;
|
||||
virtual ShareLimitAction shareLimitAction() const = 0;
|
||||
virtual void setShareLimitAction(ShareLimitAction act) = 0;
|
||||
|
||||
virtual QString getDHTBootstrapNodes() const = 0;
|
||||
virtual void setDHTBootstrapNodes(const QString &nodes) = 0;
|
||||
virtual bool isDHTEnabled() const = 0;
|
||||
|
@ -446,9 +440,6 @@ namespace BitTorrent
|
|||
virtual const CacheStatus &cacheStatus() const = 0;
|
||||
virtual bool isListening() const = 0;
|
||||
|
||||
virtual MaxRatioAction maxRatioAction() const = 0;
|
||||
virtual void setMaxRatioAction(MaxRatioAction act) = 0;
|
||||
|
||||
virtual void banIP(const QString &ip) = 0;
|
||||
|
||||
virtual bool isKnownTorrent(const InfoHash &infoHash) const = 0;
|
||||
|
|
|
@ -492,7 +492,8 @@ SessionImpl::SessionImpl(QObject *parent)
|
|||
, m_seedChokingAlgorithm(BITTORRENT_SESSION_KEY(u"SeedChokingAlgorithm"_s), SeedChokingAlgorithm::FastestUpload
|
||||
, clampValue(SeedChokingAlgorithm::RoundRobin, SeedChokingAlgorithm::AntiLeech))
|
||||
, m_storedTags(BITTORRENT_SESSION_KEY(u"Tags"_s))
|
||||
, m_maxRatioAction(BITTORRENT_SESSION_KEY(u"MaxRatioAction"_s), Pause)
|
||||
, m_shareLimitAction(BITTORRENT_SESSION_KEY(u"ShareLimitAction"_s), ShareLimitAction::Stop
|
||||
, [](const ShareLimitAction action) { return (action == ShareLimitAction::Default) ? ShareLimitAction::Stop : action; })
|
||||
, m_savePath(BITTORRENT_SESSION_KEY(u"DefaultSavePath"_s), specialFolderLocation(SpecialFolder::Downloads))
|
||||
, m_downloadPath(BITTORRENT_SESSION_KEY(u"TempPath"_s), (savePath() / Path(u"temp"_s)))
|
||||
, m_isDownloadPathEnabled(BITTORRENT_SESSION_KEY(u"TempPathEnabled"_s), false)
|
||||
|
@ -2219,9 +2220,7 @@ void SessionImpl::populateAdditionalTrackers()
|
|||
|
||||
void SessionImpl::processShareLimits()
|
||||
{
|
||||
qDebug("Processing share limits...");
|
||||
|
||||
const auto resolveLimitValue = []<typename T>(const T limit, const T useGlobalLimit, const T globalLimit) -> T
|
||||
const auto effectiveLimit = []<typename T>(const T limit, const T useGlobalLimit, const T globalLimit) -> T
|
||||
{
|
||||
return (limit == useGlobalLimit) ? globalLimit : limit;
|
||||
};
|
||||
|
@ -2234,108 +2233,57 @@ void SessionImpl::processShareLimits()
|
|||
if (!torrent->isFinished() || torrent->isForced())
|
||||
continue;
|
||||
|
||||
if (const qreal ratioLimit = resolveLimitValue(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
|
||||
ratioLimit >= 0)
|
||||
{
|
||||
const qreal ratio = torrent->realRatio();
|
||||
qDebug("Ratio: %f (limit: %f)", ratio, ratioLimit);
|
||||
const qreal ratioLimit = effectiveLimit(torrent->ratioLimit(), Torrent::USE_GLOBAL_RATIO, globalMaxRatio());
|
||||
const int seedingTimeLimit = effectiveLimit(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
|
||||
const int inactiveSeedingTimeLimit = effectiveLimit(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
|
||||
|
||||
if ((ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit))
|
||||
bool reached = false;
|
||||
QString description;
|
||||
|
||||
if (const qreal ratio = torrent->realRatio();
|
||||
(ratioLimit >= 0) && (ratio <= Torrent::MAX_RATIO) && (ratio >= ratioLimit))
|
||||
{
|
||||
reached = true;
|
||||
description = tr("Torrent reached the share ratio limit.");
|
||||
}
|
||||
else if (const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60;
|
||||
(seedingTimeLimit >= 0) && (seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
|
||||
{
|
||||
reached = true;
|
||||
description = tr("Torrent reached the seeding time limit.");
|
||||
}
|
||||
else if (const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60;
|
||||
(inactiveSeedingTimeLimit >= 0) && (inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit))
|
||||
{
|
||||
reached = true;
|
||||
description = tr("Torrent reached the inactive seeding time limit.");
|
||||
}
|
||||
|
||||
if (reached)
|
||||
{
|
||||
const QString description = tr("Torrent reached the share ratio limit.");
|
||||
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
||||
const ShareLimitAction shareLimitAction = (torrent->shareLimitAction() == ShareLimitAction::Default) ? m_shareLimitAction : torrent->shareLimitAction();
|
||||
|
||||
if (m_maxRatioAction == Remove)
|
||||
if (shareLimitAction == ShareLimitAction::Remove)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent."), torrentName));
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent."), torrentName));
|
||||
deleteTorrent(torrentID);
|
||||
}
|
||||
else if (m_maxRatioAction == DeleteFiles)
|
||||
else if (shareLimitAction == ShareLimitAction::RemoveWithContent)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent and deleted its content."), torrentName));
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removing torrent and deleting its content."), torrentName));
|
||||
deleteTorrent(torrentID, DeleteTorrentAndFiles);
|
||||
}
|
||||
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||
else if ((shareLimitAction == ShareLimitAction::Stop) && !torrent->isPaused())
|
||||
{
|
||||
torrent->pause();
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent paused."), torrentName));
|
||||
}
|
||||
else if ((m_maxRatioAction == EnableSuperSeeding) && !torrent->isPaused() && !torrent->superSeeding())
|
||||
else if ((shareLimitAction == ShareLimitAction::EnableSuperSeeding) && !torrent->isPaused() && !torrent->superSeeding())
|
||||
{
|
||||
torrent->setSuperSeeding(true);
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (const int seedingTimeLimit = resolveLimitValue(torrent->seedingTimeLimit(), Torrent::USE_GLOBAL_SEEDING_TIME, globalMaxSeedingMinutes());
|
||||
seedingTimeLimit >= 0)
|
||||
{
|
||||
const qlonglong seedingTimeInMinutes = torrent->finishedTime() / 60;
|
||||
|
||||
if ((seedingTimeInMinutes <= Torrent::MAX_SEEDING_TIME) && (seedingTimeInMinutes >= seedingTimeLimit))
|
||||
{
|
||||
const QString description = tr("Torrent reached the seeding time limit.");
|
||||
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
||||
|
||||
if (m_maxRatioAction == Remove)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent."), torrentName));
|
||||
deleteTorrent(torrentID);
|
||||
}
|
||||
else if (m_maxRatioAction == DeleteFiles)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent and deleted its content."), torrentName));
|
||||
deleteTorrent(torrentID, DeleteTorrentAndFiles);
|
||||
}
|
||||
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||
{
|
||||
torrent->pause();
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent paused."), torrentName));
|
||||
}
|
||||
else if ((m_maxRatioAction == EnableSuperSeeding) && !torrent->isPaused() && !torrent->superSeeding())
|
||||
{
|
||||
torrent->setSuperSeeding(true);
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (const int inactiveSeedingTimeLimit = resolveLimitValue(torrent->inactiveSeedingTimeLimit(), Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME, globalMaxInactiveSeedingMinutes());
|
||||
inactiveSeedingTimeLimit >= 0)
|
||||
{
|
||||
const qlonglong inactiveSeedingTimeInMinutes = torrent->timeSinceActivity() / 60;
|
||||
|
||||
if ((inactiveSeedingTimeInMinutes <= Torrent::MAX_INACTIVE_SEEDING_TIME) && (inactiveSeedingTimeInMinutes >= inactiveSeedingTimeLimit))
|
||||
{
|
||||
const QString description = tr("Torrent reached the inactive seeding time limit.");
|
||||
const QString torrentName = tr("Torrent: \"%1\".").arg(torrent->name());
|
||||
|
||||
if (m_maxRatioAction == Remove)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent."), torrentName));
|
||||
deleteTorrent(torrentID);
|
||||
}
|
||||
else if (m_maxRatioAction == DeleteFiles)
|
||||
{
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Removed torrent and deleted its content."), torrentName));
|
||||
deleteTorrent(torrentID, DeleteTorrentAndFiles);
|
||||
}
|
||||
else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
|
||||
{
|
||||
torrent->pause();
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Torrent paused."), torrentName));
|
||||
}
|
||||
else if ((m_maxRatioAction == EnableSuperSeeding) && !torrent->isPaused() && !torrent->superSeeding())
|
||||
{
|
||||
torrent->setSuperSeeding(true);
|
||||
LogMsg(u"%1 %2 %3"_s.arg(description, tr("Super seeding enabled."), torrentName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2654,6 +2602,7 @@ LoadTorrentParams SessionImpl::initLoadTorrentParams(const AddTorrentParams &add
|
|||
loadTorrentParams.ratioLimit = addTorrentParams.ratioLimit;
|
||||
loadTorrentParams.seedingTimeLimit = addTorrentParams.seedingTimeLimit;
|
||||
loadTorrentParams.inactiveSeedingTimeLimit = addTorrentParams.inactiveSeedingTimeLimit;
|
||||
loadTorrentParams.shareLimitAction = addTorrentParams.shareLimitAction;
|
||||
loadTorrentParams.sslParameters = addTorrentParams.sslParameters;
|
||||
|
||||
const QString category = addTorrentParams.category;
|
||||
|
@ -4832,14 +4781,16 @@ bool SessionImpl::isListening() const
|
|||
return m_nativeSessionExtension->isSessionListening();
|
||||
}
|
||||
|
||||
MaxRatioAction SessionImpl::maxRatioAction() const
|
||||
ShareLimitAction SessionImpl::shareLimitAction() const
|
||||
{
|
||||
return static_cast<MaxRatioAction>(m_maxRatioAction.get());
|
||||
return m_shareLimitAction;
|
||||
}
|
||||
|
||||
void SessionImpl::setMaxRatioAction(const MaxRatioAction act)
|
||||
void SessionImpl::setShareLimitAction(const ShareLimitAction act)
|
||||
{
|
||||
m_maxRatioAction = static_cast<int>(act);
|
||||
Q_ASSERT(act != ShareLimitAction::Default);
|
||||
|
||||
m_shareLimitAction = act;
|
||||
}
|
||||
|
||||
bool SessionImpl::isKnownTorrent(const InfoHash &infoHash) const
|
||||
|
|
|
@ -176,6 +176,9 @@ namespace BitTorrent
|
|||
void setGlobalMaxSeedingMinutes(int minutes) override;
|
||||
int globalMaxInactiveSeedingMinutes() const override;
|
||||
void setGlobalMaxInactiveSeedingMinutes(int minutes) override;
|
||||
ShareLimitAction shareLimitAction() const override;
|
||||
void setShareLimitAction(ShareLimitAction act) override;
|
||||
|
||||
QString getDHTBootstrapNodes() const override;
|
||||
void setDHTBootstrapNodes(const QString &nodes) override;
|
||||
bool isDHTEnabled() const override;
|
||||
|
@ -413,9 +416,6 @@ namespace BitTorrent
|
|||
const CacheStatus &cacheStatus() const override;
|
||||
bool isListening() const override;
|
||||
|
||||
MaxRatioAction maxRatioAction() const override;
|
||||
void setMaxRatioAction(MaxRatioAction act) override;
|
||||
|
||||
void banIP(const QString &ip) override;
|
||||
|
||||
bool isKnownTorrent(const InfoHash &infoHash) const override;
|
||||
|
@ -692,7 +692,7 @@ namespace BitTorrent
|
|||
CachedSettingValue<ChokingAlgorithm> m_chokingAlgorithm;
|
||||
CachedSettingValue<SeedChokingAlgorithm> m_seedChokingAlgorithm;
|
||||
CachedSettingValue<QStringList> m_storedTags;
|
||||
CachedSettingValue<int> m_maxRatioAction;
|
||||
CachedSettingValue<ShareLimitAction> m_shareLimitAction;
|
||||
CachedSettingValue<Path> m_savePath;
|
||||
CachedSettingValue<Path> m_downloadPath;
|
||||
CachedSettingValue<bool> m_isDownloadPathEnabled;
|
||||
|
|
57
src/base/bittorrent/sharelimitaction.h
Normal file
57
src/base/bittorrent/sharelimitaction.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* In addition, as a special exception, the copyright holders give permission to
|
||||
* link this program with the OpenSSL project's "OpenSSL" library (or with
|
||||
* modified versions of it that use the same license as the "OpenSSL" library),
|
||||
* and distribute the linked executables. You must obey the GNU General Public
|
||||
* License in all respects for all of the code used other than "OpenSSL". If you
|
||||
* modify file(s), you may extend this exception to your version of the file(s),
|
||||
* but you are not obligated to do so. If you do not wish to do so, delete this
|
||||
* exception statement from your version.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
namespace BitTorrent
|
||||
{
|
||||
// Using `Q_ENUM_NS()` without a wrapper namespace in our case is not advised
|
||||
// since `Q_NAMESPACE` cannot be used when the same namespace resides at different files.
|
||||
// https://www.kdab.com/new-qt-5-8-meta-object-support-namespaces/#comment-143779
|
||||
inline namespace ShareLimitActionNS
|
||||
{
|
||||
Q_NAMESPACE
|
||||
|
||||
// These values should remain unchanged when adding new items
|
||||
// so as not to break the existing user settings.
|
||||
enum class ShareLimitAction
|
||||
{
|
||||
Default = -1, // special value
|
||||
|
||||
Stop = 0,
|
||||
Remove = 1,
|
||||
RemoveWithContent = 3,
|
||||
EnableSuperSeeding = 2
|
||||
};
|
||||
|
||||
Q_ENUM_NS(ShareLimitAction)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -37,6 +37,7 @@
|
|||
#include "base/3rdparty/expected.hpp"
|
||||
#include "base/pathfwd.h"
|
||||
#include "base/tagset.h"
|
||||
#include "sharelimitaction.h"
|
||||
#include "torrentcontenthandler.h"
|
||||
|
||||
class QBitArray;
|
||||
|
@ -212,9 +213,16 @@ namespace BitTorrent
|
|||
virtual int piecesHave() const = 0;
|
||||
virtual qreal progress() const = 0;
|
||||
virtual QDateTime addedTime() const = 0;
|
||||
|
||||
// Share limits
|
||||
virtual qreal ratioLimit() const = 0;
|
||||
virtual void setRatioLimit(qreal limit) = 0;
|
||||
virtual int seedingTimeLimit() const = 0;
|
||||
virtual void setSeedingTimeLimit(int limit) = 0;
|
||||
virtual int inactiveSeedingTimeLimit() const = 0;
|
||||
virtual void setInactiveSeedingTimeLimit(int limit) = 0;
|
||||
virtual ShareLimitAction shareLimitAction() const = 0;
|
||||
virtual void setShareLimitAction(ShareLimitAction action) = 0;
|
||||
|
||||
virtual PathList filePaths() const = 0;
|
||||
|
||||
|
@ -287,9 +295,6 @@ namespace BitTorrent
|
|||
virtual void forceReannounce(int index = -1) = 0;
|
||||
virtual void forceDHTAnnounce() = 0;
|
||||
virtual void forceRecheck() = 0;
|
||||
virtual void setRatioLimit(qreal limit) = 0;
|
||||
virtual void setSeedingTimeLimit(int limit) = 0;
|
||||
virtual void setInactiveSeedingTimeLimit(int limit) = 0;
|
||||
virtual void setUploadLimit(int limit) = 0;
|
||||
virtual void setDownloadLimit(int limit) = 0;
|
||||
virtual void setSuperSeeding(bool enable) = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -298,6 +298,7 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
|
|||
, m_ratioLimit(params.ratioLimit)
|
||||
, m_seedingTimeLimit(params.seedingTimeLimit)
|
||||
, m_inactiveSeedingTimeLimit(params.inactiveSeedingTimeLimit)
|
||||
, m_shareLimitAction(params.shareLimitAction)
|
||||
, m_operatingMode(params.operatingMode)
|
||||
, m_contentLayout(params.contentLayout)
|
||||
, m_hasFinishedStatus(params.hasFinishedStatus)
|
||||
|
@ -2143,6 +2144,7 @@ void TorrentImpl::prepareResumeData(const lt::add_torrent_params ¶ms)
|
|||
.ratioLimit = m_ratioLimit,
|
||||
.seedingTimeLimit = m_seedingTimeLimit,
|
||||
.inactiveSeedingTimeLimit = m_inactiveSeedingTimeLimit,
|
||||
.shareLimitAction = m_shareLimitAction,
|
||||
.sslParameters = m_sslParams
|
||||
};
|
||||
|
||||
|
@ -2618,6 +2620,21 @@ void TorrentImpl::setInactiveSeedingTimeLimit(int limit)
|
|||
}
|
||||
}
|
||||
|
||||
ShareLimitAction TorrentImpl::shareLimitAction() const
|
||||
{
|
||||
return m_shareLimitAction;
|
||||
}
|
||||
|
||||
void TorrentImpl::setShareLimitAction(const ShareLimitAction action)
|
||||
{
|
||||
if (m_shareLimitAction != action)
|
||||
{
|
||||
m_shareLimitAction = action;
|
||||
deferredRequestResumeData();
|
||||
m_session->handleTorrentShareLimitChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentImpl::setUploadLimit(const int limit)
|
||||
{
|
||||
const int cleanValue = cleanLimitValue(limit);
|
||||
|
|
|
@ -139,9 +139,15 @@ namespace BitTorrent
|
|||
int piecesHave() const override;
|
||||
qreal progress() const override;
|
||||
QDateTime addedTime() const override;
|
||||
|
||||
qreal ratioLimit() const override;
|
||||
void setRatioLimit(qreal limit) override;
|
||||
int seedingTimeLimit() const override;
|
||||
void setSeedingTimeLimit(int limit) override;
|
||||
int inactiveSeedingTimeLimit() const override;
|
||||
void setInactiveSeedingTimeLimit(int limit) override;
|
||||
ShareLimitAction shareLimitAction() const override;
|
||||
void setShareLimitAction(ShareLimitAction action) override;
|
||||
|
||||
Path filePath(int index) const override;
|
||||
Path actualFilePath(int index) const override;
|
||||
|
@ -223,9 +229,6 @@ namespace BitTorrent
|
|||
void forceRecheck() override;
|
||||
void renameFile(int index, const Path &path) override;
|
||||
void prioritizeFiles(const QVector<DownloadPriority> &priorities) override;
|
||||
void setRatioLimit(qreal limit) override;
|
||||
void setSeedingTimeLimit(int limit) override;
|
||||
void setInactiveSeedingTimeLimit(int limit) override;
|
||||
void setUploadLimit(int limit) override;
|
||||
void setDownloadLimit(int limit) override;
|
||||
void setSuperSeeding(bool enable) override;
|
||||
|
@ -356,16 +359,17 @@ namespace BitTorrent
|
|||
Path m_downloadPath;
|
||||
QString m_category;
|
||||
TagSet m_tags;
|
||||
qreal m_ratioLimit;
|
||||
int m_seedingTimeLimit;
|
||||
int m_inactiveSeedingTimeLimit;
|
||||
TorrentOperatingMode m_operatingMode;
|
||||
TorrentContentLayout m_contentLayout;
|
||||
bool m_hasFinishedStatus;
|
||||
qreal m_ratioLimit = 0;
|
||||
int m_seedingTimeLimit = 0;
|
||||
int m_inactiveSeedingTimeLimit = 0;
|
||||
ShareLimitAction m_shareLimitAction = ShareLimitAction::Default;
|
||||
TorrentOperatingMode m_operatingMode = TorrentOperatingMode::AutoManaged;
|
||||
TorrentContentLayout m_contentLayout = TorrentContentLayout::Original;
|
||||
bool m_hasFinishedStatus = false;
|
||||
bool m_hasMissingFiles = false;
|
||||
bool m_hasFirstLastPiecePriority = false;
|
||||
bool m_useAutoTMM;
|
||||
bool m_isStopped;
|
||||
bool m_useAutoTMM = false;
|
||||
bool m_isStopped = false;
|
||||
StopCondition m_stopCondition = StopCondition::None;
|
||||
SSLParameters m_sslParams;
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ BitTorrent::AddTorrentParams AddTorrentParamsWidget::addTorrentParams() const
|
|||
addTorrentParams.ratioLimit = m_ui->torrentShareLimitsWidget->ratioLimit().value();
|
||||
addTorrentParams.seedingTimeLimit = m_ui->torrentShareLimitsWidget->seedingTimeLimit().value();
|
||||
addTorrentParams.inactiveSeedingTimeLimit = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit().value();
|
||||
addTorrentParams.shareLimitAction = m_ui->torrentShareLimitsWidget->shareLimitAction().value();
|
||||
|
||||
return addTorrentParams;
|
||||
}
|
||||
|
@ -272,6 +273,7 @@ void AddTorrentParamsWidget::populate()
|
|||
m_ui->torrentShareLimitsWidget->setRatioLimit(m_addTorrentParams.ratioLimit);
|
||||
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(m_addTorrentParams.seedingTimeLimit);
|
||||
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(m_addTorrentParams.inactiveSeedingTimeLimit);
|
||||
m_ui->torrentShareLimitsWidget->setShareLimitAction(m_addTorrentParams.shareLimitAction);
|
||||
}
|
||||
|
||||
void AddTorrentParamsWidget::loadCustomSavePathOptions()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2023-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2024 Jonathan Ketchker
|
||||
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include <QTranslator>
|
||||
|
||||
#include "base/bittorrent/session.h"
|
||||
#include "base/bittorrent/sharelimitaction.h"
|
||||
#include "base/exceptions.h"
|
||||
#include "base/global.h"
|
||||
#include "base/net/portforwarder.h"
|
||||
|
@ -1110,14 +1111,14 @@ void OptionsDialog::loadBittorrentTabOptions()
|
|||
}
|
||||
m_ui->comboRatioLimitAct->setEnabled((session->globalMaxSeedingMinutes() >= 0) || (session->globalMaxRatio() >= 0.) || (session->globalMaxInactiveSeedingMinutes() >= 0));
|
||||
|
||||
const QHash<MaxRatioAction, int> actIndex =
|
||||
const QHash<BitTorrent::ShareLimitAction, int> actIndex =
|
||||
{
|
||||
{Pause, 0},
|
||||
{Remove, 1},
|
||||
{DeleteFiles, 2},
|
||||
{EnableSuperSeeding, 3}
|
||||
{BitTorrent::ShareLimitAction::Stop, 0},
|
||||
{BitTorrent::ShareLimitAction::Remove, 1},
|
||||
{BitTorrent::ShareLimitAction::RemoveWithContent, 2},
|
||||
{BitTorrent::ShareLimitAction::EnableSuperSeeding, 3}
|
||||
};
|
||||
m_ui->comboRatioLimitAct->setCurrentIndex(actIndex.value(session->maxRatioAction()));
|
||||
m_ui->comboRatioLimitAct->setCurrentIndex(actIndex.value(session->shareLimitAction()));
|
||||
|
||||
m_ui->checkEnableAddTrackers->setChecked(session->isAddTrackersEnabled());
|
||||
m_ui->textTrackers->setPlainText(session->additionalTrackers());
|
||||
|
@ -1181,14 +1182,14 @@ void OptionsDialog::saveBittorrentTabOptions() const
|
|||
session->setGlobalMaxRatio(getMaxRatio());
|
||||
session->setGlobalMaxSeedingMinutes(getMaxSeedingMinutes());
|
||||
session->setGlobalMaxInactiveSeedingMinutes(getMaxInactiveSeedingMinutes());
|
||||
const QVector<MaxRatioAction> actIndex =
|
||||
const QVector<BitTorrent::ShareLimitAction> actIndex =
|
||||
{
|
||||
Pause,
|
||||
Remove,
|
||||
DeleteFiles,
|
||||
EnableSuperSeeding
|
||||
BitTorrent::ShareLimitAction::Stop,
|
||||
BitTorrent::ShareLimitAction::Remove,
|
||||
BitTorrent::ShareLimitAction::RemoveWithContent,
|
||||
BitTorrent::ShareLimitAction::EnableSuperSeeding
|
||||
};
|
||||
session->setMaxRatioAction(actIndex.value(m_ui->comboRatioLimitAct->currentIndex()));
|
||||
session->setShareLimitAction(actIndex.value(m_ui->comboRatioLimitAct->currentIndex()));
|
||||
|
||||
session->setAddTrackersEnabled(m_ui->checkEnableAddTrackers->isChecked());
|
||||
session->setAdditionalTrackers(m_ui->textTrackers->toPlainText());
|
||||
|
|
|
@ -82,6 +82,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
bool allSameRatio = true;
|
||||
bool allSameSeedingTime = true;
|
||||
bool allSameInactiveSeedingTime = true;
|
||||
bool allSameShareLimitAction = true;
|
||||
bool allTorrentsArePrivate = true;
|
||||
bool allSameDHT = true;
|
||||
bool allSamePEX = true;
|
||||
|
@ -103,6 +104,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
const qreal firstTorrentRatio = torrents[0]->ratioLimit();
|
||||
const int firstTorrentSeedingTime = torrents[0]->seedingTimeLimit();
|
||||
const int firstTorrentInactiveSeedingTime = torrents[0]->inactiveSeedingTimeLimit();
|
||||
const BitTorrent::ShareLimitAction firstTorrentShareLimitAction = torrents[0]->shareLimitAction();
|
||||
|
||||
const bool isFirstTorrentDHTDisabled = torrents[0]->isDHTDisabled();
|
||||
const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
|
||||
|
@ -160,6 +162,11 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
if (torrent->inactiveSeedingTimeLimit() != firstTorrentInactiveSeedingTime)
|
||||
allSameInactiveSeedingTime = false;
|
||||
}
|
||||
if (allSameShareLimitAction)
|
||||
{
|
||||
if (torrent->shareLimitAction() != firstTorrentShareLimitAction)
|
||||
allSameShareLimitAction = false;
|
||||
}
|
||||
if (allTorrentsArePrivate)
|
||||
{
|
||||
if (!torrent->isPrivate())
|
||||
|
@ -289,6 +296,8 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
m_ui->torrentShareLimitsWidget->setSeedingTimeLimit(firstTorrentSeedingTime);
|
||||
if (allSameInactiveSeedingTime)
|
||||
m_ui->torrentShareLimitsWidget->setInactiveSeedingTimeLimit(firstTorrentInactiveSeedingTime);
|
||||
if (allSameShareLimitAction)
|
||||
m_ui->torrentShareLimitsWidget->setShareLimitAction(firstTorrentShareLimitAction);
|
||||
|
||||
if (!allTorrentsArePrivate)
|
||||
{
|
||||
|
@ -340,6 +349,7 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
|
|||
.ratio = m_ui->torrentShareLimitsWidget->ratioLimit(),
|
||||
.seedingTime = m_ui->torrentShareLimitsWidget->seedingTimeLimit(),
|
||||
.inactiveSeedingTime = m_ui->torrentShareLimitsWidget->inactiveSeedingTimeLimit(),
|
||||
.shareLimitAction = m_ui->torrentShareLimitsWidget->shareLimitAction(),
|
||||
.upSpeedLimit = m_ui->spinUploadLimit->value(),
|
||||
.downSpeedLimit = m_ui->spinDownloadLimit->value(),
|
||||
.autoTMM = m_ui->checkAutoTMM->checkState(),
|
||||
|
@ -440,6 +450,12 @@ void TorrentOptionsDialog::accept()
|
|||
torrent->setInactiveSeedingTimeLimit(inactiveSeedingTimeLimit.value());
|
||||
}
|
||||
|
||||
if (const std::optional<BitTorrent::ShareLimitAction> shareLimitAction = m_ui->torrentShareLimitsWidget->shareLimitAction();
|
||||
m_initialValues.shareLimitAction != shareLimitAction)
|
||||
{
|
||||
torrent->setShareLimitAction(shareLimitAction.value());
|
||||
}
|
||||
|
||||
if (!torrent->isPrivate())
|
||||
{
|
||||
if (m_initialValues.disableDHT != m_ui->checkDisableDHT->checkState())
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <QDialog>
|
||||
|
||||
#include "base/bittorrent/sharelimitaction.h"
|
||||
#include "base/path.h"
|
||||
#include "base/settingvalue.h"
|
||||
|
||||
|
@ -87,6 +88,7 @@ private:
|
|||
std::optional<qreal> ratio;
|
||||
std::optional<int> seedingTime;
|
||||
std::optional<int> inactiveSeedingTime;
|
||||
std::optional<BitTorrent::ShareLimitAction> shareLimitAction;
|
||||
int upSpeedLimit;
|
||||
int downSpeedLimit;
|
||||
Qt::CheckState autoTMM;
|
||||
|
|
|
@ -40,6 +40,16 @@ namespace
|
|||
UnlimitedModeIndex,
|
||||
AssignedModeIndex
|
||||
};
|
||||
|
||||
enum ShareLimitActionIndex
|
||||
{
|
||||
UninitializedActionIndex = -1,
|
||||
DefaultActionIndex,
|
||||
StopActionIndex,
|
||||
RemoveActionIndex,
|
||||
RemoveWithContentActionIndex,
|
||||
SuperSeedingActionIndex
|
||||
};
|
||||
}
|
||||
|
||||
TorrentShareLimitsWidget::TorrentShareLimitsWidget(QWidget *parent)
|
||||
|
@ -119,6 +129,29 @@ void TorrentShareLimitsWidget::setInactiveSeedingTimeLimit(const int inactiveSee
|
|||
}
|
||||
}
|
||||
|
||||
void TorrentShareLimitsWidget::setShareLimitAction(const BitTorrent::ShareLimitAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case BitTorrent::ShareLimitAction::Default:
|
||||
default:
|
||||
m_ui->comboBoxAction->setCurrentIndex(DefaultActionIndex);
|
||||
break;
|
||||
case BitTorrent::ShareLimitAction::Stop:
|
||||
m_ui->comboBoxAction->setCurrentIndex(StopActionIndex);
|
||||
break;
|
||||
case BitTorrent::ShareLimitAction::Remove:
|
||||
m_ui->comboBoxAction->setCurrentIndex(RemoveActionIndex);
|
||||
break;
|
||||
case BitTorrent::ShareLimitAction::RemoveWithContent:
|
||||
m_ui->comboBoxAction->setCurrentIndex(RemoveWithContentActionIndex);
|
||||
break;
|
||||
case BitTorrent::ShareLimitAction::EnableSuperSeeding:
|
||||
m_ui->comboBoxAction->setCurrentIndex(SuperSeedingActionIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentShareLimitsWidget::setDefaultLimits(const qreal ratioLimit, const int seedingTimeLimit, const int inactiveSeedingTimeLimit)
|
||||
{
|
||||
if (m_defaultRatioLimit != ratioLimit)
|
||||
|
@ -185,6 +218,25 @@ std::optional<int> TorrentShareLimitsWidget::inactiveSeedingTimeLimit() const
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<BitTorrent::ShareLimitAction> TorrentShareLimitsWidget::shareLimitAction() const
|
||||
{
|
||||
switch (m_ui->comboBoxAction->currentIndex())
|
||||
{
|
||||
case DefaultActionIndex:
|
||||
return BitTorrent::ShareLimitAction::Default;
|
||||
case StopActionIndex:
|
||||
return BitTorrent::ShareLimitAction::Stop;
|
||||
case RemoveActionIndex:
|
||||
return BitTorrent::ShareLimitAction::Remove;
|
||||
case RemoveWithContentActionIndex:
|
||||
return BitTorrent::ShareLimitAction::RemoveWithContent;
|
||||
case SuperSeedingActionIndex:
|
||||
return BitTorrent::ShareLimitAction::EnableSuperSeeding;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void TorrentShareLimitsWidget::refreshRatioLimitControls()
|
||||
{
|
||||
const auto index = m_ui->comboBoxRatioMode->currentIndex();
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
#include "base/bittorrent/sharelimitaction.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TorrentShareLimitsWidget;
|
||||
|
@ -49,12 +51,14 @@ public:
|
|||
void setRatioLimit(qreal ratioLimit);
|
||||
void setSeedingTimeLimit(int seedingTimeLimit);
|
||||
void setInactiveSeedingTimeLimit(int inactiveSeedingTimeLimit);
|
||||
void setShareLimitAction(BitTorrent::ShareLimitAction action);
|
||||
|
||||
void setDefaultLimits(qreal ratioLimit, int seedingTimeLimit, int inactiveSeedingTimeLimit);
|
||||
|
||||
std::optional<qreal> ratioLimit() const;
|
||||
std::optional<int> seedingTimeLimit() const;
|
||||
std::optional<int> inactiveSeedingTimeLimit() const;
|
||||
std::optional<BitTorrent::ShareLimitAction> shareLimitAction() const;
|
||||
|
||||
private:
|
||||
void refreshRatioLimitControls();
|
||||
|
|
|
@ -6,47 +6,13 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>365</width>
|
||||
<height>106</height>
|
||||
<width>445</width>
|
||||
<height>132</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxRatioMode">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unlimited</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set to</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<layout class="QGridLayout" name="limitsLayout">
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxInactiveSeedingTimeMode">
|
||||
<property name="currentIndex">
|
||||
|
@ -69,58 +35,6 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelSeedingTime">
|
||||
<property name="text">
|
||||
<string>Seeding time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="spinBoxInactiveSeedingTimeValue">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string extracomment="minutes"> min</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1440</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelInactiveSeedingTime">
|
||||
<property name="text">
|
||||
<string>Inactive seeding time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSeedingTimeMode">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unlimited</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set to</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="spinBoxSeedingTimeValue">
|
||||
<property name="enabled">
|
||||
|
@ -137,6 +51,36 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelRatio">
|
||||
<property name="text">
|
||||
<string>Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelInactiveSeedingTime">
|
||||
<property name="text">
|
||||
<string>Inactive seeding time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="spinBoxInactiveSeedingTimeValue">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string extracomment="minutes"> min</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1440</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QDoubleSpinBox" name="spinBoxRatioValue">
|
||||
<property name="enabled">
|
||||
|
@ -153,15 +97,115 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelRatio">
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBoxSeedingTimeMode">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ratio:</string>
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unlimited</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set to</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBoxRatioMode">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unlimited</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Set to</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelSeedingTime">
|
||||
<property name="text">
|
||||
<string>Seeding time:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="actionLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelAction">
|
||||
<property name="text">
|
||||
<string>Action when the limit is reached:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBoxAction">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stop torrent</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Remove torrent</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Remove torrent and its content</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Enable super seeding for torrent</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="actionLayoutSpacer">
|
||||
<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>
|
||||
<resources/>
|
||||
|
|
|
@ -288,7 +288,7 @@ void AppController::preferencesAction()
|
|||
data[u"max_seeding_time"_s] = session->globalMaxSeedingMinutes();
|
||||
data[u"max_inactive_seeding_time_enabled"_s] = (session->globalMaxInactiveSeedingMinutes() >= 0.);
|
||||
data[u"max_inactive_seeding_time"_s] = session->globalMaxInactiveSeedingMinutes();
|
||||
data[u"max_ratio_act"_s] = session->maxRatioAction();
|
||||
data[u"max_ratio_act"_s] = static_cast<int>(session->shareLimitAction());
|
||||
// Add trackers
|
||||
data[u"add_trackers_enabled"_s] = session->isAddTrackersEnabled();
|
||||
data[u"add_trackers"_s] = session->additionalTrackers();
|
||||
|
@ -812,7 +812,24 @@ void AppController::setPreferencesAction()
|
|||
? m[u"max_inactive_seeding_time"_s].toInt() : -1);
|
||||
}
|
||||
if (hasKey(u"max_ratio_act"_s))
|
||||
session->setMaxRatioAction(static_cast<MaxRatioAction>(it.value().toInt()));
|
||||
{
|
||||
switch (it.value().toInt())
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
session->setShareLimitAction(BitTorrent::ShareLimitAction::Stop);
|
||||
break;
|
||||
case 1:
|
||||
session->setShareLimitAction(BitTorrent::ShareLimitAction::Remove);
|
||||
break;
|
||||
case 2:
|
||||
session->setShareLimitAction(BitTorrent::ShareLimitAction::EnableSuperSeeding);
|
||||
break;
|
||||
case 3:
|
||||
session->setShareLimitAction(BitTorrent::ShareLimitAction::RemoveWithContent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add trackers
|
||||
if (hasKey(u"add_trackers_enabled"_s))
|
||||
session->setAddTrackersEnabled(it.value().toBool());
|
||||
|
|
|
@ -697,6 +697,7 @@ void TorrentsController::addAction()
|
|||
const double ratioLimit = parseDouble(params()[u"ratioLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_RATIO);
|
||||
const int seedingTimeLimit = parseInt(params()[u"seedingTimeLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_SEEDING_TIME);
|
||||
const int inactiveSeedingTimeLimit = parseInt(params()[u"inactiveSeedingTimeLimit"_s]).value_or(BitTorrent::Torrent::USE_GLOBAL_INACTIVE_SEEDING_TIME);
|
||||
const BitTorrent::ShareLimitAction shareLimitAction = Utils::String::toEnum(params()[u"shareLimitAction"_s], BitTorrent::ShareLimitAction::Default);
|
||||
const std::optional<bool> autoTMM = parseBool(params()[u"autoTMM"_s]);
|
||||
|
||||
const QString stopConditionParam = params()[u"stopCondition"_s];
|
||||
|
@ -751,6 +752,7 @@ void TorrentsController::addAction()
|
|||
.seedingTimeLimit = seedingTimeLimit,
|
||||
.inactiveSeedingTimeLimit = inactiveSeedingTimeLimit,
|
||||
.ratioLimit = ratioLimit,
|
||||
.shareLimitAction = shareLimitAction,
|
||||
.sslParameters =
|
||||
{
|
||||
.certificate = QSslCertificate(params()[KEY_PROP_SSL_CERTIFICATE].toLatin1()),
|
||||
|
|
Loading…
Reference in a new issue