mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-10 23:07:59 +00:00
Merge pull request #3224 from glassez/fastresume
Fix resume torrents without metadata.
This commit is contained in:
commit
1396c63525
@ -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,33 +1086,34 @@ 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;
|
||||||
#else
|
#else
|
||||||
p.resume_data = buf;
|
p.resume_data = buf;
|
||||||
p.flags |= libt::add_torrent_params::flag_use_resume_save_path;
|
p.flags |= libt::add_torrent_params::flag_use_resume_save_path;
|
||||||
#endif
|
#endif
|
||||||
p.flags |= libt::add_torrent_params::flag_merge_resume_trackers;
|
p.flags |= libt::add_torrent_params::flag_merge_resume_trackers;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreach (int prio, addData.filePriorities)
|
foreach (int prio, addData.filePriorities)
|
||||||
filePriorities.push_back(prio);
|
filePriorities.push_back(prio);
|
||||||
#if LIBTORRENT_VERSION_NUM < 10000
|
#if LIBTORRENT_VERSION_NUM < 10000
|
||||||
p.file_priorities = &filePriorities;
|
p.file_priorities = &filePriorities;
|
||||||
#else
|
#else
|
||||||
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
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
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);
|
.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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,26 +1439,34 @@ 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
|
||||||
m_session->handleTorrentResumeDataFailed(this);
|
// containing Magnet URI and qBittorrent own resume data only
|
||||||
|
if (p->error.value() == libt::errors::no_metadata)
|
||||||
|
handleSaveResumeDataAlert(0);
|
||||||
|
else
|
||||||
|
m_session->handleTorrentResumeDataFailed(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentHandle::handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert *p)
|
void TorrentHandle::handleFastResumeRejectedAlert(libtorrent::fastresume_rejected_alert *p)
|
||||||
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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…
Reference in New Issue
Block a user