From 60ee353a2f043c7dca9e1a560162bce33b920513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C5=93ur?= Date: Wed, 15 Feb 2023 13:25:41 +0800 Subject: [PATCH 1/3] auto-fetch metainfo on new torrents --- libtransmission/torrent.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index a7b45dea4..6f5b364dd 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -1039,7 +1039,7 @@ void tr_torrent::init(tr_ctor const& ctor) { on_metainfo_completed(); } - else if (start_when_stable_) + else if (start_when_stable_ || (is_new_torrent && !has_metainfo)) { auto const bypass_queue = !has_metainfo; // to fetch metainfo from peers start(bypass_queue, has_any_local_data); From aa9e8daa4ab966599714061014ab9595e3fe7dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C5=93ur?= Date: Wed, 15 Feb 2023 13:26:39 +0800 Subject: [PATCH 2/3] Plan A fix magnet links are never paused when added --- macosx/Controller.mm | 1 - macosx/Torrent.mm | 7 ------- 2 files changed, 8 deletions(-) diff --git a/macosx/Controller.mm b/macosx/Controller.mm index 9f7b015b9..c2a060acb 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -709,7 +709,6 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool //load previous transfers tr_ctor* ctor = tr_ctorNew(session); - tr_ctorSetPaused(ctor, TR_FORCE, true); // paused by default; unpause below after checking state history auto const n_torrents = tr_sessionLoadTorrents(session, ctor); tr_ctorFree(ctor); diff --git a/macosx/Torrent.mm b/macosx/Torrent.mm index 6f5d83397..1843a8abc 100644 --- a/macosx/Torrent.mm +++ b/macosx/Torrent.mm @@ -152,13 +152,6 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) //restore GroupValue torrent.groupValue = [history[@"GroupValue"] intValue]; - //start transfer - NSNumber* active; - if (!pause && (active = history[@"Active"]) && active.boolValue) - { - [torrent startTransferNoQueue]; - } - NSNumber* ratioLimit; if ((ratioLimit = history[@"RatioLimit"])) { From 603f78153fbbcd3712a032d268310b2ea8c818fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C5=93ur?= Date: Tue, 14 Feb 2023 20:50:05 +0800 Subject: [PATCH 3/3] Plan B support torrent stabilization without starting --- libtransmission/torrent.cc | 9 +++++++++ libtransmission/transmission.h | 6 ++++++ macosx/Controller.mm | 24 ++++++++++++++++++------ macosx/Torrent.h | 5 ++++- macosx/Torrent.mm | 32 +++++++++++++++++++++++++++++--- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc index 6f5b364dd..819bc5a00 100644 --- a/libtransmission/torrent.cc +++ b/libtransmission/torrent.cc @@ -1339,6 +1339,7 @@ tr_stat tr_torrent::stats() const stats.desiredAvailable = tr_peerMgrGetDesiredAvailable(this); stats.ratio = tr_getRatio(stats.uploadedEver, this->size_when_done()); + stats.startWhenStable = this->start_when_stable_; auto seed_ratio_bytes_left = uint64_t{}; auto seed_ratio_bytes_goal = uint64_t{}; @@ -1536,6 +1537,14 @@ void tr_torrentStartNow(tr_torrent* tor) } } +void tr_torrentStabilize(tr_torrent* tor) +{ + if (tr_isTorrent(tor)) + { + tor->start(!tor->has_metainfo(), {}); + } +} + // --- void tr_torrentVerify(tr_torrent* tor) diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 2c3730cb6..8bd141829 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -588,6 +588,9 @@ void tr_sessionSetAntiBruteForceEnabled(tr_session* session, bool enabled); /** @brief Like `tr_torrentStart()`, but resumes right away regardless of the queues. */ void tr_torrentStartNow(tr_torrent* tor); +/** @brief Like `tr_torrentStart()`, but doesn't modify `start_when_stable`. */ +void tr_torrentStabilize(tr_torrent* tor); + /** @brief Return the queued torrent's position in the queue it's in. [0...n) */ size_t tr_torrentGetQueuePosition(tr_torrent const* tor); @@ -1543,6 +1546,9 @@ struct tr_stat /** If seeding, number of seconds left until the idle time limit is reached. */ time_t etaIdle; + /** Non-paused */ + bool startWhenStable; + /** What is this torrent doing right now? */ tr_torrent_activity activity; diff --git a/macosx/Controller.mm b/macosx/Controller.mm index c2a060acb..ecb20d2ee 100644 --- a/macosx/Controller.mm +++ b/macosx/Controller.mm @@ -709,6 +709,7 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool //load previous transfers tr_ctor* ctor = tr_ctorNew(session); + tr_ctorSetPaused(ctor, TR_FORCE, true); // paused by default; unpause below after checking state history auto const n_torrents = tr_sessionLoadTorrents(session, ctor); tr_ctorFree(ctor); @@ -746,25 +747,36 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool // theoretical max without doing a lot of work NSMutableArray* waitToStartTorrents = [NSMutableArray arrayWithCapacity:((history.count > 0 && !self.fPauseOnLaunch) ? history.count - 1 : 0)]; + NSMutableArray* waitToStabilizeTorrents = [NSMutableArray + arrayWithCapacity:((history.count > 0 && !self.fPauseOnLaunch) ? history.count - 1 : 0)]; - Torrent* t = [[Torrent alloc] init]; for (NSDictionary* historyItem in history) { NSString* hash = historyItem[@"TorrentHash"]; if ([self.fTorrentHashes.allKeys containsObject:hash]) { Torrent* torrent = self.fTorrentHashes[hash]; - [t setResumeStatusForTorrent:torrent withHistory:historyItem forcePause:self.fPauseOnLaunch]; + [torrent setResumeStatusWithHistory:historyItem forcePause:self.fPauseOnLaunch]; - NSNumber* waitToStart; - if (!self.fPauseOnLaunch && (waitToStart = historyItem[@"WaitToStart"]) && waitToStart.boolValue) + if (!self.fPauseOnLaunch && [historyItem[@"WaitToStart"] boolValue]) { - [waitToStartTorrents addObject:torrent]; + if ([historyItem[@"StartWhenStable"] boolValue]) + { + [waitToStartTorrents addObject:torrent]; + } + else + { + [waitToStabilizeTorrents addObject:torrent]; + } } } } - //now that all are loaded, let's set those in the queue to waiting + // now that all are loaded, let's set those in the queue to waiting + for (Torrent* torrent in waitToStabilizeTorrents) + { + [torrent stabilize]; + } for (Torrent* torrent in waitToStartTorrents) { [torrent startTransfer]; diff --git a/macosx/Torrent.h b/macosx/Torrent.h index ff3693881..d53640d17 100644 --- a/macosx/Torrent.h +++ b/macosx/Torrent.h @@ -21,7 +21,7 @@ extern NSString* const kTorrentDidChangeGroupNotification; lib:(tr_session*)lib; - (instancetype)initWithTorrentStruct:(tr_torrent*)torrentStruct location:(NSString*)location lib:(tr_session*)lib; - (instancetype)initWithMagnetAddress:(NSString*)address location:(NSString*)location lib:(tr_session*)lib; -- (void)setResumeStatusForTorrent:(Torrent*)torrent withHistory:(NSDictionary*)history forcePause:(BOOL)pause; +- (void)setResumeStatusWithHistory:(NSDictionary*)history forcePause:(BOOL)pause; @property(nonatomic, readonly) NSDictionary* history; @@ -37,6 +37,7 @@ extern NSString* const kTorrentDidChangeGroupNotification; - (void)update; +- (void)stabilize; - (void)startTransferIgnoringQueue:(BOOL)ignoreQueue; - (void)startTransferNoQueue; - (void)startTransfer; @@ -126,6 +127,8 @@ extern NSString* const kTorrentDidChangeGroupNotification; @property(nonatomic, readonly) CGFloat availableDesired; +/// True if non-paused. +@property(nonatomic, readonly) BOOL startWhenStable; /// True if non-paused. Running. @property(nonatomic, getter=isActive, readonly) BOOL active; /// True if downloading or uploading. diff --git a/macosx/Torrent.mm b/macosx/Torrent.mm index 1843a8abc..e1c8850dd 100644 --- a/macosx/Torrent.mm +++ b/macosx/Torrent.mm @@ -147,10 +147,23 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) return self; } -- (void)setResumeStatusForTorrent:(Torrent*)torrent withHistory:(NSDictionary*)history forcePause:(BOOL)pause +- (void)setResumeStatusWithHistory:(NSDictionary*)history forcePause:(BOOL)pause { - //restore GroupValue - torrent.groupValue = [history[@"GroupValue"] intValue]; + // restore GroupValue + self.groupValue = [history[@"GroupValue"] intValue]; + + // start transfer + if (!pause && [history[@"Active"] boolValue]) + { + if ([history[@"StartWhenStable"] boolValue]) + { + [self startTransferNoQueue]; + } + else + { + [self stabilize]; + } + } NSNumber* ratioLimit; if ((ratioLimit = history[@"RatioLimit"])) @@ -165,6 +178,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) @"TorrentHash" : self.hashString, @"Active" : @(self.active), @"WaitToStart" : @(self.waitingToStart), + @"StartWhenStable" : @(self.startWhenStable), @"GroupValue" : @(self.groupValue), @"RemoveWhenFinishSeeding" : @(_removeWhenFinishSeeding) }; @@ -251,6 +265,12 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) } } +- (void)stabilize +{ + tr_torrentStabilize(self.fHandle); + [self update]; +} + - (void)startTransferIgnoringQueue:(BOOL)ignoreQueue { if ([self alertForRemainingDiskSpace]) @@ -439,6 +459,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) { return tr_torrentGetPeerLimit(self.fHandle); } + - (BOOL)waitingToStart { return self.fStat->activity == TR_STATUS_DOWNLOAD_WAIT || self.fStat->activity == TR_STATUS_SEED_WAIT; @@ -862,6 +883,11 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error) return (CGFloat)self.fStat->desiredAvailable / self.sizeLeft; } +- (BOOL)startWhenStable +{ + return self.fStat->startWhenStable; +} + - (BOOL)isActive { return self.fStat->activity != TR_STATUS_STOPPED && self.fStat->activity != TR_STATUS_DOWNLOAD_WAIT &&