Browse Source

Access some more data in a non-blocking manner

* Cache URL seeds to access in a non-blocking manner
* Provide non-blocking way to create magnet URI for torrent

PR #18572.
adaptive-webui-19844
Vladimir Golovnev 2 years ago committed by GitHub
parent
commit
4c0ebc0e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/base/bittorrent/extensiondata.h
  2. 3
      src/base/bittorrent/nativesessionextension.cpp
  3. 3
      src/base/bittorrent/nativetorrentextension.cpp
  4. 68
      src/base/bittorrent/torrentimpl.cpp
  5. 1
      src/base/bittorrent/torrentimpl.h

5
src/base/bittorrent/extensiondata.h

@ -1,6 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2022 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2022-2023 Vladimir Golovnev <glassez@yandex.ru>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -28,6 +28,8 @@
#pragma once #pragma once
#include <set>
#include <string>
#include <vector> #include <vector>
#include <libtorrent/announce_entry.hpp> #include <libtorrent/announce_entry.hpp>
@ -44,4 +46,5 @@ struct ExtensionData
{ {
lt::torrent_status status; lt::torrent_status status;
std::vector<lt::announce_entry> trackers; std::vector<lt::announce_entry> trackers;
std::set<std::string> urlSeeds;
}; };

3
src/base/bittorrent/nativesessionextension.cpp

@ -1,6 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2020-2022 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2020-2023 Vladimir Golovnev <glassez@yandex.ru>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -51,6 +51,7 @@ namespace
{ {
data->status = alert->handle.status({}); data->status = alert->handle.status({});
data->trackers = alert->handle.trackers(); data->trackers = alert->handle.trackers();
data->urlSeeds = alert->handle.url_seeds();
} }
#endif #endif
} }

3
src/base/bittorrent/nativetorrentextension.cpp

@ -1,6 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2020-2022 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2020-2023 Vladimir Golovnev <glassez@yandex.ru>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -46,6 +46,7 @@ NativeTorrentExtension::NativeTorrentExtension(const lt::torrent_handle &torrent
{ {
m_data->status = m_torrentHandle.status({}); m_data->status = m_torrentHandle.status({});
m_data->trackers = m_torrentHandle.trackers(); m_data->trackers = m_torrentHandle.trackers();
m_data->urlSeeds = m_torrentHandle.url_seeds();
} }
#endif #endif

68
src/base/bittorrent/torrentimpl.cpp

@ -1,6 +1,6 @@
/* /*
* Bittorrent Client using Qt and libtorrent. * Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015-2022 Vladimir Golovnev <glassez@yandex.ru> * Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org> * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -36,7 +36,6 @@
#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 <libtorrent/session.hpp> #include <libtorrent/session.hpp>
#include <libtorrent/storage_defs.hpp> #include <libtorrent/storage_defs.hpp>
#include <libtorrent/time.hpp> #include <libtorrent/time.hpp>
@ -302,6 +301,9 @@ TorrentImpl::TorrentImpl(SessionImpl *session, lt::session *nativeSession
m_trackerEntries.reserve(static_cast<decltype(m_trackerEntries)::size_type>(extensionData->trackers.size())); m_trackerEntries.reserve(static_cast<decltype(m_trackerEntries)::size_type>(extensionData->trackers.size()));
for (const lt::announce_entry &announceEntry : extensionData->trackers) for (const lt::announce_entry &announceEntry : extensionData->trackers)
m_trackerEntries.append({QString::fromStdString(announceEntry.url), announceEntry.tier}); m_trackerEntries.append({QString::fromStdString(announceEntry.url), announceEntry.tier});
m_urlSeeds.reserve(static_cast<decltype(m_urlSeeds)::size_type>(extensionData->urlSeeds.size()));
for (const std::string &urlSeed : extensionData->urlSeeds)
m_urlSeeds.append(QString::fromStdString(urlSeed));
m_nativeStatus = extensionData->status; m_nativeStatus = extensionData->status;
updateState(); updateState();
@ -608,15 +610,7 @@ void TorrentImpl::replaceTrackers(QVector<TrackerEntry> trackers)
QVector<QUrl> TorrentImpl::urlSeeds() const QVector<QUrl> TorrentImpl::urlSeeds() const
{ {
const std::set<std::string> currentSeeds = m_nativeHandle.url_seeds(); return m_urlSeeds;
QVector<QUrl> urlSeeds;
urlSeeds.reserve(static_cast<decltype(urlSeeds)::size_type>(currentSeeds.size()));
for (const std::string &urlSeed : currentSeeds)
urlSeeds.append(QString::fromStdString(urlSeed));
return urlSeeds;
} }
void TorrentImpl::addUrlSeeds(const QVector<QUrl> &urlSeeds) void TorrentImpl::addUrlSeeds(const QVector<QUrl> &urlSeeds)
@ -645,11 +639,13 @@ void TorrentImpl::addUrlSeeds(const QVector<QUrl> &urlSeeds)
} }
} }
session->invoke([session, thisTorrent, addedUrlSeeds] currentSeeds.append(addedUrlSeeds);
session->invoke([session, thisTorrent, currentSeeds, addedUrlSeeds]
{ {
if (!thisTorrent) if (!thisTorrent)
return; return;
thisTorrent->m_urlSeeds = currentSeeds;
if (!addedUrlSeeds.isEmpty()) if (!addedUrlSeeds.isEmpty())
{ {
session->handleTorrentNeedSaveResumeData(thisTorrent); session->handleTorrentNeedSaveResumeData(thisTorrent);
@ -680,18 +676,20 @@ void TorrentImpl::removeUrlSeeds(const QVector<QUrl> &urlSeeds)
for (const QUrl &url : urlSeeds) for (const QUrl &url : urlSeeds)
{ {
if (currentSeeds.contains(url)) if (currentSeeds.removeOne(url))
{ {
nativeHandle.remove_url_seed(url.toString().toStdString()); nativeHandle.remove_url_seed(url.toString().toStdString());
removedUrlSeeds.append(url); removedUrlSeeds.append(url);
} }
} }
session->invoke([session, thisTorrent, removedUrlSeeds] session->invoke([session, thisTorrent, currentSeeds, removedUrlSeeds]
{ {
if (!thisTorrent) if (!thisTorrent)
return; return;
thisTorrent->m_urlSeeds = currentSeeds;
if (!removedUrlSeeds.isEmpty()) if (!removedUrlSeeds.isEmpty())
{ {
session->handleTorrentNeedSaveResumeData(thisTorrent); session->handleTorrentNeedSaveResumeData(thisTorrent);
@ -1887,6 +1885,14 @@ void TorrentImpl::handleTorrentResumedAlert(const lt::torrent_resumed_alert *p)
void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p) void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
{ {
if (m_ltAddTorrentParams.url_seeds != p->params.url_seeds)
{
// URL seed list have been changed by libtorrent for some reason, so we need to update cached one.
// Unfortunately, URL seed list containing in "resume data" is generated according to different rules
// than the list we usually cache, so we have to request it from the appropriate source.
fetchURLSeeds([this](const QVector<QUrl> &urlSeeds) { m_urlSeeds = urlSeeds; });
}
if (m_maintenanceJob == MaintenanceJob::HandleMetadata) if (m_maintenanceJob == MaintenanceJob::HandleMetadata)
{ {
Q_ASSERT(m_indexMap.isEmpty()); Q_ASSERT(m_indexMap.isEmpty());
@ -2403,7 +2409,39 @@ void TorrentImpl::flushCache() const
QString TorrentImpl::createMagnetURI() const QString TorrentImpl::createMagnetURI() const
{ {
return QString::fromStdString(lt::make_magnet_uri(m_nativeHandle)); QString ret = u"magnet:?"_qs;
const SHA1Hash infoHash1 = infoHash().v1();
if (infoHash1.isValid())
{
ret += u"xt=urn:btih:" + infoHash1.toString();
}
const SHA256Hash infoHash2 = infoHash().v2();
if (infoHash2.isValid())
{
if (infoHash1.isValid())
ret += u'&';
ret += u"xt=urn:btmh:1220" + infoHash2.toString();
}
const QString displayName = name();
if (displayName != id().toString())
{
ret += u"&dn=" + QString::fromLatin1(QUrl::toPercentEncoding(displayName));
}
for (const TrackerEntry &tracker : asConst(trackers()))
{
ret += u"&tr=" + QString::fromLatin1(QUrl::toPercentEncoding(tracker.url));
}
for (const QUrl &urlSeed : asConst(urlSeeds()))
{
ret += u"&ws=" + QString::fromLatin1(urlSeed.toEncoded());
}
return ret;
} }
nonstd::expected<lt::entry, QString> TorrentImpl::exportTorrent() const nonstd::expected<lt::entry, QString> TorrentImpl::exportTorrent() const

1
src/base/bittorrent/torrentimpl.h

@ -327,6 +327,7 @@ namespace BitTorrent
MaintenanceJob m_maintenanceJob = MaintenanceJob::None; MaintenanceJob m_maintenanceJob = MaintenanceJob::None;
QVector<TrackerEntry> m_trackerEntries; QVector<TrackerEntry> m_trackerEntries;
QVector<QUrl> m_urlSeeds;
FileErrorInfo m_lastFileError; FileErrorInfo m_lastFileError;
// Persistent data // Persistent data

Loading…
Cancel
Save