Compare commits
7 Commits
faa03dc5de
...
3ca5aceb3c
Author | SHA1 | Date |
---|---|---|
Cœur | 3ca5aceb3c | |
Pooyan Khanjankhani | 821a6816ef | |
Dzmitry Neviadomski | ef18816b7f | |
Dzmitry Neviadomski | 0e25584e78 | |
Cœur | 603f78153f | |
Cœur | aa9e8daa4a | |
Cœur | 60ee353a2f |
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue