From 561b597031bfb868dfba0850f7af68e9d9f7bdab Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Fri, 5 Mar 2021 12:43:58 +0300 Subject: [PATCH] Improve "info hash" handling Define "torrent ID" concept, which is either a SHA1 hash for torrents of version 1, or a SHA256 hash (truncated to SHA1 hash length) for torrents of version 2. Add support for native libtorrent2 info hashes. --- src/app/application.cpp | 3 +- src/base/bittorrent/filesearcher.cpp | 2 +- src/base/bittorrent/filesearcher.h | 6 +- src/base/bittorrent/infohash.cpp | 50 ++++- src/base/bittorrent/infohash.h | 45 +++- src/base/bittorrent/magneturi.cpp | 16 +- src/base/bittorrent/magneturi.h | 4 +- src/base/bittorrent/session.cpp | 205 +++++++++++------- src/base/bittorrent/session.h | 30 +-- src/base/bittorrent/torrent.cpp | 7 + src/base/bittorrent/torrent.h | 4 +- src/base/bittorrent/torrentimpl.cpp | 12 +- src/base/bittorrent/torrentimpl.h | 4 +- src/base/bittorrent/torrentinfo.cpp | 9 +- src/base/bittorrent/torrentinfo.h | 2 +- src/base/bittorrent/tracker.cpp | 16 +- src/base/bittorrent/tracker.h | 2 +- src/base/torrentfilter.cpp | 20 +- src/base/torrentfilter.h | 12 +- src/gui/addnewtorrentdialog.cpp | 20 +- src/gui/mainwindow.cpp | 6 +- src/gui/properties/propertieswidget.cpp | 5 +- src/gui/torrentoptionsdialog.cpp | 8 +- src/gui/torrentoptionsdialog.h | 4 +- src/gui/transferlistfilterswidget.cpp | 84 +++---- src/gui/transferlistfilterswidget.h | 28 +-- src/gui/transferlistsortmodel.cpp | 6 +- src/gui/transferlistsortmodel.h | 2 +- src/gui/transferlistwidget.cpp | 30 +-- src/gui/transferlistwidget.h | 4 +- src/webui/api/serialize/serialize_torrent.cpp | 3 +- src/webui/api/serialize/serialize_torrent.h | 2 +- src/webui/api/synccontroller.cpp | 20 +- src/webui/api/torrentscontroller.cpp | 112 +++++----- 34 files changed, 463 insertions(+), 320 deletions(-) diff --git a/src/app/application.cpp b/src/app/application.cpp index 0ac15cb4f..a555bffa3 100644 --- a/src/app/application.cpp +++ b/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("%Z", QString::number(torrent->totalSize())); 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->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program)); diff --git a/src/base/bittorrent/filesearcher.cpp b/src/base/bittorrent/filesearcher.cpp index 563cfbddb..a8a3b6594 100644 --- a/src/base/bittorrent/filesearcher.cpp +++ b/src/base/bittorrent/filesearcher.cpp @@ -33,7 +33,7 @@ #include "base/bittorrent/common.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 auto findInDir = [](const QString &dirPath, QStringList &fileNames) -> bool diff --git a/src/base/bittorrent/filesearcher.h b/src/base/bittorrent/filesearcher.h index 7084f2084..69ab5a318 100644 --- a/src/base/bittorrent/filesearcher.h +++ b/src/base/bittorrent/filesearcher.h @@ -32,7 +32,7 @@ namespace BitTorrent { - class InfoHash; + class TorrentID; } class FileSearcher final : public QObject @@ -44,9 +44,9 @@ public: FileSearcher() = default; 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); 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); }; diff --git a/src/base/bittorrent/infohash.cpp b/src/base/bittorrent/infohash.cpp index d46116e48..765113682 100644 --- a/src/base/bittorrent/infohash.cpp +++ b/src/base/bittorrent/infohash.cpp @@ -28,14 +28,54 @@ #include "infohash.h" -const int InfoHashTypeId = qRegisterMetaType(); +const int TorrentIDTypeId = qRegisterMetaType(); -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()(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()(key), seed); +} + +bool BitTorrent::operator==(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right) +{ + return (static_cast(left) == static_cast(right)); +} + +bool BitTorrent::operator!=(const BitTorrent::InfoHash &left, const BitTorrent::InfoHash &right) +{ + return !(left == right); } diff --git a/src/base/bittorrent/infohash.h b/src/base/bittorrent/infohash.h index d6a4c874c..e161dbd1d 100644 --- a/src/base/bittorrent/infohash.h +++ b/src/base/bittorrent/infohash.h @@ -28,6 +28,11 @@ #pragma once +#include +#if (LIBTORRENT_VERSION_NUM >= 20000) +#include +#endif + #include #include @@ -38,15 +43,45 @@ using SHA256Hash = Digest32<256>; namespace BitTorrent { - class InfoHash : public SHA1Hash + class InfoHash; + + class TorrentID : public Digest32<160> { 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) diff --git a/src/base/bittorrent/magneturi.cpp b/src/base/bittorrent/magneturi.cpp index 0d8461fff..b6f9e11d7 100644 --- a/src/base/bittorrent/magneturi.cpp +++ b/src/base/bittorrent/magneturi.cpp @@ -47,8 +47,8 @@ namespace // == 20 (SHA-1 length in bytes) * 2 (each byte maps to 2 hex characters) // 2. 32 chars Base32 encoded string // == 20 (SHA-1 length in bytes) * 1.6 (the efficiency of Base32 encoding) - const int SHA1_HEX_SIZE = BitTorrent::InfoHash::length() * 2; - const int SHA1_BASE32_SIZE = BitTorrent::InfoHash::length() * 1.6; + const int SHA1_HEX_SIZE = SHA1Hash::length() * 2; + const int SHA1_BASE32_SIZE = SHA1Hash::length() * 1.6; return ((((string.size() == SHA1_HEX_SIZE)) && !string.contains(QRegularExpression(QLatin1String("[^0-9A-Fa-f]")))) @@ -73,7 +73,13 @@ MagnetUri::MagnetUri(const QString &source) if (ec) return; 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_trackers.reserve(m_addTorrentParams.trackers.size()); @@ -90,9 +96,9 @@ bool MagnetUri::isValid() const return m_valid; } -InfoHash MagnetUri::hash() const +InfoHash MagnetUri::infoHash() const { - return m_hash; + return m_infoHash; } QString MagnetUri::name() const diff --git a/src/base/bittorrent/magneturi.h b/src/base/bittorrent/magneturi.h index 1bce815bc..fdc205c50 100644 --- a/src/base/bittorrent/magneturi.h +++ b/src/base/bittorrent/magneturi.h @@ -46,7 +46,7 @@ namespace BitTorrent explicit MagnetUri(const QString &source = {}); bool isValid() const; - InfoHash hash() const; + InfoHash infoHash() const; QString name() const; QVector trackers() const; QVector urlSeeds() const; @@ -57,7 +57,7 @@ namespace BitTorrent private: bool m_valid; QString m_url; - InfoHash m_hash; + InfoHash m_infoHash; QString m_name; QVector m_trackers; QVector m_urlSeeds; diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 19e6f35a5..880b84a9a 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1616,7 +1616,7 @@ void Session::processShareLimits() // We shouldn't iterate over `m_torrents` in the loop below // since `deleteTorrent()` modifies it indirectly - const QHash torrents {m_torrents}; + const QHash torrents {m_torrents}; for (TorrentImpl *const torrent : torrents) { if (torrent->isSeed() && !torrent->isForced()) @@ -1638,12 +1638,12 @@ void Session::processShareLimits() if (m_maxRatioAction == Remove) { LogMsg(tr("'%1' reached the maximum ratio you set. Removed.").arg(torrent->name())); - deleteTorrent(torrent->hash()); + deleteTorrent(torrent->id()); } else if (m_maxRatioAction == DeleteFiles) { 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()) { @@ -1677,12 +1677,12 @@ void Session::processShareLimits() if (m_maxRatioAction == Remove) { 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) { 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()) { @@ -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); if (torrent) @@ -1745,9 +1745,9 @@ void Session::fileSearchFinished(const InfoHash &id, const QString &savePath, co } // 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 @@ -1795,18 +1795,18 @@ void Session::banIP(const QString &ip) // Delete a torrent from the session, given its hash // 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; - qDebug("Deleting torrent with hash: %s", qUtf8Printable(torrent->hash().toString())); + qDebug("Deleting torrent with ID: %s", qUtf8Printable(torrent->id().toString())); emit torrentAboutToBeRemoved(torrent); // Remove it from session 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 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(); } - m_removingTorrents[torrent->hash()] = {torrent->name(), rootPath, deleteOption}; + m_removingTorrents[torrent->id()] = {torrent->name(), rootPath, deleteOption}; if (m_moveStorageQueue.size() > 1) { @@ -1854,8 +1854,8 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio } // Remove it from torrent resume directory - const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->hash().toString()); - const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->hash().toString()); + const QString resumedataFile = QString::fromLatin1("%1.fastresume").arg(torrent->id().toString()); + const QString metadataFile = QString::fromLatin1("%1.torrent").arg(torrent->id().toString()); #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) QMetaObject::invokeMethod(m_resumeDataSavingManager, [this, resumedataFile, metadataFile]() { @@ -1871,19 +1871,19 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio 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; m_downloadedMetadata.erase(downloadedMetadataIter); --m_extraLimit; 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; } -void Session::increaseTorrentsQueuePos(const QVector &hashes) +void Session::increaseTorrentsQueuePos(const QVector &ids) { using ElementType = std::pair; std::priority_queue &hashes) , std::greater> torrentQueue; // 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 (const int position = torrent->queuePosition(); position >= 0) torrentQueue.emplace(position, torrent); @@ -1910,15 +1910,15 @@ void Session::increaseTorrentsQueuePos(const QVector &hashes) saveTorrentsQueue(); } -void Session::decreaseTorrentsQueuePos(const QVector &hashes) +void Session::decreaseTorrentsQueuePos(const QVector &ids) { using ElementType = std::pair; std::priority_queue torrentQueue; // 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 (const int position = torrent->queuePosition(); position >= 0) torrentQueue.emplace(position, torrent); @@ -1938,15 +1938,15 @@ void Session::decreaseTorrentsQueuePos(const QVector &hashes) saveTorrentsQueue(); } -void Session::topTorrentsQueuePos(const QVector &hashes) +void Session::topTorrentsQueuePos(const QVector &ids) { using ElementType = std::pair; std::priority_queue torrentQueue; // 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 (const int position = torrent->queuePosition(); position >= 0) torrentQueue.emplace(position, torrent); @@ -1963,7 +1963,7 @@ void Session::topTorrentsQueuePos(const QVector &hashes) saveTorrentsQueue(); } -void Session::bottomTorrentsQueuePos(const QVector &hashes) +void Session::bottomTorrentsQueuePos(const QVector &ids) { using ElementType = std::pair; std::priority_queue &hashes) , std::greater> torrentQueue; // 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 (const int position = torrent->queuePosition(); position >= 0) torrentQueue.emplace(position, torrent); @@ -2088,20 +2088,20 @@ bool Session::addTorrent_impl(const std::variant &source const bool hasMetadata = std::holds_alternative(source); TorrentInfo metadata = (hasMetadata ? std::get(source) : TorrentInfo {}); const MagnetUri &magnetUri = (hasMetadata ? MagnetUri {} : std::get(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, // but as previous experience has shown, it actually creates unnecessary // problems and unwanted behavior due to the fact that it was originally // added with parameters other than those provided by the user. - cancelDownloadMetadata(hash); + cancelDownloadMetadata(id); // We should not add the torrent if it is already // processed or is pending to add to session - if (m_loadingTorrents.contains(hash)) + if (m_loadingTorrents.contains(id)) return false; - TorrentImpl *const torrent = m_torrents.value(hash); + TorrentImpl *const torrent = m_torrents.value(id); if (torrent) { // a duplicate torrent is added if (torrent->isPrivate() || (hasMetadata && metadata.isPrivate())) @@ -2192,7 +2192,7 @@ bool Session::addTorrent_impl(const std::variant &source if (!isFindingIncompleteFiles) return loadTorrent(loadTorrentParams); - m_loadingTorrents.insert(hash, loadTorrentParams); + m_loadingTorrents.insert(id, loadTorrentParams); return true; } @@ -2209,8 +2209,12 @@ bool Session::loadTorrent(LoadTorrentParams params) p.max_uploads = maxUploadsPerTorrent(); const bool hasMetadata = (p.ti && p.ti->is_valid()); - const InfoHash hash = (hasMetadata ? p.ti->info_hash() : p.info_hash); - m_loadingTorrents.insert(hash, params); +#if (LIBTORRENT_VERSION_NUM >= 20000) + 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 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 { - const InfoHash searchId = torrentInfo.hash(); + const auto searchId = TorrentID::fromInfoHash(torrentInfo.infoHash()); const QStringList originalFileNames = torrentInfo.filePaths(); const QString completeSavePath = savePath; const QString incompleteSavePath = (isTempPathEnabled() ? torrentTempPath(torrentInfo) : QString {}); @@ -2231,7 +2235,7 @@ void Session::findIncompleteFiles(const TorrentInfo &torrentInfo, const QString }); #else 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)); #endif } @@ -2242,17 +2246,17 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri) { if (!magnetUri.isValid()) return false; - const InfoHash hash = magnetUri.hash(); + const auto id = TorrentID::fromInfoHash(magnetUri.infoHash()); const QString name = magnetUri.name(); // We should not add torrent if it's already // processed or adding to session - if (m_torrents.contains(hash)) return false; - if (m_loadingTorrents.contains(hash)) return false; - if (m_downloadedMetadata.contains(hash)) return false; + if (m_torrents.contains(id)) return false; + if (m_loadingTorrents.contains(id)) return false; + if (m_downloadedMetadata.contains(id)) return false; qDebug("Adding torrent to preload metadata..."); - qDebug(" -> Hash: %s", qUtf8Printable(hash.toString())); + qDebug(" -> Torrent ID: %s", qUtf8Printable(id.toString())); qDebug(" -> Name: %s", qUtf8Printable(name)); lt::add_torrent_params p = magnetUri.addTorrentParams(); @@ -2268,7 +2272,7 @@ bool Session::downloadMetadata(const MagnetUri &magnetUri) p.max_connections = maxConnectionsPerTorrent(); 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(); // Forced start @@ -2301,7 +2305,7 @@ void Session::exportTorrentFile(const Torrent *torrent, TorrentExportFolder fold ((folder == TorrentExportFolder::Finished) && !finishedTorrentExportDirectory().isEmpty())); 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); const QString torrentPath = QDir(m_resumeFolderPath).absoluteFilePath(torrentFilename); const QDir exportPath(folder == TorrentExportFolder::Regular ? torrentExportDirectory() : finishedTorrentExportDirectory()); @@ -2374,13 +2378,13 @@ void Session::saveTorrentsQueue() const // We require actual (non-cached) queue position here! const int queuePos = static_cast>(torrent->nativeHandle().queue_position()); if (queuePos >= 0) - queue[queuePos] = torrent->hash().toString(); + queue[queuePos] = torrent->id().toString(); } QByteArray data; - data.reserve(((InfoHash::length() * 2) + 1) * queue.size()); - for (const QString &hash : asConst(queue)) - data += (hash.toLatin1() + '\n'); + data.reserve(((TorrentID::length() * 2) + 1) * queue.size()); + for (const QString &torrentID : asConst(queue)) + data += (torrentID.toLatin1() + '\n'); const QString filename = QLatin1String {"queue"}; #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, // 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) - || m_loadingTorrents.contains(hash) - || m_downloadedMetadata.contains(hash)); + return (m_torrents.contains(id) + || m_loadingTorrents.contains(id) + || m_downloadedMetadata.contains(id)); } void Session::updateSeedingLimitTimer() @@ -3868,7 +3872,7 @@ void Session::handleTorrentMetadataReceived(TorrentImpl *const torrent) { // Save metadata 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 { 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. // 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)) QMetaObject::invokeMethod(m_resumeDataSavingManager , [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 { - const InfoHash infoHash = job.torrentHandle.info_hash(); - const TorrentImpl *torrent = m_torrents.value(infoHash); - const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); +#if (LIBTORRENT_VERSION_NUM >= 20000) + const auto id = TorrentID::fromInfoHash(job.torrentHandle.info_hashes()); +#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)); job.torrentHandle.move_storage(job.path.toUtf8().constData() @@ -4157,9 +4165,9 @@ void Session::disableIPFilter() 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; 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()); 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(); @@ -4599,7 +4607,7 @@ void Session::createTorrent(const lt::torrent_handle &nativeHandle) { // Backup torrent file 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 { 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) { - 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->deleteOption == DeleteTorrent) @@ -4672,8 +4684,13 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p) void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p) { - const InfoHash infoHash {p->info_hash}; - const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); +#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(id); if (removingTorrentDataIter == m_removingTorrents.end()) return; @@ -4685,8 +4702,13 @@ void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p) void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_alert *p) { - const InfoHash infoHash {p->info_hash}; - const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); +#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(id); if (removingTorrentDataIter == m_removingTorrents.end()) return; @@ -4710,8 +4732,13 @@ void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_ale void Session::handleMetadataReceivedAlert(const lt::metadata_received_alert *p) { - const InfoHash hash {p->handle.info_hash()}; - const auto downloadedMetadataIter = m_downloadedMetadata.find(hash); +#if (LIBTORRENT_VERSION_NUM >= 20000) + 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()) { @@ -4732,11 +4759,11 @@ void Session::handleFileErrorAlert(const lt::file_error_alert *p) if (!torrent) 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()); 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()}; Q_ASSERT(newPath == currentJob.path); - const InfoHash infoHash = currentJob.torrentHandle.info_hash(); - TorrentImpl *torrent = m_torrents.value(infoHash); - const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); +#if (LIBTORRENT_VERSION_NUM >= 20000) + const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes()); +#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)); handleMoveTorrentStorageJobFinished(); @@ -4950,9 +4982,14 @@ void Session::handleStorageMovedFailedAlert(const lt::storage_moved_failed_alert const MoveStorageJob ¤tJob = m_moveStorageQueue.first(); Q_ASSERT(currentJob.torrentHandle == p->handle); - const InfoHash infoHash = currentJob.torrentHandle.info_hash(); - TorrentImpl *torrent = m_torrents.value(infoHash); - const QString torrentName = (torrent ? torrent->name() : infoHash.toString()); +#if (LIBTORRENT_VERSION_NUM >= 20000) + const auto id = TorrentID::fromInfoHash(currentJob.torrentHandle.info_hashes()); +#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 errorMessage = QString::fromStdString(p->message()); 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) { - 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) continue; diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index db0209235..e7f6ccb52 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -434,7 +434,7 @@ namespace BitTorrent #endif void startUpTorrents(); - Torrent *findTorrent(const InfoHash &hash) const; + Torrent *findTorrent(const TorrentID &id) const; QVector torrents() const; bool hasActiveTorrents() const; bool hasUnfinishedTorrents() const; @@ -450,19 +450,19 @@ namespace BitTorrent void banIP(const QString &ip); - bool isKnownTorrent(const InfoHash &hash) const; + bool isKnownTorrent(const TorrentID &id) const; bool addTorrent(const QString &source, const AddTorrentParams ¶ms = AddTorrentParams()); bool addTorrent(const MagnetUri &magnetUri, const AddTorrentParams ¶ms = AddTorrentParams()); bool addTorrent(const TorrentInfo &torrentInfo, const AddTorrentParams ¶ms = AddTorrentParams()); - bool deleteTorrent(const InfoHash &hash, DeleteOption deleteOption = DeleteTorrent); + bool deleteTorrent(const TorrentID &id, DeleteOption deleteOption = DeleteTorrent); bool downloadMetadata(const MagnetUri &magnetUri); - bool cancelDownloadMetadata(const InfoHash &hash); + bool cancelDownloadMetadata(const TorrentID &id); - void recursiveTorrentDownload(const InfoHash &hash); - void increaseTorrentsQueuePos(const QVector &hashes); - void decreaseTorrentsQueuePos(const QVector &hashes); - void topTorrentsQueuePos(const QVector &hashes); - void bottomTorrentsQueuePos(const QVector &hashes); + void recursiveTorrentDownload(const TorrentID &id); + void increaseTorrentsQueuePos(const QVector &ids); + void decreaseTorrentsQueuePos(const QVector &ids); + void topTorrentsQueuePos(const QVector &ids); + void bottomTorrentsQueuePos(const QVector &ids); // Torrent interface void handleTorrentSaveResumeDataRequested(const TorrentImpl *torrent); @@ -539,7 +539,7 @@ namespace BitTorrent void handleIPFilterParsed(int ruleCount); void handleIPFilterError(); 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 void networkOnlineStateChanged(bool online); @@ -764,17 +764,17 @@ namespace BitTorrent ResumeDataSavingManager *m_resumeDataSavingManager = nullptr; FileSearcher *m_fileSearcher = nullptr; - QSet m_downloadedMetadata; + QSet m_downloadedMetadata; - QHash m_torrents; - QHash m_loadingTorrents; + QHash m_torrents; + QHash m_loadingTorrents; QHash m_downloadedTorrents; - QHash m_removingTorrents; + QHash m_removingTorrents; QStringMap m_categories; QSet m_tags; // I/O errored torrents - QSet m_recentErroredTorrents; + QSet m_recentErroredTorrents; QTimer *m_recentErroredTorrentsTimer = nullptr; SessionMetricIndices m_metricIndices; diff --git a/src/base/bittorrent/torrent.cpp b/src/base/bittorrent/torrent.cpp index d7e52ff8d..700011461 100644 --- a/src/base/bittorrent/torrent.cpp +++ b/src/base/bittorrent/torrent.cpp @@ -31,6 +31,8 @@ #include +#include "infohash.h" + namespace BitTorrent { uint qHash(const TorrentState key, const uint seed) @@ -49,6 +51,11 @@ namespace BitTorrent const qreal Torrent::MAX_RATIO = 9999; const int Torrent::MAX_SEEDING_TIME = 525600; + TorrentID Torrent::id() const + { + return infoHash().toTorrentID(); + } + bool Torrent::isResumed() const { return !isPaused(); diff --git a/src/base/bittorrent/torrent.h b/src/base/bittorrent/torrent.h index 5396f34dc..97a051c63 100644 --- a/src/base/bittorrent/torrent.h +++ b/src/base/bittorrent/torrent.h @@ -44,6 +44,7 @@ namespace BitTorrent enum class DownloadPriority; class InfoHash; class PeerInfo; + class TorrentID; class TorrentInfo; struct PeerAddress; struct TrackerEntry; @@ -105,7 +106,7 @@ namespace BitTorrent virtual ~Torrent() = default; - virtual InfoHash hash() const = 0; + virtual InfoHash infoHash() const = 0; virtual QString name() const = 0; virtual QDateTime creationDate() const = 0; virtual QString creator() const = 0; @@ -290,6 +291,7 @@ namespace BitTorrent virtual QString createMagnetURI() const = 0; + TorrentID id() const; bool isResumed() const; qlonglong remainingSize() const; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index eaf9cd415..b5fb2bf94 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -218,6 +218,11 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession , m_session(session) , m_nativeSession(nativeSession) , 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_savePath(Utils::Fs::toNativePath(params.savePath)) , m_category(params.category) @@ -235,7 +240,6 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession if (m_useAutoTMM) m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category)); - m_hash = InfoHash {m_nativeHandle.info_hash()}; if (m_ltAddTorrentParams.ti) { // Initialize it only if torrent is added with metadata. @@ -280,9 +284,9 @@ bool TorrentImpl::isValid() const return m_nativeHandle.is_valid(); } -InfoHash TorrentImpl::hash() const +InfoHash TorrentImpl::infoHash() const { - return m_hash; + return m_infoHash; } QString TorrentImpl::name() const @@ -297,7 +301,7 @@ QString TorrentImpl::name() const if (!name.isEmpty()) return name; - return m_hash.toString(); + return id().toString(); } QDateTime TorrentImpl::creationDate() const diff --git a/src/base/bittorrent/torrentimpl.h b/src/base/bittorrent/torrentimpl.h index 4ef9fa32b..16a935066 100644 --- a/src/base/bittorrent/torrentimpl.h +++ b/src/base/bittorrent/torrentimpl.h @@ -99,7 +99,7 @@ namespace BitTorrent bool isValid() const; - InfoHash hash() const override; + InfoHash infoHash() const override; QString name() const override; QDateTime creationDate() const override; QString creator() const override; @@ -301,7 +301,7 @@ namespace BitTorrent TorrentInfo m_torrentInfo; SpeedMonitor m_speedMonitor; - InfoHash m_hash; + InfoHash m_infoHash; // m_moveFinishedTriggers is activated only when the following conditions are met: // all file rename jobs complete, all file move jobs complete diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index ffe228c3a..7630c24bf 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/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)); } -InfoHash TorrentInfo::hash() const +InfoHash TorrentInfo::infoHash() const { if (!isValid()) return {}; + +#if (LIBTORRENT_VERSION_NUM >= 20000) + return m_nativeInfo->info_hashes(); +#else return m_nativeInfo->info_hash(); +#endif } QString TorrentInfo::name() const @@ -374,7 +379,7 @@ QVector TorrentInfo::pieceHashes() const hashes.reserve(count); 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; } diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index 7c842102d..17d4b5ddb 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -62,7 +62,7 @@ namespace BitTorrent TorrentInfo &operator=(const TorrentInfo &other); bool isValid() const; - InfoHash hash() const; + InfoHash infoHash() const; QString name() const; QDateTime creationDate() const; QString creator() const; diff --git a/src/base/bittorrent/tracker.cpp b/src/base/bittorrent/tracker.cpp index f4cfeae43..372242d49 100644 --- a/src/base/bittorrent/tracker.cpp +++ b/src/base/bittorrent/tracker.cpp @@ -153,7 +153,7 @@ struct Tracker::TrackerAnnounceRequest { QHostAddress socketAddress; QByteArray claimedAddress; // self claimed by peer - InfoHash infoHash; + TorrentID torrentID; QString event; Peer peer; int numwant = 50; @@ -295,11 +295,11 @@ void Tracker::processAnnounceRequest() if (infoHashIter == queryParams.end()) throw TrackerError("Missing \"info_hash\" parameter"); - const auto infoHash = InfoHash::fromString(infoHashIter->toHex()); - if (!infoHash.isValid()) + const auto torrentID = TorrentID::fromString(infoHashIter->toHex()); + if (!torrentID.isValid()) throw TrackerError("Invalid \"info_hash\" parameter"); - announceReq.infoHash = infoHash; + announceReq.torrentID = torrentID; // 2. peer_id const auto peerIdIter = queryParams.find(ANNOUNCE_REQUEST_PEER_ID); @@ -381,19 +381,19 @@ void Tracker::processAnnounceRequest() 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 if (m_torrents.size() >= MAX_TORRENTS) 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) { - const auto torrentStatsIter = m_torrents.find(announceReq.infoHash); + const auto torrentStatsIter = m_torrents.find(announceReq.torrentID); if (torrentStatsIter == m_torrents.end()) return; @@ -405,7 +405,7 @@ void Tracker::unregisterPeer(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 { diff --git a/src/base/bittorrent/tracker.h b/src/base/bittorrent/tracker.h index 440e1bf2f..4a9ba6ed2 100644 --- a/src/base/bittorrent/tracker.h +++ b/src/base/bittorrent/tracker.h @@ -102,6 +102,6 @@ namespace BitTorrent Http::Request m_request; Http::Environment m_env; - QHash m_torrents; + QHash m_torrents; }; } diff --git a/src/base/torrentfilter.cpp b/src/base/torrentfilter.cpp index c8c154d28..58a7b7d89 100644 --- a/src/base/torrentfilter.cpp +++ b/src/base/torrentfilter.cpp @@ -32,7 +32,7 @@ #include "bittorrent/torrent.h" const QString TorrentFilter::AnyCategory; -const InfoHashSet TorrentFilter::AnyHash {{}}; +const TorrentIDSet TorrentFilter::AnyID {{}}; const QString TorrentFilter::AnyTag; const TorrentFilter TorrentFilter::DownloadingTorrent(TorrentFilter::Downloading); @@ -49,19 +49,19 @@ const TorrentFilter TorrentFilter::ErroredTorrent(TorrentFilter::Errored); 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_category(category) , 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_category(category) , m_tag(tag) - , m_hashSet(hashSet) + , m_idSet(idSet) { setTypeByName(filter); } @@ -107,11 +107,11 @@ bool TorrentFilter::setTypeByName(const QString &filter) 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; } @@ -189,9 +189,9 @@ bool TorrentFilter::matchState(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 diff --git a/src/base/torrentfilter.h b/src/base/torrentfilter.h index 44f85699b..08364144c 100644 --- a/src/base/torrentfilter.h +++ b/src/base/torrentfilter.h @@ -38,7 +38,7 @@ namespace BitTorrent class Torrent; } -using InfoHashSet = QSet; +using TorrentIDSet = QSet; class TorrentFilter { @@ -61,7 +61,7 @@ public: // These mean any permutation, including no category / tag. static const QString AnyCategory; - static const InfoHashSet AnyHash; + static const TorrentIDSet AnyID; static const QString AnyTag; static const TorrentFilter DownloadingTorrent; @@ -79,12 +79,12 @@ public: TorrentFilter() = default; // category & tags: pass empty string for uncategorized / untagged 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(const QString &filter, const InfoHashSet &hashSet = AnyHash, const QString &category = AnyCategory, const QString &tags = AnyTag); + TorrentFilter(Type type, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tag = AnyTag); + TorrentFilter(const QString &filter, const TorrentIDSet &idSet = AnyID, const QString &category = AnyCategory, const QString &tags = AnyTag); bool setType(Type type); bool setTypeByName(const QString &filter); - bool setHashSet(const InfoHashSet &hashSet); + bool setTorrentIDSet(const TorrentIDSet &idSet); bool setCategory(const QString &category); bool setTag(const QString &tag); @@ -99,5 +99,5 @@ private: Type m_type {All}; QString m_category; QString m_tag; - InfoHashSet m_hashSet; + TorrentIDSet m_idSet; }; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index f98361577..6546a845a 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -270,12 +270,12 @@ bool AddNewTorrentDialog::loadTorrentFile(const QString &torrentPath) bool AddNewTorrentDialog::loadTorrentImpl() { 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 - 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->isPrivate() || m_torrentInfo.isPrivate()) @@ -296,7 +296,7 @@ bool AddNewTorrentDialog::loadTorrentImpl() return false; } - m_ui->labelHashData->setText(infoHash.toString()); + m_ui->labelHashData->setText(torrentID.toString()); setupTreeview(); TMMChanged(m_ui->comboTTM->currentIndex()); return true; @@ -312,11 +312,11 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri) m_torrentGuard = std::make_unique(); - const BitTorrent::InfoHash infoHash = magnetUri.hash(); + const auto torrentID = BitTorrent::TorrentID::fromInfoHash(magnetUri.infoHash()); // 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->isPrivate()) @@ -348,7 +348,7 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri) BitTorrent::Session::instance()->downloadMetadata(magnetUri); setMetadataProgressIndicator(true, tr("Retrieving metadata...")); - m_ui->labelHashData->setText(infoHash.toString()); + m_ui->labelHashData->setText(torrentID.toString()); m_magnetURI = magnetUri; return true; @@ -629,7 +629,7 @@ void AddNewTorrentDialog::reject() if (!m_hasMetadata) { setMetadataProgressIndicator(false); - BitTorrent::Session::instance()->cancelDownloadMetadata(m_magnetURI.hash()); + BitTorrent::Session::instance()->cancelDownloadMetadata(m_magnetURI.infoHash().toTorrentID()); } QDialog::reject(); @@ -637,7 +637,7 @@ void AddNewTorrentDialog::reject() 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); diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index b6a208062..e0f3cc117 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -958,7 +958,7 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co Preferences *const pref = Preferences::instance(); if (pref->recursiveDownloadDisabled()) return; - const auto torrentHash = torrent->hash(); + const auto torrentID = torrent->id(); 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()) @@ -969,10 +969,10 @@ void MainWindow::askRecursiveTorrentDownloadConfirmation(BitTorrent::Torrent *co const QPushButton *yes = confirmBox->addButton(tr("Yes"), QMessageBox::YesRole); /*QPushButton *no = */ confirmBox->addButton(tr("No"), 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) - BitTorrent::Session::instance()->recursiveTorrentDownload(torrentHash); + BitTorrent::Session::instance()->recursiveTorrentDownload(torrentID); if (button == never) Preferences::instance()->disableRecursiveDownload(); }); diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index b74e4312c..48d901f84 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -312,8 +312,9 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::Torrent *const torrent) // Save path updateSavePath(m_torrent); - // Hash - m_ui->labelHashVal->setText(m_torrent->hash().toString()); + // Info hash (Truncated info hash (torrent ID) with libtorrent2) + // 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(); if (m_torrent->hasMetadata()) { diff --git a/src/gui/torrentoptionsdialog.cpp b/src/gui/torrentoptionsdialog.cpp index 45968960d..71326f71c 100644 --- a/src/gui/torrentoptionsdialog.cpp +++ b/src/gui/torrentoptionsdialog.cpp @@ -77,10 +77,10 @@ TorrentOptionsDialog::TorrentOptionsDialog(QWidget *parent, const QVectorisPEXDisabled(); const bool isFirstTorrentLSDDisabled = torrents[0]->isLSDDisabled(); - m_torrentHashes.reserve(torrents.size()); + m_torrentIDs.reserve(torrents.size()); for (const BitTorrent::Torrent *torrent : torrents) { - m_torrentHashes << torrent->hash(); + m_torrentIDs << torrent->id(); if (allSameUpLimit) { if (qMax(0, torrent->uploadLimit()) != firstTorrentUpLimit) @@ -288,9 +288,9 @@ void TorrentOptionsDialog::accept() } 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 (m_initialValues.upSpeedLimit != m_ui->spinUploadLimit->value()) diff --git a/src/gui/torrentoptionsdialog.h b/src/gui/torrentoptionsdialog.h index e5927cda4..8ecdb6824 100644 --- a/src/gui/torrentoptionsdialog.h +++ b/src/gui/torrentoptionsdialog.h @@ -36,8 +36,8 @@ namespace BitTorrent { - class InfoHash; class Torrent; + class TorrentID; } namespace Ui @@ -67,7 +67,7 @@ private: qreal getRatio() const; int getSeedingTime() const; - QVector m_torrentHashes; + QVector m_torrentIDs; Ui::TorrentOptionsDialog *m_ui; SettingValue m_storeDialogSize; struct diff --git a/src/gui/transferlistfilterswidget.cpp b/src/gui/transferlistfilterswidget.cpp index cb8d8489a..678b50ddd 100644 --- a/src/gui/transferlistfilterswidget.cpp +++ b/src/gui/transferlistfilterswidget.cpp @@ -321,7 +321,7 @@ TrackerFiltersList::~TrackerFiltersList() 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 bool exists {m_trackers.contains(host)}; @@ -329,7 +329,7 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH if (exists) { - if (m_trackers.value(host).contains(hash)) + if (m_trackers.value(host).contains(id)) return; trackerItem = item((host == NULL_HOST) @@ -346,18 +346,18 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH } if (!trackerItem) return; - QSet &hashes {m_trackers[host]}; - hashes.insert(hash); + QSet &torrentIDs {m_trackers[host]}; + torrentIDs.insert(id); if (host == NULL_HOST) { - trackerItem->setText(tr("Trackerless (%1)").arg(hashes.size())); + trackerItem->setText(tr("Trackerless (%1)").arg(torrentIDs.size())); if (currentRow() == TRACKERLESS_ROW) applyFilter(TRACKERLESS_ROW); 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 (currentRow() == rowFromTracker(host)) @@ -379,14 +379,14 @@ void TrackerFiltersList::addItem(const QString &tracker, const BitTorrent::InfoH 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); - QSet hashes = m_trackers.value(host); + QSet torrentIDs = m_trackers.value(host); - if (hashes.empty()) + if (torrentIDs.empty()) return; - hashes.remove(hash); + torrentIDs.remove(id); int row = 0; QListWidgetItem *trackerItem = nullptr; @@ -394,11 +394,11 @@ void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::In if (!host.isEmpty()) { // Remove from 'Error' and 'Warning' view - trackerSuccess(hash, tracker); + trackerSuccess(id, tracker); row = rowFromTracker(host); trackerItem = item(row); - if (hashes.empty()) + if (torrentIDs.empty()) { if (currentRow() == row) setCurrentRow(0, QItemSelectionModel::SelectCurrent); @@ -409,27 +409,27 @@ void TrackerFiltersList::removeItem(const QString &tracker, const BitTorrent::In } 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 { row = 1; 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) applyFilter(row); } -void TrackerFiltersList::changeTrackerless(const bool trackerless, const BitTorrent::InfoHash &hash) +void TrackerFiltersList::changeTrackerless(const bool trackerless, const BitTorrent::TorrentID &id) { if (trackerless) - addItem(NULL_HOST, hash); + addItem(NULL_HOST, id); else - removeItem(NULL_HOST, hash); + removeItem(NULL_HOST, id); } 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()) { QSet &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()) { QSet &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 &trackers {m_errors[hash]}; + QSet &trackers {m_errors[id]}; if (trackers.contains(tracker)) return; @@ -495,9 +495,9 @@ void TrackerFiltersList::trackerError(const BitTorrent::InfoHash &hash, const QS applyFilter(ERROR_ROW); } -void TrackerFiltersList::trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker) +void TrackerFiltersList::trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker) { - QSet &trackers {m_warnings[hash]}; + QSet &trackers {m_warnings[id]}; if (trackers.contains(tracker)) return; @@ -572,33 +572,33 @@ void TrackerFiltersList::applyFilter(const int row) if (row == ALL_ROW) transferList->applyTrackerFilterAll(); else if (isVisible()) - transferList->applyTrackerFilter(getInfoHashes(row)); + transferList->applyTrackerFilter(getTorrentIDs(row)); } void TrackerFiltersList::handleNewTorrent(BitTorrent::Torrent *const torrent) { - const BitTorrent::InfoHash hash {torrent->hash()}; + const BitTorrent::TorrentID torrentID {torrent->id()}; const QVector trackers {torrent->trackers()}; for (const BitTorrent::TrackerEntry &tracker : trackers) - addItem(tracker.url, hash); + addItem(tracker.url, torrentID); // Check for trackerless torrent 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)); } void TrackerFiltersList::torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) { - const BitTorrent::InfoHash hash {torrent->hash()}; + const BitTorrent::TorrentID torrentID {torrent->id()}; const QVector trackers {torrent->trackers()}; for (const BitTorrent::TrackerEntry &tracker : trackers) - removeItem(tracker.url, hash); + removeItem(tracker.url, torrentID); // Check for trackerless torrent 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)); } @@ -624,7 +624,7 @@ int TrackerFiltersList::rowFromTracker(const QString &tracker) const return -1; } -QSet TrackerFiltersList::getInfoHashes(const int row) const +QSet TrackerFiltersList::getTorrentIDs(const int row) const { switch (row) { @@ -727,11 +727,11 @@ TransferListFiltersWidget::TransferListFiltersWidget(QWidget *parent, TransferLi connect(trackerLabel, &QCheckBox::toggled, m_trackerFilters, &TrackerFiltersList::toggleFilter); connect(trackerLabel, &QCheckBox::toggled, pref, &Preferences::setTrackerFilterState); - connect(this, qOverload(&TransferListFiltersWidget::trackerSuccess) + connect(this, qOverload(&TransferListFiltersWidget::trackerSuccess) , m_trackerFilters, &TrackerFiltersList::trackerSuccess); - connect(this, qOverload(&TransferListFiltersWidget::trackerError) + connect(this, qOverload(&TransferListFiltersWidget::trackerError) , m_trackerFilters, &TrackerFiltersList::trackerError); - connect(this, qOverload(&TransferListFiltersWidget::trackerWarning) + connect(this, qOverload(&TransferListFiltersWidget::trackerWarning) , m_trackerFilters, &TrackerFiltersList::trackerWarning); } @@ -743,33 +743,33 @@ void TransferListFiltersWidget::setDownloadTrackerFavicon(bool value) void TransferListFiltersWidget::addTrackers(const BitTorrent::Torrent *torrent, const QVector &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 &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) { - m_trackerFilters->changeTrackerless(trackerless, torrent->hash()); + m_trackerFilters->changeTrackerless(trackerless, torrent->id()); } 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) { - emit trackerWarning(torrent->hash(), tracker); + emit trackerWarning(torrent->id(), 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) diff --git a/src/gui/transferlistfilterswidget.h b/src/gui/transferlistfilterswidget.h index 0c29753e0..0d384f216 100644 --- a/src/gui/transferlistfilterswidget.h +++ b/src/gui/transferlistfilterswidget.h @@ -39,8 +39,8 @@ class TransferListWidget; namespace BitTorrent { - class InfoHash; class Torrent; + class TorrentID; struct TrackerEntry; } @@ -104,15 +104,15 @@ public: ~TrackerFiltersList() override; // Redefine addItem() to make sure the list stays sorted - void addItem(const QString &tracker, const BitTorrent::InfoHash &hash); - void removeItem(const QString &tracker, const BitTorrent::InfoHash &hash); - void changeTrackerless(bool trackerless, const BitTorrent::InfoHash &hash); + void addItem(const QString &tracker, const BitTorrent::TorrentID &id); + void removeItem(const QString &tracker, const BitTorrent::TorrentID &id); + void changeTrackerless(bool trackerless, const BitTorrent::TorrentID &id); void setDownloadTrackerFavicon(bool value); public slots: - void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker); - void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker); - void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker); + void trackerSuccess(const BitTorrent::TorrentID &id, const QString &tracker); + void trackerError(const BitTorrent::TorrentID &id, const QString &tracker); + void trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker); private slots: void handleFavicoDownloadFinished(const Net::DownloadResult &result); @@ -126,12 +126,12 @@ private: void torrentAboutToBeDeleted(BitTorrent::Torrent *const torrent) override; QString trackerFromRow(int row) const; int rowFromTracker(const QString &tracker) const; - QSet getInfoHashes(int row) const; + QSet getTorrentIDs(int row) const; void downloadFavicon(const QString &url); - QHash> m_trackers; // - QHash> m_errors; // - QHash> m_warnings; // + QHash> m_trackers; // + QHash> m_errors; // + QHash> m_warnings; // QStringList m_iconPaths; int m_totalTorrents; bool m_downloadTrackerFavicon; @@ -158,9 +158,9 @@ public slots: void trackerError(const BitTorrent::Torrent *torrent, const QString &tracker); signals: - void trackerSuccess(const BitTorrent::InfoHash &hash, const QString &tracker); - void trackerError(const BitTorrent::InfoHash &hash, const QString &tracker); - void trackerWarning(const BitTorrent::InfoHash &hash, const QString &tracker); + void trackerSuccess(const BitTorrent::TorrentID &id, const QString &tracker); + void trackerError(const BitTorrent::TorrentID &id, const QString &tracker); + void trackerWarning(const BitTorrent::TorrentID &id, const QString &tracker); private slots: void onCategoryFilterStateChanged(bool enabled); diff --git a/src/gui/transferlistsortmodel.cpp b/src/gui/transferlistsortmodel.cpp index 2e804887c..c977d2246 100644 --- a/src/gui/transferlistsortmodel.cpp +++ b/src/gui/transferlistsortmodel.cpp @@ -99,15 +99,15 @@ void TransferListSortModel::disableTagFilter() invalidateFilter(); } -void TransferListSortModel::setTrackerFilter(const QSet &hashes) +void TransferListSortModel::setTrackerFilter(const QSet &torrentIDs) { - if (m_filter.setHashSet(hashes)) + if (m_filter.setTorrentIDSet(torrentIDs)) invalidateFilter(); } void TransferListSortModel::disableTrackerFilter() { - if (m_filter.setHashSet(TorrentFilter::AnyHash)) + if (m_filter.setTorrentIDSet(TorrentFilter::AnyID)) invalidateFilter(); } diff --git a/src/gui/transferlistsortmodel.h b/src/gui/transferlistsortmodel.h index a8ea23dac..2a4f88aa4 100644 --- a/src/gui/transferlistsortmodel.h +++ b/src/gui/transferlistsortmodel.h @@ -50,7 +50,7 @@ public: void disableCategoryFilter(); void setTagFilter(const QString &tag); void disableTagFilter(); - void setTrackerFilter(const QSet &hashes); + void setTrackerFilter(const QSet &torrentIDs); void disableTrackerFilter(); private: diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index df1d3b638..9fce01fc5 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -78,13 +78,13 @@ namespace { - QVector extractHashes(const QVector &torrents) + QVector extractIDs(const QVector &torrents) { - QVector hashes; - hashes.reserve(torrents.size()); + QVector torrentIDs; + torrentIDs.reserve(torrents.size()); for (const BitTorrent::Torrent *torrent : torrents) - hashes << torrent->hash(); - return hashes; + torrentIDs << torrent->id(); + return torrentIDs; } bool torrentContainsPreviewableFiles(const BitTorrent::Torrent *const torrent) @@ -121,7 +121,7 @@ namespace auto *session = BitTorrent::Session::instance(); const DeleteOption deleteOption = isDeleteFileSelected ? DeleteTorrentAndFiles : DeleteTorrent; 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; if (m_mainWindow->currentTabWidget() == this) - BitTorrent::Session::instance()->increaseTorrentsQueuePos(extractHashes(getSelectedTorrents())); + BitTorrent::Session::instance()->increaseTorrentsQueuePos(extractIDs(getSelectedTorrents())); } void TransferListWidget::decreaseQueuePosSelectedTorrents() { qDebug() << Q_FUNC_INFO; if (m_mainWindow->currentTabWidget() == this) - BitTorrent::Session::instance()->decreaseTorrentsQueuePos(extractHashes(getSelectedTorrents())); + BitTorrent::Session::instance()->decreaseTorrentsQueuePos(extractIDs(getSelectedTorrents())); } void TransferListWidget::topQueuePosSelectedTorrents() { if (m_mainWindow->currentTabWidget() == this) - BitTorrent::Session::instance()->topTorrentsQueuePos(extractHashes(getSelectedTorrents())); + BitTorrent::Session::instance()->topTorrentsQueuePos(extractIDs(getSelectedTorrents())); } void TransferListWidget::bottomQueuePosSelectedTorrents() { if (m_mainWindow->currentTabWidget() == this) - BitTorrent::Session::instance()->bottomTorrentsQueuePos(extractHashes(getSelectedTorrents())); + BitTorrent::Session::instance()->bottomTorrentsQueuePos(extractIDs(getSelectedTorrents())); } void TransferListWidget::copySelectedMagnetURIs() const @@ -494,11 +494,11 @@ void TransferListWidget::copySelectedNames() const void TransferListWidget::copySelectedHashes() const { - QStringList torrentHashes; + QStringList torrentIDs; 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) @@ -1129,9 +1129,9 @@ void TransferListWidget::applyTrackerFilterAll() m_sortFilterModel->disableTrackerFilter(); } -void TransferListWidget::applyTrackerFilter(const QSet &hashes) +void TransferListWidget::applyTrackerFilter(const QSet &torrentIDs) { - m_sortFilterModel->setTrackerFilter(hashes); + m_sortFilterModel->setTrackerFilter(torrentIDs); } void TransferListWidget::applyNameFilter(const QString &name) diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index baffb9e06..d1604b2bb 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -39,8 +39,8 @@ class TransferListSortModel; namespace BitTorrent { - class InfoHash; class Torrent; + class TorrentID; } class TransferListWidget final : public QTreeView @@ -88,7 +88,7 @@ public slots: void applyCategoryFilter(const QString &category); void applyTagFilter(const QString &tag); void applyTrackerFilterAll(); - void applyTrackerFilter(const QSet &hashes); + void applyTrackerFilter(const QSet &torrentIDs); void previewFile(const QString &filePath); void renameSelectedTorrent(); diff --git a/src/webui/api/serialize/serialize_torrent.cpp b/src/webui/api/serialize/serialize_torrent.cpp index d39115091..76065ab69 100644 --- a/src/webui/api/serialize/serialize_torrent.cpp +++ b/src/webui/api/serialize/serialize_torrent.cpp @@ -103,7 +103,8 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent) }; 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_MAGNET_URI, torrent.createMagnetURI()}, {KEY_TORRENT_SIZE, torrent.wantedSize()}, diff --git a/src/webui/api/serialize/serialize_torrent.h b/src/webui/api/serialize/serialize_torrent.h index 1db455af1..de42077b5 100644 --- a/src/webui/api/serialize/serialize_torrent.h +++ b/src/webui/api/serialize/serialize_torrent.h @@ -36,7 +36,7 @@ namespace BitTorrent } // Torrent keys -const char KEY_TORRENT_HASH[] = "hash"; +const char KEY_TORRENT_ID[] = "hash"; const char KEY_TORRENT_NAME[] = "name"; const char KEY_TORRENT_MAGNET_URI[] = "magnet_uri"; const char KEY_TORRENT_SIZE[] = "size"; diff --git a/src/webui/api/synccontroller.cpp b/src/webui/api/synccontroller.cpp index 5ebe2881a..57e71cc70 100644 --- a/src/webui/api/synccontroller.cpp +++ b/src/webui/api/synccontroller.cpp @@ -460,10 +460,10 @@ void SyncController::maindataAction() QHash trackers; for (const BitTorrent::Torrent *torrent : asConst(session->torrents())) { - const BitTorrent::InfoHash torrentHash = torrent->hash(); + const BitTorrent::TorrentID torrentID = torrent->id(); 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). // So we don't need unnecessary updates of last activity time in response. @@ -471,11 +471,11 @@ void SyncController::maindataAction() if (iterTorrents != lastResponse.end()) { 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); if (iterLastActivity != torrentData.end()) @@ -488,9 +488,9 @@ void SyncController::maindataAction() } 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; @@ -534,15 +534,15 @@ void SyncController::maindataAction() } // GET param: -// - hash (string): torrent hash +// - hash (string): torrent hash (ID) // - rid (int): last response id void SyncController::torrentPeersAction() { auto lastResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastResponse")).toMap(); auto lastAcceptedResponse = sessionManager()->session()->getData(QLatin1String("syncTorrentPeersLastAcceptedResponse")).toMap(); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp index 30ca1358c..45edc13e1 100644 --- a/src/webui/api/torrentscontroller.cpp +++ b/src/webui/api/torrentscontroller.cpp @@ -120,18 +120,18 @@ namespace using Utils::String::parseInt; using Utils::String::parseDouble; - void applyToTorrents(const QStringList &hashes, const std::function &func) + void applyToTorrents(const QStringList &idList, const std::function &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())) func(torrent); } 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); if (torrent) func(torrent); @@ -211,20 +211,20 @@ namespace return {dht, pex, lsd}; } - QVector toInfoHashes(const QStringList &hashes) + QVector toTorrentIDs(const QStringList &idStrings) { - QVector infoHashes; - infoHashes.reserve(hashes.size()); - for (const QString &hash : hashes) - infoHashes << BitTorrent::InfoHash::fromString(hash); - return infoHashes; + QVector idList; + idList.reserve(idStrings.size()); + for (const QString &hash : idStrings) + idList << BitTorrent::TorrentID::fromString(hash); + return idList; } } // Returns all the torrents in JSON format. // The return value is a JSON-formatted list of dictionaries. // The dictionary keys are: -// - "hash": Torrent hash +// - "hash": Torrent hash (ID) // - "name": Torrent name // - "size": Torrent size // - "progress": Torrent progress @@ -260,11 +260,11 @@ void TorrentsController::infoAction() int offset {params()["offset"].toInt()}; const QStringList hashes {params()["hashes"].split('|', QString::SkipEmptyParts)}; - InfoHashSet hashSet; + TorrentIDSet idSet; 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; for (const BitTorrent::Torrent *torrent : asConst(BitTorrent::Session::instance()->torrents())) { @@ -374,8 +374,8 @@ void TorrentsController::propertiesAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -445,8 +445,8 @@ void TorrentsController::trackersAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -481,8 +481,8 @@ void TorrentsController::webseedsAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -512,8 +512,8 @@ void TorrentsController::filesAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + const BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -558,8 +558,8 @@ void TorrentsController::pieceHashesAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -580,8 +580,8 @@ void TorrentsController::pieceStatesAction() { requireParams({"hash"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -691,8 +691,8 @@ void TorrentsController::addTrackersAction() { requireParams({"hash", "urls"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -710,11 +710,11 @@ void TorrentsController::editTrackerAction() { 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 newUrl = params()["newUrl"]; - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -751,8 +751,8 @@ void TorrentsController::removeTrackersAction() { requireParams({"hash", "urls"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -804,7 +804,7 @@ void TorrentsController::addPeersAction() return torrent->connectPeer(peer); }); - results[torrent->hash().toString()] = QJsonObject + results[torrent->id().toString()] = QJsonObject { {"added", peersAdded}, {"failed", (peers.size() - peersAdded)} @@ -826,15 +826,15 @@ void TorrentsController::resumeAction() { requireParams({"hashes"}); - const QStringList hashes = params()["hashes"].split('|'); - applyToTorrents(hashes, [](BitTorrent::Torrent *const torrent) { torrent->resume(); }); + const QStringList idStrings = params()["hashes"].split('|'); + applyToTorrents(idStrings, [](BitTorrent::Torrent *const torrent) { torrent->resume(); }); } void TorrentsController::filePrioAction() { requireParams({"hash", "id", "priority"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); bool ok = false; const auto priority = static_cast(params()["priority"].toInt(&ok)); if (!ok) @@ -843,7 +843,7 @@ void TorrentsController::filePrioAction() if (!BitTorrent::isValidDownloadPriority(priority)) 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) throw APIError(APIErrorType::NotFound); if (!torrent->hasMetadata()) @@ -875,15 +875,15 @@ void TorrentsController::uploadLimitAction() { requireParams({"hashes"}); - const QStringList hashes {params()["hashes"].split('|')}; + const QStringList idList {params()["hashes"].split('|')}; QJsonObject map; - for (const QString &hash : hashes) + for (const QString &id : idList) { 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) limit = torrent->uploadLimit(); - map[hash] = limit; + map[id] = limit; } setResult(map); @@ -893,15 +893,15 @@ void TorrentsController::downloadLimitAction() { requireParams({"hashes"}); - const QStringList hashes {params()["hashes"].split('|')}; + const QStringList idList {params()["hashes"].split('|')}; QJsonObject map; - for (const QString &hash : hashes) + for (const QString &id : idList) { 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) limit = torrent->downloadLimit(); - map[hash] = limit; + map[id] = limit; } setResult(map); @@ -992,7 +992,7 @@ void TorrentsController::deleteAction() ? DeleteTorrentAndFiles : DeleteTorrent; 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")); const QStringList hashes {params()["hashes"].split('|')}; - BitTorrent::Session::instance()->increaseTorrentsQueuePos(toInfoHashes(hashes)); + BitTorrent::Session::instance()->increaseTorrentsQueuePos(toTorrentIDs(hashes)); } void TorrentsController::decreasePrioAction() @@ -1015,7 +1015,7 @@ void TorrentsController::decreasePrioAction() throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); const QStringList hashes {params()["hashes"].split('|')}; - BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toInfoHashes(hashes)); + BitTorrent::Session::instance()->decreaseTorrentsQueuePos(toTorrentIDs(hashes)); } void TorrentsController::topPrioAction() @@ -1026,7 +1026,7 @@ void TorrentsController::topPrioAction() throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); const QStringList hashes {params()["hashes"].split('|')}; - BitTorrent::Session::instance()->topTorrentsQueuePos(toInfoHashes(hashes)); + BitTorrent::Session::instance()->topTorrentsQueuePos(toTorrentIDs(hashes)); } void TorrentsController::bottomPrioAction() @@ -1037,7 +1037,7 @@ void TorrentsController::bottomPrioAction() throw APIError(APIErrorType::Conflict, tr("Torrent queueing must be enabled")); const QStringList hashes {params()["hashes"].split('|')}; - BitTorrent::Session::instance()->bottomTorrentsQueuePos(toInfoHashes(hashes)); + BitTorrent::Session::instance()->bottomTorrentsQueuePos(toTorrentIDs(hashes)); } void TorrentsController::setLocationAction() @@ -1070,13 +1070,13 @@ void TorrentsController::renameAction() { requireParams({"hash", "name"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); QString name = params()["name"].trimmed(); if (name.isEmpty()) 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) throw APIError(APIErrorType::NotFound); @@ -1257,8 +1257,8 @@ void TorrentsController::renameFileAction() { requireParams({"hash", "oldPath", "newPath"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound); @@ -1279,8 +1279,8 @@ void TorrentsController::renameFolderAction() { requireParams({"hash", "oldPath", "newPath"}); - const auto hash = BitTorrent::InfoHash::fromString(params()["hash"]); - BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(hash); + const auto id = BitTorrent::TorrentID::fromString(params()["hash"]); + BitTorrent::Torrent *const torrent = BitTorrent::Session::instance()->findTorrent(id); if (!torrent) throw APIError(APIErrorType::NotFound);