Browse Source

Merge pull request #14503 from glassez/torrent-id

Improve "info hash" handling (step 2)
adaptive-webui-19844
Vladimir Golovnev 4 years ago committed by GitHub
parent
commit
86a283b4ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .travis.yml
  2. 3
      src/app/application.cpp
  3. 2
      src/base/bittorrent/filesearcher.cpp
  4. 6
      src/base/bittorrent/filesearcher.h
  5. 50
      src/base/bittorrent/infohash.cpp
  6. 45
      src/base/bittorrent/infohash.h
  7. 16
      src/base/bittorrent/magneturi.cpp
  8. 4
      src/base/bittorrent/magneturi.h
  9. 205
      src/base/bittorrent/session.cpp
  10. 30
      src/base/bittorrent/session.h
  11. 7
      src/base/bittorrent/torrent.cpp
  12. 4
      src/base/bittorrent/torrent.h
  13. 12
      src/base/bittorrent/torrentimpl.cpp
  14. 4
      src/base/bittorrent/torrentimpl.h
  15. 9
      src/base/bittorrent/torrentinfo.cpp
  16. 2
      src/base/bittorrent/torrentinfo.h
  17. 16
      src/base/bittorrent/tracker.cpp
  18. 2
      src/base/bittorrent/tracker.h
  19. 20
      src/base/torrentfilter.cpp
  20. 12
      src/base/torrentfilter.h
  21. 20
      src/gui/addnewtorrentdialog.cpp
  22. 6
      src/gui/mainwindow.cpp
  23. 5
      src/gui/properties/propertieswidget.cpp
  24. 8
      src/gui/torrentoptionsdialog.cpp
  25. 4
      src/gui/torrentoptionsdialog.h
  26. 84
      src/gui/transferlistfilterswidget.cpp
  27. 28
      src/gui/transferlistfilterswidget.h
  28. 6
      src/gui/transferlistsortmodel.cpp
  29. 2
      src/gui/transferlistsortmodel.h
  30. 30
      src/gui/transferlistwidget.cpp
  31. 4
      src/gui/transferlistwidget.h
  32. 3
      src/webui/api/serialize/serialize_torrent.cpp
  33. 2
      src/webui/api/serialize/serialize_torrent.h
  34. 20
      src/webui/api/synccontroller.cpp
  35. 112
      src/webui/api/torrentscontroller.cpp

2
.travis.yml

@ -146,7 +146,7 @@ install:
cmake \ cmake \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=17 \ -DCMAKE_CXX_STANDARD=17 \
-Ddeprecated-functions=ON \ -Ddeprecated-functions=OFF \
-DOPENSSL_ROOT_DIR="$openssl_root_path" \ -DOPENSSL_ROOT_DIR="$openssl_root_path" \
./ ./
make make

3
src/app/application.cpp

@ -339,7 +339,8 @@ void Application::runExternalProgram(const BitTorrent::Torrent *torrent) const
program.replace("%C", QString::number(torrent->filesCount())); program.replace("%C", QString::number(torrent->filesCount()));
program.replace("%Z", QString::number(torrent->totalSize())); program.replace("%Z", QString::number(torrent->totalSize()));
program.replace("%T", torrent->currentTracker()); program.replace("%T", torrent->currentTracker());
program.replace("%I", torrent->hash().toString()); // TODO: Update GUI/WebUI labels for this parameter to express its meaning more clearly
program.replace("%I", torrent->id().toString());
Logger *logger = Logger::instance(); Logger *logger = Logger::instance();
logger->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program)); logger->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program));

2
src/base/bittorrent/filesearcher.cpp

@ -33,7 +33,7 @@
#include "base/bittorrent/common.h" #include "base/bittorrent/common.h"
#include "base/bittorrent/infohash.h" #include "base/bittorrent/infohash.h"
void FileSearcher::search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames void FileSearcher::search(const BitTorrent::TorrentID &id, const QStringList &originalFileNames
, const QString &completeSavePath, const QString &incompleteSavePath) , const QString &completeSavePath, const QString &incompleteSavePath)
{ {
const auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool const auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool

6
src/base/bittorrent/filesearcher.h

@ -32,7 +32,7 @@
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash; class TorrentID;
} }
class FileSearcher final : public QObject class FileSearcher final : public QObject
@ -44,9 +44,9 @@ public:
FileSearcher() = default; FileSearcher() = default;
public slots: public slots:
void search(const BitTorrent::InfoHash &id, const QStringList &originalFileNames void search(const BitTorrent::TorrentID &id, const QStringList &originalFileNames
, const QString &completeSavePath, const QString &incompleteSavePath); , const QString &completeSavePath, const QString &incompleteSavePath);
signals: signals:
void searchFinished(const BitTorrent::InfoHash &id, const QString &savePath, const QStringList &fileNames); void searchFinished(const BitTorrent::TorrentID &id, const QString &savePath, const QStringList &fileNames);
}; };

50
src/base/bittorrent/infohash.cpp

@ -28,14 +28,54 @@
#include "infohash.h" #include "infohash.h"
const int InfoHashTypeId = qRegisterMetaType<BitTorrent::InfoHash>(); const int TorrentIDTypeId = qRegisterMetaType<BitTorrent::TorrentID>();
BitTorrent::InfoHash BitTorrent::InfoHash::fromString(const QString &hashString) BitTorrent::InfoHash::InfoHash(const WrappedType &nativeHash)
: m_valid {true}
, m_nativeHash {nativeHash}
{ {
return {SHA1Hash::fromString(hashString)};
} }
uint BitTorrent::qHash(const BitTorrent::InfoHash &key, const uint seed) bool BitTorrent::InfoHash::isValid() const
{ {
return ::qHash(std::hash<InfoHash::UnderlyingType>()(key), seed); return m_valid;
}
BitTorrent::TorrentID BitTorrent::InfoHash::toTorrentID() const
{
#if (LIBTORRENT_VERSION_NUM >= 20000)
return m_nativeHash.get_best();
#else
return {m_nativeHash};
#endif
}
BitTorrent::InfoHash::operator WrappedType() const
{
return m_nativeHash;
}
BitTorrent::TorrentID BitTorrent::TorrentID::fromString(const QString &hashString)
{
return {BaseType::fromString(hashString)};
}
BitTorrent::TorrentID BitTorrent::TorrentID::fromInfoHash(const BitTorrent::InfoHash &infoHash)
{
return infoHash.toTorrentID();
}
uint BitTorrent::qHash(const BitTorrent::TorrentID &key, const uint seed)
{
return ::qHash(std::hash<TorrentID::UnderlyingType>()(key), seed);
}
bool BitTorrent::operator==(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right)
{
return (static_cast<InfoHash::WrappedType>(left) == static_cast<InfoHash::WrappedType>(right));
}
bool BitTorrent::operator!=(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right)
{
return !(left == right);
} }

45
src/base/bittorrent/infohash.h

@ -28,6 +28,11 @@
#pragma once #pragma once
#include <libtorrent/version.hpp>
#if (LIBTORRENT_VERSION_NUM >= 20000)
#include <libtorrent/info_hash.hpp>
#endif
#include <QHash> #include <QHash>
#include <QMetaType> #include <QMetaType>
@ -38,15 +43,45 @@ using SHA256Hash = Digest32<256>;
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash : public SHA1Hash class InfoHash;
class TorrentID : public Digest32<160>
{ {
public: public:
using SHA1Hash::SHA1Hash; using BaseType = Digest32<160>;
using BaseType::BaseType;
static InfoHash fromString(const QString &hashString); static TorrentID fromString(const QString &hashString);
static TorrentID fromInfoHash(const InfoHash &infoHash);
}; };
uint qHash(const InfoHash &key, const uint seed); class InfoHash
{
public:
#if (LIBTORRENT_VERSION_NUM >= 20000)
using WrappedType = lt::info_hash_t;
#else
using WrappedType = lt::sha1_hash;
#endif
InfoHash() = default;
InfoHash(const InfoHash &other) = default;
InfoHash(const WrappedType &nativeHash);
bool isValid() const;
TorrentID toTorrentID() const;
operator WrappedType() const;
private:
bool m_valid = false;
WrappedType m_nativeHash;
};
uint qHash(const TorrentID &key, uint seed);
bool operator==(const InfoHash &left, const InfoHash &right);
bool operator!=(const InfoHash &left, const InfoHash &right);
} }
Q_DECLARE_METATYPE(BitTorrent::InfoHash) Q_DECLARE_METATYPE(BitTorrent::TorrentID)

16
src/base/bittorrent/magneturi.cpp

@ -47,8 +47,8 @@ namespace
// == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters) // == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters)
// 2. 32 chars Base32 encoded string // 2. 32 chars Base32 encoded string
// == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding) // == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding)
const int SHA1_HEX_SIZE = BitTorrent::InfoHash::length() * 2; const int SHA1_HEX_SIZE = SHA1Hash::length() * 2;
const int SHA1_BASE32_SIZE = BitTorrent::InfoHash::length() * 1.6; const int SHA1_BASE32_SIZE = SHA1Hash::length() * 1.6;
return ((((string.size() == SHA1_HEX_SIZE)) return ((((string.size() == SHA1_HEX_SIZE))
&& !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]")))) && !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]"))))
@ -73,7 +73,13 @@ MagnetUri::MagnetUri(const QString &source)
if (ec) return; if (ec) return;
m_valid = true; m_valid = true;
m_hash = m_addTorrentParams.info_hash;
#if (LIBTORRENT_VERSION_NUM >= 20000)
m_infoHash = m_addTorrentParams.info_hashes;
#else
m_infoHash = m_addTorrentParams.info_hash;
#endif
m_name = QString::fromStdString(m_addTorrentParams.name); m_name = QString::fromStdString(m_addTorrentParams.name);
m_trackers.reserve(m_addTorrentParams.trackers.size()); m_trackers.reserve(m_addTorrentParams.trackers.size());
@ -90,9 +96,9 @@ bool MagnetUri::isValid() const
return m_valid; return m_valid;
} }
InfoHash MagnetUri::hash() const InfoHash MagnetUri::infoHash() const
{ {
return m_hash; return m_infoHash;
} }
QString MagnetUri::name() const QString MagnetUri::name() const

4
src/base/bittorrent/magneturi.h

@ -46,7 +46,7 @@ namespace BitTorrent
explicit MagnetUri(const QString &source = {}); explicit MagnetUri(const QString &source = {});
bool isValid() const; bool isValid() const;
InfoHash hash() const; InfoHash infoHash() const;
QString name() const; QString name() const;
QVector<TrackerEntry> trackers() const; QVector<TrackerEntry> trackers() const;
QVector<QUrl> urlSeeds() const; QVector<QUrl> urlSeeds() const;
@ -57,7 +57,7 @@ namespace BitTorrent
private: private:
bool m_valid; bool m_valid;
QString m_url; QString m_url;
InfoHash m_hash; InfoHash m_infoHash;
QString m_name; QString m_name;
QVector<TrackerEntry> m_trackers; QVector<TrackerEntry> m_trackers;
QVector<QUrl> m_urlSeeds; QVector<QUrl> m_urlSeeds;

205
src/base/bittorrent/session.cpp

@ -1616,7 +1616,7 @@ void Session::processShareLimits()
// We shouldn't iterate over `m_torrents` in the loop below // We shouldn't iterate over `m_torrents` in the loop below
// since `deleteTorrent()` modifies it indirectly // since `deleteTorrent()` modifies it indirectly
const QHash<InfoHash, TorrentImpl *> torrents {m_torrents}; const QHash<TorrentID, TorrentImpl *> torrents {m_torrents};
for (TorrentImpl *const torrent : torrents) for (TorrentImpl *const torrent : torrents)
{ {
if (torrent->isSeed() && !torrent->isForced()) if (torrent->isSeed() && !torrent->isForced())
@ -1638,12 +1638,12 @@ void Session::processShareLimits()
if (m_maxRatioAction == Remove) if (m_maxRatioAction == Remove)
{ {
LogMsg(tr("'%1' reached the maximum ratio you set. Removed.").arg(torrent->name())); LogMsg(tr("'%1' reached the maximum ratio you set. Removed.").arg(torrent->name()));
deleteTorrent(torrent->hash()); deleteTorrent(torrent->id());
} }
else if (m_maxRatioAction == DeleteFiles) else if (m_maxRatioAction == DeleteFiles)
{ {
LogMsg(tr("'%1' reached the maximum ratio you set. Removed torrent and its files.").arg(torrent->name())); LogMsg(tr("'%1' reached the maximum ratio you set. Removed torrent and its files.").arg(torrent->name()));
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles); deleteTorrent(torrent->id(), DeleteTorrentAndFiles);
} }
else if ((m_maxRatioAction == Pause) && !torrent->isPaused()) else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
{ {
@ -1677,12 +1677,12 @@ void Session::processShareLimits()
if (m_maxRatioAction == Remove) if (m_maxRatioAction == Remove)
{ {
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed.").arg(torrent->name())); LogMsg(tr("'%1' reached the maximum seeding time you set. Removed.").arg(torrent->name()));
deleteTorrent(torrent->hash()); deleteTorrent(torrent->id());
} }
else if (m_maxRatioAction == DeleteFiles) else if (m_maxRatioAction == DeleteFiles)
{ {
LogMsg(tr("'%1' reached the maximum seeding time you set. Removed torrent and its files.").arg(torrent->name())); LogMsg(tr("'%1' reached the maximum seeding time you set. Removed torrent and its files.").arg(torrent->name()));
deleteTorrent(torrent->hash(), DeleteTorrentAndFiles); deleteTorrent(torrent->id(), DeleteTorrentAndFiles);
} }
else if ((m_maxRatioAction == Pause) && !torrent->isPaused()) else if ((m_maxRatioAction == Pause) && !torrent->isPaused())
{ {
@ -1719,7 +1719,7 @@ void Session::handleDownloadFinished(const Net::DownloadResult &result)
} }
} }
void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames) void Session::fileSearchFinished(const TorrentID &id, const QString &savePath, const QStringList &fileNames)
{ {
TorrentImpl *torrent = m_torrents.value(id); TorrentImpl *torrent = m_torrents.value(id);
if (torrent) if (torrent)
@ -1745,9 +1745,9 @@ void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, co
} }
// Return the torrent handle, given its hash // Return the torrent handle, given its hash
Torrent *Session::findTorrent(const InfoHash &hash) const Torrent *Session::findTorrent(const TorrentID &id) const
{ {
return m_torrents.value(hash); return m_torrents.value(id);
} }
bool Session::hasActiveTorrents() const bool Session::hasActiveTorrents() const
@ -1795,18 +1795,18 @@ void Session::banIP(const QString &ip)
// Delete a torrent from the session, given its hash // Delete a torrent from the session, given its hash
// and from the disk, if the corresponding deleteOption is chosen // and from the disk, if the corresponding deleteOption is chosen
bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOption) bool Session::deleteTorrent(const TorrentID &id, const DeleteOption deleteOption)
{ {
TorrentImpl *const torrent = m_torrents.take(hash); TorrentImpl *const torrent = m_torrents.take(id);
if (!torrent) return false; if (!torrent) return false;
qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash().toString())); qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrent->id().toString()));
emit torrentAboutToBeRemoved(torrent); emit torrentAboutToBeRemoved(torrent);
// Remove it from session // Remove it from session
if (deleteOption == DeleteTorrent) if (deleteOption == DeleteTorrent)
{ {
m_removingTorrents[torrent->hash()] = {torrent->name(), "", deleteOption}; m_removingTorrents[torrent->id()] = {torrent->name(), "", deleteOption};
const lt::torrent_handle nativeHandle {torrent->nativeHandle()}; const lt::torrent_handle nativeHandle {torrent->nativeHandle()};
const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end() const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end()
@ -1835,7 +1835,7 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
rootPath = torrent->actualStorageLocation(); rootPath = torrent->actualStorageLocation();
} }
m_removingTorrents[torrent->hash()] = {torrent->name(), rootPath, deleteOption}; m_removingTorrents[torrent->id()] = {torrent->name(), rootPath, deleteOption};
if (m_moveStorageQueue.size() > 1) if (m_moveStorageQueue.size() > 1)
{ {
@ -1854,8 +1854,8 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
} }
// Remove it from torrent resume directory // Remove it from torrent resume directory
const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->hash().toString()); const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->id().toString());
const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->hash().toString()); const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->id().toString());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(m_resumeDataSavingManager, [this, resumedataFile, metadataFile]() QMetaObject::invokeMethod(m_resumeDataSavingManager, [this, resumedataFile, metadataFile]()
{ {
@ -1871,19 +1871,19 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio
return true; return true;
} }
bool Session::cancelDownloadMetadata(const InfoHash &hash) bool Session::cancelDownloadMetadata(const TorrentID &id)
{ {
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash); const auto downloadedMetadataIter = m_downloadedMetadata.find(id);
if (downloadedMetadataIter == m_downloadedMetadata.end()) return false; if (downloadedMetadataIter == m_downloadedMetadata.end()) return false;
m_downloadedMetadata.erase(downloadedMetadataIter); m_downloadedMetadata.erase(downloadedMetadataIter);
--m_extraLimit; --m_extraLimit;
adjustLimits(); adjustLimits();
m_nativeSession->remove_torrent(m_nativeSession->find_torrent(hash), lt::session::delete_files); m_nativeSession->remove_torrent(m_nativeSession->find_torrent(id), lt::session::delete_files);
return true; return true;
} }
void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes) void Session::increaseTorrentsQueuePos(const QVector<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType std::priority_queue<ElementType
@ -1891,9 +1891,9 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
, std::greater<ElementType>> torrentQueue; , std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash &infoHash : hashes) for (const TorrentID &id : ids)
{ {
const TorrentImpl *torrent = m_torrents.value(infoHash); const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue; if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0) if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent); torrentQueue.emplace(position, torrent);
@ -1910,15 +1910,15 @@ void Session::increaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes) void Session::decreaseTorrentsQueuePos(const QVector<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType> torrentQueue; std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash &infoHash : hashes) for (const TorrentID &id : ids)
{ {
const TorrentImpl *torrent = m_torrents.value(infoHash); const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue; if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0) if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent); torrentQueue.emplace(position, torrent);
@ -1938,15 +1938,15 @@ void Session::decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes) void Session::topTorrentsQueuePos(const QVector<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType> torrentQueue; std::priority_queue<ElementType> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash &infoHash : hashes) for (const TorrentID &id : ids)
{ {
const TorrentImpl *torrent = m_torrents.value(infoHash); const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue; if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0) if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent); torrentQueue.emplace(position, torrent);
@ -1963,7 +1963,7 @@ void Session::topTorrentsQueuePos(const QVector<InfoHash> &hashes)
saveTorrentsQueue(); saveTorrentsQueue();
} }
void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes) void Session::bottomTorrentsQueuePos(const QVector<TorrentID> &ids)
{ {
using ElementType = std::pair<int, const TorrentImpl *>; using ElementType = std::pair<int, const TorrentImpl *>;
std::priority_queue<ElementType std::priority_queue<ElementType
@ -1971,9 +1971,9 @@ void Session::bottomTorrentsQueuePos(const QVector<InfoHash> &hashes)
, std::greater<ElementType>> torrentQueue; , std::greater<ElementType>> torrentQueue;
// Sort torrents by queue position // Sort torrents by queue position
for (const InfoHash &infoHash : hashes) for (const TorrentID &id : ids)
{ {
const TorrentImpl *torrent = m_torrents.value(infoHash); const TorrentImpl *torrent = m_torrents.value(id);
if (!torrent) continue; if (!torrent) continue;
if (const int position = torrent->queuePosition(); position >= 0) if (const int position = torrent->queuePosition(); position >= 0)
torrentQueue.emplace(position, torrent); torrentQueue.emplace(position, torrent);
@ -2088,20 +2088,20 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
const bool hasMetadata = std::holds_alternative<TorrentInfo>(source); const bool hasMetadata = std::holds_alternative<TorrentInfo>(source);
TorrentInfo metadata = (hasMetadata ? std::get<TorrentInfo>(source) : TorrentInfo {}); TorrentInfo metadata = (hasMetadata ? std::get<TorrentInfo>(source) : TorrentInfo {});
const MagnetUri &magnetUri = (hasMetadata ? MagnetUri {} : std::get<MagnetUri>(source)); const MagnetUri &magnetUri = (hasMetadata ? MagnetUri {} : std::get<MagnetUri>(source));
const InfoHash hash = (hasMetadata ? metadata.hash() : magnetUri.hash()); const auto id = TorrentID::fromInfoHash(hasMetadata ? metadata.infoHash() : magnetUri.infoHash());
// It looks illogical that we don't just use an existing handle, // It looks illogical that we don't just use an existing handle,
// but as previous experience has shown, it actually creates unnecessary // but as previous experience has shown, it actually creates unnecessary
// problems and unwanted behavior due to the fact that it was originally // problems and unwanted behavior due to the fact that it was originally
// added with parameters other than those provided by the user. // added with parameters other than those provided by the user.
cancelDownloadMetadata(hash); cancelDownloadMetadata(id);
// We should not add the torrent if it is already // We should not add the torrent if it is already
// processed or is pending to add to session // processed or is pending to add to session
if (m_loadingTorrents.contains(hash)) if (m_loadingTorrents.contains(id))
return false; return false;
TorrentImpl *const torrent = m_torrents.value(hash); TorrentImpl *const torrent = m_torrents.value(id);
if (torrent) if (torrent)
{ // a duplicate torrent is added { // a duplicate torrent is added
if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate())) if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate()))
@ -2192,7 +2192,7 @@ bool Session::addTorrent_impl(const std::variant<MagnetUri, TorrentInfo> &source
if (!isFindingIncompleteFiles) if (!isFindingIncompleteFiles)
return loadTorrent(loadTorrentParams); return loadTorrent(loadTorrentParams);
m_loadingTorrents.insert(hash, loadTorrentParams); m_loadingTorrents.insert(id, loadTorrentParams);
return true; return true;
} }
@ -2209,8 +2209,12 @@ bool Session::loadTorrent(LoadTorrentParams params)
p.max_uploads = maxUploadsPerTorrent(); p.max_uploads = maxUploadsPerTorrent();
const bool hasMetadata = (p.ti && p.ti->is_valid()); const bool hasMetadata = (p.ti && p.ti->is_valid());
const InfoHash hash = (hasMetadata ? p.ti->info_hash() : p.info_hash); #if (LIBTORRENT_VERSION_NUM >= 20000)
m_loadingTorrents.insert(hash, params); const auto id = TorrentID::fromInfoHash(hasMetadata ? p.ti->info_hashes() : p.info_hashes);
#else
const auto id = TorrentID::fromInfoHash(hasMetadata ? p.ti->info_hash() : p.info_hash);
#endif
m_loadingTorrents.insert(id, params);
// Adding torrent to BitTorrent session // Adding torrent to BitTorrent session
m_nativeSession->async_add_torrent(p); m_nativeSession->async_add_torrent(p);
@ -2220,7 +2224,7 @@ bool Session::loadTorrent(LoadTorrentParams params)
void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString &savePath) const
{ {
const InfoHash searchId = torrentInfo.hash(); const auto searchId = TorrentID::fromInfoHash(torrentInfo.infoHash());
const QStringList originalFileNames = torrentInfo.filePaths(); const QStringList originalFileNames = torrentInfo.filePaths();
const QString completeSavePath = savePath; const QString completeSavePath = savePath;
const QString incompleteSavePath = (isTempPathEnabled() ? torrentTempPath(torrentInfo) : QString {}); const QString incompleteSavePath = (isTempPathEnabled() ? torrentTempPath(torrentInfo) : QString {});
@ -2231,7 +2235,7 @@ void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString
}); });
#else #else
QMetaObject::invokeMethod(m_fileSearcher, "search" QMetaObject::invokeMethod(m_fileSearcher, "search"
, Q_ARG(BitTorrent::InfoHash, searchId), Q_ARG(QStringList, originalFileNames) , Q_ARG(BitTorrent::TorrentID, searchId), Q_ARG(QStringList, originalFileNames)
, Q_ARG(QString, completeSavePath), Q_ARG(QString, incompleteSavePath)); , Q_ARG(QString, completeSavePath), Q_ARG(QString, incompleteSavePath));
#endif #endif
} }
@ -2242,17 +2246,17 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri)
{ {
if (!magnetUri.isValid()) return false; if (!magnetUri.isValid()) return false;
const InfoHash hash = magnetUri.hash(); const auto id = TorrentID::fromInfoHash(magnetUri.infoHash());
const QString name = magnetUri.name(); const QString name = magnetUri.name();
// We should not add torrent if it's already // We should not add torrent if it's already
// processed or adding to session // processed or adding to session
if (m_torrents.contains(hash)) return false; if (m_torrents.contains(id)) return false;
if (m_loadingTorrents.contains(hash)) return false; if (m_loadingTorrents.contains(id)) return false;
if (m_downloadedMetadata.contains(hash)) return false; if (m_downloadedMetadata.contains(id)) return false;
qDebug("Adding torrent to preload metadata..."); qDebug("Adding torrent to preload metadata...");
qDebug(" -> Hash: %s", qUtf8Printable(hash.toString())); qDebug(" -> Torrent ID: %s", qUtf8Printable(id.toString()));
qDebug(" -> Name: %s", qUtf8Printable(name)); qDebug(" -> Name: %s", qUtf8Printable(name));
lt::add_torrent_params p = magnetUri.addTorrentParams(); lt::add_torrent_params p = magnetUri.addTorrentParams();
@ -2268,7 +2272,7 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri)
p.max_connections = maxConnectionsPerTorrent(); p.max_connections = maxConnectionsPerTorrent();
p.max_uploads = maxUploadsPerTorrent(); p.max_uploads = maxUploadsPerTorrent();
const QString savePath = Utils::Fs::tempPath() + hash.toString(); const QString savePath = Utils::Fs::tempPath() + id.toString();
p.save_path = Utils::Fs::toNativePath(savePath).toStdString(); p.save_path = Utils::Fs::toNativePath(savePath).toStdString();
// Forced start // Forced start
@ -2301,7 +2305,7 @@ void Session::exportTorrentFile(const Torrent *torrent, TorrentExportFolder fold
((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty())); ((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty()));
const QString validName = Utils::Fs::toValidFileSystemName(torrent->name()); const QString validName = Utils::Fs::toValidFileSystemName(torrent->name());
const QString torrentFilename = QString::fromLatin1("%1.torrent").arg(torrent->hash().toString()); const QString torrentFilename = QString::fromLatin1("%1.torrent").arg(torrent->id().toString());
QString torrentExportFilename = QString::fromLatin1("%1.torrent").arg(validName); QString torrentExportFilename = QString::fromLatin1("%1.torrent").arg(validName);
const QString torrentPath = QDir(m_resumeFolderPath).absoluteFilePath(torrentFilename); const QString torrentPath = QDir(m_resumeFolderPath).absoluteFilePath(torrentFilename);
const QDir exportPath(folder == TorrentExportFolder::Regular ? torrentExportDirectory() : finishedTorrentExportDirectory()); const QDir exportPath(folder == TorrentExportFolder::Regular ? torrentExportDirectory() : finishedTorrentExportDirectory());
@ -2374,13 +2378,13 @@ void Session::saveTorrentsQueue() const
// We require actual (non-cached) queue position here! // We require actual (non-cached) queue position here!
const int queuePos = static_cast<LTUnderlyingType<lt::queue_position_t>>(torrent->nativeHandle().queue_position()); const int queuePos = static_cast<LTUnderlyingType<lt::queue_position_t>>(torrent->nativeHandle().queue_position());
if (queuePos >= 0) if (queuePos >= 0)
queue[queuePos] = torrent->hash().toString(); queue[queuePos] = torrent->id().toString();
} }
QByteArray data; QByteArray data;
data.reserve(((InfoHash::length() * 2) + 1) * queue.size()); data.reserve(((TorrentID::length() * 2) + 1) * queue.size());
for (const QString &hash : asConst(queue)) for (const QString &torrentID : asConst(queue))
data += (hash.toLatin1() + '\n'); data += (torrentID.toLatin1() + '\n');
const QString filename = QLatin1String {"queue"}; const QString filename = QLatin1String {"queue"};
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
@ -3758,11 +3762,11 @@ void Session::setMaxRatioAction(const MaxRatioAction act)
// If this functions returns true, we cannot add torrent to session, // If this functions returns true, we cannot add torrent to session,
// but it is still possible to merge trackers in some cases // but it is still possible to merge trackers in some cases
bool Session::isKnownTorrent(const InfoHash &hash) const bool Session::isKnownTorrent(const TorrentID &id) const
{ {
return (m_torrents.contains(hash) return (m_torrents.contains(id)
|| m_loadingTorrents.contains(hash) || m_loadingTorrents.contains(id)
|| m_downloadedMetadata.contains(hash)); || m_downloadedMetadata.contains(id));
} }
void Session::updateSeedingLimitTimer() void Session::updateSeedingLimitTimer()
@ -3868,7 +3872,7 @@ void Session::handleTorrentMetadataReceived(TorrentImpl *const torrent)
{ {
// Save metadata // Save metadata
const QDir resumeDataDir {m_resumeFolderPath}; const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash().toString())}; const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->id().toString())};
try try
{ {
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName)); torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
@ -3948,7 +3952,7 @@ void Session::handleTorrentResumeDataReady(TorrentImpl *const torrent, const std
// Separated thread is used for the blocking IO which results in slow processing of many torrents. // Separated thread is used for the blocking IO which results in slow processing of many torrents.
// Copying lt::entry objects around isn't cheap. // Copying lt::entry objects around isn't cheap.
const QString filename = QString::fromLatin1("%1.fastresume").arg(torrent->hash().toString()); const QString filename = QString::fromLatin1("%1.fastresume").arg(torrent->id().toString());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
QMetaObject::invokeMethod(m_resumeDataSavingManager QMetaObject::invokeMethod(m_resumeDataSavingManager
, [this, filename, data]() { m_resumeDataSavingManager->save(filename, data); }); , [this, filename, data]() { m_resumeDataSavingManager->save(filename, data); });
@ -4024,9 +4028,13 @@ bool Session::addMoveTorrentStorageJob(TorrentImpl *torrent, const QString &newP
void Session::moveTorrentStorage(const MoveStorageJob &job) const void Session::moveTorrentStorage(const MoveStorageJob &job) const
{ {
const InfoHash infoHash = job.torrentHandle.info_hash(); #if (LIBTORRENT_VERSION_NUM >= 20000)
const TorrentImpl *torrent = m_torrents.value(infoHash); const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hashes());
const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); #else
const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hash());
#endif
const TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
LogMsg(tr("Moving \"%1\" to \"%2\"...").arg(torrentName, job.path)); LogMsg(tr("Moving \"%1\" to \"%2\"...").arg(torrentName, job.path));
job.torrentHandle.move_storage(job.path.toUtf8().constData() job.torrentHandle.move_storage(job.path.toUtf8().constData()
@ -4157,9 +4165,9 @@ void Session::disableIPFilter()
m_nativeSession->set_ip_filter(filter); m_nativeSession->set_ip_filter(filter);
} }
void Session::recursiveTorrentDownload(const InfoHash &hash) void Session::recursiveTorrentDownload(const TorrentID &id)
{ {
TorrentImpl *const torrent = m_torrents.value(hash); TorrentImpl *const torrent = m_torrents.value(id);
if (!torrent) return; if (!torrent) return;
for (int i = 0; i < torrent->filesCount(); ++i) for (int i = 0; i < torrent->filesCount(); ++i)
@ -4584,7 +4592,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
const LoadTorrentParams params = m_loadingTorrents.take(nativeHandle.info_hash()); const LoadTorrentParams params = m_loadingTorrents.take(nativeHandle.info_hash());
auto *const torrent = new TorrentImpl {this, m_nativeSession, nativeHandle, params}; auto *const torrent = new TorrentImpl {this, m_nativeSession, nativeHandle, params};
m_torrents.insert(torrent->hash(), torrent); m_torrents.insert(torrent->id(), torrent);
const bool hasMetadata = torrent->hasMetadata(); const bool hasMetadata = torrent->hasMetadata();
@ -4599,7 +4607,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle)
{ {
// Backup torrent file // Backup torrent file
const QDir resumeDataDir {m_resumeFolderPath}; const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString::fromLatin1("%1.torrent").arg(torrent->hash().toString())}; const QString torrentFileName {QString::fromLatin1("%1.torrent").arg(torrent->id().toString())};
try try
{ {
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName)); torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
@ -4657,9 +4665,13 @@ void Session::handleAddTorrentAlert(const lt::add_torrent_alert *p)
void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p) void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
{ {
const InfoHash infoHash {p->info_hash}; #if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter != m_removingTorrents.end()) if (removingTorrentDataIter != m_removingTorrents.end())
{ {
if (removingTorrentDataIter->deleteOption == DeleteTorrent) if (removingTorrentDataIter->deleteOption == DeleteTorrent)
@ -4672,8 +4684,13 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p)
void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p) void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p)
{ {
const InfoHash infoHash {p->info_hash}; #if (LIBTORRENT_VERSION_NUM >= 20000)
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter == m_removingTorrents.end()) if (removingTorrentDataIter == m_removingTorrents.end())
return; return;
@ -4685,8 +4702,13 @@ void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p)
void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p) void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p)
{ {
const InfoHash infoHash {p->info_hash}; #if (LIBTORRENT_VERSION_NUM >= 20000)
const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); const auto id = TorrentID::fromInfoHash(p->info_hashes);
#else
const auto id = TorrentID::fromInfoHash(p->info_hash);
#endif
const auto removingTorrentDataIter = m_removingTorrents.find(id);
if (removingTorrentDataIter == m_removingTorrents.end()) if (removingTorrentDataIter == m_removingTorrents.end())
return; return;
@ -4710,8 +4732,13 @@ void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_ale
void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p) void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p)
{ {
const InfoHash hash {p->handle.info_hash()}; #if (LIBTORRENT_VERSION_NUM >= 20000)
const auto downloadedMetadataIter = m_downloadedMetadata.find(hash); const auto id = TorrentID::fromInfoHash(p->handle.info_hashes());
#else
const auto id = TorrentID::fromInfoHash(p->handle.info_hash());
#endif
const auto downloadedMetadataIter = m_downloadedMetadata.find(id);
if (downloadedMetadataIter != m_downloadedMetadata.end()) if (downloadedMetadataIter != m_downloadedMetadata.end())
{ {
@ -4732,11 +4759,11 @@ void Session::handleFileErrorAlert(const lt::file_error_alert *p)
if (!torrent) if (!torrent)
return; return;
const InfoHash hash = torrent->hash(); const TorrentID id = torrent->id();
if (!m_recentErroredTorrents.contains(hash)) if (!m_recentErroredTorrents.contains(id))
{ {
m_recentErroredTorrents.insert(hash); m_recentErroredTorrents.insert(id);
const QString msg = QString::fromStdString(p->message()); const QString msg = QString::fromStdString(p->message());
LogMsg(tr("File error alert. Torrent: \"%1\". File: \"%2\". Reason: %3") LogMsg(tr("File error alert. Torrent: \"%1\". File: \"%2\". Reason: %3")
@ -4935,9 +4962,14 @@ void Session::handleStorageMovedAlert(const lt::storage_moved_alert *p)
const QString newPath {p->storage_path()}; const QString newPath {p->storage_path()};
Q_ASSERT(newPath == currentJob.path); Q_ASSERT(newPath == currentJob.path);
const InfoHash infoHash = currentJob.torrentHandle.info_hash(); #if (LIBTORRENT_VERSION_NUM >= 20000)
TorrentImpl *torrent = m_torrents.value(infoHash); const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes());
const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); #else
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash());
#endif
TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
LogMsg(tr("\"%1\" is successfully moved to \"%2\".").arg(torrentName, newPath)); LogMsg(tr("\"%1\" is successfully moved to \"%2\".").arg(torrentName, newPath));
handleMoveTorrentStorageJobFinished(); handleMoveTorrentStorageJobFinished();
@ -4950,9 +4982,14 @@ void Session::handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert
const MoveStorageJob &currentJob = m_moveStorageQueue.first(); const MoveStorageJob &currentJob = m_moveStorageQueue.first();
Q_ASSERT(currentJob.torrentHandle == p->handle); Q_ASSERT(currentJob.torrentHandle == p->handle);
const InfoHash infoHash = currentJob.torrentHandle.info_hash(); #if (LIBTORRENT_VERSION_NUM >= 20000)
TorrentImpl *torrent = m_torrents.value(infoHash); const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes());
const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); #else
const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hash());
#endif
TorrentImpl *torrent = m_torrents.value(id);
const QString torrentName = (torrent ? torrent->name() : id.toString());
const QString currentLocation = QString::fromStdString(p->handle.status(lt::torrent_handle::query_save_path).save_path); const QString currentLocation = QString::fromStdString(p->handle.status(lt::torrent_handle::query_save_path).save_path);
const QString errorMessage = QString::fromStdString(p->message()); const QString errorMessage = QString::fromStdString(p->message());
LogMsg(tr("Failed to move \"%1\" from \"%2\" to \"%3\". Reason: %4.") LogMsg(tr("Failed to move \"%1\" from \"%2\" to \"%3\". Reason: %4.")
@ -4968,8 +5005,12 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
for (const lt::torrent_status &status : p->status) for (const lt::torrent_status &status : p->status)
{ {
TorrentImpl *const torrent = m_torrents.value(status.info_hash); #if (LIBTORRENT_VERSION_NUM >= 20000)
const auto id = TorrentID::fromInfoHash(status.info_hashes);
#else
const auto id = TorrentID::fromInfoHash(status.info_hash);
#endif
TorrentImpl *const torrent = m_torrents.value(id);
if (!torrent) if (!torrent)
continue; continue;

30
src/base/bittorrent/session.h

@ -434,7 +434,7 @@ namespace BitTorrent
#endif #endif
void startUpTorrents(); void startUpTorrents();
Torrent *findTorrent(const InfoHash &hash) const; Torrent *findTorrent(const TorrentID &id) const;
QVector<Torrent *> torrents() const; QVector<Torrent *> torrents() const;
bool hasActiveTorrents() const; bool hasActiveTorrents() const;
bool hasUnfinishedTorrents() const; bool hasUnfinishedTorrents() const;
@ -450,19 +450,19 @@ namespace BitTorrent
void banIP(const QString &ip); void banIP(const QString &ip);
bool isKnownTorrent(const InfoHash &hash) const; bool isKnownTorrent(const TorrentID &id) const;
bool addTorrent(const QString &source, const AddTorrentParams &params = AddTorrentParams()); bool addTorrent(const QString &source, const AddTorrentParams &params = AddTorrentParams());
bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &params = AddTorrentParams()); bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams &params = AddTorrentParams());
bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams &params = AddTorrentParams()); bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams &params = AddTorrentParams());
bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = DeleteTorrent); bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent);
bool downloadMetadata(const MagnetUri &magnetUri); bool downloadMetadata(const MagnetUri &magnetUri);
bool cancelDownloadMetadata(const InfoHash &hash); bool cancelDownloadMetadata(const TorrentID &id);
void recursiveTorrentDownload(const InfoHash &hash); void recursiveTorrentDownload(const TorrentID &id);
void increaseTorrentsQueuePos(const QVector<InfoHash> &hashes); void increaseTorrentsQueuePos(const QVector<TorrentID> &ids);
void decreaseTorrentsQueuePos(const QVector<InfoHash> &hashes); void decreaseTorrentsQueuePos(const QVector<TorrentID> &ids);
void topTorrentsQueuePos(const QVector<InfoHash> &hashes); void topTorrentsQueuePos(const QVector<TorrentID> &ids);
void bottomTorrentsQueuePos(const QVector<InfoHash> &hashes); void bottomTorrentsQueuePos(const QVector<TorrentID> &ids);
// Torrent interface // Torrent interface
void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent); void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent);
@ -539,7 +539,7 @@ namespace BitTorrent
void handleIPFilterParsed(int ruleCount); void handleIPFilterParsed(int ruleCount);
void handleIPFilterError(); void handleIPFilterError();
void handleDownloadFinished(const Net::DownloadResult &result); void handleDownloadFinished(const Net::DownloadResult &result);
void fileSearchFinished(const InfoHash &id, const QString &savePath, const QStringList &fileNames); void fileSearchFinished(const TorrentID &id, const QString &savePath, const QStringList &fileNames);
// Session reconfiguration triggers // Session reconfiguration triggers
void networkOnlineStateChanged(bool online); void networkOnlineStateChanged(bool online);
@ -764,17 +764,17 @@ namespace BitTorrent
ResumeDataSavingManager *m_resumeDataSavingManager = nullptr; ResumeDataSavingManager *m_resumeDataSavingManager = nullptr;
FileSearcher *m_fileSearcher = nullptr; FileSearcher *m_fileSearcher = nullptr;
QSet<InfoHash> m_downloadedMetadata; QSet<TorrentID> m_downloadedMetadata;
QHash<InfoHash, TorrentImpl *> m_torrents; QHash<TorrentID, TorrentImpl *> m_torrents;
QHash<InfoHash, LoadTorrentParams> m_loadingTorrents; QHash<TorrentID, LoadTorrentParams> m_loadingTorrents;
QHash<QString, AddTorrentParams> m_downloadedTorrents; QHash<QString, AddTorrentParams> m_downloadedTorrents;
QHash<InfoHash, RemovingTorrentData> m_removingTorrents; QHash<TorrentID, RemovingTorrentData> m_removingTorrents;
QStringMap m_categories; QStringMap m_categories;
QSet<QString> m_tags; QSet<QString> m_tags;
// I/O errored torrents // I/O errored torrents
QSet<InfoHash> m_recentErroredTorrents; QSet<TorrentID> m_recentErroredTorrents;
QTimer *m_recentErroredTorrentsTimer = nullptr; QTimer *m_recentErroredTorrentsTimer = nullptr;
SessionMetricIndices m_metricIndices; SessionMetricIndices m_metricIndices;

7
src/base/bittorrent/torrent.cpp

@ -31,6 +31,8 @@
#include <QHash> #include <QHash>
#include "infohash.h"
namespace BitTorrent namespace BitTorrent
{ {
uint qHash(const TorrentState key, const uint seed) uint qHash(const TorrentState key, const uint seed)
@ -49,6 +51,11 @@ namespace BitTorrent
const qreal Torrent::MAX_RATIO = 9999; const qreal Torrent::MAX_RATIO = 9999;
const int Torrent::MAX_SEEDING_TIME = 525600; const int Torrent::MAX_SEEDING_TIME = 525600;
TorrentID Torrent::id() const
{
return infoHash().toTorrentID();
}
bool Torrent::isResumed() const bool Torrent::isResumed() const
{ {
return !isPaused(); return !isPaused();

4
src/base/bittorrent/torrent.h

@ -44,6 +44,7 @@ namespace BitTorrent
enum class DownloadPriority; enum class DownloadPriority;
class InfoHash; class InfoHash;
class PeerInfo; class PeerInfo;
class TorrentID;
class TorrentInfo; class TorrentInfo;
struct PeerAddress; struct PeerAddress;
struct TrackerEntry; struct TrackerEntry;
@ -105,7 +106,7 @@ namespace BitTorrent
virtual ~Torrent() = default; virtual ~Torrent() = default;
virtual InfoHash hash() const = 0; virtual InfoHash infoHash() const = 0;
virtual QString name() const = 0; virtual QString name() const = 0;
virtual QDateTime creationDate() const = 0; virtual QDateTime creationDate() const = 0;
virtual QString creator() const = 0; virtual QString creator() const = 0;
@ -290,6 +291,7 @@ namespace BitTorrent
virtual QString createMagnetURI() const = 0; virtual QString createMagnetURI() const = 0;
TorrentID id() const;
bool isResumed() const; bool isResumed() const;
qlonglong remainingSize() const; qlonglong remainingSize() const;

12
src/base/bittorrent/torrentimpl.cpp

@ -220,6 +220,11 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
, m_session(session) , m_session(session)
, m_nativeSession(nativeSession) , m_nativeSession(nativeSession)
, m_nativeHandle(nativeHandle) , m_nativeHandle(nativeHandle)
#if (LIBTORRENT_VERSION_NUM >= 20000)
, m_infoHash(m_nativeHandle.info_hashes())
#else
, m_infoHash(m_nativeHandle.info_hash())
#endif
, m_name(params.name) , m_name(params.name)
, m_savePath(Utils::Fs::toNativePath(params.savePath)) , m_savePath(Utils::Fs::toNativePath(params.savePath))
, m_category(params.category) , m_category(params.category)
@ -237,7 +242,6 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
if (m_useAutoTMM) if (m_useAutoTMM)
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category)); m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
m_hash = InfoHash {m_nativeHandle.info_hash()};
if (m_ltAddTorrentParams.ti) if (m_ltAddTorrentParams.ti)
{ {
// Initialize it only if torrent is added with metadata. // Initialize it only if torrent is added with metadata.
@ -282,9 +286,9 @@ bool TorrentImpl::isValid() const
return m_nativeHandle.is_valid(); return m_nativeHandle.is_valid();
} }
InfoHash TorrentImpl::hash() const InfoHash TorrentImpl::infoHash() const
{ {
return m_hash; return m_infoHash;
} }
QString TorrentImpl::name() const QString TorrentImpl::name() const
@ -299,7 +303,7 @@ QString TorrentImpl::name() const
if (!name.isEmpty()) if (!name.isEmpty())
return name; return name;
return m_hash.toString(); return id().toString();
} }
QDateTime TorrentImpl::creationDate() const QDateTime TorrentImpl::creationDate() const

4
src/base/bittorrent/torrentimpl.h

@ -99,7 +99,7 @@ namespace BitTorrent
bool isValid() const; bool isValid() const;
InfoHash hash() const override; InfoHash infoHash() const override;
QString name() const override; QString name() const override;
QDateTime creationDate() const override; QDateTime creationDate() const override;
QString creator() const override; QString creator() const override;
@ -301,7 +301,7 @@ namespace BitTorrent
TorrentInfo m_torrentInfo; TorrentInfo m_torrentInfo;
SpeedMonitor m_speedMonitor; SpeedMonitor m_speedMonitor;
InfoHash m_hash; InfoHash m_infoHash;
// m_moveFinishedTriggers is activated only when the following conditions are met: // m_moveFinishedTriggers is activated only when the following conditions are met:
// all file rename jobs complete, all file move jobs complete // all file rename jobs complete, all file move jobs complete

9
src/base/bittorrent/torrentinfo.cpp

@ -184,10 +184,15 @@ bool TorrentInfo::isValid() const
return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0)); return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0));
} }
InfoHash TorrentInfo::hash() const InfoHash TorrentInfo::infoHash() const
{ {
if (!isValid()) return {}; if (!isValid()) return {};
#if (LIBTORRENT_VERSION_NUM >= 20000)
return m_nativeInfo->info_hashes();
#else
return m_nativeInfo->info_hash(); return m_nativeInfo->info_hash();
#endif
} }
QString TorrentInfo::name() const QString TorrentInfo::name() const
@ -374,7 +379,7 @@ QVector<QByteArray> TorrentInfo::pieceHashes() const
hashes.reserve(count); hashes.reserve(count);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
hashes += {m_nativeInfo->hash_for_piece_ptr(lt::piece_index_t {i}), InfoHash::length()}; hashes += {m_nativeInfo->hash_for_piece_ptr(lt::piece_index_t {i}), SHA1Hash::length()};
return hashes; return hashes;
} }

2
src/base/bittorrent/torrentinfo.h

@ -62,7 +62,7 @@ namespace BitTorrent
TorrentInfo &operator=(const TorrentInfo &other); TorrentInfo &operator=(const TorrentInfo &other);
bool isValid() const; bool isValid() const;
InfoHash hash() const; InfoHash infoHash() const;
QString name() const; QString name() const;
QDateTime creationDate() const; QDateTime creationDate() const;
QString creator() const; QString creator() const;

16
src/base/bittorrent/tracker.cpp

@ -153,7 +153,7 @@ struct Tracker::TrackerAnnounceRequest
{ {
QHostAddress socketAddress; QHostAddress socketAddress;
QByteArray claimedAddress; // self claimed by peer QByteArray claimedAddress; // self claimed by peer
InfoHash infoHash; TorrentID torrentID;
QString event; QString event;
Peer peer; Peer peer;
int numwant = 50; int numwant = 50;
@ -295,11 +295,11 @@ void Tracker::processAnnounceRequest()
if (infoHashIter == queryParams.end()) if (infoHashIter == queryParams.end())
throw TrackerError("Missing \"info_hash\" parameter"); throw TrackerError("Missing \"info_hash\" parameter");
const auto infoHash = InfoHash::fromString(infoHashIter->toHex()); const auto torrentID = TorrentID::fromString(infoHashIter->toHex());
if (!infoHash.isValid()) if (!torrentID.isValid())
throw TrackerError("Invalid \"info_hash\" parameter"); throw TrackerError("Invalid \"info_hash\" parameter");
announceReq.infoHash = infoHash; announceReq.torrentID = torrentID;
// 2. peer_id // 2. peer_id
const auto peerIdIter = queryParams.find(ANNOUNCE_REQUEST_PEER_ID); const auto peerIdIter = queryParams.find(ANNOUNCE_REQUEST_PEER_ID);
@ -381,19 +381,19 @@ void Tracker::processAnnounceRequest()
void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq) void Tracker::registerPeer(const TrackerAnnounceRequest &announceReq)
{ {
if (!m_torrents.contains(announceReq.infoHash)) if (!m_torrents.contains(announceReq.torrentID))
{ {
// Reached max size, remove a random torrent // Reached max size, remove a random torrent
if (m_torrents.size() >= MAX_TORRENTS) if (m_torrents.size() >= MAX_TORRENTS)
m_torrents.erase(m_torrents.begin()); m_torrents.erase(m_torrents.begin());
} }
m_torrents[announceReq.infoHash].setPeer(announceReq.peer); m_torrents[announceReq.torrentID].setPeer(announceReq.peer);
} }
void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq) void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
{ {
const auto torrentStatsIter = m_torrents.find(announceReq.infoHash); const auto torrentStatsIter = m_torrents.find(announceReq.torrentID);
if (torrentStatsIter == m_torrents.end()) if (torrentStatsIter == m_torrents.end())
return; return;
@ -405,7 +405,7 @@ void Tracker::unregisterPeer(const TrackerAnnounceRequest &announceReq)
void Tracker::prepareAnnounceResponse(const TrackerAnnounceRequest &announceReq) void Tracker::prepareAnnounceResponse(const TrackerAnnounceRequest &announceReq)
{ {
const TorrentStats &torrentStats = m_torrents[announceReq.infoHash]; const TorrentStats &torrentStats = m_torrents[announceReq.torrentID];
lt::entry::dictionary_type replyDict lt::entry::dictionary_type replyDict
{ {

2
src/base/bittorrent/tracker.h

@ -102,6 +102,6 @@ namespace BitTorrent
Http::Request m_request; Http::Request m_request;
Http::Environment m_env; Http::Environment m_env;
QHash<InfoHash, TorrentStats> m_torrents; QHash<TorrentID, TorrentStats> m_torrents;
}; };
} }

20
src/base/torrentfilter.cpp

@ -32,7 +32,7 @@
#include "bittorrent/torrent.h" #include "bittorrent/torrent.h"
const QString TorrentFilter::AnyCategory; const QString TorrentFilter::AnyCategory;
const InfoHashSet TorrentFilter::AnyHash {{}}; const TorrentIDSet TorrentFilter::AnyID {{}};
const QString TorrentFilter::AnyTag; const QString TorrentFilter::AnyTag;
const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading); const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading);
@ -49,19 +49,19 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored);
using BitTorrent::Torrent; using BitTorrent::Torrent;
TorrentFilter::TorrentFilter(const Type type, const InfoHashSet &hashSet, const QString &category, const QString &tag) TorrentFilter::TorrentFilter(const Type type, const TorrentIDSet &idSet, const QString &category, const QString &tag)
: m_type(type) : m_type(type)
, m_category(category) , m_category(category)
, m_tag(tag) , m_tag(tag)
, m_hashSet(hashSet) , m_idSet(idSet)
{ {
} }
TorrentFilter::TorrentFilter(const QString &filter, const InfoHashSet &hashSet, const QString &category, const QString &tag) TorrentFilter::TorrentFilter(const QString &filter, const TorrentIDSet &idSet, const QString &category, const QString &tag)
: m_type(All) : m_type(All)
, m_category(category) , m_category(category)
, m_tag(tag) , m_tag(tag)
, m_hashSet(hashSet) , m_idSet(idSet)
{ {
setTypeByName(filter); setTypeByName(filter);
} }
@ -107,11 +107,11 @@ bool TorrentFilter::setTypeByName(const QString &filter)
return setType(type); return setType(type);
} }
bool TorrentFilter::setHashSet(const InfoHashSet &hashSet) bool TorrentFilter::setTorrentIDSet(const TorrentIDSet &idSet)
{ {
if (m_hashSet != hashSet) if (m_idSet != idSet)
{ {
m_hashSet = hashSet; m_idSet = idSet;
return true; return true;
} }
@ -189,9 +189,9 @@ bool TorrentFilter::matchState(const BitTorrent::Torrent *const torrent) const
bool TorrentFilter::matchHash(const BitTorrent::Torrent *const torrent) const bool TorrentFilter::matchHash(const BitTorrent::Torrent *const torrent) const
{ {
if (m_hashSet == AnyHash) return true; if (m_idSet == AnyID) return true;
return m_hashSet.contains(torrent->hash()); return m_idSet.contains(torrent->id());
} }
bool TorrentFilter::matchCategory(const BitTorrent::Torrent *const torrent) const bool TorrentFilter::matchCategory(const BitTorrent::Torrent *const torrent) const

12
src/base/torrentfilter.h

@ -38,7 +38,7 @@ namespace BitTorrent
class Torrent; class Torrent;
} }
using InfoHashSet = QSet<BitTorrent::InfoHash>; using TorrentIDSet = QSet<BitTorrent::TorrentID>;
class TorrentFilter class TorrentFilter
{ {
@ -61,7 +61,7 @@ public:
// These mean any permutation, including no category / tag. // These mean any permutation, including no category / tag.
static const QString AnyCategory; static const QString AnyCategory;
static const InfoHashSet AnyHash; static const TorrentIDSet AnyID;
static const QString AnyTag; static const QString AnyTag;
static const TorrentFilter DownloadingTorrent; static const TorrentFilter DownloadingTorrent;
@ -79,12 +79,12 @@ public:
TorrentFilter() = default; TorrentFilter() = default;
// category & tags: pass empty string for uncategorized / untagged torrents. // category & tags: pass empty string for uncategorized / untagged torrents.
// Pass null string (QString()) to disable filtering (i.e. all torrents). // Pass null string (QString()) to disable filtering (i.e. all torrents).
TorrentFilter(Type type, const InfoHashSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tag = AnyTag); TorrentFilter(Type type, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tag = AnyTag);
TorrentFilter(const QString &filter, const InfoHashSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tags = AnyTag); TorrentFilter(const QString &filter, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tags = AnyTag);
bool setType(Type type); bool setType(Type type);
bool setTypeByName(const QString &filter); bool setTypeByName(const QString &filter);
bool setHashSet(const InfoHashSet &hashSet); bool setTorrentIDSet(const TorrentIDSet &idSet);
bool setCategory(const QString &category); bool setCategory(const QString &category);
bool setTag(const QString &tag); bool setTag(const QString &tag);
@ -99,5 +99,5 @@ private:
Type m_type {All}; Type m_type {All};
QString m_category; QString m_category;
QString m_tag; QString m_tag;
InfoHashSet m_hashSet; TorrentIDSet m_idSet;
}; };

20
src/gui/addnewtorrentdialog.cpp

@ -270,12 +270,12 @@ bool AddNewTorrentDialog::loadTorrentFile(const QString &torrentPath)
bool AddNewTorrentDialog::loadTorrentImpl() bool AddNewTorrentDialog::loadTorrentImpl()
{ {
m_hasMetadata = true; m_hasMetadata = true;
const BitTorrent::InfoHash infoHash = m_torrentInfo.hash(); const auto torrentID = BitTorrent::TorrentID::fromInfoHash(m_torrentInfo.infoHash());
// Prevent showing the dialog if download is already present // Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) if (BitTorrent::Session::instance()->isKnownTorrent(torrentID))
{ {
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(torrentID);
if (torrent) if (torrent)
{ {
if (torrent->isPrivate() || m_torrentInfo.isPrivate()) if (torrent->isPrivate() || m_torrentInfo.isPrivate())
@ -296,7 +296,7 @@ bool AddNewTorrentDialog::loadTorrentImpl()
return false; return false;
} }
m_ui->labelHashData->setText(infoHash.toString()); m_ui->labelHashData->setText(torrentID.toString());
setupTreeview(); setupTreeview();
TMMChanged(m_ui->comboTTM->currentIndex()); TMMChanged(m_ui->comboTTM->currentIndex());
return true; return true;
@ -312,11 +312,11 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
m_torrentGuard = std::make_unique<TorrentFileGuard>(); m_torrentGuard = std::make_unique<TorrentFileGuard>();
const BitTorrent::InfoHash infoHash = magnetUri.hash(); const auto torrentID = BitTorrent::TorrentID::fromInfoHash(magnetUri.infoHash());
// Prevent showing the dialog if download is already present // Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) if (BitTorrent::Session::instance()->isKnownTorrent(torrentID))
{ {
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(torrentID);
if (torrent) if (torrent)
{ {
if (torrent->isPrivate()) if (torrent->isPrivate())
@ -348,7 +348,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
BitTorrent::Session::instance()->downloadMetadata(magnetUri); BitTorrent::Session::instance()->downloadMetadata(magnetUri);
setMetadataProgressIndicator(true, tr("Retrieving metadata...")); setMetadataProgressIndicator(true, tr("Retrieving metadata..."));
m_ui->labelHashData->setText(infoHash.toString()); m_ui->labelHashData->setText(torrentID.toString());
m_magnetURI = magnetUri; m_magnetURI = magnetUri;
return true; return true;
@ -629,7 +629,7 @@ void AddNewTorrentDialog::reject()
if (!m_hasMetadata) if (!m_hasMetadata)
{ {
setMetadataProgressIndicator(false); setMetadataProgressIndicator(false);
BitTorrent::Session::instance()->cancelDownloadMetadata(m_magnetURI.hash()); BitTorrent::Session::instance()->cancelDownloadMetadata(m_magnetURI.infoHash().toTorrentID());
} }
QDialog::reject(); QDialog::reject();
@ -637,7 +637,7 @@ void AddNewTorrentDialog::reject()
void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &metadata) void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &metadata)
{ {
if (metadata.hash() != m_magnetURI.hash()) return; if (metadata.infoHash() != m_magnetURI.infoHash()) return;
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata); disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataDownloaded, this, &AddNewTorrentDialog::updateMetadata);

6
src/gui/mainwindow.cpp

@ -958,7 +958,7 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co
Preferences *const pref = Preferences::instance(); Preferences *const pref = Preferences::instance();
if (pref->recursiveDownloadDisabled()) return; if (pref->recursiveDownloadDisabled()) return;
const auto torrentHash = torrent->hash(); const auto torrentID = torrent->id();
QMessageBox *confirmBox = new QMessageBox(QMessageBox::Question, tr("Recursive download confirmation") QMessageBox *confirmBox = new QMessageBox(QMessageBox::Question, tr("Recursive download confirmation")
, tr("The torrent '%1' contains torrent files, do you want to proceed with their download?").arg(torrent->name()) , tr("The torrent '%1' contains torrent files, do you want to proceed with their download?").arg(torrent->name())
@ -969,10 +969,10 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co
const QPushButton *yes = confirmBox->addButton(tr("Yes"), QMessageBox::YesRole); const QPushButton *yes = confirmBox->addButton(tr("Yes"), QMessageBox::YesRole);
/*QPushButton *no = */ confirmBox->addButton(tr("No"), QMessageBox::NoRole); /*QPushButton *no = */ confirmBox->addButton(tr("No"), QMessageBox::NoRole);
const QPushButton *never = confirmBox->addButton(tr("Never"), QMessageBox::NoRole); const QPushButton *never = confirmBox->addButton(tr("Never"), QMessageBox::NoRole);
connect(confirmBox, &QMessageBox::buttonClicked, this, [torrentHash, yes, never](const QAbstractButton *button) connect(confirmBox, &QMessageBox::buttonClicked, this, [torrentID, yes, never](const QAbstractButton *button)
{ {
if (button == yes) if (button == yes)
BitTorrent::Session::instance()->recursiveTorrentDownload(torrentHash); BitTorrent::Session::instance()->recursiveTorrentDownload(torrentID);
if (button == never) if (button == never)
Preferences::instance()->disableRecursiveDownload(); Preferences::instance()->disableRecursiveDownload();
}); });

5
src/gui/properties/propertieswidget.cpp

@ -312,8 +312,9 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::Torrent *const torrent)
// Save path // Save path
updateSavePath(m_torrent); updateSavePath(m_torrent);
// Hash // Info hash (Truncated info hash (torrent ID) with libtorrent2)
m_ui->labelHashVal->setText(m_torrent->hash().toString()); // TODO: Update label for this property to express its meaning more clearly (or change it to display real info hash(es))
m_ui->labelHashVal->setText(m_torrent->id().toString());
m_propListModel->model()->clear(); m_propListModel->model()->clear();
if (m_torrent->hasMetadata()) if (m_torrent->hasMetadata())
{ {

8
src/gui/torrentoptionsdialog.cpp

@ -77,10 +77,10 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVector<BitTor
const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled(); const bool isFirstTorrentPEXDisabled = torrents[0]->isPEXDisabled();
const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled(); const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled();
m_torrentHashes.reserve(torrents.size()); m_torrentIDs.reserve(torrents.size());
for (const BitTorrent::Torrent *torrent : torrents) for (const BitTorrent::Torrent *torrent : torrents)
{ {
m_torrentHashes << torrent->hash(); m_torrentIDs << torrent->id();
if (allSameUpLimit) if (allSameUpLimit)
{ {
if (qMax(0, torrent->uploadLimit()) != firstTorrentUpLimit) if (qMax(0, torrent->uploadLimit()) != firstTorrentUpLimit)
@ -288,9 +288,9 @@ void TorrentOptionsDialog::accept()
} }
const auto *session = BitTorrent::Session::instance(); const auto *session = BitTorrent::Session::instance();
for (const BitTorrent::InfoHash &hash : asConst(m_torrentHashes)) for (const BitTorrent::TorrentID &id : asConst(m_torrentIDs))
{ {
BitTorrent::Torrent *torrent = session->findTorrent(hash); BitTorrent::Torrent *torrent = session->findTorrent(id);
if (!torrent) continue; if (!torrent) continue;
if (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value()) if (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value())

4
src/gui/torrentoptionsdialog.h

@ -36,8 +36,8 @@
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash;
class Torrent; class Torrent;
class TorrentID;
} }
namespace Ui namespace Ui
@ -67,7 +67,7 @@ private:
qreal getRatio() const; qreal getRatio() const;
int getSeedingTime() const; int getSeedingTime() const;
QVector<BitTorrent::InfoHash> m_torrentHashes; QVector<BitTorrent::TorrentID> m_torrentIDs;
Ui::TorrentOptionsDialog *m_ui; Ui::TorrentOptionsDialog *m_ui;
SettingValue<QSize> m_storeDialogSize; SettingValue<QSize> m_storeDialogSize;
struct struct

84
src/gui/transferlistfilterswidget.cpp

@ -321,7 +321,7 @@ TrackerFiltersList::~TrackerFiltersList()
Utils::Fs::forceRemove(iconPath); Utils::Fs::forceRemove(iconPath);
} }
void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoHash &hash) void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::TorrentID &id)
{ {
const QString host {getHost(tracker)}; const QString host {getHost(tracker)};
const bool exists {m_trackers.contains(host)}; const bool exists {m_trackers.contains(host)};
@ -329,7 +329,7 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH
if (exists) if (exists)
{ {
if (m_trackers.value(host).contains(hash)) if (m_trackers.value(host).contains(id))
return; return;
trackerItem = item((host == NULL_HOST) trackerItem = item((host == NULL_HOST)
@ -346,18 +346,18 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH
} }
if (!trackerItem) return; if (!trackerItem) return;
QSet<BitTorrent::InfoHash> &hashes {m_trackers[host]}; QSet<BitTorrent::TorrentID> &torrentIDs {m_trackers[host]};
hashes.insert(hash); torrentIDs.insert(id);
if (host == NULL_HOST) if (host == NULL_HOST)
{ {
trackerItem->setText(tr("Trackerless (%1)").arg(hashes.size())); trackerItem->setText(tr("Trackerless (%1)").arg(torrentIDs.size()));
if (currentRow() == TRACKERLESS_ROW) if (currentRow() == TRACKERLESS_ROW)
applyFilter(TRACKERLESS_ROW); applyFilter(TRACKERLESS_ROW);
return; return;
} }
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(hashes.size()))); trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(torrentIDs.size())));
if (exists) if (exists)
{ {
if (currentRow() == rowFromTracker(host)) if (currentRow() == rowFromTracker(host))
@ -379,14 +379,14 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH
updateGeometry(); updateGeometry();
} }
void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::InfoHash &hash) void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::TorrentID &id)
{ {
const QString host = getHost(tracker); const QString host = getHost(tracker);
QSet<BitTorrent::InfoHash> hashes = m_trackers.value(host); QSet<BitTorrent::TorrentID> torrentIDs = m_trackers.value(host);
if (hashes.empty()) if (torrentIDs.empty())
return; return;
hashes.remove(hash); torrentIDs.remove(id);
int row = 0; int row = 0;
QListWidgetItem *trackerItem = nullptr; QListWidgetItem *trackerItem = nullptr;
@ -394,11 +394,11 @@ void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::In
if (!host.isEmpty()) if (!host.isEmpty())
{ {
// Remove from 'Error' and 'Warning' view // Remove from 'Error' and 'Warning' view
trackerSuccess(hash, tracker); trackerSuccess(id, tracker);
row = rowFromTracker(host); row = rowFromTracker(host);
trackerItem = item(row); trackerItem = item(row);
if (hashes.empty()) if (torrentIDs.empty())
{ {
if (currentRow() == row) if (currentRow() == row)
setCurrentRow(0, QItemSelectionModel::SelectCurrent); setCurrentRow(0, QItemSelectionModel::SelectCurrent);
@ -409,27 +409,27 @@ void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::In
} }
if (trackerItem) if (trackerItem)
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(hashes.size()))); trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(torrentIDs.size())));
} }
else else
{ {
row = 1; row = 1;
trackerItem = item(TRACKERLESS_ROW); trackerItem = item(TRACKERLESS_ROW);
trackerItem->setText(tr("Trackerless (%1)").arg(hashes.size())); trackerItem->setText(tr("Trackerless (%1)").arg(torrentIDs.size()));
} }
m_trackers.insert(host, hashes); m_trackers.insert(host, torrentIDs);
if (currentRow() == row) if (currentRow() == row)
applyFilter(row); applyFilter(row);
} }
void TrackerFiltersList::changeTrackerless(const bool trackerless, const BitTorrent::InfoHash &hash) void TrackerFiltersList::changeTrackerless(const bool trackerless, const BitTorrent::TorrentID &id)
{ {
if (trackerless) if (trackerless)
addItem(NULL_HOST, hash); addItem(NULL_HOST, id);
else else
removeItem(NULL_HOST, hash); removeItem(NULL_HOST, id);
} }
void TrackerFiltersList::setDownloadTrackerFavicon(bool value) void TrackerFiltersList::setDownloadTrackerFavicon(bool value)
@ -452,9 +452,9 @@ void TrackerFiltersList::setDownloadTrackerFavicon(bool value)
} }
} }
void TrackerFiltersList::trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker) void TrackerFiltersList::trackerSuccess(const BitTorrent::TorrentID &id, const QString &tracker)
{ {
const auto errorHashesIter = m_errors.find(hash); const auto errorHashesIter = m_errors.find(id);
if (errorHashesIter != m_errors.end()) if (errorHashesIter != m_errors.end())
{ {
QSet<QString> &errored = *errorHashesIter; QSet<QString> &errored = *errorHashesIter;
@ -468,7 +468,7 @@ void TrackerFiltersList::trackerSuccess(const BitTorrent::InfoHash &hash, const
} }
} }
const auto warningHashesIter = m_warnings.find(hash); const auto warningHashesIter = m_warnings.find(id);
if (warningHashesIter != m_warnings.end()) if (warningHashesIter != m_warnings.end())
{ {
QSet<QString> &warned = *warningHashesIter; QSet<QString> &warned = *warningHashesIter;
@ -483,9 +483,9 @@ void TrackerFiltersList::trackerSuccess(const BitTorrent::InfoHash &hash, const
} }
} }
void TrackerFiltersList::trackerError(const BitTorrent::InfoHash &hash, const QString &tracker) void TrackerFiltersList::trackerError(const BitTorrent::TorrentID &id, const QString &tracker)
{ {
QSet<QString> &trackers {m_errors[hash]}; QSet<QString> &trackers {m_errors[id]};
if (trackers.contains(tracker)) if (trackers.contains(tracker))
return; return;
@ -495,9 +495,9 @@ void TrackerFiltersList::trackerError(const BitTorrent::InfoHash &hash, const QS
applyFilter(ERROR_ROW); applyFilter(ERROR_ROW);
} }
void TrackerFiltersList::trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker) void TrackerFiltersList::trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker)
{ {
QSet<QString> &trackers {m_warnings[hash]}; QSet<QString> &trackers {m_warnings[id]};
if (trackers.contains(tracker)) if (trackers.contains(tracker))
return; return;
@ -572,33 +572,33 @@ void TrackerFiltersList::applyFilter(const int row)
if (row == ALL_ROW) if (row == ALL_ROW)
transferList->applyTrackerFilterAll(); transferList->applyTrackerFilterAll();
else if (isVisible()) else if (isVisible())
transferList->applyTrackerFilter(getInfoHashes(row)); transferList->applyTrackerFilter(getTorrentIDs(row));
} }
void TrackerFiltersList::handleNewTorrent(BitTorrent::Torrent *const torrent) void TrackerFiltersList::handleNewTorrent(BitTorrent::Torrent *const torrent)
{ {
const BitTorrent::InfoHash hash {torrent->hash()}; const BitTorrent::TorrentID torrentID {torrent->id()};
const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()}; const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()};
for (const BitTorrent::TrackerEntry &tracker : trackers) for (const BitTorrent::TrackerEntry &tracker : trackers)
addItem(tracker.url, hash); addItem(tracker.url, torrentID);
// Check for trackerless torrent // Check for trackerless torrent
if (trackers.isEmpty()) if (trackers.isEmpty())
addItem(NULL_HOST, hash); addItem(NULL_HOST, torrentID);
item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(++m_totalTorrents)); item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(++m_totalTorrents));
} }
void TrackerFiltersList::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) void TrackerFiltersList::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent)
{ {
const BitTorrent::InfoHash hash {torrent->hash()}; const BitTorrent::TorrentID torrentID {torrent->id()};
const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()}; const QVector<BitTorrent::TrackerEntry> trackers {torrent->trackers()};
for (const BitTorrent::TrackerEntry &tracker : trackers) for (const BitTorrent::TrackerEntry &tracker : trackers)
removeItem(tracker.url, hash); removeItem(tracker.url, torrentID);
// Check for trackerless torrent // Check for trackerless torrent
if (trackers.isEmpty()) if (trackers.isEmpty())
removeItem(NULL_HOST, hash); removeItem(NULL_HOST, torrentID);
item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(--m_totalTorrents)); item(ALL_ROW)->setText(tr("All (%1)", "this is for the tracker filter").arg(--m_totalTorrents));
} }
@ -624,7 +624,7 @@ int TrackerFiltersList::rowFromTracker(const QString &tracker) const
return -1; return -1;
} }
QSet<BitTorrent::InfoHash> TrackerFiltersList::getInfoHashes(const int row) const QSet<BitTorrent::TorrentID> TrackerFiltersList::getTorrentIDs(const int row) const
{ {
switch (row) switch (row)
{ {
@ -727,11 +727,11 @@ TransferListFiltersWidget::TransferListFiltersWidget(QWidget *parent, TransferLi
connect(trackerLabel, &QCheckBox::toggled, m_trackerFilters, &TrackerFiltersList::toggleFilter); connect(trackerLabel, &QCheckBox::toggled, m_trackerFilters, &TrackerFiltersList::toggleFilter);
connect(trackerLabel, &QCheckBox::toggled, pref, &Preferences::setTrackerFilterState); connect(trackerLabel, &QCheckBox::toggled, pref, &Preferences::setTrackerFilterState);
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerSuccess) connect(this, qOverload<const BitTorrent::TorrentID &, const QString &>(&TransferListFiltersWidget::trackerSuccess)
, m_trackerFilters, &TrackerFiltersList::trackerSuccess); , m_trackerFilters, &TrackerFiltersList::trackerSuccess);
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerError) connect(this, qOverload<const BitTorrent::TorrentID &, const QString &>(&TransferListFiltersWidget::trackerError)
, m_trackerFilters, &TrackerFiltersList::trackerError); , m_trackerFilters, &TrackerFiltersList::trackerError);
connect(this, qOverload<const BitTorrent::InfoHash &, const QString &>(&TransferListFiltersWidget::trackerWarning) connect(this, qOverload<const BitTorrent::TorrentID &, const QString &>(&TransferListFiltersWidget::trackerWarning)
, m_trackerFilters, &TrackerFiltersList::trackerWarning); , m_trackerFilters, &TrackerFiltersList::trackerWarning);
} }
@ -743,33 +743,33 @@ void TransferListFiltersWidget::setDownloadTrackerFavicon(bool value)
void TransferListFiltersWidget::addTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers) void TransferListFiltersWidget::addTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
{ {
for (const BitTorrent::TrackerEntry &tracker : trackers) for (const BitTorrent::TrackerEntry &tracker : trackers)
m_trackerFilters->addItem(tracker.url, torrent->hash()); m_trackerFilters->addItem(tracker.url, torrent->id());
} }
void TransferListFiltersWidget::removeTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers) void TransferListFiltersWidget::removeTrackers(const BitTorrent::Torrent *torrent, const QVector<BitTorrent::TrackerEntry> &trackers)
{ {
for (const BitTorrent::TrackerEntry &tracker : trackers) for (const BitTorrent::TrackerEntry &tracker : trackers)
m_trackerFilters->removeItem(tracker.url, torrent->hash()); m_trackerFilters->removeItem(tracker.url, torrent->id());
} }
void TransferListFiltersWidget::changeTrackerless(const BitTorrent::Torrent *torrent, const bool trackerless) void TransferListFiltersWidget::changeTrackerless(const BitTorrent::Torrent *torrent, const bool trackerless)
{ {
m_trackerFilters->changeTrackerless(trackerless, torrent->hash()); m_trackerFilters->changeTrackerless(trackerless, torrent->id());
} }
void TransferListFiltersWidget::trackerSuccess(const BitTorrent::Torrent *torrent, const QString &tracker) void TransferListFiltersWidget::trackerSuccess(const BitTorrent::Torrent *torrent, const QString &tracker)
{ {
emit trackerSuccess(torrent->hash(), tracker); emit trackerSuccess(torrent->id(), tracker);
} }
void TransferListFiltersWidget::trackerWarning(const BitTorrent::Torrent *torrent, const QString &tracker) void TransferListFiltersWidget::trackerWarning(const BitTorrent::Torrent *torrent, const QString &tracker)
{ {
emit trackerWarning(torrent->hash(), tracker); emit trackerWarning(torrent->id(), tracker);
} }
void TransferListFiltersWidget::trackerError(const BitTorrent::Torrent *torrent, const QString &tracker) void TransferListFiltersWidget::trackerError(const BitTorrent::Torrent *torrent, const QString &tracker)
{ {
emit trackerError(torrent->hash(), tracker); emit trackerError(torrent->id(), tracker);
} }
void TransferListFiltersWidget::onCategoryFilterStateChanged(bool enabled) void TransferListFiltersWidget::onCategoryFilterStateChanged(bool enabled)

28
src/gui/transferlistfilterswidget.h

@ -39,8 +39,8 @@ class TransferListWidget;
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash;
class Torrent; class Torrent;
class TorrentID;
struct TrackerEntry; struct TrackerEntry;
} }
@ -104,15 +104,15 @@ public:
~TrackerFiltersList() override; ~TrackerFiltersList() override;
// Redefine addItem() to make sure the list stays sorted // Redefine addItem() to make sure the list stays sorted
void addItem(const QString &tracker, const BitTorrent::InfoHash &hash); void addItem(const QString &tracker, const BitTorrent::TorrentID &id);
void removeItem(const QString &tracker, const BitTorrent::InfoHash &hash); void removeItem(const QString &tracker, const BitTorrent::TorrentID &id);
void changeTrackerless(bool trackerless, const BitTorrent::InfoHash &hash); void changeTrackerless(bool trackerless, const BitTorrent::TorrentID &id);
void setDownloadTrackerFavicon(bool value); void setDownloadTrackerFavicon(bool value);
public slots: public slots:
void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerSuccess(const BitTorrent::TorrentID &id, const QString &tracker);
void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerError(const BitTorrent::TorrentID &id, const QString &tracker);
void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker);
private slots: private slots:
void handleFavicoDownloadFinished(const Net::DownloadResult &result); void handleFavicoDownloadFinished(const Net::DownloadResult &result);
@ -126,12 +126,12 @@ private:
void torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) override; void torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) override;
QString trackerFromRow(int row) const; QString trackerFromRow(int row) const;
int rowFromTracker(const QString &tracker) const; int rowFromTracker(const QString &tracker) const;
QSet<BitTorrent::InfoHash> getInfoHashes(int row) const; QSet<BitTorrent::TorrentID> getTorrentIDs(int row) const;
void downloadFavicon(const QString &url); void downloadFavicon(const QString &url);
QHash<QString, QSet<BitTorrent::InfoHash>> m_trackers; // <tracker host, torrent hashes> QHash<QString, QSet<BitTorrent::TorrentID>> m_trackers; // <tracker host, torrent IDs>
QHash<BitTorrent::InfoHash, QSet<QString>> m_errors; // <torrent hash, tracker hosts> QHash<BitTorrent::TorrentID, QSet<QString>> m_errors; // <torrent ID, tracker hosts>
QHash<BitTorrent::InfoHash, QSet<QString>> m_warnings; // <torrent hash, tracker hosts> QHash<BitTorrent::TorrentID, QSet<QString>> m_warnings; // <torrent ID, tracker hosts>
QStringList m_iconPaths; QStringList m_iconPaths;
int m_totalTorrents; int m_totalTorrents;
bool m_downloadTrackerFavicon; bool m_downloadTrackerFavicon;
@ -158,9 +158,9 @@ public slots:
void trackerError(const BitTorrent::Torrent *torrent, const QString &tracker); void trackerError(const BitTorrent::Torrent *torrent, const QString &tracker);
signals: signals:
void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerSuccess(const BitTorrent::TorrentID &id, const QString &tracker);
void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerError(const BitTorrent::TorrentID &id, const QString &tracker);
void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker); void trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker);
private slots: private slots:
void onCategoryFilterStateChanged(bool enabled); void onCategoryFilterStateChanged(bool enabled);

6
src/gui/transferlistsortmodel.cpp

@ -99,15 +99,15 @@ void TransferListSortModel::disableTagFilter()
invalidateFilter(); invalidateFilter();
} }
void TransferListSortModel::setTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes) void TransferListSortModel::setTrackerFilter(const QSet<BitTorrent::TorrentID> &torrentIDs)
{ {
if (m_filter.setHashSet(hashes)) if (m_filter.setTorrentIDSet(torrentIDs))
invalidateFilter(); invalidateFilter();
} }
void TransferListSortModel::disableTrackerFilter() void TransferListSortModel::disableTrackerFilter()
{ {
if (m_filter.setHashSet(TorrentFilter::AnyHash)) if (m_filter.setTorrentIDSet(TorrentFilter::AnyID))
invalidateFilter(); invalidateFilter();
} }

2
src/gui/transferlistsortmodel.h

@ -50,7 +50,7 @@ public:
void disableCategoryFilter(); void disableCategoryFilter();
void setTagFilter(const QString &tag); void setTagFilter(const QString &tag);
void disableTagFilter(); void disableTagFilter();
void setTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes); void setTrackerFilter(const QSet<BitTorrent::TorrentID> &torrentIDs);
void disableTrackerFilter(); void disableTrackerFilter();
private: private:

30
src/gui/transferlistwidget.cpp

@ -78,13 +78,13 @@
namespace namespace
{ {
QVector<BitTorrent::InfoHash> extractHashes(const QVector<BitTorrent::Torrent *> &torrents) QVector<BitTorrent::TorrentID> extractIDs(const QVector<BitTorrent::Torrent *> &torrents)
{ {
QVector<BitTorrent::InfoHash> hashes; QVector<BitTorrent::TorrentID> torrentIDs;
hashes.reserve(torrents.size()); torrentIDs.reserve(torrents.size());
for (const BitTorrent::Torrent *torrent : torrents) for (const BitTorrent::Torrent *torrent : torrents)
hashes << torrent->hash(); torrentIDs << torrent->id();
return hashes; return torrentIDs;
} }
bool torrentContainsPreviewableFiles(const BitTorrent::Torrent *const torrent) bool torrentContainsPreviewableFiles(const BitTorrent::Torrent *const torrent)
@ -121,7 +121,7 @@ namespace
auto *session = BitTorrent::Session::instance(); auto *session = BitTorrent::Session::instance();
const DeleteOption deleteOption = isDeleteFileSelected ? DeleteTorrentAndFiles : DeleteTorrent; const DeleteOption deleteOption = isDeleteFileSelected ? DeleteTorrentAndFiles : DeleteTorrent;
for (const BitTorrent::Torrent *torrent : torrents) for (const BitTorrent::Torrent *torrent : torrents)
session->deleteTorrent(torrent->hash(), deleteOption); session->deleteTorrent(torrent->id(), deleteOption);
} }
} }
@ -452,26 +452,26 @@ void TransferListWidget::increaseQueuePosSelectedTorrents()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
if (m_mainWindow->currentTabWidget() == this) if (m_mainWindow->currentTabWidget() == this)
BitTorrent::Session::instance()->increaseTorrentsQueuePos(extractHashes(getSelectedTorrents())); BitTorrent::Session::instance()->increaseTorrentsQueuePos(extractIDs(getSelectedTorrents()));
} }
void TransferListWidget::decreaseQueuePosSelectedTorrents() void TransferListWidget::decreaseQueuePosSelectedTorrents()
{ {
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
if (m_mainWindow->currentTabWidget() == this) if (m_mainWindow->currentTabWidget() == this)
BitTorrent::Session::instance()->decreaseTorrentsQueuePos(extractHashes(getSelectedTorrents())); BitTorrent::Session::instance()->decreaseTorrentsQueuePos(extractIDs(getSelectedTorrents()));
} }
void TransferListWidget::topQueuePosSelectedTorrents() void TransferListWidget::topQueuePosSelectedTorrents()
{ {
if (m_mainWindow->currentTabWidget() == this) if (m_mainWindow->currentTabWidget() == this)
BitTorrent::Session::instance()->topTorrentsQueuePos(extractHashes(getSelectedTorrents())); BitTorrent::Session::instance()->topTorrentsQueuePos(extractIDs(getSelectedTorrents()));
} }
void TransferListWidget::bottomQueuePosSelectedTorrents() void TransferListWidget::bottomQueuePosSelectedTorrents()
{ {
if (m_mainWindow->currentTabWidget() == this) if (m_mainWindow->currentTabWidget() == this)
BitTorrent::Session::instance()->bottomTorrentsQueuePos(extractHashes(getSelectedTorrents())); BitTorrent::Session::instance()->bottomTorrentsQueuePos(extractIDs(getSelectedTorrents()));
} }
void TransferListWidget::copySelectedMagnetURIs() const void TransferListWidget::copySelectedMagnetURIs() const
@ -494,11 +494,11 @@ void TransferListWidget::copySelectedNames() const
void TransferListWidget::copySelectedHashes() const void TransferListWidget::copySelectedHashes() const
{ {
QStringList torrentHashes; QStringList torrentIDs;
for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents())) for (BitTorrent::Torrent *const torrent : asConst(getSelectedTorrents()))
torrentHashes << torrent->hash().toString(); torrentIDs << torrent->id().toString();
qApp->clipboard()->setText(torrentHashes.join('\n')); qApp->clipboard()->setText(torrentIDs.join('\n'));
} }
void TransferListWidget::hideQueuePosColumn(bool hide) void TransferListWidget::hideQueuePosColumn(bool hide)
@ -1129,9 +1129,9 @@ void TransferListWidget::applyTrackerFilterAll()
m_sortFilterModel->disableTrackerFilter(); m_sortFilterModel->disableTrackerFilter();
} }
void TransferListWidget::applyTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes) void TransferListWidget::applyTrackerFilter(const QSet<BitTorrent::TorrentID> &torrentIDs)
{ {
m_sortFilterModel->setTrackerFilter(hashes); m_sortFilterModel->setTrackerFilter(torrentIDs);
} }
void TransferListWidget::applyNameFilter(const QString &name) void TransferListWidget::applyNameFilter(const QString &name)

4
src/gui/transferlistwidget.h

@ -39,8 +39,8 @@ class TransferListSortModel;
namespace BitTorrent namespace BitTorrent
{ {
class InfoHash;
class Torrent; class Torrent;
class TorrentID;
} }
class TransferListWidget final : public QTreeView class TransferListWidget final : public QTreeView
@ -88,7 +88,7 @@ public slots:
void applyCategoryFilter(const QString &category); void applyCategoryFilter(const QString &category);
void applyTagFilter(const QString &tag); void applyTagFilter(const QString &tag);
void applyTrackerFilterAll(); void applyTrackerFilterAll();
void applyTrackerFilter(const QSet<BitTorrent::InfoHash> &hashes); void applyTrackerFilter(const QSet<BitTorrent::TorrentID> &torrentIDs);
void previewFile(const QString &filePath); void previewFile(const QString &filePath);
void renameSelectedTorrent(); void renameSelectedTorrent();

3
src/webui/api/serialize/serialize_torrent.cpp

@ -103,7 +103,8 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
}; };
return { return {
{KEY_TORRENT_HASH, QString(torrent.hash().toString())}, // TODO: Add fields for real SHA1 and SHA256 hashes
{KEY_TORRENT_ID, QString(torrent.id().toString())},
{KEY_TORRENT_NAME, torrent.name()}, {KEY_TORRENT_NAME, torrent.name()},
{KEY_TORRENT_MAGNET_URI, torrent.createMagnetURI()}, {KEY_TORRENT_MAGNET_URI, torrent.createMagnetURI()},
{KEY_TORRENT_SIZE, torrent.wantedSize()}, {KEY_TORRENT_SIZE, torrent.wantedSize()},

2
src/webui/api/serialize/serialize_torrent.h

@ -36,7 +36,7 @@ namespace BitTorrent
} }
// Torrent keys // Torrent keys
const char KEY_TORRENT_HASH[] = "hash"; const char KEY_TORRENT_ID[] = "hash";
const char KEY_TORRENT_NAME[] = "name"; const char KEY_TORRENT_NAME[] = "name";
const char KEY_TORRENT_MAGNET_URI[] = "magnet_uri"; const char KEY_TORRENT_MAGNET_URI[] = "magnet_uri";
const char KEY_TORRENT_SIZE[] = "size"; const char KEY_TORRENT_SIZE[] = "size";

20
src/webui/api/synccontroller.cpp

@ -460,10 +460,10 @@ void SyncController::maindataAction()
QHash<QString, QStringList> trackers; QHash<QString, QStringList> trackers;
for (const BitTorrent::Torrent *torrent : asConst(session->torrents())) for (const BitTorrent::Torrent *torrent : asConst(session->torrents()))
{ {
const BitTorrent::InfoHash torrentHash = torrent->hash(); const BitTorrent::TorrentID torrentID = torrent->id();
QVariantMap map = serialize(*torrent); QVariantMap map = serialize(*torrent);
map.remove(KEY_TORRENT_HASH); map.remove(KEY_TORRENT_ID);
// Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue). // Calculated last activity time can differ from actual value by up to 10 seconds (this is a libtorrent issue).
// So we don't need unnecessary updates of last activity time in response. // So we don't need unnecessary updates of last activity time in response.
@ -471,11 +471,11 @@ void SyncController::maindataAction()
if (iterTorrents != lastResponse.end()) if (iterTorrents != lastResponse.end())
{ {
const QVariantHash lastResponseTorrents = iterTorrents->toHash(); const QVariantHash lastResponseTorrents = iterTorrents->toHash();
const auto iterHash = lastResponseTorrents.find(torrentHash.toString()); const auto iterID = lastResponseTorrents.find(torrentID.toString());
if (iterHash != lastResponseTorrents.end()) if (iterID != lastResponseTorrents.end())
{ {
const QVariantMap torrentData = iterHash->toMap(); const QVariantMap torrentData = iterID->toMap();
const auto iterLastActivity = torrentData.find(KEY_TORRENT_LAST_ACTIVITY_TIME); const auto iterLastActivity = torrentData.find(KEY_TORRENT_LAST_ACTIVITY_TIME);
if (iterLastActivity != torrentData.end()) if (iterLastActivity != torrentData.end())
@ -488,9 +488,9 @@ void SyncController::maindataAction()
} }
for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers())) for (const BitTorrent::TrackerEntry &tracker : asConst(torrent->trackers()))
trackers[tracker.url] << torrentHash.toString(); trackers[tracker.url] << torrentID.toString();
torrents[torrentHash.toString()] = map; torrents[torrentID.toString()] = map;
} }
data["torrents"] = torrents; data["torrents"] = torrents;
@ -534,15 +534,15 @@ void SyncController::maindataAction()
} }
// GET param: // GET param:
// - hash (string): torrent hash // - hash (string): torrent hash (ID)
// - rid (int): last response id // - rid (int): last response id
void SyncController::torrentPeersAction() void SyncController::torrentPeersAction()
{ {
auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap(); auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap();
auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap(); auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap();
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);

112
src/webui/api/torrentscontroller.cpp

@ -120,18 +120,18 @@ namespace
using Utils::String::parseInt; using Utils::String::parseInt;
using Utils::String::parseDouble; using Utils::String::parseDouble;
void applyToTorrents(const QStringList &hashes, const std::function<void (BitTorrent::Torrent *torrent)> &func) void applyToTorrents(const QStringList &idList, const std::function<void (BitTorrent::Torrent *torrent)> &func)
{ {
if ((hashes.size() == 1) && (hashes[0] == QLatin1String("all"))) if ((idList.size() == 1) && (idList[0] == QLatin1String("all")))
{ {
for (BitTorrent::Torrent *const torrent : asConst(BitTorrent::Session::instance()->torrents())) for (BitTorrent::Torrent *const torrent : asConst(BitTorrent::Session::instance()->torrents()))
func(torrent); func(torrent);
} }
else else
{ {
for (const QString &hashString : hashes) for (const QString &idString : idList)
{ {
const auto hash = BitTorrent::InfoHash::fromString(hashString); const auto hash = BitTorrent::TorrentID::fromString(idString);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash);
if (torrent) if (torrent)
func(torrent); func(torrent);
@ -211,20 +211,20 @@ namespace
return {dht, pex, lsd}; return {dht, pex, lsd};
} }
QVector<BitTorrent::InfoHash> toInfoHashes(const QStringList &hashes) QVector<BitTorrent::TorrentID> toTorrentIDs(const QStringList &idStrings)
{ {
QVector<BitTorrent::InfoHash> infoHashes; QVector<BitTorrent::TorrentID> idList;
infoHashes.reserve(hashes.size()); idList.reserve(idStrings.size());
for (const QString &hash : hashes) for (const QString &hash : idStrings)
infoHashes << BitTorrent::InfoHash::fromString(hash); idList << BitTorrent::TorrentID::fromString(hash);
return infoHashes; return idList;
} }
} }
// Returns all the torrents in JSON format. // Returns all the torrents in JSON format.
// The return value is a JSON-formatted list of dictionaries. // The return value is a JSON-formatted list of dictionaries.
// The dictionary keys are: // The dictionary keys are:
// - "hash": Torrent hash // - "hash": Torrent hash (ID)
// - "name": Torrent name // - "name": Torrent name
// - "size": Torrent size // - "size": Torrent size
// - "progress": Torrent progress // - "progress": Torrent progress
@ -260,11 +260,11 @@ void TorrentsController::infoAction()
int offset {params()["offset"].toInt()}; int offset {params()["offset"].toInt()};
const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)}; const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)};
InfoHashSet hashSet; TorrentIDSet idSet;
for (const QString &hash : hashes) for (const QString &hash : hashes)
hashSet.insert(BitTorrent::InfoHash::fromString(hash)); idSet.insert(BitTorrent::TorrentID::fromString(hash));
const TorrentFilter torrentFilter(filter, (hashes.isEmpty() ? TorrentFilter::AnyHash : hashSet), category); const TorrentFilter torrentFilter(filter, (hashes.isEmpty() ? TorrentFilter::AnyID : idSet), category);
QVariantList torrentList; QVariantList torrentList;
for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents())) for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents()))
{ {
@ -374,8 +374,8 @@ void TorrentsController::propertiesAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -445,8 +445,8 @@ void TorrentsController::trackersAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -481,8 +481,8 @@ void TorrentsController::webseedsAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -512,8 +512,8 @@ void TorrentsController::filesAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -558,8 +558,8 @@ void TorrentsController::pieceHashesAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -580,8 +580,8 @@ void TorrentsController::pieceStatesAction()
{ {
requireParams({"hash"}); requireParams({"hash"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -691,8 +691,8 @@ void TorrentsController::addTrackersAction()
{ {
requireParams({"hash", "urls"}); requireParams({"hash", "urls"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -710,11 +710,11 @@ void TorrentsController::editTrackerAction()
{ {
requireParams({"hash", "origUrl", "newUrl"}); requireParams({"hash", "origUrl", "newUrl"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
const QString origUrl = params()["origUrl"]; const QString origUrl = params()["origUrl"];
const QString newUrl = params()["newUrl"]; const QString newUrl = params()["newUrl"];
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -751,8 +751,8 @@ void TorrentsController::removeTrackersAction()
{ {
requireParams({"hash", "urls"}); requireParams({"hash", "urls"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -804,7 +804,7 @@ void TorrentsController::addPeersAction()
return torrent->connectPeer(peer); return torrent->connectPeer(peer);
}); });
results[torrent->hash().toString()] = QJsonObject results[torrent->id().toString()] = QJsonObject
{ {
{"added", peersAdded}, {"added", peersAdded},
{"failed", (peers.size() - peersAdded)} {"failed", (peers.size() - peersAdded)}
@ -826,15 +826,15 @@ void TorrentsController::resumeAction()
{ {
requireParams({"hashes"}); requireParams({"hashes"});
const QStringList hashes = params()["hashes"].split('|'); const QStringList idStrings = params()["hashes"].split('|');
applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->resume(); }); applyToTorrents(idStrings, [](BitTorrent::Torrent *const torrent) { torrent->resume(); });
} }
void TorrentsController::filePrioAction() void TorrentsController::filePrioAction()
{ {
requireParams({"hash", "id", "priority"}); requireParams({"hash", "id", "priority"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
bool ok = false; bool ok = false;
const auto priority = static_cast<BitTorrent::DownloadPriority>(params()["priority"].toInt(&ok)); const auto priority = static_cast<BitTorrent::DownloadPriority>(params()["priority"].toInt(&ok));
if (!ok) if (!ok)
@ -843,7 +843,7 @@ void TorrentsController::filePrioAction()
if (!BitTorrent::isValidDownloadPriority(priority)) if (!BitTorrent::isValidDownloadPriority(priority))
throw APIError(APIErrorType::BadParams, tr("Priority is not valid")); throw APIError(APIErrorType::BadParams, tr("Priority is not valid"));
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
if (!torrent->hasMetadata()) if (!torrent->hasMetadata())
@ -875,15 +875,15 @@ void TorrentsController::uploadLimitAction()
{ {
requireParams({"hashes"}); requireParams({"hashes"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList idList {params()["hashes"].split('|')};
QJsonObject map; QJsonObject map;
for (const QString &hash : hashes) for (const QString &id : idList)
{ {
int limit = -1; int limit = -1;
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(BitTorrent::InfoHash::fromString(hash)); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(BitTorrent::TorrentID::fromString(id));
if (torrent) if (torrent)
limit = torrent->uploadLimit(); limit = torrent->uploadLimit();
map[hash] = limit; map[id] = limit;
} }
setResult(map); setResult(map);
@ -893,15 +893,15 @@ void TorrentsController::downloadLimitAction()
{ {
requireParams({"hashes"}); requireParams({"hashes"});
const QStringList hashes {params()["hashes"].split('|')}; const QStringList idList {params()["hashes"].split('|')};
QJsonObject map; QJsonObject map;
for (const QString &hash : hashes) for (const QString &id : idList)
{ {
int limit = -1; int limit = -1;
const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(BitTorrent::InfoHash::fromString(hash)); const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(BitTorrent::TorrentID::fromString(id));
if (torrent) if (torrent)
limit = torrent->downloadLimit(); limit = torrent->downloadLimit();
map[hash] = limit; map[id] = limit;
} }
setResult(map); setResult(map);
@ -992,7 +992,7 @@ void TorrentsController::deleteAction()
? DeleteTorrentAndFiles : DeleteTorrent; ? DeleteTorrentAndFiles : DeleteTorrent;
applyToTorrents(hashes, [deleteOption](const BitTorrent::Torrent *torrent) applyToTorrents(hashes, [deleteOption](const BitTorrent::Torrent *torrent)
{ {
BitTorrent::Session::instance()->deleteTorrent(torrent->hash(), deleteOption); BitTorrent::Session::instance()->deleteTorrent(torrent->id(), deleteOption);
}); });
} }
@ -1004,7 +1004,7 @@ void TorrentsController::increasePrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->increaseTorrentsQueuePos(toInfoHashes(hashes)); BitTorrent::Session::instance()->increaseTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::decreasePrioAction() void TorrentsController::decreasePrioAction()
@ -1015,7 +1015,7 @@ void TorrentsController::decreasePrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toInfoHashes(hashes)); BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::topPrioAction() void TorrentsController::topPrioAction()
@ -1026,7 +1026,7 @@ void TorrentsController::topPrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->topTorrentsQueuePos(toInfoHashes(hashes)); BitTorrent::Session::instance()->topTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::bottomPrioAction() void TorrentsController::bottomPrioAction()
@ -1037,7 +1037,7 @@ void TorrentsController::bottomPrioAction()
throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled"));
const QStringList hashes {params()["hashes"].split('|')}; const QStringList hashes {params()["hashes"].split('|')};
BitTorrent::Session::instance()->bottomTorrentsQueuePos(toInfoHashes(hashes)); BitTorrent::Session::instance()->bottomTorrentsQueuePos(toTorrentIDs(hashes));
} }
void TorrentsController::setLocationAction() void TorrentsController::setLocationAction()
@ -1070,13 +1070,13 @@ void TorrentsController::renameAction()
{ {
requireParams({"hash", "name"}); requireParams({"hash", "name"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
QString name = params()["name"].trimmed(); QString name = params()["name"].trimmed();
if (name.isEmpty()) if (name.isEmpty())
throw APIError(APIErrorType::Conflict, tr("Incorrect torrent name")); throw APIError(APIErrorType::Conflict, tr("Incorrect torrent name"));
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -1257,8 +1257,8 @@ void TorrentsController::renameFileAction()
{ {
requireParams({"hash", "oldPath", "newPath"}); requireParams({"hash", "oldPath", "newPath"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);
@ -1279,8 +1279,8 @@ void TorrentsController::renameFolderAction()
{ {
requireParams({"hash", "oldPath", "newPath"}); requireParams({"hash", "oldPath", "newPath"});
const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); const auto id = BitTorrent::TorrentID::fromString(params()["hash"]);
BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id);
if (!torrent) if (!torrent)
throw APIError(APIErrorType::NotFound); throw APIError(APIErrorType::NotFound);

Loading…
Cancel
Save