mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-28 23:44:32 +00:00
Merge pull request #10074 from Chocobo1/magneturi
Drop support for "BC Link" format
This commit is contained in:
commit
b87987ec89
@ -31,29 +31,26 @@
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/error_code.hpp>
|
||||
#include <libtorrent/magnet_uri.hpp>
|
||||
#include <libtorrent/sha1_hash.hpp>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
|
||||
#include "base/utils/string.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
QString bcLinkToMagnet(QString bcLink)
|
||||
bool isBitTorrentInfoHash(const QString &string)
|
||||
{
|
||||
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();
|
||||
// There are 2 represenations for BitTorrent info hash:
|
||||
// 1. 40 chars hex-encoded string
|
||||
// == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters)
|
||||
// 2. 32 chars Base32 encoded string
|
||||
// == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding)
|
||||
const int SHA1_HEX_SIZE = libtorrent::sha1_hash::size * 2;
|
||||
const int SHA1_BASE32_SIZE = libtorrent::sha1_hash::size * 1.6;
|
||||
|
||||
QString filename = parts.at(1);
|
||||
QString hash = parts.at(3);
|
||||
QString magnet = "magnet:?xt=urn:btih:" + hash;
|
||||
magnet += "&dn=" + filename;
|
||||
return magnet;
|
||||
return ((((string.size() == SHA1_HEX_SIZE))
|
||||
&& !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]"))))
|
||||
|| ((string.size() == SHA1_BASE32_SIZE)
|
||||
&& !string.contains(QRegularExpression(QLatin1String("[^2-7A-Za-z]")))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,17 +63,11 @@ MagnetUri::MagnetUri(const QString &source)
|
||||
{
|
||||
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(QRegularExpression("[^0-9A-Fa-f]")))
|
||||
|| ((source.size() == 32) && !source.contains(QRegularExpression("[^2-7A-Za-z]")))) {
|
||||
m_url = "magnet:?xt=urn:btih:" + source;
|
||||
}
|
||||
if (isBitTorrentInfoHash(source))
|
||||
m_url = QLatin1String("magnet:?xt=urn:btih:") + source;
|
||||
|
||||
libt::error_code ec;
|
||||
libt::parse_magnet_uri(m_url.toUtf8().constData(), m_addTorrentParams, ec);
|
||||
libt::parse_magnet_uri(m_url.toStdString(), m_addTorrentParams, ec);
|
||||
if (ec) return;
|
||||
|
||||
m_valid = true;
|
||||
@ -84,10 +75,10 @@ MagnetUri::MagnetUri(const QString &source)
|
||||
m_name = QString::fromStdString(m_addTorrentParams.name);
|
||||
|
||||
for (const std::string &tracker : m_addTorrentParams.trackers)
|
||||
m_trackers.append(QString::fromStdString(tracker));
|
||||
m_trackers.append(TrackerEntry(tracker));
|
||||
|
||||
for (const std::string &urlSeed : m_addTorrentParams.url_seeds)
|
||||
m_urlSeeds.append(QUrl(urlSeed.c_str()));
|
||||
m_urlSeeds.append(QUrl(QString::fromStdString(urlSeed)));
|
||||
}
|
||||
|
||||
bool MagnetUri::isValid() const
|
||||
|
@ -2090,14 +2090,11 @@ TorrentStatusReport Session::torrentStatusReport() const
|
||||
return m_torrentStatusReport;
|
||||
}
|
||||
|
||||
// source - .torrent file path/url or magnet uri
|
||||
bool Session::addTorrent(QString source, const AddTorrentParams ¶ms)
|
||||
bool Session::addTorrent(const QString &source, const AddTorrentParams ¶ms)
|
||||
{
|
||||
MagnetUri magnetUri(source);
|
||||
if (magnetUri.isValid())
|
||||
return addTorrent_impl(CreateTorrentParams(params), magnetUri);
|
||||
// `source`: .torrent file path/url or magnet uri
|
||||
|
||||
if (Utils::Misc::isUrl(source)) {
|
||||
if (Net::DownloadManager::hasSupportedScheme(source)) {
|
||||
LogMsg(tr("Downloading '%1', please wait...", "e.g: Downloading 'xxx.torrent', please wait...").arg(source));
|
||||
// Launch downloader
|
||||
Net::DownloadHandler *handler =
|
||||
@ -2110,6 +2107,10 @@ bool Session::addTorrent(QString source, const AddTorrentParams ¶ms)
|
||||
return true;
|
||||
}
|
||||
|
||||
const MagnetUri magnetUri {source};
|
||||
if (magnetUri.isValid())
|
||||
return addTorrent_impl(CreateTorrentParams(params), magnetUri);
|
||||
|
||||
TorrentFileGuard guard(source);
|
||||
if (addTorrent_impl(CreateTorrentParams(params)
|
||||
, MagnetUri(), TorrentInfo::loadFromFile(source))) {
|
||||
|
@ -469,7 +469,7 @@ namespace BitTorrent
|
||||
void banIP(const QString &ip);
|
||||
|
||||
bool isKnownTorrent(const InfoHash &hash) const;
|
||||
bool addTorrent(QString source, const AddTorrentParams ¶ms = AddTorrentParams());
|
||||
bool addTorrent(const 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 MagnetUri &magnetUri);
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include "downloadmanager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QNetworkCookie>
|
||||
@ -210,6 +212,15 @@ bool Net::DownloadManager::deleteCookie(const QNetworkCookie &cookie)
|
||||
return static_cast<NetworkCookieJar *>(m_networkManager.cookieJar())->deleteCookie(cookie);
|
||||
}
|
||||
|
||||
bool Net::DownloadManager::hasSupportedScheme(const QString &url)
|
||||
{
|
||||
const QStringList schemes = instance()->m_networkManager.supportedSchemes();
|
||||
return std::any_of(schemes.cbegin(), schemes.cend(), [&url](const QString &scheme)
|
||||
{
|
||||
return url.startsWith((scheme + QLatin1Char(':')), Qt::CaseInsensitive);
|
||||
});
|
||||
}
|
||||
|
||||
void Net::DownloadManager::applyProxySettings()
|
||||
{
|
||||
auto proxyManager = ProxyConfigurationManager::instance();
|
||||
|
@ -103,6 +103,8 @@ namespace Net
|
||||
void setAllCookies(const QList<QNetworkCookie> &cookieList);
|
||||
bool deleteCookie(const QNetworkCookie &cookie);
|
||||
|
||||
static bool hasSupportedScheme(const QString &url);
|
||||
|
||||
private slots:
|
||||
#ifndef QT_NO_OPENSSL
|
||||
void ignoreSslErrors(QNetworkReply *, const QList<QSslError> &);
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include "base/utils/bytearray.h"
|
||||
#include "base/utils/foreignapps.h"
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "searchdownloadhandler.h"
|
||||
#include "searchhandler.h"
|
||||
|
||||
@ -198,7 +197,7 @@ void SearchPluginManager::installPlugin(const QString &source)
|
||||
{
|
||||
clearPythonCache(engineLocation());
|
||||
|
||||
if (Utils::Misc::isUrl(source)) {
|
||||
if (Net::DownloadManager::hasSupportedScheme(source)) {
|
||||
using namespace Net;
|
||||
DownloadHandler *handler = DownloadManager::instance()->download(DownloadRequest(source).saveToFile(true));
|
||||
connect(handler, static_cast<void (DownloadHandler::*)(const QString &, const QString &)>(&DownloadHandler::downloadFinished)
|
||||
|
@ -414,14 +414,6 @@ QList<bool> Utils::Misc::boolListfromStringList(const QStringList &l)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Utils::Misc::isUrl(const QString &s)
|
||||
{
|
||||
static const QRegularExpression reURLScheme(
|
||||
"http[s]?|ftp", QRegularExpression::CaseInsensitiveOption);
|
||||
|
||||
return reURLScheme.match(QUrl(s).scheme()).hasMatch();
|
||||
}
|
||||
|
||||
QString Utils::Misc::parseHtmlLinks(const QString &rawText)
|
||||
{
|
||||
QString result = rawText;
|
||||
|
@ -71,7 +71,6 @@ namespace Utils
|
||||
};
|
||||
|
||||
QString parseHtmlLinks(const QString &rawText);
|
||||
bool isUrl(const QString &s);
|
||||
|
||||
void shutdownComputer(const ShutdownDialogAction &action);
|
||||
|
||||
|
@ -227,11 +227,11 @@ void AddNewTorrentDialog::saveState()
|
||||
settings()->storeValue(KEY_EXPANDED, m_ui->toolButtonAdvanced->isChecked());
|
||||
}
|
||||
|
||||
void AddNewTorrentDialog::show(QString source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
|
||||
void AddNewTorrentDialog::show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent)
|
||||
{
|
||||
AddNewTorrentDialog *dlg = new AddNewTorrentDialog(inParams, parent);
|
||||
|
||||
if (Utils::Misc::isUrl(source)) {
|
||||
if (Net::DownloadManager::hasSupportedScheme(source)) {
|
||||
// Launch downloader
|
||||
// TODO: Don't save loaded torrent to file, just use downloaded data!
|
||||
Net::DownloadHandler *handler = Net::DownloadManager::instance()->download(
|
||||
@ -240,27 +240,27 @@ void AddNewTorrentDialog::show(QString source, const BitTorrent::AddTorrentParam
|
||||
, dlg, &AddNewTorrentDialog::handleDownloadFinished);
|
||||
connect(handler, &Net::DownloadHandler::downloadFailed, dlg, &AddNewTorrentDialog::handleDownloadFailed);
|
||||
connect(handler, &Net::DownloadHandler::redirectedToMagnet, dlg, &AddNewTorrentDialog::handleRedirectedToMagnet);
|
||||
return;
|
||||
}
|
||||
|
||||
const BitTorrent::MagnetUri magnetUri(source);
|
||||
const bool isLoaded = magnetUri.isValid()
|
||||
? dlg->loadMagnet(magnetUri)
|
||||
: dlg->loadTorrent(source);
|
||||
|
||||
if (isLoaded) {
|
||||
#ifdef Q_OS_MAC
|
||||
dlg->exec();
|
||||
#else
|
||||
dlg->open();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
bool ok = false;
|
||||
BitTorrent::MagnetUri magnetUri(source);
|
||||
if (magnetUri.isValid())
|
||||
ok = dlg->loadMagnet(magnetUri);
|
||||
else
|
||||
ok = dlg->loadTorrent(source);
|
||||
|
||||
if (ok)
|
||||
#ifdef Q_OS_MAC
|
||||
dlg->exec();
|
||||
#else
|
||||
dlg->open();
|
||||
#endif
|
||||
else
|
||||
delete dlg;
|
||||
delete dlg;
|
||||
}
|
||||
}
|
||||
|
||||
void AddNewTorrentDialog::show(QString source, QWidget *parent)
|
||||
void AddNewTorrentDialog::show(const QString &source, QWidget *parent)
|
||||
{
|
||||
show(source, BitTorrent::AddTorrentParams(), parent);
|
||||
}
|
||||
|
@ -68,8 +68,8 @@ public:
|
||||
static int savePathHistoryLength();
|
||||
static void setSavePathHistoryLength(int value);
|
||||
|
||||
static void show(QString source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent);
|
||||
static void show(QString source, QWidget *parent);
|
||||
static void show(const QString &source, const BitTorrent::AddTorrentParams &inParams, QWidget *parent);
|
||||
static void show(const QString &source, QWidget *parent);
|
||||
|
||||
private slots:
|
||||
void showAdvancedSettings(bool show);
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <QMimeData>
|
||||
#include <QProcess>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QSplitter>
|
||||
@ -61,6 +60,7 @@
|
||||
#include "base/bittorrent/torrenthandle.h"
|
||||
#include "base/global.h"
|
||||
#include "base/logger.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/preferences.h"
|
||||
#include "base/rss/rss_folder.h"
|
||||
#include "base/rss/rss_session.h"
|
||||
@ -1296,7 +1296,7 @@ void MainWindow::dropEvent(QDropEvent *event)
|
||||
for (const QString &file : asConst(files)) {
|
||||
const bool isTorrentLink = (file.startsWith("magnet:", Qt::CaseInsensitive)
|
||||
|| file.endsWith(C_TORRENT_FILE_EXTENSION, Qt::CaseInsensitive)
|
||||
|| Utils::Misc::isUrl(file));
|
||||
|| Net::DownloadManager::hasSupportedScheme(file));
|
||||
if (isTorrentLink)
|
||||
torrentFiles << file;
|
||||
else
|
||||
@ -1628,11 +1628,7 @@ void MainWindow::showNotificationBaloon(QString title, QString msg) const
|
||||
void MainWindow::downloadFromURLList(const QStringList &urlList)
|
||||
{
|
||||
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
|
||||
for (QString url : urlList) {
|
||||
if (((url.size() == 40) && !url.contains(QRegularExpression("[^0-9A-Fa-f]")))
|
||||
|| ((url.size() == 32) && !url.contains(QRegularExpression("[^2-7A-Za-z]"))))
|
||||
url = "magnet:?xt=urn:btih:" + url;
|
||||
|
||||
for (const QString &url : urlList) {
|
||||
if (useTorrentAdditionDialog)
|
||||
AddNewTorrentDialog::show(url, this);
|
||||
else
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "base/rss/rss_feed.h"
|
||||
#include "base/rss/rss_folder.h"
|
||||
#include "base/rss/rss_session.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "addnewtorrentdialog.h"
|
||||
#include "articlelistwidget.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
@ -249,7 +248,7 @@ void RSSWidget::on_newFeedButton_clicked()
|
||||
{
|
||||
// Ask for feed URL
|
||||
const QString clipText = qApp->clipboard()->text();
|
||||
const QString defaultURL = (Utils::Misc::isUrl(clipText) ? clipText : "http://");
|
||||
const QString defaultURL = Net::DownloadManager::hasSupportedScheme(clipText) ? clipText : "http://";
|
||||
|
||||
bool ok;
|
||||
QString newURL = AutoExpandableDialog::getText(
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "base/net/downloadhandler.h"
|
||||
#include "base/net/downloadmanager.h"
|
||||
#include "base/utils/fs.h"
|
||||
#include "base/utils/misc.h"
|
||||
#include "autoexpandabledialog.h"
|
||||
#include "guiiconprovider.h"
|
||||
#include "pluginsourcedialog.h"
|
||||
@ -337,7 +336,7 @@ void PluginSelectDialog::askForPluginUrl()
|
||||
bool ok = false;
|
||||
QString clipTxt = qApp->clipboard()->text();
|
||||
QString defaultUrl = "http://";
|
||||
if (Utils::Misc::isUrl(clipTxt) && clipTxt.endsWith(".py"))
|
||||
if (Net::DownloadManager::hasSupportedScheme(clipTxt) && clipTxt.endsWith(".py"))
|
||||
defaultUrl = clipTxt;
|
||||
QString url = AutoExpandableDialog::getText(
|
||||
this, tr("New search engine plugin URL"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user