transmission/qt/Torrent.h

703 lines
16 KiB
C
Raw Normal View History

// This file Copyright © 2009-2023 Mnemosyne LLC.
2022-08-08 18:05:39 +00:00
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
2009-04-09 18:55:47 +00:00
#pragma once
2009-04-09 18:55:47 +00:00
#include <bitset>
2022-04-25 01:49:52 +00:00
#include <cstddef> // size_t
#include <cstdint> // uint64_t
#include <ctime> // time_t
#include <optional>
Qt 6 support (#2069) * Bump minimum Qt version to 5.6 * Switch from QRegExp to QRegularExpression While still available, QRegExp has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Use qIsEffectiveTLD instead of QUrl::topLevelDomain The latter is not part of Qt6::Core. The former is a private utility in Qt6::Network; using it for now, until (and if) we switch to something non-Qt-specific. * Use QStyle::State_Horizontal state when drawing progress bars Although available for a long time, this state either didn't apply to progress bars before Qt 6, or was deduced based on bar size. With Qt 6, failing to specify it results in bad rendering. * Don't use QStringRef (and associated methods) While still available, QStringRef has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. Related method (e.g. QString::midRef) have been removed in Qt 6. * Use Qt::ItemIsAutoTristate instead of Qt::ItemIsTristate The latter was deprecated and replaced with the former in Qt 5.6. * Don't use QApplication::globalStrut This property has been deprecated in Qt 5.15 and removed in Qt 6. * Use QImage::fromHICON instead of QtWin::fromHICON WinExtras module (providind the latter helper) has been removed in Qt 6. * Use QStringDecoder instead of QTextCodec While still available, QTextCodec has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Don't forward-declare QStringList Instead of being a standalone class, its definition has changed to QList<QString> template specialization in Qt 6. * Use explicit (since Qt 6) QFileInfo constructor * Use QDateTime's {to,from}SecsSinceEpoch instead of {to,from}Time_t The latter was deprecated in Qt 5.8 and removed in Qt 6. * Don't use QFuture<>'s operator== It has been removed in Qt 6. Since the original issue this code was solving was caused by future reuse, just don't reuse futures and create new finished ones when necessary. * Use std::vector<> instead of QVector<> The latter has been changed to a typedef for QList<>, which might not be what one wants, and which also changed behavior a bit leading to compilation errors. * Don't use + for flags, cast to int explicitly Operator+ for enum values has been deleted in Qt 6, so using operator| instead. Then, there's no conversion from QFlags<> to QVariant, so need to cast to int. * Support Qt 6 in CMake and for MSI packaging * Remove extra (empty) CMake variable use when constructing Qt target names * Simplify logic in tr_qt_add_translation CMake helper Co-authored-by: Charles Kerr <charles@charleskerr.com>
2021-11-03 21:20:11 +00:00
#include <vector>
2009-04-09 18:55:47 +00:00
#include <QIcon>
#include <QMetaType>
#include <QObject>
2009-04-09 18:55:47 +00:00
#include <QString>
#include <libtransmission/transmission.h>
#include <libtransmission/crypto-utils.h>
#include <libtransmission/quark.h>
#include <libtransmission/tr-macros.h>
2009-04-09 18:55:47 +00:00
#include "FaviconCache.h"
#include "IconCache.h"
#include "Speed.h"
2009-04-09 18:55:47 +00:00
#ifdef ERROR
#undef ERROR
#endif
class QPixmap;
2015-06-12 22:12:12 +00:00
class Prefs;
2009-04-09 18:55:47 +00:00
extern "C"
{
struct tr_variant;
2009-04-09 18:55:47 +00:00
}
struct Peer
{
bool client_is_choked;
bool client_is_interested;
bool is_downloading_from;
bool is_encrypted;
bool is_incoming;
bool is_uploading_to;
bool peer_is_choked;
bool peer_is_interested;
QString address;
QString client_name;
QString flags;
int port;
Speed rate_to_client;
Speed rate_to_peer;
double progress;
2009-04-09 18:55:47 +00:00
};
Qt 6 support (#2069) * Bump minimum Qt version to 5.6 * Switch from QRegExp to QRegularExpression While still available, QRegExp has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Use qIsEffectiveTLD instead of QUrl::topLevelDomain The latter is not part of Qt6::Core. The former is a private utility in Qt6::Network; using it for now, until (and if) we switch to something non-Qt-specific. * Use QStyle::State_Horizontal state when drawing progress bars Although available for a long time, this state either didn't apply to progress bars before Qt 6, or was deduced based on bar size. With Qt 6, failing to specify it results in bad rendering. * Don't use QStringRef (and associated methods) While still available, QStringRef has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. Related method (e.g. QString::midRef) have been removed in Qt 6. * Use Qt::ItemIsAutoTristate instead of Qt::ItemIsTristate The latter was deprecated and replaced with the former in Qt 5.6. * Don't use QApplication::globalStrut This property has been deprecated in Qt 5.15 and removed in Qt 6. * Use QImage::fromHICON instead of QtWin::fromHICON WinExtras module (providind the latter helper) has been removed in Qt 6. * Use QStringDecoder instead of QTextCodec While still available, QTextCodec has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Don't forward-declare QStringList Instead of being a standalone class, its definition has changed to QList<QString> template specialization in Qt 6. * Use explicit (since Qt 6) QFileInfo constructor * Use QDateTime's {to,from}SecsSinceEpoch instead of {to,from}Time_t The latter was deprecated in Qt 5.8 and removed in Qt 6. * Don't use QFuture<>'s operator== It has been removed in Qt 6. Since the original issue this code was solving was caused by future reuse, just don't reuse futures and create new finished ones when necessary. * Use std::vector<> instead of QVector<> The latter has been changed to a typedef for QList<>, which might not be what one wants, and which also changed behavior a bit leading to compilation errors. * Don't use + for flags, cast to int explicitly Operator+ for enum values has been deleted in Qt 6, so using operator| instead. Then, there's no conversion from QFlags<> to QVariant, so need to cast to int. * Support Qt 6 in CMake and for MSI packaging * Remove extra (empty) CMake variable use when constructing Qt target names * Simplify logic in tr_qt_add_translation CMake helper Co-authored-by: Charles Kerr <charles@charleskerr.com>
2021-11-03 21:20:11 +00:00
using PeerList = std::vector<Peer>;
2009-04-09 18:55:47 +00:00
struct TrackerStat
{
QPixmap getFavicon() const;
bool has_announced;
bool has_scraped;
bool is_backup;
bool last_announce_succeeded;
bool last_announce_timed_out;
bool last_scrape_succeeded;
bool last_scrape_timed_out;
int announce_state;
int download_count;
int id;
int last_announce_peer_count;
int last_announce_start_time;
int last_announce_time;
int last_scrape_start_time;
int last_scrape_time;
int leecher_count;
int next_announce_time;
int next_scrape_time;
int scrape_state;
int seeder_count;
int tier;
QString announce;
QString last_announce_result;
QString last_scrape_result;
QString sitename;
};
Qt 6 support (#2069) * Bump minimum Qt version to 5.6 * Switch from QRegExp to QRegularExpression While still available, QRegExp has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Use qIsEffectiveTLD instead of QUrl::topLevelDomain The latter is not part of Qt6::Core. The former is a private utility in Qt6::Network; using it for now, until (and if) we switch to something non-Qt-specific. * Use QStyle::State_Horizontal state when drawing progress bars Although available for a long time, this state either didn't apply to progress bars before Qt 6, or was deduced based on bar size. With Qt 6, failing to specify it results in bad rendering. * Don't use QStringRef (and associated methods) While still available, QStringRef has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. Related method (e.g. QString::midRef) have been removed in Qt 6. * Use Qt::ItemIsAutoTristate instead of Qt::ItemIsTristate The latter was deprecated and replaced with the former in Qt 5.6. * Don't use QApplication::globalStrut This property has been deprecated in Qt 5.15 and removed in Qt 6. * Use QImage::fromHICON instead of QtWin::fromHICON WinExtras module (providind the latter helper) has been removed in Qt 6. * Use QStringDecoder instead of QTextCodec While still available, QTextCodec has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Don't forward-declare QStringList Instead of being a standalone class, its definition has changed to QList<QString> template specialization in Qt 6. * Use explicit (since Qt 6) QFileInfo constructor * Use QDateTime's {to,from}SecsSinceEpoch instead of {to,from}Time_t The latter was deprecated in Qt 5.8 and removed in Qt 6. * Don't use QFuture<>'s operator== It has been removed in Qt 6. Since the original issue this code was solving was caused by future reuse, just don't reuse futures and create new finished ones when necessary. * Use std::vector<> instead of QVector<> The latter has been changed to a typedef for QList<>, which might not be what one wants, and which also changed behavior a bit leading to compilation errors. * Don't use + for flags, cast to int explicitly Operator+ for enum values has been deleted in Qt 6, so using operator| instead. Then, there's no conversion from QFlags<> to QVariant, so need to cast to int. * Support Qt 6 in CMake and for MSI packaging * Remove extra (empty) CMake variable use when constructing Qt target names * Simplify logic in tr_qt_add_translation CMake helper Co-authored-by: Charles Kerr <charles@charleskerr.com>
2021-11-03 21:20:11 +00:00
using TrackerStatsList = std::vector<TrackerStat>;
struct TorrentFile
2009-04-09 18:55:47 +00:00
{
bool wanted = true;
int index = -1;
int priority = 0;
QString filename;
uint64_t size = 0;
uint64_t have = 0;
2009-04-09 18:55:47 +00:00
};
Qt 6 support (#2069) * Bump minimum Qt version to 5.6 * Switch from QRegExp to QRegularExpression While still available, QRegExp has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Use qIsEffectiveTLD instead of QUrl::topLevelDomain The latter is not part of Qt6::Core. The former is a private utility in Qt6::Network; using it for now, until (and if) we switch to something non-Qt-specific. * Use QStyle::State_Horizontal state when drawing progress bars Although available for a long time, this state either didn't apply to progress bars before Qt 6, or was deduced based on bar size. With Qt 6, failing to specify it results in bad rendering. * Don't use QStringRef (and associated methods) While still available, QStringRef has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. Related method (e.g. QString::midRef) have been removed in Qt 6. * Use Qt::ItemIsAutoTristate instead of Qt::ItemIsTristate The latter was deprecated and replaced with the former in Qt 5.6. * Don't use QApplication::globalStrut This property has been deprecated in Qt 5.15 and removed in Qt 6. * Use QImage::fromHICON instead of QtWin::fromHICON WinExtras module (providind the latter helper) has been removed in Qt 6. * Use QStringDecoder instead of QTextCodec While still available, QTextCodec has been moved to Qt6::Core5Compat module and is not part of Qt6::Core. * Don't forward-declare QStringList Instead of being a standalone class, its definition has changed to QList<QString> template specialization in Qt 6. * Use explicit (since Qt 6) QFileInfo constructor * Use QDateTime's {to,from}SecsSinceEpoch instead of {to,from}Time_t The latter was deprecated in Qt 5.8 and removed in Qt 6. * Don't use QFuture<>'s operator== It has been removed in Qt 6. Since the original issue this code was solving was caused by future reuse, just don't reuse futures and create new finished ones when necessary. * Use std::vector<> instead of QVector<> The latter has been changed to a typedef for QList<>, which might not be what one wants, and which also changed behavior a bit leading to compilation errors. * Don't use + for flags, cast to int explicitly Operator+ for enum values has been deleted in Qt 6, so using operator| instead. Then, there's no conversion from QFlags<> to QVariant, so need to cast to int. * Support Qt 6 in CMake and for MSI packaging * Remove extra (empty) CMake variable use when constructing Qt target names * Simplify logic in tr_qt_add_translation CMake helper Co-authored-by: Charles Kerr <charles@charleskerr.com>
2021-11-03 21:20:11 +00:00
using FileList = std::vector<TorrentFile>;
2009-04-09 18:55:47 +00:00
class TorrentHash
{
private:
tr_sha1_digest_t data_ = {};
public:
TorrentHash() = default;
explicit TorrentHash(tr_sha1_digest_t const& data)
: data_{ data }
{
}
explicit TorrentHash(char const* str)
{
if (auto const hash = tr_sha1_from_string(str != nullptr ? str : ""); hash)
{
data_ = *hash;
}
}
explicit TorrentHash(QString const& str)
{
if (auto const hash = tr_sha1_from_string(str.toStdString()); hash)
{
data_ = *hash;
}
}
[[nodiscard]] TR_CONSTEXPR20 auto operator==(TorrentHash const& that) const
{
return data_ == that.data_;
}
[[nodiscard]] TR_CONSTEXPR20 auto operator!=(TorrentHash const& that) const
{
return !(*this == that);
}
[[nodiscard]] auto operator<(TorrentHash const& that) const
{
return data_ < that.data_;
}
QString toString() const
{
return QString::fromStdString(tr_sha1_to_string(data_));
}
};
class Torrent : public QObject
2009-04-09 18:55:47 +00:00
{
Q_OBJECT
TR_DISABLE_COPY_MOVE(Torrent)
2013-09-14 22:45:04 +00:00
public:
Torrent(Prefs const&, int id);
[[nodiscard]] constexpr auto getBandwidthPriority() const noexcept
{
return bandwidth_priority_;
}
[[nodiscard]] constexpr auto id() const noexcept
{
return id_;
}
[[nodiscard]] constexpr auto const& name() const noexcept
{
return name_;
}
bool hasName() const
{
return !name_.isEmpty();
}
[[nodiscard]] constexpr auto const& creator() const noexcept
{
return creator_;
}
[[nodiscard]] constexpr auto const& comment() const noexcept
{
return comment_;
}
[[nodiscard]] constexpr auto const& getPath() const noexcept
{
return download_dir_;
}
QString getError() const;
[[nodiscard]] constexpr auto const& trackerList() const noexcept
{
return tracker_list_;
}
[[nodiscard]] constexpr auto const& hash() const noexcept
{
return hash_;
}
[[nodiscard]] constexpr auto hasError() const noexcept
{
return error_ != TR_STAT_OK;
}
[[nodiscard]] constexpr auto leftUntilDone() const noexcept
{
return left_until_done_;
}
[[nodiscard]] constexpr auto isDone() const noexcept
{
return leftUntilDone() == 0;
}
[[nodiscard]] constexpr auto haveVerified() const noexcept
{
return have_verified_;
}
[[nodiscard]] constexpr auto totalSize() const noexcept
{
return total_size_;
}
[[nodiscard]] constexpr auto isSeed() const noexcept
{
return haveVerified() >= totalSize();
}
[[nodiscard]] constexpr auto isPrivate() const noexcept
{
return is_private_;
}
std::optional<double> getSeedRatioLimit() const;
[[nodiscard]] constexpr auto haveUnverified() const noexcept
{
return have_unchecked_;
}
[[nodiscard]] constexpr auto desiredAvailable() const noexcept
{
return desired_available_;
}
[[nodiscard]] constexpr auto haveTotal() const noexcept
{
return haveVerified() + haveUnverified();
}
[[nodiscard]] constexpr auto sizeWhenDone() const noexcept
{
return size_when_done_;
}
[[nodiscard]] constexpr auto pieceSize() const noexcept
{
return piece_size_;
}
[[nodiscard]] constexpr auto metadataPercentDone() const noexcept
{
return metadata_percent_complete_;
}
[[nodiscard]] constexpr auto hasMetadata() const noexcept
{
return metadataPercentDone() >= 1.0;
}
[[nodiscard]] constexpr auto pieceCount() const noexcept
{
return piece_count_;
}
[[nodiscard]] constexpr auto downloadedEver() const noexcept
{
return downloaded_ever_;
}
[[nodiscard]] constexpr auto uploadedEver() const noexcept
{
return uploaded_ever_;
}
[[nodiscard]] constexpr auto ratio() const noexcept
{
auto const numerator = static_cast<double>(uploadedEver());
auto const denominator = sizeWhenDone();
return denominator > 0U ? numerator / denominator : double{};
}
[[nodiscard]] constexpr double percentComplete() const noexcept
{
return totalSize() != 0 ? haveTotal() / static_cast<double>(totalSize()) : 0;
}
[[nodiscard]] constexpr double percentDone() const noexcept
{
auto const l = leftUntilDone();
auto const s = sizeWhenDone();
return s ? static_cast<double>(s - l) / static_cast<double>(s) : 0.0;
}
[[nodiscard]] constexpr auto failedEver() const noexcept
{
return failed_ever_;
}
int compareSeedProgress(Torrent const&) const;
int compareRatio(Torrent const&) const;
int compareETA(Torrent const&) const;
[[nodiscard]] constexpr auto getETA() const noexcept
{
return eta_;
}
[[nodiscard]] constexpr auto hasETA() const noexcept
{
return getETA() >= 0;
}
[[nodiscard]] constexpr auto lastActivity() const noexcept
{
return activity_date_;
}
[[nodiscard]] constexpr auto lastStarted() const noexcept
{
return start_date_;
}
[[nodiscard]] constexpr auto dateAdded() const noexcept
{
return added_date_;
}
[[nodiscard]] constexpr auto dateCreated() const noexcept
{
return date_created_;
}
[[nodiscard]] constexpr auto dateEdited() const noexcept
{
return edit_date_;
}
[[nodiscard]] constexpr auto manualAnnounceTime() const noexcept
{
return manual_announce_time_;
}
[[nodiscard]] constexpr auto peersWeAreDownloadingFrom() const noexcept
{
return peers_sending_to_us_;
}
[[nodiscard]] constexpr auto webseedsWeAreDownloadingFrom() const noexcept
{
return webseeds_sending_to_us_;
}
[[nodiscard]] constexpr auto peersWeAreUploadingTo() const noexcept
{
return peers_getting_from_us_;
}
[[nodiscard]] constexpr auto isUploading() const noexcept
{
return peersWeAreUploadingTo() > 0;
}
[[nodiscard]] constexpr auto connectedPeers() const noexcept
{
return peers_connected_;
}
[[nodiscard]] constexpr auto connectedPeersAndWebseeds() const noexcept
{
return connectedPeers() + webseedsWeAreDownloadingFrom();
}
[[nodiscard]] constexpr auto const& downloadSpeed() const noexcept
{
return download_speed_;
}
[[nodiscard]] constexpr auto const& uploadSpeed() const noexcept
{
return upload_speed_;
}
[[nodiscard]] constexpr auto getVerifyProgress() const noexcept
{
return recheck_progress_;
}
bool includesTracker(QString const& sitename) const;
[[nodiscard]] constexpr auto const& sitenames() const noexcept
{
return sitenames_;
}
[[nodiscard]] Speed uploadLimit() const
{
return Speed::fromKBps(upload_limit_);
}
[[nodiscard]] Speed downloadLimit() const
{
return Speed::fromKBps(download_limit_);
}
[[nodiscard]] constexpr auto uploadIsLimited() const noexcept
{
return upload_limited_;
}
[[nodiscard]] constexpr auto downloadIsLimited() const noexcept
{
return download_limited_;
}
[[nodiscard]] constexpr auto honorsSessionLimits() const noexcept
{
return honors_session_limits_;
}
[[nodiscard]] constexpr auto peerLimit() const noexcept
{
return peer_limit_;
}
[[nodiscard]] constexpr auto seedRatioLimit() const noexcept
{
return seed_ratio_limit_;
}
[[nodiscard]] constexpr auto seedRatioMode() const noexcept
{
return static_cast<tr_ratiolimit>(seed_ratio_mode_);
}
[[nodiscard]] constexpr auto seedIdleLimit() const noexcept
{
return seed_idle_limit_;
}
[[nodiscard]] constexpr auto seedIdleMode() const noexcept
{
return static_cast<tr_idlelimit>(seed_idle_mode_);
}
[[nodiscard]] constexpr auto const& trackerStats() const noexcept
{
return tracker_stats_;
}
[[nodiscard]] constexpr auto const& peers() const noexcept
{
return peers_;
}
[[nodiscard]] constexpr auto const& files() const noexcept
{
return files_;
}
[[nodiscard]] auto constexpr queuePosition() const noexcept
{
return queue_position_;
}
[[nodiscard]] auto constexpr isStalled() const noexcept
{
return is_stalled_;
}
QString activityString() const;
[[nodiscard]] auto constexpr getActivity() const noexcept
{
return static_cast<tr_torrent_activity>(status_);
}
[[nodiscard]] auto constexpr isFinished() const noexcept
{
return is_finished_;
}
[[nodiscard]] auto constexpr isPaused() const noexcept
{
return getActivity() == TR_STATUS_STOPPED;
}
[[nodiscard]] auto constexpr isWaitingToVerify() const noexcept
{
return getActivity() == TR_STATUS_CHECK_WAIT;
}
[[nodiscard]] auto constexpr isVerifying() const noexcept
{
return getActivity() == TR_STATUS_CHECK;
}
[[nodiscard]] auto constexpr isDownloading() const noexcept
{
return getActivity() == TR_STATUS_DOWNLOAD;
}
[[nodiscard]] auto constexpr isWaitingToDownload() const noexcept
{
return getActivity() == TR_STATUS_DOWNLOAD_WAIT;
}
[[nodiscard]] auto constexpr isSeeding() const noexcept
{
return getActivity() == TR_STATUS_SEED;
}
[[nodiscard]] auto constexpr isWaitingToSeed() const noexcept
{
return getActivity() == TR_STATUS_SEED_WAIT;
}
[[nodiscard]] auto constexpr isReadyToTransfer() const noexcept
{
return getActivity() == TR_STATUS_DOWNLOAD || getActivity() == TR_STATUS_SEED;
}
[[nodiscard]] auto constexpr isQueued() const noexcept
{
return isWaitingToDownload() || isWaitingToSeed();
}
[[nodiscard]] auto constexpr canManualAnnounceAt(time_t t) const noexcept
{
return isReadyToTransfer() && (manualAnnounceTime() <= t);
}
QIcon getMimeTypeIcon() const;
enum Field
{
ACTIVITY_DATE,
ADDED_DATE,
BANDWIDTH_PRIORITY,
COMMENT,
CREATOR,
DATE_CREATED,
DESIRED_AVAILABLE,
DOWNLOADED_EVER,
DOWNLOAD_DIR,
DOWNLOAD_LIMIT,
DOWNLOAD_LIMITED,
DOWNLOAD_SPEED,
EDIT_DATE,
ERROR,
ERROR_STRING,
ETA,
FAILED_EVER,
FILE_COUNT,
FILES,
HASH,
HAVE_UNCHECKED,
HAVE_VERIFIED,
HONORS_SESSION_LIMITS,
ICON,
IS_FINISHED,
IS_PRIVATE,
IS_STALLED,
LEFT_UNTIL_DONE,
MANUAL_ANNOUNCE_TIME,
METADATA_PERCENT_COMPLETE,
NAME,
PEERS,
PEERS_CONNECTED,
PEERS_GETTING_FROM_US,
PEERS_SENDING_TO_US,
PEER_LIMIT,
PERCENT_DONE,
PIECE_COUNT,
PIECE_SIZE,
PRIMARY_MIME_TYPE,
QUEUE_POSITION,
RECHECK_PROGRESS,
SEED_IDLE_LIMIT,
SEED_IDLE_MODE,
SEED_RATIO_LIMIT,
SEED_RATIO_MODE,
SIZE_WHEN_DONE,
START_DATE,
STATUS,
TOTAL_SIZE,
TRACKER_STATS,
TRACKER_LIST,
UPLOADED_EVER,
UPLOAD_LIMIT,
UPLOAD_LIMITED,
UPLOAD_SPEED,
WEBSEEDS_SENDING_TO_US,
N_FIELDS
};
using fields_t = std::bitset<N_FIELDS>;
fields_t update(tr_quark const* keys, tr_variant const* const* values, size_t n);
private:
tr_torrent_id_t const id_;
bool download_limited_ = {};
bool honors_session_limits_ = {};
bool is_finished_ = {};
bool is_private_ = {};
bool is_stalled_ = {};
bool upload_limited_ = {};
time_t activity_date_ = {};
time_t added_date_ = {};
time_t date_created_ = {};
time_t edit_date_ = {};
time_t manual_announce_time_ = {};
time_t start_date_ = {};
int bandwidth_priority_ = {};
int download_limit_ = {};
int error_ = {};
int eta_ = {};
int peer_limit_ = {};
int peers_connected_ = {};
int peers_getting_from_us_ = {};
int peers_sending_to_us_ = {};
int piece_count_ = {};
int queue_position_ = {};
int seed_idle_limit_ = {};
int seed_idle_mode_ = {};
int seed_ratio_mode_ = {};
int status_ = {};
int upload_limit_ = {};
int webseeds_sending_to_us_ = {};
uint64_t desired_available_ = {};
uint64_t downloaded_ever_ = {};
uint64_t failed_ever_ = {};
uint64_t file_count_ = {};
uint64_t have_unchecked_ = {};
uint64_t have_verified_ = {};
uint64_t left_until_done_ = {};
uint64_t piece_size_ = {};
uint64_t size_when_done_ = {};
uint64_t total_size_ = {};
uint64_t uploaded_ever_ = {};
double metadata_percent_complete_ = {};
double percent_done_ = {};
double recheck_progress_ = {};
double seed_ratio_limit_ = {};
QString comment_;
QString creator_;
QString download_dir_;
QString error_string_;
QString name_;
QString primary_mime_type_;
QString tracker_list_;
// mutable because it's a lazy lookup
mutable QIcon icon_ = IconCache::get().fileIcon();
PeerList peers_;
FileList files_;
std::vector<QString> sitenames_;
TrackerStatsList tracker_stats_;
Speed upload_speed_;
Speed download_speed_;
Prefs const& prefs_;
TorrentHash hash_;
2009-04-09 18:55:47 +00:00
};
Q_DECLARE_METATYPE(Torrent const*)