mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 20:35:36 +00:00
refactor: add tr_torrentWebseed(), tr_torrentWebseedCount() (#2277)
* refactor: add tr_torrentWebseedCount()
This commit is contained in:
@@ -1403,7 +1403,7 @@ void DetailsDialog::Impl::refreshPeerList(std::vector<tr_torrent*> const& torren
|
||||
|
||||
void DetailsDialog::Impl::refreshWebseedList(std::vector<tr_torrent*> const& torrents)
|
||||
{
|
||||
int total = 0;
|
||||
auto has_any_webseeds = bool{ false };
|
||||
auto& hash = webseed_hash_;
|
||||
auto& store = webseed_store_;
|
||||
|
||||
@@ -1416,13 +1416,11 @@ void DetailsDialog::Impl::refreshWebseedList(std::vector<tr_torrent*> const& tor
|
||||
/* step 2: add any new webseeds */
|
||||
for (auto const* const tor : torrents)
|
||||
{
|
||||
auto const* inf = tr_torrentInfo(tor);
|
||||
|
||||
total += inf->webseedCount;
|
||||
|
||||
for (unsigned int j = 0; j < inf->webseedCount; ++j)
|
||||
for (size_t j = 0, n = tr_torrentWebseedCount(tor); j < n; ++j)
|
||||
{
|
||||
char const* url = inf->webseeds[j];
|
||||
has_any_webseeds = true;
|
||||
|
||||
auto const* const url = tr_torrentWebseed(tor, j).url;
|
||||
auto const key = gtr_sprintf("%d.%s", tr_torrentId(tor), url);
|
||||
|
||||
if (hash.find(key) == hash.end())
|
||||
@@ -1438,27 +1436,23 @@ void DetailsDialog::Impl::refreshWebseedList(std::vector<tr_torrent*> const& tor
|
||||
/* step 3: update the webseeds */
|
||||
for (auto const* const tor : torrents)
|
||||
{
|
||||
auto const* inf = tr_torrentInfo(tor);
|
||||
double* speeds_KBps = tr_torrentWebSpeeds_KBps(tor);
|
||||
|
||||
for (unsigned int j = 0; j < inf->webseedCount; ++j)
|
||||
for (size_t j = 0, n = tr_torrentWebseedCount(tor); j < n; ++j)
|
||||
{
|
||||
char const* const url = inf->webseeds[j];
|
||||
auto const key = gtr_sprintf("%d.%s", tr_torrentId(tor), url);
|
||||
auto const webseed = tr_torrentWebseed(tor, j);
|
||||
auto const key = gtr_sprintf("%d.%s", tr_torrentId(tor), webseed.url);
|
||||
auto const iter = store->get_iter(hash.at(key).get_path());
|
||||
|
||||
char buf[128] = { 0 };
|
||||
if (speeds_KBps[j] > 0)
|
||||
auto const KBps = double(webseed.download_bytes_per_second) / speed_K;
|
||||
auto buf = std::array<char, 128>{};
|
||||
if (webseed.is_downloading)
|
||||
{
|
||||
tr_formatter_speed_KBps(buf, speeds_KBps[j], sizeof(buf));
|
||||
tr_formatter_speed_KBps(std::data(buf), KBps, std::size(buf));
|
||||
}
|
||||
|
||||
(*iter)[webseed_cols.download_rate_double] = speeds_KBps[j];
|
||||
(*iter)[webseed_cols.download_rate_string] = buf;
|
||||
(*iter)[webseed_cols.download_rate_double] = KBps;
|
||||
(*iter)[webseed_cols.download_rate_string] = std::data(buf);
|
||||
(*iter)[webseed_cols.was_updated] = true;
|
||||
}
|
||||
|
||||
tr_free(speeds_KBps);
|
||||
}
|
||||
|
||||
/* step 4: remove webseeds that have disappeared */
|
||||
@@ -1481,7 +1475,7 @@ void DetailsDialog::Impl::refreshWebseedList(std::vector<tr_torrent*> const& tor
|
||||
|
||||
/* most of the time there are no webseeds...
|
||||
don't waste space showing an empty list */
|
||||
webseed_view_->set_visible(total > 0);
|
||||
webseed_view_->set_visible(has_any_webseeds);
|
||||
}
|
||||
|
||||
void DetailsDialog::Impl::refreshPeers(std::vector<tr_torrent*> const& torrents)
|
||||
|
||||
@@ -1704,36 +1704,14 @@ uint64_t tr_peerMgrGetDesiredAvailable(tr_torrent const* tor)
|
||||
return desired_available;
|
||||
}
|
||||
|
||||
double* tr_peerMgrWebSpeeds_KBps(tr_torrent const* tor)
|
||||
tr_webseed_view tr_peerMgrWebseed(tr_torrent const* tor, size_t i)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
TR_ASSERT(tor->swarm != nullptr);
|
||||
size_t const n = tr_ptrArraySize(&tor->swarm->webseeds);
|
||||
TR_ASSERT(i < n);
|
||||
|
||||
auto const now = tr_time_msec();
|
||||
|
||||
tr_swarm* const s = tor->swarm;
|
||||
TR_ASSERT(s->manager != nullptr);
|
||||
|
||||
unsigned int n = tr_ptrArraySize(&s->webseeds);
|
||||
TR_ASSERT(n == tor->info.webseedCount);
|
||||
|
||||
double* ret = tr_new0(double, n);
|
||||
|
||||
for (unsigned int i = 0; i < n; ++i)
|
||||
{
|
||||
unsigned int Bps = 0;
|
||||
auto const* const peer = static_cast<tr_peer*>(tr_ptrArrayNth(&s->webseeds, i));
|
||||
|
||||
if (peer->is_transferring_pieces(now, TR_DOWN, &Bps))
|
||||
{
|
||||
ret[i] = Bps / (double)tr_speed_K;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret[i] = -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return i >= n ? tr_webseed_view{} : tr_webseedView(static_cast<tr_peer const*>(tr_ptrArrayNth(&tor->swarm->webseeds, i)));
|
||||
}
|
||||
|
||||
static auto getPeerStats(tr_peerMsgs const* peer, time_t now, uint64_t now_msec)
|
||||
|
||||
@@ -138,7 +138,7 @@ void tr_peerMgrOnBlocklistChanged(tr_peerMgr* manager);
|
||||
|
||||
struct tr_peer_stat* tr_peerMgrPeerStats(tr_torrent const* tor, int* setmeCount);
|
||||
|
||||
double* tr_peerMgrWebSpeeds_KBps(tr_torrent const* tor);
|
||||
tr_webseed_view tr_peerMgrWebseed(tr_torrent const* tor, size_t i);
|
||||
|
||||
unsigned int tr_peerGetPieceSpeed_Bps(tr_peer const* peer, uint64_t now, tr_direction direction);
|
||||
|
||||
|
||||
@@ -1241,17 +1241,22 @@ size_t tr_torrentFileCount(tr_torrent const* torrent)
|
||||
return torrent->fileCount();
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
tr_webseed_view tr_torrentWebseed(tr_torrent const* tor, size_t i)
|
||||
{
|
||||
return tr_peerMgrWebseed(tor, i);
|
||||
}
|
||||
|
||||
double* tr_torrentWebSpeeds_KBps(tr_torrent const* tor)
|
||||
size_t tr_torrentWebseedCount(tr_torrent const* tor)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
return tr_peerMgrWebSpeeds_KBps(tor);
|
||||
return tor->webseedCount();
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
tr_peer_stat* tr_torrentPeers(tr_torrent const* tor, int* peerCount)
|
||||
{
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
@@ -327,6 +327,27 @@ public:
|
||||
|
||||
std::optional<tr_found_file_t> findFile(std::string& filename, tr_file_index_t i) const;
|
||||
|
||||
/// WEBSEEDS
|
||||
|
||||
auto webseedCount() const
|
||||
{
|
||||
return info.webseedCount;
|
||||
}
|
||||
|
||||
auto const& webseed(size_t i) const
|
||||
{
|
||||
TR_ASSERT(i < webseedCount());
|
||||
|
||||
return info.webseeds[i];
|
||||
}
|
||||
|
||||
auto& webseed(size_t i)
|
||||
{
|
||||
TR_ASSERT(i < webseedCount());
|
||||
|
||||
return info.webseeds[i];
|
||||
}
|
||||
|
||||
/// CHECKSUMS
|
||||
|
||||
bool ensurePieceIsChecked(tr_piece_index_t piece)
|
||||
|
||||
@@ -1501,18 +1501,6 @@ tr_tracker_stat* tr_torrentTrackers(tr_torrent const* torrent, int* setmeTracker
|
||||
|
||||
void tr_torrentTrackersFree(tr_tracker_stat* trackerStats, int trackerCount);
|
||||
|
||||
/**
|
||||
* @brief get the download speeds for each of this torrent's webseed sources.
|
||||
*
|
||||
* @return an array of tor->info.webseedCount floats giving download speeds.
|
||||
* Each speed in the array corresponds to the webseed at the same
|
||||
* array index in tor->info.webseeds.
|
||||
* To differentiate "idle" and "stalled" status, idle webseeds will
|
||||
* return -1 instead of 0 KiB/s.
|
||||
* NOTE: always free this array with tr_free() when you're done with it.
|
||||
*/
|
||||
double* tr_torrentWebSpeeds_KBps(tr_torrent const* torrent);
|
||||
|
||||
/*
|
||||
* This view structure is intended for short-term use. Its pointers are owned
|
||||
* by the torrent and may be invalidated if the torrent is edited or removed.
|
||||
@@ -1530,6 +1518,21 @@ tr_file_view tr_torrentFile(tr_torrent const* torrent, tr_file_index_t file);
|
||||
|
||||
size_t tr_torrentFileCount(tr_torrent const* torrent);
|
||||
|
||||
/*
|
||||
* This view structure is intended for short-term use. Its pointers are owned
|
||||
* by the torrent and may be invalidated if the torrent is edited or removed.
|
||||
*/
|
||||
struct tr_webseed_view
|
||||
{
|
||||
char const* url; // the url to download from
|
||||
bool is_downloading; // can be true even if speed is 0, e.g. slow download
|
||||
unsigned download_bytes_per_second; // current download speed
|
||||
};
|
||||
|
||||
struct tr_webseed_view tr_torrentWebseed(tr_torrent const* torrent, size_t nth);
|
||||
|
||||
size_t tr_torrentWebseedCount(tr_torrent const* torrent);
|
||||
|
||||
/***********************************************************************
|
||||
* tr_torrentAvailability
|
||||
***********************************************************************
|
||||
|
||||
@@ -125,6 +125,19 @@ public:
|
||||
|
||||
} // namespace
|
||||
|
||||
tr_webseed_view tr_webseedView(tr_peer const* peer)
|
||||
{
|
||||
auto const* w = dynamic_cast<tr_webseed const*>(peer);
|
||||
if (w == nullptr)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto bytes_per_second = unsigned{ 0 };
|
||||
auto const is_downloading = peer->is_transferring_pieces(tr_time_msec(), TR_DOWN, &bytes_per_second);
|
||||
return { w->base_url.c_str(), is_downloading, bytes_per_second };
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
@@ -17,3 +17,5 @@
|
||||
#include "peer-common.h"
|
||||
|
||||
tr_peer* tr_webseedNew(struct tr_torrent* torrent, std::string_view, tr_peer_callback callback, void* callback_data);
|
||||
|
||||
tr_webseed_view tr_webseedView(tr_peer const* peer);
|
||||
|
||||
@@ -1080,32 +1080,30 @@ bool trashDataFile(char const* filename, tr_error** error)
|
||||
|
||||
- (NSUInteger)webSeedCount
|
||||
{
|
||||
return fInfo->webseedCount;
|
||||
return tr_torrentWebseedCount(fHandle);
|
||||
}
|
||||
|
||||
- (NSArray*)webSeeds
|
||||
{
|
||||
NSMutableArray* webSeeds = [NSMutableArray arrayWithCapacity:fInfo->webseedCount];
|
||||
NSUInteger n = tr_torrentWebseedCount(fHandle);
|
||||
NSMutableArray* webSeeds = [NSMutableArray arrayWithCapacity:n];
|
||||
|
||||
double* dlSpeeds = tr_torrentWebSpeeds_KBps(fHandle);
|
||||
|
||||
for (NSInteger i = 0; i < fInfo->webseedCount; i++)
|
||||
for (NSUInteger i = 0; i < n; ++i)
|
||||
{
|
||||
auto const webseed = tr_torrentWebseed(fHandle, i);
|
||||
NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithCapacity:3];
|
||||
|
||||
dict[@"Name"] = self.name;
|
||||
dict[@"Address"] = @(fInfo->webseeds[i]);
|
||||
dict[@"Address"] = @(webseed.url);
|
||||
|
||||
if (dlSpeeds[i] != -1.0)
|
||||
if (webseed.is_downloading)
|
||||
{
|
||||
dict[@"DL From Rate"] = @(dlSpeeds[i]);
|
||||
dict[@"DL From Rate"] = @(double(webseed.download_bytes_per_second) / 1000);
|
||||
}
|
||||
|
||||
[webSeeds addObject:dict];
|
||||
}
|
||||
|
||||
tr_free(dlSpeeds);
|
||||
|
||||
return webSeeds;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user