mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-15 09:43:07 -07:00
Merge pull request #13340 from glassez/fix-magnet
Improve adding torrent using Magnet URI
This commit is contained in:
commit
defdd5121c
4 changed files with 48 additions and 81 deletions
|
@ -1775,18 +1775,9 @@ bool Session::cancelLoadMetadata(const InfoHash &hash)
|
||||||
if (loadedMetadataIter == m_loadedMetadata.end()) return false;
|
if (loadedMetadataIter == m_loadedMetadata.end()) return false;
|
||||||
|
|
||||||
m_loadedMetadata.erase(loadedMetadataIter);
|
m_loadedMetadata.erase(loadedMetadataIter);
|
||||||
const lt::torrent_handle torrent = m_nativeSession->find_torrent(hash);
|
|
||||||
if (!torrent.is_valid()) return false;
|
|
||||||
|
|
||||||
if (!torrent.status(lt::status_flags_t {0}).has_metadata) {
|
|
||||||
// if hidden torrent is still loading metadata...
|
|
||||||
--m_extraLimit;
|
--m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
}
|
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
|
||||||
|
|
||||||
// Remove it from session
|
|
||||||
m_nativeSession->remove_torrent(torrent, lt::session::delete_files);
|
|
||||||
qDebug("Preloaded torrent deleted.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1834,7 +1825,7 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
||||||
|
|
||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
@ -1883,7 +1874,7 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
for (auto i = m_loadedMetadata.cbegin(); i != m_loadedMetadata.cend(); ++i)
|
||||||
torrentQueuePositionBottom(m_nativeSession->find_torrent(i.key()));
|
torrentQueuePositionBottom(m_nativeSession->find_torrent(*i));
|
||||||
|
|
||||||
saveTorrentsQueue();
|
saveTorrentsQueue();
|
||||||
}
|
}
|
||||||
|
@ -1938,42 +1929,14 @@ bool Session::addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &par
|
||||||
|
|
||||||
const auto it = m_loadedMetadata.constFind(hash);
|
const auto it = m_loadedMetadata.constFind(hash);
|
||||||
if (it != m_loadedMetadata.constEnd()) {
|
if (it != m_loadedMetadata.constEnd()) {
|
||||||
// Adding preloaded torrent...
|
// It looks illogical that we don't just use an existing handle,
|
||||||
const TorrentInfo metadata = it->metadata;
|
// but as previous experience has shown, it actually creates unnecessary
|
||||||
if (metadata.isValid()) {
|
// problems and unwanted behavior due to the fact that it was originally
|
||||||
// Metadata is received and torrent_handle is being deleted
|
// added with parameters other than those provided by the user.
|
||||||
// so we can't reuse it. Just add torrent using its metadata.
|
m_loadedMetadata.erase(it);
|
||||||
return addTorrent(metadata, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reuse existing torrent_handle
|
|
||||||
lt::torrent_handle handle = m_nativeSession->find_torrent(hash);
|
|
||||||
|
|
||||||
// Preloaded torrent is in "Upload mode" so we need to disable it
|
|
||||||
// otherwise the torrent never be downloaded (until application restart)
|
|
||||||
handle.unset_flags(lt::torrent_flags::upload_mode);
|
|
||||||
|
|
||||||
LoadTorrentParams createTorrentParams = initLoadTorrentParams(params);
|
|
||||||
createTorrentParams.ltAddTorrentParams = it->ltAddTorrentParams;
|
|
||||||
|
|
||||||
if (createTorrentParams.paused) {
|
|
||||||
// Preloaded torrent isn't auto managed already
|
|
||||||
handle.pause();
|
|
||||||
}
|
|
||||||
else if (!createTorrentParams.forced) {
|
|
||||||
handle.set_flags(lt::torrent_flags::auto_managed);
|
|
||||||
handle.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_loadedMetadata.remove(hash);
|
|
||||||
m_loadingTorrents.insert(hash, createTorrentParams);
|
|
||||||
|
|
||||||
--m_extraLimit;
|
--m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
|
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files);
|
||||||
// use common last step of torrent loading
|
|
||||||
createTorrentHandle(handle);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return addTorrent_impl(params, magnetUri);
|
return addTorrent_impl(params, magnetUri);
|
||||||
|
@ -2081,6 +2044,10 @@ bool Session::addTorrent_impl(const AddTorrentParams &addTorrentParams, const Ma
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = magnetUri.addTorrentParams();
|
p = magnetUri.addTorrentParams();
|
||||||
|
|
||||||
|
if (loadTorrentParams.name.isEmpty() && !p.name.empty())
|
||||||
|
loadTorrentParams.name = QString::fromStdString(p.name);
|
||||||
|
|
||||||
if (isTempPathEnabled())
|
if (isTempPathEnabled())
|
||||||
actualSavePath = tempPath();
|
actualSavePath = tempPath();
|
||||||
}
|
}
|
||||||
|
@ -2211,7 +2178,7 @@ bool Session::loadMetadata(const MagnetUri &magnetUri)
|
||||||
if (ec) return false;
|
if (ec) return false;
|
||||||
|
|
||||||
// waiting for metadata...
|
// waiting for metadata...
|
||||||
m_loadedMetadata.insert(h.info_hash(), {p, TorrentInfo {}});
|
m_loadedMetadata.insert(h.info_hash());
|
||||||
++m_extraLimit;
|
++m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
|
|
||||||
|
@ -4056,6 +4023,10 @@ bool Session::loadTorrentResumeData(const QByteArray &data, const TorrentInfo &m
|
||||||
const lt::bdecode_node addedTimeNode = root.dict_find("qBt-addedTime");
|
const lt::bdecode_node addedTimeNode = root.dict_find("qBt-addedTime");
|
||||||
if (addedTimeNode.type() == lt::bdecode_node::int_t)
|
if (addedTimeNode.type() == lt::bdecode_node::int_t)
|
||||||
p.added_time = addedTimeNode.int_value();
|
p.added_time = addedTimeNode.int_value();
|
||||||
|
|
||||||
|
if (torrentParams.name.isEmpty() && !p.name.empty())
|
||||||
|
torrentParams.name = QString::fromStdString(p.name);
|
||||||
|
|
||||||
}
|
}
|
||||||
// === END DEPRECATED CODE === //
|
// === END DEPRECATED CODE === //
|
||||||
else {
|
else {
|
||||||
|
@ -4394,12 +4365,6 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
|
||||||
{
|
{
|
||||||
const InfoHash infoHash {p->info_hash};
|
const InfoHash infoHash {p->info_hash};
|
||||||
|
|
||||||
const auto loadedMetadataIter = m_loadedMetadata.find(infoHash);
|
|
||||||
if (loadedMetadataIter != m_loadedMetadata.end()) {
|
|
||||||
emit metadataLoaded(loadedMetadataIter->metadata);
|
|
||||||
m_loadedMetadata.erase(loadedMetadataIter);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
|
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash);
|
||||||
if (removingTorrentDataIter != m_removingTorrents.end()) {
|
if (removingTorrentDataIter != m_removingTorrents.end()) {
|
||||||
if (removingTorrentDataIter->deleteOption == Torrent) {
|
if (removingTorrentDataIter->deleteOption == Torrent) {
|
||||||
|
@ -4451,10 +4416,14 @@ void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
|
||||||
const auto loadedMetadataIter = m_loadedMetadata.find(hash);
|
const auto loadedMetadataIter = m_loadedMetadata.find(hash);
|
||||||
|
|
||||||
if (loadedMetadataIter != m_loadedMetadata.end()) {
|
if (loadedMetadataIter != m_loadedMetadata.end()) {
|
||||||
|
TorrentInfo metadata {p->handle.torrent_file()};
|
||||||
|
|
||||||
|
m_loadedMetadata.erase(loadedMetadataIter);
|
||||||
--m_extraLimit;
|
--m_extraLimit;
|
||||||
adjustLimits();
|
adjustLimits();
|
||||||
loadedMetadataIter->metadata = TorrentInfo {p->handle.torrent_file()};
|
|
||||||
m_nativeSession->remove_torrent(p->handle, lt::session::delete_files);
|
m_nativeSession->remove_torrent(p->handle, lt::session::delete_files);
|
||||||
|
|
||||||
|
emit metadataLoaded(metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -758,12 +758,7 @@ namespace BitTorrent
|
||||||
QThread *m_ioThread = nullptr;
|
QThread *m_ioThread = nullptr;
|
||||||
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
|
||||||
|
|
||||||
struct LoadedMetadataHandle
|
QSet<InfoHash> m_loadedMetadata;
|
||||||
{
|
|
||||||
lt::add_torrent_params ltAddTorrentParams {};
|
|
||||||
TorrentInfo metadata;
|
|
||||||
};
|
|
||||||
QHash<InfoHash, LoadedMetadataHandle> m_loadedMetadata;
|
|
||||||
|
|
||||||
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
QHash<InfoHash, TorrentHandleImpl *> m_torrents;
|
||||||
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include "base/bittorrent/downloadpriority.h"
|
#include "base/bittorrent/downloadpriority.h"
|
||||||
|
#include "base/bittorrent/infohash.h"
|
||||||
#include "base/bittorrent/magneturi.h"
|
#include "base/bittorrent/magneturi.h"
|
||||||
#include "base/bittorrent/session.h"
|
#include "base/bittorrent/session.h"
|
||||||
#include "base/bittorrent/torrenthandle.h"
|
#include "base/bittorrent/torrenthandle.h"
|
||||||
|
@ -276,11 +277,11 @@ bool AddNewTorrentDialog::loadTorrentFile(const QString &torrentPath)
|
||||||
bool AddNewTorrentDialog::loadTorrentImpl()
|
bool AddNewTorrentDialog::loadTorrentImpl()
|
||||||
{
|
{
|
||||||
m_hasMetadata = true;
|
m_hasMetadata = true;
|
||||||
m_hash = m_torrentInfo.hash();
|
const BitTorrent::InfoHash infoHash = m_torrentInfo.hash();
|
||||||
|
|
||||||
// Prevent showing the dialog if download is already present
|
// Prevent showing the dialog if download is already present
|
||||||
if (BitTorrent::Session::instance()->isKnownTorrent(m_hash)) {
|
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) {
|
||||||
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(m_hash);
|
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
||||||
if (torrent) {
|
if (torrent) {
|
||||||
if (torrent->isPrivate() || m_torrentInfo.isPrivate()) {
|
if (torrent->isPrivate() || m_torrentInfo.isPrivate()) {
|
||||||
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
|
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
|
||||||
|
@ -297,7 +298,7 @@ bool AddNewTorrentDialog::loadTorrentImpl()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->labelHashData->setText(m_hash);
|
m_ui->labelHashData->setText(infoHash);
|
||||||
setupTreeview();
|
setupTreeview();
|
||||||
TMMChanged(m_ui->comboTTM->currentIndex());
|
TMMChanged(m_ui->comboTTM->currentIndex());
|
||||||
m_ui->keepTopLevelFolderCheckBox->setEnabled(m_torrentInfo.hasRootFolder());
|
m_ui->keepTopLevelFolderCheckBox->setEnabled(m_torrentInfo.hasRootFolder());
|
||||||
|
@ -312,10 +313,11 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_torrentGuard = std::make_unique<TorrentFileGuard>();
|
m_torrentGuard = std::make_unique<TorrentFileGuard>();
|
||||||
m_hash = magnetUri.hash();
|
|
||||||
|
const BitTorrent::InfoHash infoHash = magnetUri.hash();
|
||||||
// Prevent showing the dialog if download is already present
|
// Prevent showing the dialog if download is already present
|
||||||
if (BitTorrent::Session::instance()->isKnownTorrent(m_hash)) {
|
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) {
|
||||||
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(m_hash);
|
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
|
||||||
if (torrent) {
|
if (torrent) {
|
||||||
if (torrent->isPrivate()) {
|
if (torrent->isPrivate()) {
|
||||||
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
|
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
|
||||||
|
@ -335,7 +337,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
||||||
connect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
connect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
||||||
|
|
||||||
// Set dialog title
|
// Set dialog title
|
||||||
QString torrentName = magnetUri.name();
|
const QString torrentName = magnetUri.name();
|
||||||
setWindowTitle(torrentName.isEmpty() ? tr("Magnet link") : torrentName);
|
setWindowTitle(torrentName.isEmpty() ? tr("Magnet link") : torrentName);
|
||||||
|
|
||||||
setupTreeview();
|
setupTreeview();
|
||||||
|
@ -343,8 +345,9 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
|
||||||
|
|
||||||
BitTorrent::Session::instance()->loadMetadata(magnetUri);
|
BitTorrent::Session::instance()->loadMetadata(magnetUri);
|
||||||
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
|
setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
|
||||||
m_ui->labelHashData->setText(m_hash);
|
m_ui->labelHashData->setText(infoHash);
|
||||||
|
|
||||||
|
m_magnetURI = magnetUri;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +576,7 @@ void AddNewTorrentDialog::accept()
|
||||||
|
|
||||||
// Add torrent
|
// Add torrent
|
||||||
if (!m_hasMetadata)
|
if (!m_hasMetadata)
|
||||||
BitTorrent::Session::instance()->addTorrent(m_hash, m_torrentParams);
|
BitTorrent::Session::instance()->addTorrent(m_magnetURI, m_torrentParams);
|
||||||
else
|
else
|
||||||
BitTorrent::Session::instance()->addTorrent(m_torrentInfo, m_torrentParams);
|
BitTorrent::Session::instance()->addTorrent(m_torrentInfo, m_torrentParams);
|
||||||
|
|
||||||
|
@ -585,26 +588,26 @@ void AddNewTorrentDialog::reject()
|
||||||
{
|
{
|
||||||
if (!m_hasMetadata) {
|
if (!m_hasMetadata) {
|
||||||
setMetadataProgressIndicator(false);
|
setMetadataProgressIndicator(false);
|
||||||
BitTorrent::Session::instance()->cancelLoadMetadata(m_hash);
|
BitTorrent::Session::instance()->cancelLoadMetadata(m_magnetURI.hash());
|
||||||
}
|
}
|
||||||
|
|
||||||
QDialog::reject();
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &info)
|
void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &metadata)
|
||||||
{
|
{
|
||||||
if (info.hash() != m_hash) return;
|
if (metadata.hash() != m_magnetURI.hash()) return;
|
||||||
|
|
||||||
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
|
||||||
|
|
||||||
if (!info.isValid()) {
|
if (!metadata.isValid()) {
|
||||||
RaisedMessageBox::critical(this, tr("I/O Error"), ("Invalid metadata."));
|
RaisedMessageBox::critical(this, tr("I/O Error"), ("Invalid metadata."));
|
||||||
setMetadataProgressIndicator(false, tr("Invalid metadata"));
|
setMetadataProgressIndicator(false, tr("Invalid metadata"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Good to go
|
// Good to go
|
||||||
m_torrentInfo = info;
|
m_torrentInfo = metadata;
|
||||||
m_hasMetadata = true;
|
m_hasMetadata = true;
|
||||||
setMetadataProgressIndicator(true, tr("Parsing metadata..."));
|
setMetadataProgressIndicator(true, tr("Parsing metadata..."));
|
||||||
|
|
||||||
|
|
|
@ -34,13 +34,13 @@
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include "base/bittorrent/addtorrentparams.h"
|
#include "base/bittorrent/addtorrentparams.h"
|
||||||
#include "base/bittorrent/infohash.h"
|
#include "base/bittorrent/magneturi.h"
|
||||||
#include "base/bittorrent/torrentinfo.h"
|
#include "base/bittorrent/torrentinfo.h"
|
||||||
#include "base/settingvalue.h"
|
#include "base/settingvalue.h"
|
||||||
|
|
||||||
namespace BitTorrent
|
namespace BitTorrent
|
||||||
{
|
{
|
||||||
class MagnetUri;
|
class InfoHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Net
|
namespace Net
|
||||||
|
@ -82,7 +82,7 @@ private slots:
|
||||||
void displayContentTreeMenu(const QPoint &);
|
void displayContentTreeMenu(const QPoint &);
|
||||||
void updateDiskSpaceLabel();
|
void updateDiskSpaceLabel();
|
||||||
void onSavePathChanged(const QString &newPath);
|
void onSavePathChanged(const QString &newPath);
|
||||||
void updateMetadata(const BitTorrent::TorrentInfo &info);
|
void updateMetadata(const BitTorrent::TorrentInfo &metadata);
|
||||||
void handleDownloadFinished(const Net::DownloadResult &result);
|
void handleDownloadFinished(const Net::DownloadResult &result);
|
||||||
void TMMChanged(int index);
|
void TMMChanged(int index);
|
||||||
void categoryChanged(int index);
|
void categoryChanged(int index);
|
||||||
|
@ -112,7 +112,7 @@ private:
|
||||||
TorrentContentFilterModel *m_contentModel;
|
TorrentContentFilterModel *m_contentModel;
|
||||||
PropListDelegate *m_contentDelegate;
|
PropListDelegate *m_contentDelegate;
|
||||||
bool m_hasMetadata;
|
bool m_hasMetadata;
|
||||||
BitTorrent::InfoHash m_hash;
|
BitTorrent::MagnetUri m_magnetURI;
|
||||||
BitTorrent::TorrentInfo m_torrentInfo;
|
BitTorrent::TorrentInfo m_torrentInfo;
|
||||||
QByteArray m_headerState;
|
QByteArray m_headerState;
|
||||||
int m_oldIndex;
|
int m_oldIndex;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue