Compare commits

...

7 Commits

Author SHA1 Message Date
Cœur 3ca5aceb3c
Merge 603f78153f into 821a6816ef 2024-04-24 11:40:00 +02:00
Pooyan Khanjankhani 821a6816ef
doc: fix typo (#6790) 2024-04-21 18:21:17 -05:00
Dzmitry Neviadomski ef18816b7f
Fix code style script path in CONTRIBUTING.md (#6787)
Signed-off-by: Dzmitry Neviadomski <nevack.d@gmail.com>
2024-04-21 07:36:13 -05:00
Dzmitry Neviadomski 0e25584e78
Make std::hash specialization for tr_socket_address a struct (#6788)
To be in line with std::hash declaration

See https://en.cppreference.com/w/cpp/utility/hash

Signed-off-by: Dzmitry Neviadomski <nevack.d@gmail.com>
2024-04-20 21:01:47 -05:00
Cœur 603f78153f Plan B support torrent stabilization without starting 2024-02-13 15:03:26 +01:00
Cœur aa9e8daa4a Plan A fix magnet links are never paused when added 2024-02-13 15:03:26 +01:00
Cœur 60ee353a2f auto-fetch metainfo on new torrents 2024-02-13 15:03:26 +01:00
8 changed files with 66 additions and 18 deletions

View File

@ -41,7 +41,7 @@ On macOS, Transmission is usually built with Xcode. Everywhere else, it's CMake
- Prefer `enum class` over `enum` - Prefer `enum class` over `enum`
- Prefer new-style headers, e.g. `<cstring>` over `<string.h>` - Prefer new-style headers, e.g. `<cstring>` over `<string.h>`
- Fix any warnings in new code before merging - Fix any warnings in new code before merging
- Run `./code-style.sh` on your code to ensure the whole codebase has consistent indentation. - Run `./code_style.sh` on your code to ensure the whole codebase has consistent indentation.
Note that Transmission existed in C for over a decade and those idioms don't change overnight. "Follow the C++ core guidelines" can be difficult when working with older code, and the maintainers will understand that when reviewing your PRs. :smiley: Note that Transmission existed in C for over a decade and those idioms don't change overnight. "Follow the C++ core guidelines" can be difficult when working with older code, and the maintainers will understand that when reviewing your PRs. :smiley:

View File

@ -404,7 +404,7 @@ struct tr_socket_address
}; };
template<> template<>
class std::hash<tr_socket_address> struct std::hash<tr_socket_address>
{ {
public: public:
std::size_t operator()(tr_socket_address const& socket_address) const noexcept std::size_t operator()(tr_socket_address const& socket_address) const noexcept

View File

@ -1044,7 +1044,7 @@ void tr_torrent::init(tr_ctor const& ctor)
{ {
on_metainfo_completed(); 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 auto const bypass_queue = !has_metainfo; // to fetch metainfo from peers
start(bypass_queue, has_any_local_data); start(bypass_queue, has_any_local_data);
@ -1344,6 +1344,7 @@ tr_stat tr_torrent::stats() const
stats.desiredAvailable = tr_peerMgrGetDesiredAvailable(this); stats.desiredAvailable = tr_peerMgrGetDesiredAvailable(this);
stats.ratio = tr_getRatio(stats.uploadedEver, this->size_when_done()); 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_left = uint64_t{};
auto seed_ratio_bytes_goal = uint64_t{}; auto seed_ratio_bytes_goal = uint64_t{};
@ -1541,6 +1542,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) void tr_torrentVerify(tr_torrent* tor)

View File

@ -588,6 +588,9 @@ void tr_sessionSetAntiBruteForceEnabled(tr_session* session, bool enabled);
/** @brief Like `tr_torrentStart()`, but resumes right away regardless of the queues. */ /** @brief Like `tr_torrentStart()`, but resumes right away regardless of the queues. */
void tr_torrentStartNow(tr_torrent* tor); 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) */ /** @brief Return the queued torrent's position in the queue it's in. [0...n) */
size_t tr_torrentGetQueuePosition(tr_torrent const* tor); 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. */ /** If seeding, number of seconds left until the idle time limit is reached. */
time_t etaIdle; time_t etaIdle;
/** Non-paused */
bool startWhenStable;
/** What is this torrent doing right now? */ /** What is this torrent doing right now? */
tr_torrent_activity activity; tr_torrent_activity activity;

View File

@ -759,25 +759,36 @@ void onTorrentCompletenessChanged(tr_torrent* tor, tr_completeness status, bool
// theoretical max without doing a lot of work // theoretical max without doing a lot of work
NSMutableArray* waitToStartTorrents = [NSMutableArray NSMutableArray* waitToStartTorrents = [NSMutableArray
arrayWithCapacity:((history.count > 0 && !self.fPauseOnLaunch) ? history.count - 1 : 0)]; 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) for (NSDictionary* historyItem in history)
{ {
NSString* hash = historyItem[@"TorrentHash"]; NSString* hash = historyItem[@"TorrentHash"];
if ([self.fTorrentHashes.allKeys containsObject:hash]) if ([self.fTorrentHashes.allKeys containsObject:hash])
{ {
Torrent* torrent = self.fTorrentHashes[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 && [historyItem[@"WaitToStart"] boolValue])
if (!self.fPauseOnLaunch && (waitToStart = historyItem[@"WaitToStart"]) && 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) for (Torrent* torrent in waitToStartTorrents)
{ {
[torrent startTransfer]; [torrent startTransfer];

View File

@ -21,7 +21,7 @@ extern NSString* const kTorrentDidChangeGroupNotification;
lib:(tr_session*)lib; lib:(tr_session*)lib;
- (instancetype)initWithTorrentStruct:(tr_torrent*)torrentStruct location:(NSString*)location 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; - (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; @property(nonatomic, readonly) NSDictionary* history;
@ -37,6 +37,7 @@ extern NSString* const kTorrentDidChangeGroupNotification;
- (void)update; - (void)update;
- (void)stabilize;
- (void)startTransferIgnoringQueue:(BOOL)ignoreQueue; - (void)startTransferIgnoringQueue:(BOOL)ignoreQueue;
- (void)startTransferNoQueue; - (void)startTransferNoQueue;
- (void)startTransfer; - (void)startTransfer;
@ -127,6 +128,8 @@ extern NSString* const kTorrentDidChangeGroupNotification;
@property(nonatomic, readonly) CGFloat availableDesired; @property(nonatomic, readonly) CGFloat availableDesired;
/// True if non-paused.
@property(nonatomic, readonly) BOOL startWhenStable;
/// True if non-paused. Running. /// True if non-paused. Running.
@property(nonatomic, getter=isActive, readonly) BOOL active; @property(nonatomic, getter=isActive, readonly) BOOL active;
/// True if downloading or uploading. /// True if downloading or uploading.

View File

@ -147,16 +147,22 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
return self; return self;
} }
- (void)setResumeStatusForTorrent:(Torrent*)torrent withHistory:(NSDictionary*)history forcePause:(BOOL)pause - (void)setResumeStatusWithHistory:(NSDictionary*)history forcePause:(BOOL)pause
{ {
//restore GroupValue // restore GroupValue
torrent.groupValue = [history[@"GroupValue"] intValue]; self.groupValue = [history[@"GroupValue"] intValue];
//start transfer // start transfer
NSNumber* active; if (!pause && [history[@"Active"] boolValue])
if (!pause && (active = history[@"Active"]) && active.boolValue)
{ {
[torrent startTransferNoQueue]; if ([history[@"StartWhenStable"] boolValue])
{
[self startTransferNoQueue];
}
else
{
[self stabilize];
}
} }
NSNumber* ratioLimit; NSNumber* ratioLimit;
@ -172,6 +178,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
@"TorrentHash" : self.hashString, @"TorrentHash" : self.hashString,
@"Active" : @(self.active), @"Active" : @(self.active),
@"WaitToStart" : @(self.waitingToStart), @"WaitToStart" : @(self.waitingToStart),
@"StartWhenStable" : @(self.startWhenStable),
@"GroupValue" : @(self.groupValue), @"GroupValue" : @(self.groupValue),
@"RemoveWhenFinishSeeding" : @(_removeWhenFinishSeeding) @"RemoveWhenFinishSeeding" : @(_removeWhenFinishSeeding)
}; };
@ -258,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 - (void)startTransferIgnoringQueue:(BOOL)ignoreQueue
{ {
if ([self alertForRemainingDiskSpace]) if ([self alertForRemainingDiskSpace])
@ -446,6 +459,7 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
{ {
return tr_torrentGetPeerLimit(self.fHandle); return tr_torrentGetPeerLimit(self.fHandle);
} }
- (BOOL)waitingToStart - (BOOL)waitingToStart
{ {
return self.fStat->activity == TR_STATUS_DOWNLOAD_WAIT || self.fStat->activity == TR_STATUS_SEED_WAIT; return self.fStat->activity == TR_STATUS_DOWNLOAD_WAIT || self.fStat->activity == TR_STATUS_SEED_WAIT;
@ -888,6 +902,11 @@ bool trashDataFile(char const* filename, void* /*user_data*/, tr_error* error)
return (CGFloat)self.fStat->desiredAvailable / self.sizeLeft; return (CGFloat)self.fStat->desiredAvailable / self.sizeLeft;
} }
- (BOOL)startWhenStable
{
return self.fStat->startWhenStable;
}
- (BOOL)isActive - (BOOL)isActive
{ {
return self.fStat->activity != TR_STATUS_STOPPED && self.fStat->activity != TR_STATUS_DOWNLOAD_WAIT && return self.fStat->activity != TR_STATUS_STOPPED && self.fStat->activity != TR_STATUS_DOWNLOAD_WAIT &&

View File

@ -150,7 +150,7 @@ Get a file list for the current torrent(s)
.It Fl g Fl -get Ar all | file-index | files .It Fl g Fl -get Ar all | file-index | files
Mark file(s) for download. Mark file(s) for download.
.Ar all .Ar all
marks all all of the torrent's files for downloading, marks all of the torrent's files for downloading,
.Ar file-index .Ar file-index
adds a single file to the download list, and adds a single file to the download list, and
.Ar files .Ar files