mirror of
https://github.com/transmission/transmission
synced 2024-12-25 01:03:01 +00:00
refactor: make tr_torrent date fields private (#6281)
This commit is contained in:
parent
7e8eca0e96
commit
d8c2074cb7
4 changed files with 163 additions and 131 deletions
|
@ -2328,14 +2328,9 @@ struct peer_candidate
|
|||
tr_peer_info const* peer_info;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool torrentWasRecentlyStarted(tr_torrent const* tor)
|
||||
[[nodiscard]] constexpr uint64_t addValToKey(uint64_t value, unsigned int width, uint64_t addme)
|
||||
{
|
||||
return difftime(tr_time(), tor->startDate) < 120;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr uint64_t addValToKey(uint64_t value, int width, uint64_t addme)
|
||||
{
|
||||
value = value << (uint64_t)width;
|
||||
value <<= width;
|
||||
value |= addme;
|
||||
return value;
|
||||
}
|
||||
|
@ -2348,11 +2343,11 @@ struct peer_candidate
|
|||
|
||||
/* prefer peers we've connected to, or never tried, over peers we failed to connect to. */
|
||||
i = peer_info.connection_failure_count() != 0U ? 1U : 0U;
|
||||
score = addValToKey(score, 1, i);
|
||||
score = addValToKey(score, 1U, i);
|
||||
|
||||
/* prefer the one we attempted least recently (to cycle through all peers) */
|
||||
i = peer_info.connection_attempt_time();
|
||||
score = addValToKey(score, 32, i);
|
||||
score = addValToKey(score, 32U, i);
|
||||
|
||||
/* prefer peers belonging to a torrent of a higher priority */
|
||||
switch (tor->get_priority())
|
||||
|
@ -2370,30 +2365,30 @@ struct peer_candidate
|
|||
break;
|
||||
}
|
||||
|
||||
score = addValToKey(score, 4, i);
|
||||
score = addValToKey(score, 4U, i);
|
||||
|
||||
/* prefer recently-started torrents */
|
||||
i = torrentWasRecentlyStarted(tor) ? 0 : 1;
|
||||
score = addValToKey(score, 1, i);
|
||||
// prefer recently-started torrents
|
||||
i = tor->started_recently(tr_time()) ? 0 : 1;
|
||||
score = addValToKey(score, 1U, i);
|
||||
|
||||
/* prefer torrents we're downloading with */
|
||||
i = tor->is_done() ? 1 : 0;
|
||||
score = addValToKey(score, 1, i);
|
||||
score = addValToKey(score, 1U, i);
|
||||
|
||||
/* prefer peers that are known to be connectible */
|
||||
i = peer_info.is_connectable().value_or(false) ? 0 : 1;
|
||||
score = addValToKey(score, 1, i);
|
||||
score = addValToKey(score, 1U, i);
|
||||
|
||||
/* prefer peers that we might be able to upload to */
|
||||
i = peer_info.is_seed() ? 0 : 1;
|
||||
score = addValToKey(score, 1, i);
|
||||
score = addValToKey(score, 1U, i);
|
||||
|
||||
/* Prefer peers that we got from more trusted sources.
|
||||
* lower `fromBest` values indicate more trusted sources */
|
||||
score = addValToKey(score, 4, peer_info.from_best());
|
||||
score = addValToKey(score, 4U, peer_info.from_best());
|
||||
|
||||
/* salt */
|
||||
score = addValToKey(score, 8, salt);
|
||||
score = addValToKey(score, 8U, salt);
|
||||
|
||||
return score;
|
||||
}
|
||||
|
|
|
@ -711,13 +711,13 @@ tr_resume::fields_t loadFromFile(tr_torrent* tor, tr_torrent::ResumeHelper& help
|
|||
|
||||
if ((fields_to_load & tr_resume::AddedDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_added_date, &i))
|
||||
{
|
||||
tor->addedDate = i;
|
||||
helper.load_date_added(static_cast<time_t>(i));
|
||||
fields_loaded |= tr_resume::AddedDate;
|
||||
}
|
||||
|
||||
if ((fields_to_load & tr_resume::DoneDate) != 0 && tr_variantDictFindInt(&top, TR_KEY_done_date, &i))
|
||||
{
|
||||
tor->doneDate = i;
|
||||
helper.load_date_done(static_cast<time_t>(i));
|
||||
fields_loaded |= tr_resume::DoneDate;
|
||||
}
|
||||
|
||||
|
@ -884,10 +884,10 @@ void save(tr_torrent* const tor, tr_torrent::ResumeHelper const& helper)
|
|||
tr_variantInitDict(&top, 50); /* arbitrary "big enough" number */
|
||||
tr_variantDictAddInt(&top, TR_KEY_seeding_time_seconds, helper.seconds_seeding(now));
|
||||
tr_variantDictAddInt(&top, TR_KEY_downloading_time_seconds, helper.seconds_downloading(now));
|
||||
tr_variantDictAddInt(&top, TR_KEY_activity_date, tor->activityDate);
|
||||
tr_variantDictAddInt(&top, TR_KEY_added_date, tor->addedDate);
|
||||
tr_variantDictAddInt(&top, TR_KEY_activity_date, helper.date_active());
|
||||
tr_variantDictAddInt(&top, TR_KEY_added_date, helper.date_added());
|
||||
tr_variantDictAddInt(&top, TR_KEY_corrupt, tor->bytes_corrupt_.ever());
|
||||
tr_variantDictAddInt(&top, TR_KEY_done_date, tor->doneDate);
|
||||
tr_variantDictAddInt(&top, TR_KEY_done_date, helper.date_done());
|
||||
tr_variantDictAddStrView(&top, TR_KEY_destination, tor->download_dir().sv());
|
||||
|
||||
if (!std::empty(tor->incomplete_dir()))
|
||||
|
|
|
@ -622,30 +622,6 @@ void torrentResetTransferStats(tr_torrent* tor)
|
|||
tor->set_dirty();
|
||||
}
|
||||
|
||||
void torrentStartImpl(tr_torrent* const tor)
|
||||
{
|
||||
auto const lock = tor->unique_lock();
|
||||
|
||||
TR_ASSERT(tr_isTorrent(tor));
|
||||
|
||||
tor->recheck_completeness();
|
||||
tor->set_is_queued(false);
|
||||
|
||||
time_t const now = tr_time();
|
||||
|
||||
tor->is_running_ = true;
|
||||
tor->completeness = tor->completion.status();
|
||||
tor->startDate = now;
|
||||
tor->mark_changed();
|
||||
tor->error().clear();
|
||||
tor->finished_seeding_by_idle_ = false;
|
||||
|
||||
torrentResetTransferStats(tor);
|
||||
tor->session->announcer_->startTorrent(tor);
|
||||
tor->lpdAnnounceAt = now;
|
||||
tor->started_.emit(tor);
|
||||
}
|
||||
|
||||
bool removeTorrentFile(char const* filename, void* /*user_data*/, tr_error* error)
|
||||
{
|
||||
return tr_sys_path_remove(filename, error);
|
||||
|
@ -773,10 +749,35 @@ void torrentStart(tr_torrent* tor, torrent_start_opts opts)
|
|||
|
||||
tor->is_running_ = true;
|
||||
tor->set_dirty();
|
||||
tor->session->runInSessionThread(torrentStartImpl, tor);
|
||||
tor->session->runInSessionThread([tor]() { tor->start_in_session_thread(); });
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void tr_torrent::start_in_session_thread()
|
||||
{
|
||||
using namespace start_stop_helpers;
|
||||
|
||||
TR_ASSERT(session->am_in_session_thread());
|
||||
auto const lock = unique_lock();
|
||||
|
||||
recheck_completeness();
|
||||
set_is_queued(false);
|
||||
|
||||
time_t const now = tr_time();
|
||||
|
||||
is_running_ = true;
|
||||
completeness = completion.status();
|
||||
date_started_ = now;
|
||||
mark_changed();
|
||||
error().clear();
|
||||
finished_seeding_by_idle_ = false;
|
||||
|
||||
torrentResetTransferStats(this);
|
||||
session->announcer_->startTorrent(this);
|
||||
lpdAnnounceAt = now;
|
||||
started_.emit(this);
|
||||
}
|
||||
|
||||
void tr_torrent::stop_now()
|
||||
{
|
||||
TR_ASSERT(session->am_in_session_thread());
|
||||
|
@ -857,22 +858,18 @@ void tr_torrentFreeInSessionThread(tr_torrent* tor)
|
|||
|
||||
// ---
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace torrent_init_helpers
|
||||
{
|
||||
// Sniff out newly-added seeds so that they can skip the verify step
|
||||
bool isNewTorrentASeed(tr_torrent* tor)
|
||||
bool tr_torrent::is_new_torrent_a_seed()
|
||||
{
|
||||
if (!tor->has_metainfo())
|
||||
if (!has_metainfo())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (tr_file_index_t i = 0, n = tor->file_count(); i < n; ++i)
|
||||
for (tr_file_index_t i = 0, n = file_count(); i < n; ++i)
|
||||
{
|
||||
// it's not a new seed if a file is missing
|
||||
auto const found = tor->find_file(i);
|
||||
auto const found = find_file(i);
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
|
@ -885,52 +882,22 @@ bool isNewTorrentASeed(tr_torrent* tor)
|
|||
}
|
||||
|
||||
// it's not a new seed if a file size is wrong
|
||||
if (found->size != tor->file_size(i))
|
||||
if (found->size != file_size(i))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// it's not a new seed if it was modified after it was added
|
||||
if (found->last_modified_at >= tor->addedDate)
|
||||
if (found->last_modified_at >= date_added_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check the first piece
|
||||
return tor->ensure_piece_is_checked(0);
|
||||
return ensure_piece_is_checked(0);
|
||||
}
|
||||
|
||||
void on_metainfo_completed(tr_torrent* tor)
|
||||
{
|
||||
// we can look for files now that we know what files are in the torrent
|
||||
tor->refresh_current_dir();
|
||||
|
||||
callScriptIfEnabled(tor, TR_SCRIPT_ON_TORRENT_ADDED);
|
||||
|
||||
if (tor->session->shouldFullyVerifyAddedTorrents() || !isNewTorrentASeed(tor))
|
||||
{
|
||||
tr_torrentVerify(tor);
|
||||
}
|
||||
else
|
||||
{
|
||||
tor->completion.set_has_all();
|
||||
tor->doneDate = tor->addedDate;
|
||||
tor->recheck_completeness();
|
||||
|
||||
if (tor->start_when_stable)
|
||||
{
|
||||
torrentStart(tor, {});
|
||||
}
|
||||
else if (tor->is_running())
|
||||
{
|
||||
tr_torrentStop(tor);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace torrent_init_helpers
|
||||
} // namespace
|
||||
|
||||
void tr_torrent::on_metainfo_updated()
|
||||
{
|
||||
completion = tr_completion{ this, &block_info() };
|
||||
|
@ -942,10 +909,36 @@ void tr_torrent::on_metainfo_updated()
|
|||
checked_pieces_ = tr_bitfield{ size_t(piece_count()) };
|
||||
}
|
||||
|
||||
void tr_torrent::on_metainfo_completed()
|
||||
{
|
||||
// we can look for files now that we know what files are in the torrent
|
||||
refresh_current_dir();
|
||||
|
||||
callScriptIfEnabled(this, TR_SCRIPT_ON_TORRENT_ADDED);
|
||||
|
||||
if (session->shouldFullyVerifyAddedTorrents() || !is_new_torrent_a_seed())
|
||||
{
|
||||
tr_torrentVerify(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
completion.set_has_all();
|
||||
date_done_ = date_added_;
|
||||
recheck_completeness();
|
||||
|
||||
if (start_when_stable)
|
||||
{
|
||||
torrentStart(this, {});
|
||||
}
|
||||
else if (is_running())
|
||||
{
|
||||
tr_torrentStop(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tr_torrent::init(tr_ctor const* const ctor)
|
||||
{
|
||||
using namespace torrent_init_helpers;
|
||||
|
||||
session = tr_ctorGetSession(ctor);
|
||||
TR_ASSERT(session != nullptr);
|
||||
auto const lock = unique_lock();
|
||||
|
@ -982,7 +975,7 @@ void tr_torrent::init(tr_ctor const* const ctor)
|
|||
|
||||
mark_changed();
|
||||
|
||||
addedDate = tr_time(); // this is a default that will be overwritten by the resume file
|
||||
date_added_ = tr_time(); // this is a default that will be overwritten by the resume file
|
||||
|
||||
tr_resume::fields_t loaded = {};
|
||||
|
||||
|
@ -1068,7 +1061,7 @@ void tr_torrent::init(tr_ctor const* const ctor)
|
|||
|
||||
if (auto const has_metainfo = this->has_metainfo(); is_new_torrent && has_metainfo)
|
||||
{
|
||||
on_metainfo_completed(this);
|
||||
on_metainfo_completed();
|
||||
}
|
||||
else if (start_when_stable)
|
||||
{
|
||||
|
@ -1085,8 +1078,6 @@ void tr_torrent::init(tr_ctor const* const ctor)
|
|||
|
||||
void tr_torrent::set_metainfo(tr_torrent_metainfo tm)
|
||||
{
|
||||
using namespace torrent_init_helpers;
|
||||
|
||||
TR_ASSERT(!has_metainfo());
|
||||
metainfo_ = std::move(tm);
|
||||
on_metainfo_updated();
|
||||
|
@ -1096,14 +1087,12 @@ void tr_torrent::set_metainfo(tr_torrent_metainfo tm)
|
|||
this->set_dirty();
|
||||
this->mark_edited();
|
||||
|
||||
on_metainfo_completed(this);
|
||||
on_metainfo_completed();
|
||||
this->on_announce_list_changed();
|
||||
}
|
||||
|
||||
tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of)
|
||||
{
|
||||
using namespace torrent_init_helpers;
|
||||
|
||||
TR_ASSERT(ctor != nullptr);
|
||||
auto* const session = tr_ctorGetSession(ctor);
|
||||
TR_ASSERT(session != nullptr);
|
||||
|
@ -1361,11 +1350,11 @@ tr_stat tr_torrent::stats() const
|
|||
|
||||
auto const verify_progress = this->verify_progress();
|
||||
stats.recheckProgress = verify_progress.value_or(0.0);
|
||||
stats.activityDate = this->activityDate;
|
||||
stats.addedDate = this->addedDate;
|
||||
stats.doneDate = this->doneDate;
|
||||
stats.editDate = this->editDate;
|
||||
stats.startDate = this->startDate;
|
||||
stats.activityDate = this->date_active_;
|
||||
stats.addedDate = this->date_added_;
|
||||
stats.doneDate = this->date_done_;
|
||||
stats.editDate = this->date_edited_;
|
||||
stats.startDate = this->date_started_;
|
||||
stats.secondsSeeding = this->seconds_seeding(now_sec);
|
||||
stats.secondsDownloading = this->seconds_downloading(now_sec);
|
||||
|
||||
|
@ -1794,7 +1783,7 @@ void tr_torrent::recheck_completeness()
|
|||
{
|
||||
tr_announcerTorrentCompleted(this);
|
||||
this->mark_changed();
|
||||
this->doneDate = tr_time();
|
||||
date_done_ = tr_time();
|
||||
}
|
||||
|
||||
if (this->current_dir() == this->incomplete_dir())
|
||||
|
@ -2271,14 +2260,14 @@ void tr_torrent::set_download_dir(std::string_view path, bool is_new_torrent)
|
|||
|
||||
if (is_new_torrent)
|
||||
{
|
||||
if (session->shouldFullyVerifyAddedTorrents() || !torrent_init_helpers::isNewTorrentASeed(this))
|
||||
if (session->shouldFullyVerifyAddedTorrents() || !is_new_torrent_a_seed())
|
||||
{
|
||||
tr_torrentVerify(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
completion.set_has_all();
|
||||
doneDate = addedDate;
|
||||
date_done_ = date_added_;
|
||||
recheck_completeness();
|
||||
}
|
||||
}
|
||||
|
@ -2555,7 +2544,7 @@ bool tr_torrentHasMetadata(tr_torrent const* tor)
|
|||
|
||||
void tr_torrent::mark_edited()
|
||||
{
|
||||
this->editDate = tr_time();
|
||||
this->date_edited_ = tr_time();
|
||||
}
|
||||
|
||||
void tr_torrent::mark_changed()
|
||||
|
@ -2611,20 +2600,54 @@ void tr_torrent::init_checked_pieces(tr_bitfield const& checked, time_t const* m
|
|||
|
||||
// ---
|
||||
|
||||
time_t tr_torrent::ResumeHelper::date_active() const noexcept
|
||||
{
|
||||
return tor_.date_active_;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
time_t tr_torrent::ResumeHelper::date_added() const noexcept
|
||||
{
|
||||
return tor_.date_added_;
|
||||
}
|
||||
|
||||
void tr_torrent::ResumeHelper::load_date_added(time_t when) noexcept
|
||||
{
|
||||
tor_.date_added_ = when;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
time_t tr_torrent::ResumeHelper::date_done() const noexcept
|
||||
{
|
||||
return tor_.date_done_;
|
||||
}
|
||||
|
||||
void tr_torrent::ResumeHelper::load_date_done(time_t when) noexcept
|
||||
{
|
||||
tor_.date_done_ = when;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
time_t tr_torrent::ResumeHelper::seconds_downloading(time_t now) const noexcept
|
||||
{
|
||||
return tor_.seconds_downloading(now);
|
||||
}
|
||||
|
||||
time_t tr_torrent::ResumeHelper::seconds_seeding(time_t now) const noexcept
|
||||
{
|
||||
return tor_.seconds_seeding(now);
|
||||
}
|
||||
void tr_torrent::ResumeHelper::load_seconds_downloading_before_current_start(time_t when) noexcept
|
||||
{
|
||||
tor_.seconds_downloading_before_current_start_ = when;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
time_t tr_torrent::ResumeHelper::seconds_seeding(time_t now) const noexcept
|
||||
{
|
||||
return tor_.seconds_seeding(now);
|
||||
}
|
||||
|
||||
void tr_torrent::ResumeHelper::load_seconds_seeding_before_current_start(time_t when) noexcept
|
||||
{
|
||||
tor_.seconds_seeding_before_current_start_ = when;
|
||||
|
|
|
@ -89,9 +89,14 @@ struct tr_torrent final : public tr_completion::torrent_view
|
|||
class ResumeHelper
|
||||
{
|
||||
public:
|
||||
void load_date_added(time_t when) noexcept;
|
||||
void load_date_done(time_t when) noexcept;
|
||||
void load_seconds_downloading_before_current_start(time_t when) noexcept;
|
||||
void load_seconds_seeding_before_current_start(time_t when) noexcept;
|
||||
|
||||
[[nodiscard]] time_t date_active() const noexcept;
|
||||
[[nodiscard]] time_t date_added() const noexcept;
|
||||
[[nodiscard]] time_t date_done() const noexcept;
|
||||
[[nodiscard]] time_t seconds_downloading(time_t now) const noexcept;
|
||||
[[nodiscard]] time_t seconds_seeding(time_t now) const noexcept;
|
||||
|
||||
|
@ -211,6 +216,11 @@ public:
|
|||
|
||||
void save_resume_file();
|
||||
|
||||
[[nodiscard]] constexpr auto started_recently(time_t const now, time_t recent_secs = 120) const noexcept
|
||||
{
|
||||
return now - date_started_ <= recent_secs;
|
||||
}
|
||||
|
||||
/// SPEED LIMIT
|
||||
|
||||
[[nodiscard]] constexpr auto& bandwidth() noexcept
|
||||
|
@ -692,7 +702,7 @@ public:
|
|||
|
||||
constexpr void set_date_active(time_t when) noexcept
|
||||
{
|
||||
this->activityDate = when;
|
||||
this->date_active_ = when;
|
||||
|
||||
bump_date_changed(when);
|
||||
}
|
||||
|
@ -778,7 +788,7 @@ public:
|
|||
|
||||
[[nodiscard]] constexpr auto has_changed_since(time_t when) const noexcept
|
||||
{
|
||||
return changed_date_ > when;
|
||||
return date_changed_ > when;
|
||||
}
|
||||
|
||||
void set_bandwidth_group(std::string_view group_name) noexcept;
|
||||
|
@ -836,7 +846,7 @@ public:
|
|||
|
||||
if (activity == TR_STATUS_DOWNLOAD || activity == TR_STATUS_SEED)
|
||||
{
|
||||
if (auto const latest = std::max(startDate, activityDate); latest != 0)
|
||||
if (auto const latest = std::max(date_started_, date_active_); latest != 0)
|
||||
{
|
||||
TR_ASSERT(now >= latest);
|
||||
return now - latest;
|
||||
|
@ -963,6 +973,8 @@ public:
|
|||
|
||||
void init(tr_ctor const* ctor);
|
||||
|
||||
void start_in_session_thread();
|
||||
|
||||
[[nodiscard]] TR_CONSTEXPR20 auto obfuscated_hash_equals(tr_sha1_digest_t const& test) const noexcept
|
||||
{
|
||||
return obfuscated_hash_ == test;
|
||||
|
@ -1022,12 +1034,6 @@ public:
|
|||
|
||||
time_t lpdAnnounceAt = 0;
|
||||
|
||||
time_t activityDate = 0;
|
||||
time_t addedDate = 0;
|
||||
time_t doneDate = 0;
|
||||
time_t editDate = 0;
|
||||
time_t startDate = 0;
|
||||
|
||||
size_t queuePosition = 0;
|
||||
|
||||
tr_completeness completeness = TR_LEECH;
|
||||
|
@ -1138,13 +1144,13 @@ private:
|
|||
|
||||
if (is_running())
|
||||
{
|
||||
if (doneDate > startDate)
|
||||
if (date_done_ > date_started_)
|
||||
{
|
||||
n_secs += doneDate - startDate;
|
||||
n_secs += date_done_ - date_started_;
|
||||
}
|
||||
else if (doneDate == 0)
|
||||
else if (date_done_ == 0)
|
||||
{
|
||||
n_secs += now - startDate;
|
||||
n_secs += now - date_started_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1157,13 +1163,13 @@ private:
|
|||
|
||||
if (is_running())
|
||||
{
|
||||
if (doneDate > startDate)
|
||||
if (date_done_ > date_started_)
|
||||
{
|
||||
n_secs += now - doneDate;
|
||||
n_secs += now - date_done_;
|
||||
}
|
||||
else if (doneDate != 0)
|
||||
else if (date_done_ != 0)
|
||||
{
|
||||
n_secs += now - startDate;
|
||||
n_secs += now - date_started_;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1228,9 +1234,9 @@ private:
|
|||
|
||||
constexpr void bump_date_changed(time_t when)
|
||||
{
|
||||
if (changed_date_ < when)
|
||||
if (date_changed_ < when)
|
||||
{
|
||||
changed_date_ = when;
|
||||
date_changed_ = when;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1247,9 +1253,12 @@ private:
|
|||
}
|
||||
|
||||
void on_metainfo_updated();
|
||||
void on_metainfo_completed();
|
||||
|
||||
void stop_now();
|
||||
|
||||
[[nodiscard]] bool is_new_torrent_a_seed();
|
||||
|
||||
tr_stat stats_ = {};
|
||||
|
||||
Error error_;
|
||||
|
@ -1276,7 +1285,12 @@ private:
|
|||
*/
|
||||
tr_peer_id_t peer_id_ = tr_peerIdInit();
|
||||
|
||||
time_t changed_date_ = 0;
|
||||
time_t date_active_ = 0;
|
||||
time_t date_added_ = 0;
|
||||
time_t date_changed_ = 0;
|
||||
time_t date_done_ = 0;
|
||||
time_t date_edited_ = 0;
|
||||
time_t date_started_ = 0;
|
||||
|
||||
time_t seconds_downloading_before_current_start_ = 0;
|
||||
time_t seconds_seeding_before_current_start_ = 0;
|
||||
|
|
Loading…
Reference in a new issue