Browse Source

Merge pull request #3224 from glassez/fastresume

Fix resume torrents without metadata.
adaptive-webui-19844
sledgehammer999 9 years ago
parent
commit
1396c63525
  1. 35
      src/core/bittorrent/session.cpp
  2. 1
      src/core/bittorrent/session.h
  3. 38
      src/core/bittorrent/torrenthandle.cpp
  4. 3
      src/core/bittorrent/torrenthandle.h
  5. 7
      src/core/bittorrent/torrentinfo.cpp
  6. 1
      src/core/bittorrent/torrentinfo.h

35
src/core/bittorrent/session.cpp

@ -95,7 +95,7 @@ namespace libt = libtorrent;
using namespace BitTorrent; using namespace BitTorrent;
static bool readFile(const QString &path, QByteArray &buf); static bool readFile(const QString &path, QByteArray &buf);
static bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out); static bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out, MagnetUri &magnetUri);
static void torrentQueuePositionUp(const libt::torrent_handle &handle); static void torrentQueuePositionUp(const libt::torrent_handle &handle);
static void torrentQueuePositionDown(const libt::torrent_handle &handle); static void torrentQueuePositionDown(const libt::torrent_handle &handle);
@ -1086,14 +1086,16 @@ bool Session::addTorrent_impl(const AddTorrentData &addData, const MagnetUri &ma
p = magnetUri.addTorrentParams(); p = magnetUri.addTorrentParams();
hash = magnetUri.hash(); hash = magnetUri.hash();
} }
else { else if (torrentInfo.isValid()) {
if (!torrentInfo.isValid()) return false;
// Metadata // Metadata
p.ti = torrentInfo.nativeInfo(); p.ti = torrentInfo.nativeInfo();
hash = torrentInfo.hash(); hash = torrentInfo.hash();
}
else {
Q_ASSERT(false);
}
if (addData.resumed) { if (addData.resumed && !fromMagnetUri) {
// Set torrent fast resume data // Set torrent fast resume data
#if LIBTORRENT_VERSION_NUM < 10000 #if LIBTORRENT_VERSION_NUM < 10000
p.resume_data = &buf; p.resume_data = &buf;
@ -1113,7 +1115,6 @@ bool Session::addTorrent_impl(const AddTorrentData &addData, const MagnetUri &ma
p.file_priorities = filePriorities; p.file_priorities = filePriorities;
#endif #endif
} }
}
// We should not add torrent if it already // We should not add torrent if it already
// processed or adding to session // processed or adding to session
@ -1929,22 +1930,15 @@ void Session::startUpTorrents()
resumeDataDir.absoluteFilePath(QString("%1.fastresume.%2").arg(hash).arg(prio)); resumeDataDir.absoluteFilePath(QString("%1.fastresume.%2").arg(hash).arg(prio));
QByteArray data; QByteArray data;
AddTorrentData resumeData; AddTorrentData resumeData;
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, resumeData)) { MagnetUri magnetUri;
if (readFile(fastresumePath, data) && loadTorrentResumeData(data, resumeData, magnetUri)) {
filePath = resumeDataDir.filePath(QString("%1.torrent").arg(hash)); filePath = resumeDataDir.filePath(QString("%1.torrent").arg(hash));
if (QFile(filePath).exists()) {
qDebug("Starting up torrent %s ...", qPrintable(hash)); qDebug("Starting up torrent %s ...", qPrintable(hash));
if (!addTorrent_impl(resumeData, MagnetUri(), TorrentInfo::loadFromFile(filePath), data)) if (!addTorrent_impl(resumeData, magnetUri, TorrentInfo::loadFromFile(filePath), data))
logger->addMessage(tr("Unable to resume torrent '%1'.", "e.g: Unable to resume torrent 'hash'.") logger->addMessage(tr("Unable to resume torrent '%1'.", "e.g: Unable to resume torrent 'hash'.")
.arg(Utils::Fs::toNativePath(hash)), Log::CRITICAL); .arg(Utils::Fs::toNativePath(hash)), Log::CRITICAL);
} }
else {
logger->addMessage(tr("Unable to resume torrent '%1': torrent file not found.", "e.g: Unable to resume torrent 'hash': torrent file not found.")
.arg(Utils::Fs::toNativePath(hash)), Log::CRITICAL);
}
}
} }
qDebug("Unfinished torrents resumed.");
} }
quint64 Session::getAlltimeDL() const quint64 Session::getAlltimeDL() const
@ -2121,6 +2115,9 @@ void Session::handleAddTorrentAlert(libtorrent::add_torrent_alert *p)
bool fromMagnetUri = !torrent->hasMetadata(); bool fromMagnetUri = !torrent->hasMetadata();
if (data.resumed) { if (data.resumed) {
if (fromMagnetUri && !data.addPaused)
torrent->resume(data.addForced);
logger->addMessage(tr("'%1' resumed. (fast resume)", "'torrent name' was resumed. (fast resume)") logger->addMessage(tr("'%1' resumed. (fast resume)", "'torrent name' was resumed. (fast resume)")
.arg(torrent->name())); .arg(torrent->name()));
} }
@ -2363,7 +2360,7 @@ bool readFile(const QString &path, QByteArray &buf)
return true; return true;
} }
bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out) bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out, MagnetUri &magnetUri)
{ {
out = AddTorrentData(); out = AddTorrentData();
out.resumed = true; out.resumed = true;
@ -2381,6 +2378,10 @@ bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out)
out.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus"); out.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus");
out.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled"); out.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled");
magnetUri = MagnetUri(Utils::String::fromStdString(fast.dict_find_string_value("qBt-magnetUri")));
out.addPaused = fast.dict_find_int_value("qBt-paused");
out.addForced = fast.dict_find_int_value("qBt-forced");
return true; return true;
} }

1
src/core/bittorrent/session.h

@ -113,6 +113,7 @@ namespace BitTorrent
QString savePath; QString savePath;
bool disableTempPath; // e.g. for imported torrents bool disableTempPath; // e.g. for imported torrents
bool sequential; bool sequential;
TriStateBool addForced;
TriStateBool addPaused; TriStateBool addPaused;
QVector<int> filePriorities; // used if TorrentInfo is set QVector<int> filePriorities; // used if TorrentInfo is set
bool ignoreShareRatio; bool ignoreShareRatio;

38
src/core/bittorrent/torrenthandle.cpp

@ -40,6 +40,7 @@
#include <libtorrent/address.hpp> #include <libtorrent/address.hpp>
#include <libtorrent/alert_types.hpp> #include <libtorrent/alert_types.hpp>
#include <libtorrent/create_torrent.hpp> #include <libtorrent/create_torrent.hpp>
#include <libtorrent/magnet_uri.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@ -130,6 +131,7 @@ AddTorrentData::AddTorrentData(const AddTorrentParams &in)
, disableTempPath(in.disableTempPath) , disableTempPath(in.disableTempPath)
, sequential(in.sequential) , sequential(in.sequential)
, hasSeedStatus(in.skipChecking) , hasSeedStatus(in.skipChecking)
, addForced(in.addForced)
, addPaused(in.addPaused) , addPaused(in.addPaused)
, filePriorities(in.filePriorities) , filePriorities(in.filePriorities)
, ratioLimit(TorrentHandle::USE_GLOBAL_RATIO) , ratioLimit(TorrentHandle::USE_GLOBAL_RATIO)
@ -1437,25 +1439,33 @@ void TorrentHandle::handleTorrentResumedAlert(libtorrent::torrent_resumed_alert
void TorrentHandle::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert *p) void TorrentHandle::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert *p)
{ {
if (p->resume_data) { const bool useDummyResumeData = !(p && p->resume_data);
(*(p->resume_data))["qBt-addedTime"] = m_addedTime.toTime_t(); libtorrent::entry dummyEntry;
(*(p->resume_data))["qBt-savePath"] = m_useDefaultSavePath ? "" : m_savePath.toUtf8().constData();
(*(p->resume_data))["qBt-ratioLimit"] = QString::number(m_ratioLimit).toUtf8().constData();
(*(p->resume_data))["qBt-label"] = m_label.toUtf8().constData();
(*(p->resume_data))["qBt-name"] = m_name.toUtf8().constData();
(*(p->resume_data))["qBt-seedStatus"] = m_hasSeedStatus;
(*(p->resume_data))["qBt-tempPathDisabled"] = m_tempPathDisabled;
m_session->handleTorrentResumeDataReady(this, *(p->resume_data)); libtorrent::entry &resumeData = useDummyResumeData ? dummyEntry : *(p->resume_data);
} if (useDummyResumeData) {
else { resumeData["qBt-magnetUri"] = Utils::String::toStdString(toMagnetUri());
m_session->handleTorrentResumeDataFailed(this); resumeData["qBt-paused"] = isPaused();
resumeData["qBt-forced"] = isForced();
} }
resumeData["qBt-addedTime"] = m_addedTime.toTime_t();
resumeData["qBt-savePath"] = m_useDefaultSavePath ? "" : Utils::String::toStdString(m_savePath);
resumeData["qBt-ratioLimit"] = Utils::String::toStdString(QString::number(m_ratioLimit));
resumeData["qBt-label"] = Utils::String::toStdString(m_label);
resumeData["qBt-name"] = Utils::String::toStdString(m_name);
resumeData["qBt-seedStatus"] = m_hasSeedStatus;
resumeData["qBt-tempPathDisabled"] = m_tempPathDisabled;
m_session->handleTorrentResumeDataReady(this, resumeData);
} }
void TorrentHandle::handleSaveResumeDataFailedAlert(libtorrent::save_resume_data_failed_alert *p) void TorrentHandle::handleSaveResumeDataFailedAlert(libtorrent::save_resume_data_failed_alert *p)
{ {
Q_UNUSED(p); // if torrent has no metadata we should save dummy fastresume data
// containing Magnet URI and qBittorrent own resume data only
if (p->error.value() == libt::errors::no_metadata)
handleSaveResumeDataAlert(0);
else
m_session->handleTorrentResumeDataFailed(this); m_session->handleTorrentResumeDataFailed(this);
} }
@ -1808,7 +1818,7 @@ void TorrentHandle::flushCache()
QString TorrentHandle::toMagnetUri() const QString TorrentHandle::toMagnetUri() const
{ {
return m_torrentInfo.toMagnetUri(); return Utils::String::fromStdString(libt::make_magnet_uri(m_nativeHandle));
} }
void TorrentHandle::resolveCountries(bool b) void TorrentHandle::resolveCountries(bool b)

3
src/core/bittorrent/torrenthandle.h

@ -91,8 +91,9 @@ namespace BitTorrent
bool disableTempPath; bool disableTempPath;
bool sequential; bool sequential;
bool hasSeedStatus; bool hasSeedStatus;
// for new torrents TriStateBool addForced;
TriStateBool addPaused; TriStateBool addPaused;
// for new torrents
QVector<int> filePriorities; QVector<int> filePriorities;
bool ignoreShareRatio; bool ignoreShareRatio;
// for resumed torrents // for resumed torrents

7
src/core/bittorrent/torrentinfo.cpp

@ -32,7 +32,6 @@
#include <QDateTime> #include <QDateTime>
#include <libtorrent/error_code.hpp> #include <libtorrent/error_code.hpp>
#include <libtorrent/magnet_uri.hpp>
#include "core/utils/misc.h" #include "core/utils/misc.h"
#include "core/utils/fs.h" #include "core/utils/fs.h"
@ -212,12 +211,6 @@ QByteArray TorrentInfo::metadata() const
return QByteArray(m_nativeInfo->metadata().get(), m_nativeInfo->metadata_size()); return QByteArray(m_nativeInfo->metadata().get(), m_nativeInfo->metadata_size());
} }
QString TorrentInfo::toMagnetUri() const
{
if (!isValid()) return QString();
return Utils::String::fromStdString(libt::make_magnet_uri(*m_nativeInfo));
}
void TorrentInfo::renameFile(uint index, const QString &newPath) void TorrentInfo::renameFile(uint index, const QString &newPath)
{ {
if (!isValid()) return; if (!isValid()) return;

1
src/core/bittorrent/torrentinfo.h

@ -75,7 +75,6 @@ namespace BitTorrent
QList<TrackerEntry> trackers() const; QList<TrackerEntry> trackers() const;
QList<QUrl> urlSeeds() const; QList<QUrl> urlSeeds() const;
QByteArray metadata() const; QByteArray metadata() const;
QString toMagnetUri() const;
void renameFile(uint index, const QString &newPath); void renameFile(uint index, const QString &newPath);
boost::intrusive_ptr<libtorrent::torrent_info> nativeInfo() const; boost::intrusive_ptr<libtorrent::torrent_info> nativeInfo() const;

Loading…
Cancel
Save