diff --git a/src/base/bittorrent/magneturi.cpp b/src/base/bittorrent/magneturi.cpp index 84673fffc..cad119c77 100644 --- a/src/base/bittorrent/magneturi.cpp +++ b/src/base/bittorrent/magneturi.cpp @@ -26,6 +26,10 @@ * exception statement from your version. */ +#include +#include +#include + #include #include #include @@ -33,17 +37,45 @@ #include "base/utils/string.h" #include "magneturi.h" +namespace +{ + QString bcLinkToMagnet(QString bcLink) + { + QByteArray rawBc = bcLink.toUtf8(); + rawBc = rawBc.mid(8); // skip bc://bt/ + rawBc = QByteArray::fromBase64(rawBc); // Decode base64 + // Format is now AA/url_encoded_filename/size_bytes/info_hash/ZZ + QStringList parts = QString(rawBc).split("/"); + if (parts.size() != 5) return QString(); + + QString filename = parts.at(1); + QString hash = parts.at(3); + QString magnet = "magnet:?xt=urn:btih:" + hash; + magnet += "&dn=" + filename; + return magnet; + } +} + namespace libt = libtorrent; using namespace BitTorrent; -MagnetUri::MagnetUri(const QString &url) +MagnetUri::MagnetUri(const QString &source) : m_valid(false) - , m_url(url) + , m_url(source) { - if (url.isEmpty()) return; + if (source.isEmpty()) return; + + if (source.startsWith("bc://bt/", Qt::CaseInsensitive)) { + qDebug("Creating magnet link from bc link"); + m_url = bcLinkToMagnet(source); + } + else if (((source.size() == 40) && !source.contains(QRegExp("[^0-9A-Fa-f]"))) + || ((source.size() == 32) && !source.contains(QRegExp("[^2-7A-Za-z]")))) { + m_url = "magnet:?xt=urn:btih:" + source; + } libt::error_code ec; - libt::parse_magnet_uri(url.toUtf8().constData(), m_addTorrentParams, ec); + libt::parse_magnet_uri(m_url.toUtf8().constData(), m_addTorrentParams, ec); if (ec) return; m_valid = true; diff --git a/src/base/bittorrent/magneturi.h b/src/base/bittorrent/magneturi.h index b4b303753..e7e23becf 100644 --- a/src/base/bittorrent/magneturi.h +++ b/src/base/bittorrent/magneturi.h @@ -43,7 +43,7 @@ namespace BitTorrent class MagnetUri { public: - explicit MagnetUri(const QString &url = QString()); + explicit MagnetUri(const QString &source = QString()); bool isValid() const; InfoHash hash() const; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index e80fdd0f4..712e044e5 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -963,16 +963,11 @@ bool Session::addTorrent(QString source, const AddTorrentParams ¶ms) return true; } - if (source.startsWith("bc://bt/", Qt::CaseInsensitive)) { - qDebug("Converting bc link to magnet link"); - source = Utils::Misc::bcLinkToMagnet(source); + MagnetUri magnetUri(source); + if (magnetUri.isValid()) { + return addTorrent_impl(params, magnetUri); } - else if (((source.size() == 40) && !source.contains(QRegExp("[^0-9A-Fa-f]"))) - || ((source.size() == 32) && !source.contains(QRegExp("[^2-7A-Za-z]")))) { - source = "magnet:?xt=urn:btih:" + source; - } - - if (Utils::Misc::isUrl(source)) { + else if (Utils::Misc::isUrl(source)) { Logger::instance()->addMessage(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source)); // Launch downloader Net::DownloadHandler *handler = Net::DownloadManager::instance()->downloadUrl(source, true, 10485760 /* 10MB */, true); @@ -981,9 +976,6 @@ bool Session::addTorrent(QString source, const AddTorrentParams ¶ms) connect(handler, SIGNAL(redirectedToMagnet(QString, QString)), this, SLOT(handleRedirectedToMagnet(QString, QString))); m_downloadedTorrents[handler->url()] = params; } - else if (source.startsWith("magnet:", Qt::CaseInsensitive)) { - return addTorrent_impl(addDataFromParams(params), MagnetUri(source)); - } else { return addTorrent_impl(addDataFromParams(params), MagnetUri(), TorrentInfo::loadFromFile(source)); } @@ -1091,15 +1083,12 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri // Add a torrent to the BitTorrent session in hidden mode // 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(); - QString name = magnet.name(); + InfoHash hash = magnetUri.hash(); + QString name = magnetUri.name(); // We should not add torrent if it already // processed or adding to session @@ -1111,7 +1100,7 @@ bool Session::loadMetadata(const QString &magnetUri) qDebug(" -> Hash: %s", qPrintable(hash)); qDebug(" -> Name: %s", qPrintable(name)); - libt::add_torrent_params p = magnet.addTorrentParams(); + libt::add_torrent_params p = magnetUri.addTorrentParams(); // Flags // Preallocation mode diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index 6eea60981..e86ab8c59 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -196,7 +196,7 @@ namespace BitTorrent bool addTorrent(QString source, const AddTorrentParams ¶ms = AddTorrentParams()); bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams()); bool deleteTorrent(const QString &hash, bool deleteLocalFiles = false); - bool loadMetadata(const QString &magnetUri); + bool loadMetadata(const MagnetUri &magnetUri); bool cancelLoadMetadata(const InfoHash &hash); void recursiveTorrentDownload(const InfoHash &hash); diff --git a/src/base/utils/misc.cpp b/src/base/utils/misc.cpp index 7e34f0a97..580fa7ad1 100644 --- a/src/base/utils/misc.cpp +++ b/src/base/utils/misc.cpp @@ -392,21 +392,6 @@ bool Utils::Misc::isPreviewable(const QString& extension) return multimedia_extensions.contains(extension.toUpper()); } -QString Utils::Misc::bcLinkToMagnet(QString bc_link) -{ - QByteArray raw_bc = bc_link.toUtf8(); - raw_bc = raw_bc.mid(8); // skip bc://bt/ - raw_bc = QByteArray::fromBase64(raw_bc); // Decode base64 - // Format is now AA/url_encoded_filename/size_bytes/info_hash/ZZ - QStringList parts = QString(raw_bc).split("/"); - if (parts.size() != 5) return QString::null; - QString filename = parts.at(1); - QString hash = parts.at(3); - QString magnet = "magnet:?xt=urn:btih:" + hash; - magnet += "&dn=" + filename; - return magnet; -} - // Take a number of seconds and return an user-friendly // time duration like "1d 2h 10m". QString Utils::Misc::userFriendlyDuration(qlonglong seconds) diff --git a/src/base/utils/misc.h b/src/base/utils/misc.h index fd62a637b..bfc4d00e4 100644 --- a/src/base/utils/misc.h +++ b/src/base/utils/misc.h @@ -66,7 +66,6 @@ namespace Utils QString friendlyUnit(qreal val, bool is_speed = false); bool isPreviewable(const QString& extension); - QString bcLinkToMagnet(QString bc_link); // Take a number of seconds and return an user-friendly // time duration like "1d 2h 10m". QString userFriendlyDuration(qlonglong seconds); diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 4c74a1973..eb844f02f 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -133,15 +133,6 @@ void AddNewTorrentDialog::saveState() void AddNewTorrentDialog::show(QString source, QWidget *parent) { - 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]"))) - || ((source.size() == 32) && !source.contains(QRegExp("[^2-7A-Za-z]")))) { - source = "magnet:?xt=urn:btih:" + source; - } - AddNewTorrentDialog *dlg = new AddNewTorrentDialog(parent); if (Utils::Misc::isUrl(source)) { @@ -153,8 +144,9 @@ void AddNewTorrentDialog::show(QString source, QWidget *parent) } else { bool ok = false; - if (source.startsWith("magnet:", Qt::CaseInsensitive)) - ok = dlg->loadMagnet(source); + BitTorrent::MagnetUri magnetUri(source); + if (magnetUri.isValid()) + ok = dlg->loadMagnet(magnetUri); else ok = dlg->loadTorrent(source); @@ -165,12 +157,12 @@ void AddNewTorrentDialog::show(QString source, QWidget *parent) } } -bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path) +bool AddNewTorrentDialog::loadTorrent(const QString &torrentPath) { - if (torrent_path.startsWith("file://", Qt::CaseInsensitive)) - m_filePath = QUrl::fromEncoded(torrent_path.toLocal8Bit()).toLocalFile(); + if (torrentPath.startsWith("file://", Qt::CaseInsensitive)) + m_filePath = QUrl::fromEncoded(torrentPath.toLocal8Bit()).toLocalFile(); else - m_filePath = torrent_path; + m_filePath = torrentPath; if (!QFile::exists(m_filePath)) { MessageBoxRaised::critical(0, tr("I/O Error"), tr("The torrent file does not exist.")); @@ -212,21 +204,20 @@ bool AddNewTorrentDialog::loadTorrent(const QString& torrent_path) return true; } -bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri) +bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri) { - BitTorrent::MagnetUri magnet(magnet_uri); - if (!magnet.isValid()) { + if (!magnetUri.isValid()) { MessageBoxRaised::critical(0, tr("Invalid magnet link"), tr("This magnet link was not recognized")); return false; } - m_hash = magnet.hash(); + m_hash = magnetUri.hash(); // Prevent showing the dialog if download is already present if (BitTorrent::Session::instance()->isKnownTorrent(m_hash)) { BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(m_hash); if (torrent) { - torrent->addTrackers(magnet.trackers()); - torrent->addUrlSeeds(magnet.urlSeeds()); + torrent->addTrackers(magnetUri.trackers()); + torrent->addUrlSeeds(magnetUri.urlSeeds()); MessageBoxRaised::information(0, tr("Already in download list"), tr("Magnet link is already in download list. Trackers were merged."), QMessageBox::Ok); } else { @@ -238,14 +229,14 @@ bool AddNewTorrentDialog::loadMagnet(const QString &magnet_uri) connect(BitTorrent::Session::instance(), SIGNAL(metadataLoaded(BitTorrent::TorrentInfo)), SLOT(updateMetadata(BitTorrent::TorrentInfo))); // Set dialog title - QString torrent_name = magnet.name(); + QString torrent_name = magnetUri.name(); setWindowTitle(torrent_name.isEmpty() ? tr("Magnet link") : torrent_name); setupTreeview(); // Set dialog position setdialogPosition(); - BitTorrent::Session::instance()->loadMetadata(magnet_uri); + BitTorrent::Session::instance()->loadMetadata(magnetUri); setMetadataProgressIndicator(true, tr("Retrieving metadata...")); ui->lblhash->setText(m_hash); @@ -732,7 +723,7 @@ void AddNewTorrentDialog::handleDownloadFailed(const QString &url, const QString void AddNewTorrentDialog::handleRedirectedToMagnet(const QString &url, const QString &magnetUri) { Q_UNUSED(url) - if (loadMagnet(magnetUri)) + if (loadMagnet(BitTorrent::MagnetUri(magnetUri))) open(); else this->deleteLater(); diff --git a/src/gui/addnewtorrentdialog.h b/src/gui/addnewtorrentdialog.h index ae54f208a..8b1cd2576 100644 --- a/src/gui/addnewtorrentdialog.h +++ b/src/gui/addnewtorrentdialog.h @@ -38,11 +38,15 @@ #include "base/bittorrent/infohash.h" #include "base/bittorrent/torrentinfo.h" -QT_BEGIN_NAMESPACE -namespace Ui { +namespace BitTorrent +{ + class MagnetUri; +} + +namespace Ui +{ class AddNewTorrentDialog; } -QT_END_NAMESPACE class TorrentContentFilterModel; class PropListDelegate; @@ -79,8 +83,8 @@ protected slots: private: explicit AddNewTorrentDialog(QWidget *parent = 0); - bool loadTorrent(const QString& torrent_path); - bool loadMagnet(const QString& magnet_uri); + bool loadTorrent(const QString &torrentPath); + bool loadMagnet(const BitTorrent::MagnetUri &magnetUri); void loadSavePathHistory(); void saveSavePathHistory() const; int indexOfSavePath(const QString& save_path); diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index 05659a9c3..2cfab6f2a 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -354,14 +354,6 @@ void WebApplication::action_command_download() foreach (QString url, list) { url = url.trimmed(); if (!url.isEmpty()) { - if (url.startsWith("bc://bt/", Qt::CaseInsensitive)) { - qDebug("Converting bc link to magnet link"); - url = Utils::Misc::bcLinkToMagnet(url); - } - if ((url.size() == 40 && !url.contains(QRegExp("[^0-9A-Fa-f]"))) - || (url.size() == 32 && !url.contains(QRegExp("[^2-7A-Za-z]")))) - url = "magnet:?xt=urn:btih:" + url; - Net::DownloadManager::instance()->setCookiesFromUrl(cookies, QUrl::fromEncoded(url.toUtf8())); BitTorrent::Session::instance()->addTorrent(url, params); }