From 24f58f70ee2bf96bfb93fe9c3f9e8d6c90cb2bd9 Mon Sep 17 00:00:00 2001 From: Yat Ho Date: Tue, 11 Mar 2025 01:07:35 +0800 Subject: [PATCH] feat: sequential download in `settings.json` `torrent-add` and `sesssion-*` RPC methods (#7047) * feat: init sequential download setting from ctor * feat: `sequantialDownload` arg in `torrent-add` RPC method * feat: sequential download settings in settings.json * feat: sequential download arguments in `session-*` RPC methods * test: fix --- docs/Editing-Configuration-Files.md | 1 + docs/rpc-spec.md | 5 +++++ libtransmission/resume.cc | 9 +++++++++ libtransmission/rpcimpl.cc | 11 +++++++++++ libtransmission/session.h | 12 ++++++++++++ libtransmission/torrent-ctor.h | 14 ++++++++++++++ libtransmission/torrent.cc | 4 +++- tests/libtransmission/rpc-test.cc | 1 + 8 files changed, 56 insertions(+), 1 deletion(-) diff --git a/docs/Editing-Configuration-Files.md b/docs/Editing-Configuration-Files.md index 986e8e699..85c8cb3c9 100644 --- a/docs/Editing-Configuration-Files.md +++ b/docs/Editing-Configuration-Files.md @@ -103,6 +103,7 @@ Here is a sample of the three basic types: respectively Boolean, Number and Stri * **peer-limit-per-torrent:** Number (default = 50) * **peer-socket-tos:** String (default = "le") Set the [DiffServ](https://en.wikipedia.org/wiki/Differentiated_services) parameter for outgoing packets. Allowed values are lowercase DSCP names. See the `tr_tos_t` class from `libtransmission/net.h` for the exact list of possible values. * **reqq:** Number (default = 2000) The number of outstanding block requests a peer is allowed to queue in the client. The higher this number, the higher the max possible upload speed towards each peer. + * **sequentialDownload** Boolean (default = false) Enable sequential download by default when adding torrents. #### Peer Port * **peer-port:** Number (default = 51413) diff --git a/docs/rpc-spec.md b/docs/rpc-spec.md index 73b62c777..1719954dc 100644 --- a/docs/rpc-spec.md +++ b/docs/rpc-spec.md @@ -469,6 +469,7 @@ Request arguments: | `priority-high` | array | indices of high-priority file(s) | `priority-low` | array | indices of low-priority file(s) | `priority-normal` | array | indices of normal-priority file(s) +| `sequentialDownload` | boolean | download torrent pieces sequentially Either `filename` **or** `metainfo` **must** be included. All other arguments are optional. @@ -572,6 +573,7 @@ Response arguments: `path`, `name`, and `id`, holding the torrent ID integer | `seed-queue-size` | number | max number of torrents to uploaded at once (see seed-queue-enabled) | `seedRatioLimit` | double | the default seed ratio for torrents to use | `seedRatioLimited` | boolean | true if seedRatioLimit is honored by default +| `sequentialDownload` | boolean | true means sequential download is enabled by default for added torrents | `session-id` | string | the current `X-Transmission-Session-Id` value | `speed-limit-down-enabled` | boolean | true means enabled | `speed-limit-down` | number | max global download speed (KBps) @@ -1027,6 +1029,9 @@ Transmission 4.0.0 (`rpc-version-semver` 5.3.0, `rpc-version`: 17) Transmission 4.1.0 (`rpc-version-semver` 5.4.0, `rpc-version`: 18) | Method | Description |:---|:--- +| `session-get` | new arg `sequentialDownload` +| `session-set` | new arg `sequentialDownload` +| `torrent-add` | new arg `sequentialDownload` | `torrent-get` | new arg `sequentialDownload` | `torrent-set` | new arg `sequentialDownload` | `torrent-get` | new arg `files.beginPiece` diff --git a/libtransmission/resume.cc b/libtransmission/resume.cc index e6a14d325..25aa8225b 100644 --- a/libtransmission/resume.cc +++ b/libtransmission/resume.cc @@ -831,6 +831,15 @@ auto set_from_ctor( } } + if ((fields & tr_resume::SequentialDownload) != 0) + { + if (auto const& val = ctor.sequential_download(mode); val) + { + tor->set_sequential_download(*val); + ret |= tr_resume::SequentialDownload; + } + } + return ret; } diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc index 720502476..7256fa5af 100644 --- a/libtransmission/rpcimpl.cc +++ b/libtransmission/rpcimpl.cc @@ -1452,6 +1452,11 @@ char const* torrentAdd(tr_session* session, tr_variant::Map const& args_in, tr_r ctor.set_labels(std::move(labels)); } + if (auto const val = args_in.value_if(TR_KEY_sequentialDownload); val) + { + ctor.set_sequential_download(TR_FORCE, *val); + } + tr_logAddTrace(fmt::format("torrentAdd: filename is '{}'", filename)); if (isCurlURL(filename)) @@ -1839,6 +1844,11 @@ char const* sessionSet(tr_session* session, tr_variant::Map const& args_in, tr_v tr_sessionSetAntiBruteForceEnabled(session, *val); } + if (auto const val = args_in.value_if(TR_KEY_sequentialDownload); val) + { + session->set_sequential_download(*val); + } + session->rpcNotify(TR_RPC_SESSION_CHANGED, nullptr); return nullptr; @@ -1974,6 +1984,7 @@ char const* sessionStats(tr_session* session, tr_variant::Map const& /*args_in*/ case TR_KEY_seedRatioLimited: return session.isRatioLimited(); case TR_KEY_seed_queue_enabled: return session.queueEnabled(TR_UP); case TR_KEY_seed_queue_size: return session.queueSize(TR_UP); + case TR_KEY_sequentialDownload: return session.sequential_download(); case TR_KEY_session_id: return session.sessionId(); case TR_KEY_speed_limit_down: return session.speed_limit(TR_DOWN).count(Speed::Units::KByps); case TR_KEY_speed_limit_down_enabled: return session.is_speed_limited(TR_DOWN); diff --git a/libtransmission/session.h b/libtransmission/session.h index aa4e7aaf0..98dc91c9f 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -403,6 +403,7 @@ public: bool script_torrent_done_enabled = false; bool script_torrent_done_seeding_enabled = false; bool seed_queue_enabled = false; + bool sequential_download = false; bool should_delete_source_torrents = false; bool should_scrape_paused_torrents = true; bool should_start_added_torrents = true; @@ -495,6 +496,7 @@ public: { TR_KEY_script_torrent_done_seeding_filename, &script_torrent_done_seeding_filename }, { TR_KEY_seed_queue_enabled, &seed_queue_enabled }, { TR_KEY_seed_queue_size, &seed_queue_size }, + { TR_KEY_sequentialDownload, &sequential_download }, { TR_KEY_sleep_per_seconds_during_verify, &sleep_per_seconds_during_verify }, { TR_KEY_speed_limit_down, &speed_limit_down }, { TR_KEY_speed_limit_down_enabled, &speed_limit_down_enabled }, @@ -734,6 +736,16 @@ public: settings_.reqq = reqq; } + [[nodiscard]] constexpr auto sequential_download() const noexcept + { + return settings().sequential_download; + } + + void set_sequential_download(bool seq) noexcept + { + settings_.sequential_download = seq; + } + // bandwidth [[nodiscard]] tr_bandwidth& getBandwidthGroup(std::string_view name); diff --git a/libtransmission/torrent-ctor.h b/libtransmission/torrent-ctor.h index 7b6eb0cbd..bd84c3c99 100644 --- a/libtransmission/torrent-ctor.h +++ b/libtransmission/torrent-ctor.h @@ -150,6 +150,7 @@ public: { return labels_; } + void set_labels(tr_torrent::labels_t&& labels) { labels_ = std::move(labels); @@ -205,10 +206,23 @@ public: verify_done_callback_ = std::move(callback); } + // --- + + [[nodiscard]] constexpr auto const& sequential_download(tr_ctorMode const mode) const noexcept + { + return optional_args_[mode].sequential_download_; + } + + constexpr void set_sequential_download(tr_ctorMode const mode, bool const seq) noexcept + { + optional_args_[mode].sequential_download_ = seq; + } + private: struct OptionalArgs { std::optional paused_; + std::optional sequential_download_; std::optional peer_limit_; std::string download_dir_; }; diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index cdf635fb9..e7f4108a8 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -922,7 +922,9 @@ void tr_torrent::init(tr_ctor const& ctor) mark_changed(); - date_added_ = now_sec; // this is a default that will be overwritten by the resume file + // these are defaults that will be overwritten by the resume file + date_added_ = now_sec; + set_sequential_download(session->sequential_download()); tr_resume::fields_t loaded = {}; diff --git a/tests/libtransmission/rpc-test.cc b/tests/libtransmission/rpc-test.cc index 36dd849ce..5b430a4a9 100644 --- a/tests/libtransmission/rpc-test.cc +++ b/tests/libtransmission/rpc-test.cc @@ -223,6 +223,7 @@ TEST_F(RpcTest, sessionGet) TR_KEY_seed_queue_size, TR_KEY_seedRatioLimit, TR_KEY_seedRatioLimited, + TR_KEY_sequentialDownload, TR_KEY_session_id, TR_KEY_speed_limit_down, TR_KEY_speed_limit_down_enabled,