|
|
@ -100,16 +100,6 @@ static void torrentQueuePositionDown(const libt::torrent_handle &handle); |
|
|
|
static void torrentQueuePositionTop(const libt::torrent_handle &handle); |
|
|
|
static void torrentQueuePositionTop(const libt::torrent_handle &handle); |
|
|
|
static void torrentQueuePositionBottom(const libt::torrent_handle &handle); |
|
|
|
static void torrentQueuePositionBottom(const libt::torrent_handle &handle); |
|
|
|
|
|
|
|
|
|
|
|
// AddTorrentParams
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AddTorrentParams::AddTorrentParams() |
|
|
|
|
|
|
|
: disableTempPath(false) |
|
|
|
|
|
|
|
, sequential(false) |
|
|
|
|
|
|
|
, ignoreShareRatio(false) |
|
|
|
|
|
|
|
, skipChecking(false) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Session
|
|
|
|
// Session
|
|
|
|
|
|
|
|
|
|
|
|
Session *Session::m_instance = 0; |
|
|
|
Session *Session::m_instance = 0; |
|
|
@ -713,7 +703,7 @@ void Session::handleDownloadFailed(const QString &url, const QString &reason) |
|
|
|
|
|
|
|
|
|
|
|
void Session::handleRedirectedToMagnet(const QString &url, const QString &magnetUri) |
|
|
|
void Session::handleRedirectedToMagnet(const QString &url, const QString &magnetUri) |
|
|
|
{ |
|
|
|
{ |
|
|
|
addTorrent_impl(addDataFromParams(m_downloadedTorrents.take(url)), MagnetUri(magnetUri)); |
|
|
|
addTorrent_impl(m_downloadedTorrents.take(url), MagnetUri(magnetUri)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Session::switchToAlternativeMode(bool alternative) |
|
|
|
void Session::switchToAlternativeMode(bool alternative) |
|
|
@ -725,7 +715,7 @@ void Session::switchToAlternativeMode(bool alternative) |
|
|
|
void Session::handleDownloadFinished(const QString &url, const QString &filePath) |
|
|
|
void Session::handleDownloadFinished(const QString &url, const QString &filePath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
emit downloadFromUrlFinished(url); |
|
|
|
emit downloadFromUrlFinished(url); |
|
|
|
addTorrent_impl(addDataFromParams(m_downloadedTorrents.take(url)), MagnetUri(), TorrentInfo::loadFromFile(filePath)); |
|
|
|
addTorrent_impl(m_downloadedTorrents.take(url), MagnetUri(), TorrentInfo::loadFromFile(filePath)); |
|
|
|
Utils::Fs::forceRemove(filePath); // remove temporary file
|
|
|
|
Utils::Fs::forceRemove(filePath); // remove temporary file
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -939,40 +929,14 @@ TorrentStatusReport Session::torrentStatusReport() const |
|
|
|
return m_torrentStatusReport; |
|
|
|
return m_torrentStatusReport; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// source - .torrent file path/url or magnet uri (hash for preloaded torrent)
|
|
|
|
// source - .torrent file path/url or magnet uri
|
|
|
|
bool Session::addTorrent(QString source, const AddTorrentParams ¶ms) |
|
|
|
bool Session::addTorrent(QString source, const AddTorrentParams ¶ms) |
|
|
|
{ |
|
|
|
{ |
|
|
|
InfoHash hash = source; |
|
|
|
MagnetUri magnetUri(source); |
|
|
|
if (hash.isValid() && m_loadedMetadata.contains(hash)) { |
|
|
|
if (magnetUri.isValid()) { |
|
|
|
// Adding preloaded torrent
|
|
|
|
return addTorrent_impl(params, magnetUri); |
|
|
|
m_loadedMetadata.remove(hash); |
|
|
|
|
|
|
|
libt::torrent_handle handle = m_nativeSession->find_torrent(hash); |
|
|
|
|
|
|
|
--m_extraLimit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
handle.auto_managed(false); |
|
|
|
|
|
|
|
handle.pause(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (std::exception &) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
adjustLimits(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// use common 2nd step of torrent addition
|
|
|
|
|
|
|
|
m_addingTorrents.insert(hash, addDataFromParams(params)); |
|
|
|
|
|
|
|
createTorrentHandle(handle); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (source.startsWith("bc://bt/", Qt::CaseInsensitive)) { |
|
|
|
|
|
|
|
qDebug("Converting bc link to magnet link"); |
|
|
|
|
|
|
|
source = Utils::Misc::bcLinkToMagnet(source); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else if (((source.size() == 40) && !source.contains(QRegExp("[^0-9A-Fa-f]"))) |
|
|
|
else if (Utils::Misc::isUrl(source)) { |
|
|
|
|| ((source.size() == 32) && !source.contains(QRegExp("[^2-7A-Za-z]")))) { |
|
|
|
|
|
|
|
source = "magnet:?xt=urn:btih:" + source; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Utils::Misc::isUrl(source)) { |
|
|
|
|
|
|
|
Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source)); |
|
|
|
Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source)); |
|
|
|
// Launch downloader
|
|
|
|
// Launch downloader
|
|
|
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, true, 10485760 /* 10MB */, true); |
|
|
|
Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, true, 10485760 /* 10MB */, true); |
|
|
@ -981,11 +945,8 @@ bool Session::addTorrent(QString source, const AddTorrentParams ¶ms) |
|
|
|
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), this, SLOT(handleRedirectedToMagnet(QString, QString))); |
|
|
|
connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), this, SLOT(handleRedirectedToMagnet(QString, QString))); |
|
|
|
m_downloadedTorrents[handler->url()] = params; |
|
|
|
m_downloadedTorrents[handler->url()] = params; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (source.startsWith("magnet:", Qt::CaseInsensitive)) { |
|
|
|
|
|
|
|
return addTorrent_impl(addDataFromParams(params), MagnetUri(source)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
else { |
|
|
|
return addTorrent_impl(addDataFromParams(params), MagnetUri(), TorrentInfo::loadFromFile(source)); |
|
|
|
return addTorrent_impl(params, MagnetUri(), TorrentInfo::loadFromFile(source)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -995,13 +956,26 @@ bool Session::addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!torrentInfo.isValid()) return false; |
|
|
|
if (!torrentInfo.isValid()) return false; |
|
|
|
|
|
|
|
|
|
|
|
return addTorrent_impl(addDataFromParams(params), MagnetUri(), torrentInfo); |
|
|
|
return addTorrent_impl(params, MagnetUri(), torrentInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Add a torrent to the BitTorrent session
|
|
|
|
// Add a torrent to the BitTorrent session
|
|
|
|
bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, |
|
|
|
bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri, |
|
|
|
const TorrentInfo &torrentInfo, const QByteArray &fastresumeData) |
|
|
|
const TorrentInfo &torrentInfo, const QByteArray &fastresumeData) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
if (!addData.resumed) { |
|
|
|
|
|
|
|
// manage save path
|
|
|
|
|
|
|
|
QString defaultSavePath = this->defaultSavePath(); |
|
|
|
|
|
|
|
if (addData.savePath.isEmpty()) |
|
|
|
|
|
|
|
addData.savePath = defaultSavePath; |
|
|
|
|
|
|
|
if (!addData.savePath.endsWith("/")) |
|
|
|
|
|
|
|
addData.savePath += "/"; |
|
|
|
|
|
|
|
if (useAppendLabelToSavePath()) { |
|
|
|
|
|
|
|
if ((addData.savePath == defaultSavePath) && !addData.label.isEmpty()) |
|
|
|
|
|
|
|
addData.savePath += QString("%1/").arg(addData.label); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
libt::add_torrent_params p; |
|
|
|
libt::add_torrent_params p; |
|
|
|
InfoHash hash; |
|
|
|
InfoHash hash; |
|
|
|
std::vector<char> buf(fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()); |
|
|
|
std::vector<char> buf(fastresumeData.constData(), fastresumeData.constData() + fastresumeData.size()); |
|
|
@ -1009,8 +983,29 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri |
|
|
|
|
|
|
|
|
|
|
|
bool fromMagnetUri = magnetUri.isValid(); |
|
|
|
bool fromMagnetUri = magnetUri.isValid(); |
|
|
|
if (fromMagnetUri) { |
|
|
|
if (fromMagnetUri) { |
|
|
|
p = magnetUri.addTorrentParams(); |
|
|
|
|
|
|
|
hash = magnetUri.hash(); |
|
|
|
hash = magnetUri.hash(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_loadedMetadata.contains(hash)) { |
|
|
|
|
|
|
|
// Adding preloaded torrent
|
|
|
|
|
|
|
|
m_loadedMetadata.remove(hash); |
|
|
|
|
|
|
|
libt::torrent_handle handle = m_nativeSession->find_torrent(hash); |
|
|
|
|
|
|
|
--m_extraLimit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
handle.auto_managed(false); |
|
|
|
|
|
|
|
handle.pause(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
catch (std::exception &) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
adjustLimits(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// use common 2nd step of torrent addition
|
|
|
|
|
|
|
|
m_addingTorrents.insert(hash, addData); |
|
|
|
|
|
|
|
createTorrentHandle(handle); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p = magnetUri.addTorrentParams(); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (torrentInfo.isValid()) { |
|
|
|
else if (torrentInfo.isValid()) { |
|
|
|
// Metadata
|
|
|
|
// Metadata
|
|
|
@ -1091,15 +1086,12 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri |
|
|
|
|
|
|
|
|
|
|
|
// Add a torrent to the BitTorrent session in hidden mode
|
|
|
|
// Add a torrent to the BitTorrent session in hidden mode
|
|
|
|
// and force it to load its metadata
|
|
|
|
// and force it to load its metadata
|
|
|
|
bool Session::loadMetadata(const QString &magnetUri) |
|
|
|
bool Session::loadMetadata(const MagnetUri &magnetUri) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Q_ASSERT(magnetUri.startsWith("magnet:", Qt::CaseInsensitive)); |
|
|
|
if (!magnetUri.isValid()) return false; |
|
|
|
|
|
|
|
|
|
|
|
MagnetUri magnet(magnetUri); |
|
|
|
|
|
|
|
if (!magnet.isValid()) return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
InfoHash hash = magnet.hash(); |
|
|
|
InfoHash hash = magnetUri.hash(); |
|
|
|
QString name = magnet.name(); |
|
|
|
QString name = magnetUri.name(); |
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
@ -1111,7 +1103,7 @@ bool Session::loadMetadata(const QString &magnetUri) |
|
|
|
qDebug(" -> Hash: %s", qPrintable(hash)); |
|
|
|
qDebug(" -> Hash: %s", qPrintable(hash)); |
|
|
|
qDebug(" -> Name: %s", qPrintable(name)); |
|
|
|
qDebug(" -> Name: %s", qPrintable(name)); |
|
|
|
|
|
|
|
|
|
|
|
libt::add_torrent_params p = magnet.addTorrentParams(); |
|
|
|
libt::add_torrent_params p = magnetUri.addTorrentParams(); |
|
|
|
|
|
|
|
|
|
|
|
// Flags
|
|
|
|
// Flags
|
|
|
|
// Preallocation mode
|
|
|
|
// Preallocation mode
|
|
|
@ -2358,6 +2350,11 @@ bool loadTorrentResumeData(const QByteArray &data, AddTorrentData &out, MagnetUr |
|
|
|
if (ec || (fast.type() != libt::lazy_entry::dict_t)) return false; |
|
|
|
if (ec || (fast.type() != libt::lazy_entry::dict_t)) return false; |
|
|
|
|
|
|
|
|
|
|
|
out.savePath = Utils::Fs::fromNativePath(Utils::String::fromStdString(fast.dict_find_string_value("qBt-savePath"))); |
|
|
|
out.savePath = Utils::Fs::fromNativePath(Utils::String::fromStdString(fast.dict_find_string_value("qBt-savePath"))); |
|
|
|
|
|
|
|
if (out.savePath.isEmpty()) { |
|
|
|
|
|
|
|
Logger::instance()->addMessage("Empty torrent save path was loaded from .fastresume file! Using default one...", Log::WARNING); |
|
|
|
|
|
|
|
out.savePath = Preferences::instance()->getSavePath(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
out.ratioLimit = Utils::String::fromStdString(fast.dict_find_string_value("qBt-ratioLimit")).toDouble(); |
|
|
|
out.ratioLimit = Utils::String::fromStdString(fast.dict_find_string_value("qBt-ratioLimit")).toDouble(); |
|
|
|
out.label = Utils::String::fromStdString(fast.dict_find_string_value("qBt-label")); |
|
|
|
out.label = Utils::String::fromStdString(fast.dict_find_string_value("qBt-label")); |
|
|
|
out.name = Utils::String::fromStdString(fast.dict_find_string_value("qBt-name")); |
|
|
|
out.name = Utils::String::fromStdString(fast.dict_find_string_value("qBt-name")); |
|
|
@ -2432,33 +2429,3 @@ void torrentQueuePositionBottom(const libt::torrent_handle &handle) |
|
|
|
qDebug() << Q_FUNC_INFO << " fails: " << exc.what(); |
|
|
|
qDebug() << Q_FUNC_INFO << " fails: " << exc.what(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
AddTorrentData Session::addDataFromParams(const AddTorrentParams ¶ms) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
AddTorrentData data; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data.resumed = false; |
|
|
|
|
|
|
|
data.name = params.name; |
|
|
|
|
|
|
|
data.label = params.label; |
|
|
|
|
|
|
|
data.savePath = params.savePath; |
|
|
|
|
|
|
|
data.disableTempPath = params.disableTempPath; |
|
|
|
|
|
|
|
data.sequential = params.sequential; |
|
|
|
|
|
|
|
data.hasSeedStatus = params.skipChecking; // do not react on 'torrent_finished_alert' when skipping
|
|
|
|
|
|
|
|
data.skipChecking = params.skipChecking; |
|
|
|
|
|
|
|
data.addForced = params.addForced; |
|
|
|
|
|
|
|
data.addPaused = params.addPaused; |
|
|
|
|
|
|
|
data.filePriorities = params.filePriorities; |
|
|
|
|
|
|
|
data.ratioLimit = params.ignoreShareRatio ? TorrentHandle::NO_RATIO_LIMIT : TorrentHandle::USE_GLOBAL_RATIO; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// normalize save path
|
|
|
|
|
|
|
|
if (data.savePath.isEmpty()) { |
|
|
|
|
|
|
|
data.savePath = m_defaultSavePath; |
|
|
|
|
|
|
|
if (m_appendLabelToSavePath && !data.label.isEmpty()) |
|
|
|
|
|
|
|
data.savePath += QString("%1/").arg(data.label); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (!data.savePath.endsWith("/")) { |
|
|
|
|
|
|
|
data.savePath += "/"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|