Browse Source

Merge pull request #9180 from glassez/resume-data

Save resume data on torrent change events. Closes #9174
adaptive-webui-19844
Vladimir Golovnev 7 years ago committed by GitHub
parent
commit
5d931ef9ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 152
      src/base/bittorrent/session.cpp
  2. 7
      src/base/bittorrent/session.h
  3. 83
      src/base/bittorrent/torrenthandle.cpp
  4. 21
      src/base/bittorrent/torrenthandle.h

152
src/base/bittorrent/session.cpp

@ -111,7 +111,7 @@ using namespace BitTorrent; @@ -111,7 +111,7 @@ using namespace BitTorrent;
namespace
{
bool readFile(const QString &path, QByteArray &buf);
bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &torrentData, int &prio, MagnetUri &magnetUri);
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &prio, MagnetUri &magnetUri);
void torrentQueuePositionUp(const libt::torrent_handle &handle);
void torrentQueuePositionDown(const libt::torrent_handle &handle);
@ -2110,15 +2110,15 @@ bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams @@ -2110,15 +2110,15 @@ bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams
}
// Add a torrent to the BitTorrent session
bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magnetUri,
TorrentInfo torrentInfo, const QByteArray &fastresumeData)
{
addData.savePath = normalizeSavePath(addData.savePath, "");
params.savePath = normalizeSavePath(params.savePath, "");
if (!addData.category.isEmpty()) {
if (!m_categories.contains(addData.category) && !addCategory(addData.category)) {
qWarning() << "Couldn't create category" << addData.category;
addData.category = "";
if (!params.category.isEmpty()) {
if (!m_categories.contains(params.category) && !addCategory(params.category)) {
qWarning() << "Couldn't create category" << params.category;
params.category = "";
}
}
@ -2127,10 +2127,10 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2127,10 +2127,10 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
std::vector<boost::uint8_t> filePriorities;
QString savePath;
if (addData.savePath.isEmpty()) // using Automatic mode
savePath = categorySavePath(addData.category);
if (params.savePath.isEmpty()) // using Automatic mode
savePath = categorySavePath(params.category);
else // using Manual mode
savePath = addData.savePath;
savePath = params.savePath;
bool fromMagnetUri = magnetUri.isValid();
if (fromMagnetUri) {
@ -2151,7 +2151,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2151,7 +2151,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
adjustLimits();
// use common 2nd step of torrent addition
m_addingTorrents.insert(hash, addData);
m_addingTorrents.insert(hash, params);
createTorrentHandle(handle);
return true;
}
@ -2159,23 +2159,23 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2159,23 +2159,23 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
p = magnetUri.addTorrentParams();
}
else if (torrentInfo.isValid()) {
if (!addData.resumed) {
if (!addData.hasRootFolder)
if (!params.restored) {
if (!params.hasRootFolder)
torrentInfo.stripRootFolder();
// Metadata
if (!addData.hasSeedStatus)
if (!params.hasSeedStatus)
findIncompleteFiles(torrentInfo, savePath);
// if torrent name wasn't explicitly set we handle the case of
// initial renaming of torrent content and rename torrent accordingly
if (addData.name.isEmpty()) {
if (params.name.isEmpty()) {
QString contentName = torrentInfo.rootFolder();
if (contentName.isEmpty() && (torrentInfo.filesCount() == 1))
contentName = torrentInfo.fileName(0);
if (!contentName.isEmpty() && (contentName != torrentInfo.name()))
addData.name = contentName;
params.name = contentName;
}
}
@ -2189,13 +2189,13 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2189,13 +2189,13 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
return false;
}
if (addData.resumed && !fromMagnetUri) {
if (params.restored && !fromMagnetUri) {
// Set torrent fast resume data
p.resume_data = {fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()};
p.flags |= libt::add_torrent_params::flag_use_resume_save_path;
}
else {
foreach (int prio, addData.filePriorities)
foreach (int prio, params.filePriorities)
filePriorities.push_back(prio);
p.file_priorities = filePriorities;
}
@ -2228,7 +2228,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2228,7 +2228,7 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
// Seeding mode
// Skip checking and directly start seeding (new in libtorrent v0.15)
if (addData.skipChecking)
if (params.skipChecking)
p.flags |= libt::add_torrent_params::flag_seed_mode;
else
p.flags &= ~libt::add_torrent_params::flag_seed_mode;
@ -2237,10 +2237,10 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri @@ -2237,10 +2237,10 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri
p.max_connections = maxConnectionsPerTorrent();
p.max_uploads = maxUploadsPerTorrent();
p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
p.upload_limit = addData.uploadLimit;
p.download_limit = addData.downloadLimit;
p.upload_limit = params.uploadLimit;
p.download_limit = params.downloadLimit;
m_addingTorrents.insert(hash, addData);
m_addingTorrents.insert(hash, params);
// Adding torrent to BitTorrent session
m_nativeSession->async_add_torrent(p);
return true;
@ -2362,7 +2362,6 @@ void Session::generateResumeData(bool final) @@ -2362,7 +2362,6 @@ void Session::generateResumeData(bool final)
if (!final && !torrent->needSaveResumeData()) continue;
saveTorrentResumeData(torrent, final);
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
}
}
@ -3529,45 +3528,58 @@ void Session::updateSeedingLimitTimer() @@ -3529,45 +3528,58 @@ void Session::updateSeedingLimitTimer()
void Session::handleTorrentShareLimitChanged(TorrentHandle *const torrent)
{
Q_UNUSED(torrent);
saveTorrentResumeData(torrent);
updateSeedingLimitTimer();
}
void Session::saveTorrentResumeData(TorrentHandle *const torrent, bool finalSave)
{
qDebug("Saving fastresume data for %s", qUtf8Printable(torrent->name()));
torrent->saveResumeData(finalSave);
++m_numResumeData;
}
void Session::handleTorrentNameChanged(TorrentHandle *const torrent)
{
saveTorrentResumeData(torrent);
}
void Session::handleTorrentSavePathChanged(TorrentHandle *const torrent)
{
saveTorrentResumeData(torrent);
emit torrentSavePathChanged(torrent);
}
void Session::handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory)
{
saveTorrentResumeData(torrent);
emit torrentCategoryChanged(torrent, oldCategory);
}
void Session::handleTorrentTagAdded(TorrentHandle *const torrent, const QString &tag)
{
saveTorrentResumeData(torrent);
emit torrentTagAdded(torrent, tag);
}
void Session::handleTorrentTagRemoved(TorrentHandle *const torrent, const QString &tag)
{
saveTorrentResumeData(torrent);
emit torrentTagRemoved(torrent, tag);
}
void Session::handleTorrentSavingModeChanged(TorrentHandle *const torrent)
{
saveTorrentResumeData(torrent);
emit torrentSavingModeChanged(torrent);
}
void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QList<TrackerEntry> &newTrackers)
{
foreach (const TrackerEntry &newTracker, newTrackers)
Logger::instance()->addMessage(tr("Tracker '%1' was added to torrent '%2'").arg(newTracker.url(), torrent->name()));
saveTorrentResumeData(torrent);
for (const TrackerEntry &newTracker : newTrackers)
LogMsg(tr("Tracker '%1' was added to torrent '%2'").arg(newTracker.url(), torrent->name()));
emit trackersAdded(torrent, newTrackers);
if (torrent->trackers().size() == newTrackers.size())
emit trackerlessStateChanged(torrent, false);
@ -3576,8 +3588,10 @@ void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QLi @@ -3576,8 +3588,10 @@ void Session::handleTorrentTrackersAdded(TorrentHandle *const torrent, const QLi
void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const QList<TrackerEntry> &deletedTrackers)
{
foreach (const TrackerEntry &deletedTracker, deletedTrackers)
Logger::instance()->addMessage(tr("Tracker '%1' was deleted from torrent '%2'").arg(deletedTracker.url(), torrent->name()));
saveTorrentResumeData(torrent);
for (const TrackerEntry &deletedTracker : deletedTrackers)
LogMsg(tr("Tracker '%1' was deleted from torrent '%2'").arg(deletedTracker.url(), torrent->name()));
emit trackersRemoved(torrent, deletedTrackers);
if (torrent->trackers().size() == 0)
emit trackerlessStateChanged(torrent, true);
@ -3586,19 +3600,22 @@ void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const Q @@ -3586,19 +3600,22 @@ void Session::handleTorrentTrackersRemoved(TorrentHandle *const torrent, const Q
void Session::handleTorrentTrackersChanged(TorrentHandle *const torrent)
{
saveTorrentResumeData(torrent);
emit trackersChanged(torrent);
}
void Session::handleTorrentUrlSeedsAdded(TorrentHandle *const torrent, const QList<QUrl> &newUrlSeeds)
{
foreach (const QUrl &newUrlSeed, newUrlSeeds)
Logger::instance()->addMessage(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString(), torrent->name()));
saveTorrentResumeData(torrent);
for (const QUrl &newUrlSeed : newUrlSeeds)
LogMsg(tr("URL seed '%1' was added to torrent '%2'").arg(newUrlSeed.toString(), torrent->name()));
}
void Session::handleTorrentUrlSeedsRemoved(TorrentHandle *const torrent, const QList<QUrl> &urlSeeds)
{
foreach (const QUrl &urlSeed, urlSeeds)
Logger::instance()->addMessage(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString(), torrent->name()));
saveTorrentResumeData(torrent);
for (const QUrl &urlSeed : urlSeeds)
LogMsg(tr("URL seed '%1' was removed from torrent '%2'").arg(urlSeed.toString(), torrent->name()));
}
void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent)
@ -3626,6 +3643,7 @@ void Session::handleTorrentPaused(TorrentHandle *const torrent) @@ -3626,6 +3643,7 @@ void Session::handleTorrentPaused(TorrentHandle *const torrent)
void Session::handleTorrentResumed(TorrentHandle *const torrent)
{
saveTorrentResumeData(torrent);
emit torrentResumed(torrent);
}
@ -3831,7 +3849,7 @@ void Session::startUpTorrents() @@ -3831,7 +3849,7 @@ void Session::startUpTorrents()
{
QString hash;
MagnetUri magnetUri;
AddTorrentData addTorrentData;
CreateTorrentParams addTorrentData;
QByteArray data;
} TorrentResumeData;
@ -3864,12 +3882,12 @@ void Session::startUpTorrents() @@ -3864,12 +3882,12 @@ void Session::startUpTorrents()
QString hash = rxMatch.captured(1);
QString fastresumePath = resumeDataDir.absoluteFilePath(fastresumeName);
QByteArray data;
AddTorrentData resumeData;
CreateTorrentParams torrentParams;
MagnetUri magnetUri;
int queuePosition;
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, resumeData, queuePosition, magnetUri)) {
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, torrentParams, queuePosition, magnetUri)) {
if (queuePosition <= nextQueuePosition) {
startupTorrent({ hash, magnetUri, resumeData, data });
startupTorrent({ hash, magnetUri, torrentParams, data });
if (queuePosition == nextQueuePosition) {
++nextQueuePosition;
@ -3886,7 +3904,7 @@ void Session::startUpTorrents() @@ -3886,7 +3904,7 @@ void Session::startUpTorrents()
if (q != queuePosition) {
++numOfRemappedFiles;
}
queuedResumeData[q] = {hash, magnetUri, resumeData, data};
queuedResumeData[q] = {hash, magnetUri, torrentParams, data};
}
}
}
@ -4012,6 +4030,7 @@ void Session::handleAlert(libt::alert *a) @@ -4012,6 +4030,7 @@ void Session::handleAlert(libt::alert *a)
case libt::storage_moved_alert::alert_type:
case libt::storage_moved_failed_alert::alert_type:
case libt::torrent_paused_alert::alert_type:
case libt::torrent_resumed_alert::alert_type:
case libt::tracker_error_alert::alert_type:
case libt::tracker_reply_alert::alert_type:
case libt::tracker_warning_alert::alert_type:
@ -4089,25 +4108,19 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) @@ -4089,25 +4108,19 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle)
// Magnet added for preload its metadata
if (!m_addingTorrents.contains(nativeHandle.info_hash())) return;
AddTorrentData data = m_addingTorrents.take(nativeHandle.info_hash());
CreateTorrentParams params = m_addingTorrents.take(nativeHandle.info_hash());
TorrentHandle *const torrent = new TorrentHandle(this, nativeHandle, data);
TorrentHandle *const torrent = new TorrentHandle(this, nativeHandle, params);
m_torrents.insert(torrent->hash(), torrent);
Logger *const logger = Logger::instance();
bool fromMagnetUri = !torrent->hasMetadata();
if (data.resumed) {
if (fromMagnetUri && !data.addPaused)
torrent->resume(data.addForced);
logger->addMessage(tr("'%1' resumed. (fast resume)", "'torrent name' was resumed. (fast resume)")
.arg(torrent->name()));
if (params.restored) {
logger->addMessage(tr("'%1' restored.", "'torrent name' restored.").arg(torrent->name()));
}
else {
qDebug("This is a NEW torrent (first time)...");
// The following is useless for newly added magnet
if (!fromMagnetUri) {
// Backup torrent file
@ -4126,9 +4139,6 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) @@ -4126,9 +4139,6 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle)
if (isAddTrackersEnabled() && !torrent->isPrivate())
torrent->addTrackers(m_additionalTrackerList);
// Start torrent because it was added in paused state
if (!data.addPaused)
torrent->resume();
logger->addMessage(tr("'%1' added to download list.", "'torrent name' was added to download list.")
.arg(torrent->name()));
@ -4144,7 +4154,7 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle) @@ -4144,7 +4154,7 @@ void Session::createTorrentHandle(const libt::torrent_handle &nativeHandle)
// Send torrent addition signal
emit torrentAdded(torrent);
// Send new torrent signal
if (!data.resumed)
if (!params.restored)
emit torrentNew(torrent);
}
@ -4494,11 +4504,11 @@ namespace @@ -4494,11 +4504,11 @@ namespace
return true;
}
bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &torrentData, int &prio, MagnetUri &magnetUri)
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &prio, MagnetUri &magnetUri)
{
torrentData = AddTorrentData();
torrentData.resumed = true;
torrentData.skipChecking = false;
torrentParams = CreateTorrentParams();
torrentParams.restored = true;
torrentParams.skipChecking = false;
libt::error_code ec;
#if LIBTORRENT_VERSION_NUM < 10100
@ -4511,36 +4521,36 @@ namespace @@ -4511,36 +4521,36 @@ namespace
if (ec || (fast.type() != libt::bdecode_node::dict_t)) return false;
#endif
torrentData.savePath = Profile::instance().fromPortablePath(
torrentParams.savePath = Profile::instance().fromPortablePath(
Utils::Fs::fromNativePath(QString::fromStdString(fast.dict_find_string_value("qBt-savePath"))));
std::string ratioLimitString = fast.dict_find_string_value("qBt-ratioLimit");
if (ratioLimitString.empty())
torrentData.ratioLimit = fast.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0;
torrentParams.ratioLimit = fast.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0;
else
torrentData.ratioLimit = QString::fromStdString(ratioLimitString).toDouble();
torrentData.seedingTimeLimit = fast.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME);
torrentParams.ratioLimit = QString::fromStdString(ratioLimitString).toDouble();
torrentParams.seedingTimeLimit = fast.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME);
// **************************************************************************************
// Workaround to convert legacy label to category
// TODO: Should be removed in future
torrentData.category = QString::fromStdString(fast.dict_find_string_value("qBt-label"));
if (torrentData.category.isEmpty())
torrentParams.category = QString::fromStdString(fast.dict_find_string_value("qBt-label"));
if (torrentParams.category.isEmpty())
// **************************************************************************************
torrentData.category = QString::fromStdString(fast.dict_find_string_value("qBt-category"));
torrentParams.category = QString::fromStdString(fast.dict_find_string_value("qBt-category"));
// auto because the return type depends on the #if above.
const auto tagsEntry = fast.dict_find_list("qBt-tags");
if (isList(tagsEntry))
torrentData.tags = entryListToSet(tagsEntry);
torrentData.name = QString::fromStdString(fast.dict_find_string_value("qBt-name"));
torrentData.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus");
torrentData.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled");
torrentData.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder");
torrentParams.tags = entryListToSet(tagsEntry);
torrentParams.name = QString::fromStdString(fast.dict_find_string_value("qBt-name"));
torrentParams.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus");
torrentParams.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled");
torrentParams.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder");
magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri")));
torrentData.addPaused = fast.dict_find_int_value("qBt-paused");
torrentData.addForced = fast.dict_find_int_value("qBt-forced");
torrentData.firstLastPiecePriority = fast.dict_find_int_value("qBt-firstLastPiecePriority");
torrentData.sequential = fast.dict_find_int_value("qBt-sequential");
torrentParams.paused = fast.dict_find_int_value("qBt-paused");
torrentParams.forced = fast.dict_find_int_value("qBt-forced");
torrentParams.firstLastPiecePriority = fast.dict_find_int_value("qBt-firstLastPiecePriority");
torrentParams.sequential = fast.dict_find_int_value("qBt-sequential");
prio = fast.dict_find_int_value("qBt-queuePosition");

7
src/base/bittorrent/session.h

@ -138,7 +138,7 @@ namespace BitTorrent @@ -138,7 +138,7 @@ namespace BitTorrent
class Tracker;
class MagnetUri;
class TrackerEntry;
struct AddTorrentData;
struct CreateTorrentParams;
struct TorrentStatusReport
{
@ -480,6 +480,7 @@ namespace BitTorrent @@ -480,6 +480,7 @@ namespace BitTorrent
// TorrentHandle interface
void handleTorrentShareLimitChanged(TorrentHandle *const torrent);
void handleTorrentNameChanged(TorrentHandle *const torrent);
void handleTorrentSavePathChanged(TorrentHandle *const torrent);
void handleTorrentCategoryChanged(TorrentHandle *const torrent, const QString &oldCategory);
void handleTorrentTagAdded(TorrentHandle *const torrent, const QString &tag);
@ -597,7 +598,7 @@ namespace BitTorrent @@ -597,7 +598,7 @@ namespace BitTorrent
void enableIPFilter();
void disableIPFilter();
bool addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri,
bool addTorrent_impl(CreateTorrentParams params, const MagnetUri &magnetUri,
TorrentInfo torrentInfo = TorrentInfo(),
const QByteArray &fastresumeData = QByteArray());
bool findIncompleteFiles(TorrentInfo &torrentInfo, QString &savePath) const;
@ -757,7 +758,7 @@ namespace BitTorrent @@ -757,7 +758,7 @@ namespace BitTorrent
QHash<InfoHash, TorrentInfo> m_loadedMetadata;
QHash<InfoHash, TorrentHandle *> m_torrents;
QHash<InfoHash, AddTorrentData> m_addingTorrents;
QHash<InfoHash, CreateTorrentParams> m_addingTorrents;
QHash<QString, AddTorrentParams> m_downloadedTorrents;
QHash<InfoHash, RemovingTorrentData> m_removingTorrents;
TorrentStatusReport m_torrentStatusReport;

83
src/base/bittorrent/torrenthandle.cpp

@ -85,16 +85,16 @@ namespace @@ -85,16 +85,16 @@ namespace
// AddTorrentData
AddTorrentData::AddTorrentData()
: resumed(false)
CreateTorrentParams::CreateTorrentParams()
: restored(false)
, disableTempPath(false)
, sequential(false)
, firstLastPiecePriority(false)
, hasSeedStatus(false)
, skipChecking(false)
, hasRootFolder(true)
, addForced(false)
, addPaused(false)
, forced(false)
, paused(false)
, uploadLimit(-1)
, downloadLimit(-1)
, ratioLimit(TorrentHandle::USE_GLOBAL_RATIO)
@ -102,8 +102,8 @@ AddTorrentData::AddTorrentData() @@ -102,8 +102,8 @@ AddTorrentData::AddTorrentData()
{
}
AddTorrentData::AddTorrentData(const AddTorrentParams &params)
: resumed(false)
CreateTorrentParams::CreateTorrentParams(const AddTorrentParams &params)
: restored(false)
, name(params.name)
, category(params.category)
, tags(params.tags)
@ -116,8 +116,8 @@ AddTorrentData::AddTorrentData(const AddTorrentParams &params) @@ -116,8 +116,8 @@ AddTorrentData::AddTorrentData(const AddTorrentParams &params)
, hasRootFolder(params.createSubfolder == TriStateBool::Undefined
? Session::instance()->isCreateTorrentSubfolder()
: params.createSubfolder == TriStateBool::True)
, addForced(params.addForced == TriStateBool::True)
, addPaused(params.addPaused == TriStateBool::Undefined
, forced(params.addForced == TriStateBool::True)
, paused(params.addPaused == TriStateBool::Undefined
? Session::instance()->isAddTorrentPaused()
: params.addPaused == TriStateBool::True)
, uploadLimit(params.uploadLimit)
@ -172,26 +172,25 @@ namespace @@ -172,26 +172,25 @@ namespace
}
TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle &nativeHandle,
const AddTorrentData &data)
const CreateTorrentParams &params)
: QObject(session)
, m_session(session)
, m_nativeHandle(nativeHandle)
, m_state(TorrentState::Unknown)
, m_renameCount(0)
, m_useAutoTMM(data.savePath.isEmpty())
, m_name(data.name)
, m_savePath(Utils::Fs::toNativePath(data.savePath))
, m_category(data.category)
, m_tags(data.tags)
, m_hasSeedStatus(data.hasSeedStatus)
, m_ratioLimit(data.ratioLimit)
, m_seedingTimeLimit(data.seedingTimeLimit)
, m_tempPathDisabled(data.disableTempPath)
, m_useAutoTMM(params.savePath.isEmpty())
, m_name(params.name)
, m_savePath(Utils::Fs::toNativePath(params.savePath))
, m_category(params.category)
, m_tags(params.tags)
, m_hasSeedStatus(params.hasSeedStatus)
, m_ratioLimit(params.ratioLimit)
, m_seedingTimeLimit(params.seedingTimeLimit)
, m_tempPathDisabled(params.disableTempPath)
, m_hasMissingFiles(false)
, m_hasRootFolder(data.hasRootFolder)
, m_hasRootFolder(params.hasRootFolder)
, m_needsToSetFirstLastPiecePriority(false)
, m_pauseAfterRecheck(false)
, m_needSaveResumeData(false)
{
if (m_useAutoTMM)
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
@ -207,15 +206,29 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle @@ -207,15 +206,29 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
// download sequentially or have first/last piece priority enabled when
// its resume data was saved. These two settings are restored later. But
// if we set them to false now, both will erroneously not be restored.
if (!data.resumed || data.sequential)
setSequentialDownload(data.sequential);
if (!data.resumed || data.firstLastPiecePriority)
setFirstLastPiecePriority(data.firstLastPiecePriority);
if (!params.restored || params.sequential)
setSequentialDownload(params.sequential);
if (!params.restored || params.firstLastPiecePriority)
setFirstLastPiecePriority(params.firstLastPiecePriority);
if (!data.resumed && hasMetadata()) {
if (!params.restored && hasMetadata()) {
if (filesCount() == 1)
m_hasRootFolder = false;
}
// "started" means "all initialization has completed and torrent has started regular processing".
// When torrent added/restored in "paused" state it become "started" immediately after construction.
// When it is added/restored in "resumed" state, it become "started" after it is really resumed
// (i.e. after receiving "torrent resumed" alert).
m_started = (params.restored && hasMetadata() ? isPaused() : params.paused);
if (!m_started) {
if (!params.restored || !hasMetadata()) {
// Resume torrent because it was added in "resumed" state
// but it's actually paused during initialization
resume(params.forced);
}
}
}
TorrentHandle::~TorrentHandle() {}
@ -488,8 +501,6 @@ bool TorrentHandle::connectPeer(const PeerAddress &peerAddress) @@ -488,8 +501,6 @@ bool TorrentHandle::connectPeer(const PeerAddress &peerAddress)
bool TorrentHandle::needSaveResumeData() const
{
if (m_needSaveResumeData) return true;
return m_nativeHandle.need_save_resume_data();
}
@ -499,7 +510,6 @@ void TorrentHandle::saveResumeData(bool updateStatus) @@ -499,7 +510,6 @@ void TorrentHandle::saveResumeData(bool updateStatus)
this->updateStatus();
m_nativeHandle.save_resume_data();
m_needSaveResumeData = false;
}
int TorrentHandle::filesCount() const
@ -573,7 +583,6 @@ bool TorrentHandle::addTag(const QString &tag) @@ -573,7 +583,6 @@ bool TorrentHandle::addTag(const QString &tag)
return false;
m_tags.insert(tag);
m_session->handleTorrentTagAdded(this, tag);
m_needSaveResumeData = true;
return true;
}
return false;
@ -583,7 +592,6 @@ bool TorrentHandle::removeTag(const QString &tag) @@ -583,7 +592,6 @@ bool TorrentHandle::removeTag(const QString &tag)
{
if (m_tags.remove(tag)) {
m_session->handleTorrentTagRemoved(this, tag);
m_needSaveResumeData = true;
return true;
}
return false;
@ -1198,7 +1206,7 @@ void TorrentHandle::setName(const QString &name) @@ -1198,7 +1206,7 @@ void TorrentHandle::setName(const QString &name)
{
if (m_name != name) {
m_name = name;
m_needSaveResumeData = true;
m_session->handleTorrentNameChanged(this);
}
}
@ -1214,7 +1222,6 @@ bool TorrentHandle::setCategory(const QString &category) @@ -1214,7 +1222,6 @@ bool TorrentHandle::setCategory(const QString &category)
QString oldCategory = m_category;
m_category = category;
m_needSaveResumeData = true;
m_session->handleTorrentCategoryChanged(this, oldCategory);
if (m_useAutoTMM) {
@ -1252,7 +1259,6 @@ void TorrentHandle::move_impl(QString path, bool overwrite) @@ -1252,7 +1259,6 @@ void TorrentHandle::move_impl(QString path, bool overwrite)
}
else {
m_savePath = path;
m_needSaveResumeData = true;
m_session->handleTorrentSavePathChanged(this);
}
}
@ -1597,7 +1603,11 @@ void TorrentHandle::handleTorrentPausedAlert(const libtorrent::torrent_paused_al @@ -1597,7 +1603,11 @@ void TorrentHandle::handleTorrentPausedAlert(const libtorrent::torrent_paused_al
void TorrentHandle::handleTorrentResumedAlert(const libtorrent::torrent_resumed_alert *p)
{
Q_UNUSED(p);
m_session->handleTorrentResumed(this);
if (m_started)
m_session->handleTorrentResumed(this);
else
m_started = true;
}
void TorrentHandle::handleSaveResumeDataAlert(const libtorrent::save_resume_data_alert *p)
@ -1806,6 +1816,9 @@ void TorrentHandle::handleAlert(libtorrent::alert *a) @@ -1806,6 +1816,9 @@ void TorrentHandle::handleAlert(libtorrent::alert *a)
case libt::torrent_paused_alert::alert_type:
handleTorrentPausedAlert(static_cast<libt::torrent_paused_alert*>(a));
break;
case libt::torrent_resumed_alert::alert_type:
handleTorrentResumedAlert(static_cast<libt::torrent_resumed_alert*>(a));
break;
case libt::tracker_error_alert::alert_type:
handleTrackerErrorAlert(static_cast<libt::tracker_error_alert*>(a));
break;
@ -1928,7 +1941,6 @@ void TorrentHandle::setRatioLimit(qreal limit) @@ -1928,7 +1941,6 @@ void TorrentHandle::setRatioLimit(qreal limit)
if (m_ratioLimit != limit) {
m_ratioLimit = limit;
m_needSaveResumeData = true;
m_session->handleTorrentShareLimitChanged(this);
}
}
@ -1942,7 +1954,6 @@ void TorrentHandle::setSeedingTimeLimit(int limit) @@ -1942,7 +1954,6 @@ void TorrentHandle::setSeedingTimeLimit(int limit)
if (m_seedingTimeLimit != limit) {
m_seedingTimeLimit = limit;
m_needSaveResumeData = true;
m_session->handleTorrentShareLimitChanged(this);
}
}

21
src/base/bittorrent/torrenthandle.h

@ -88,10 +88,10 @@ namespace BitTorrent @@ -88,10 +88,10 @@ namespace BitTorrent
class TrackerEntry;
struct AddTorrentParams;
struct AddTorrentData
struct CreateTorrentParams
{
bool resumed;
// for both new and resumed torrents
bool restored; // is existing torrent job?
// for both new and restored torrents
QString name;
QString category;
QSet<QString> tags;
@ -102,18 +102,18 @@ namespace BitTorrent @@ -102,18 +102,18 @@ namespace BitTorrent
bool hasSeedStatus;
bool skipChecking;
bool hasRootFolder;
bool addForced;
bool addPaused;
bool forced;
bool paused;
int uploadLimit;
int downloadLimit;
// for new torrents
QVector<int> filePriorities;
// for resumed torrents
// for restored torrents
qreal ratioLimit;
int seedingTimeLimit;
AddTorrentData();
AddTorrentData(const AddTorrentParams &params);
CreateTorrentParams();
CreateTorrentParams(const AddTorrentParams &params);
};
struct TrackerInfo
@ -170,7 +170,7 @@ namespace BitTorrent @@ -170,7 +170,7 @@ namespace BitTorrent
static const int MAX_SEEDING_TIME;
TorrentHandle(Session *session, const libtorrent::torrent_handle &nativeHandle,
const AddTorrentData &data);
const CreateTorrentParams &params);
~TorrentHandle();
bool isValid() const;
@ -461,8 +461,9 @@ namespace BitTorrent @@ -461,8 +461,9 @@ namespace BitTorrent
bool m_needsToSetFirstLastPiecePriority;
bool m_pauseAfterRecheck;
bool m_needSaveResumeData;
QHash<QString, TrackerInfo> m_trackerInfos;
bool m_started = false;
};
}

Loading…
Cancel
Save