diff --git a/src/base/bittorrent/torrentdescriptor.h b/src/base/bittorrent/torrentdescriptor.h index 897c1af94..54248ae57 100644 --- a/src/base/bittorrent/torrentdescriptor.h +++ b/src/base/bittorrent/torrentdescriptor.h @@ -37,7 +37,6 @@ #include "base/3rdparty/expected.hpp" #include "base/path.h" -#include "torrentdescriptor.h" #include "torrentinfo.h" class QByteArray; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 371577044..437ab2173 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -403,17 +403,27 @@ QString TorrentImpl::name() const QDateTime TorrentImpl::creationDate() const { - return m_torrentInfo.creationDate(); + if (!hasMetadata()) + return {}; + + const std::time_t date = nativeTorrentInfo()->creation_date(); + return ((date != 0) ? QDateTime::fromSecsSinceEpoch(date) : QDateTime()); } QString TorrentImpl::creator() const { - return m_torrentInfo.creator(); + if (!hasMetadata()) + return {}; + + return QString::fromStdString(nativeTorrentInfo()->creator()); } QString TorrentImpl::comment() const { - return m_torrentInfo.comment(); + if (!hasMetadata()) + return {}; + + return QString::fromStdString(nativeTorrentInfo()->comment()); } bool TorrentImpl::isPrivate() const diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index 1055c9f7a..590930fe2 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015-2023 Vladimir Golovnev + * Copyright (C) 2015-2024 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,24 +28,15 @@ #include "torrentinfo.h" -#include -#include #include #include #include -#include -#include #include -#include #include #include "base/global.h" #include "base/path.h" -#include "base/preferences.h" -#include "base/utils/fs.h" -#include "base/utils/io.h" -#include "base/utils/misc.h" #include "infohash.h" #include "trackerentry.h" @@ -82,66 +73,6 @@ bool TorrentInfo::isValid() const return (m_nativeInfo != nullptr); } -nonstd::expected TorrentInfo::load(const QByteArray &data) noexcept -{ - // 2-step construction to overcome default limits of `depth_limit` & `token_limit` which are - // used in `torrent_info()` constructor - const auto *pref = Preferences::instance(); - - lt::error_code ec; - const lt::bdecode_node node = lt::bdecode(data, ec - , nullptr, pref->getBdecodeDepthLimit(), pref->getBdecodeTokenLimit()); - if (ec) - return nonstd::make_unexpected(QString::fromStdString(ec.message())); - - const lt::torrent_info nativeInfo {node, ec}; - if (ec) - return nonstd::make_unexpected(QString::fromStdString(ec.message())); - - return TorrentInfo(nativeInfo); -} - -nonstd::expected TorrentInfo::loadFromFile(const Path &path) noexcept -{ - QByteArray data; - try - { - const qint64 torrentSizeLimit = Preferences::instance()->getTorrentFileSizeLimit(); - const auto readResult = Utils::IO::readFile(path, torrentSizeLimit); - if (!readResult) - return nonstd::make_unexpected(readResult.error().message); - data = readResult.value(); - } - catch (const std::bad_alloc &e) - { - return nonstd::make_unexpected(tr("Failed to allocate memory when reading file. File: \"%1\". Error: \"%2\"") - .arg(path.toString(), QString::fromLocal8Bit(e.what()))); - } - - return load(data); -} - -nonstd::expected TorrentInfo::saveToFile(const Path &path) const -{ - if (!isValid()) - return nonstd::make_unexpected(tr("Invalid metadata")); - - try - { - const auto torrentCreator = lt::create_torrent(*m_nativeInfo); - const lt::entry torrentEntry = torrentCreator.generate(); - const nonstd::expected result = Utils::IO::saveToFile(path, torrentEntry); - if (!result) - return result.get_unexpected(); - } - catch (const lt::system_error &err) - { - return nonstd::make_unexpected(QString::fromLocal8Bit(err.what())); - } - - return {}; -} - InfoHash TorrentInfo::infoHash() const { if (!isValid()) return {}; @@ -160,28 +91,6 @@ QString TorrentInfo::name() const return QString::fromStdString(m_nativeInfo->orig_files().name()); } -QDateTime TorrentInfo::creationDate() const -{ - if (!isValid()) return {}; - - const std::time_t date = m_nativeInfo->creation_date(); - return ((date != 0) ? QDateTime::fromSecsSinceEpoch(date) : QDateTime()); -} - -QString TorrentInfo::creator() const -{ - if (!isValid()) return {}; - - return QString::fromStdString(m_nativeInfo->creator()); -} - -QString TorrentInfo::comment() const -{ - if (!isValid()) return {}; - - return QString::fromStdString(m_nativeInfo->comment()); -} - bool TorrentInfo::isPrivate() const { if (!isValid()) return false; @@ -270,43 +179,7 @@ qlonglong TorrentInfo::fileOffset(const int index) const return m_nativeInfo->orig_files().file_offset(m_nativeIndexes[index]); } -QList TorrentInfo::trackers() const -{ - if (!isValid()) return {}; - - const std::vector trackers = m_nativeInfo->trackers(); - - QList ret; - ret.reserve(static_cast(trackers.size())); - for (const lt::announce_entry &tracker : trackers) - ret.append({.url = QString::fromStdString(tracker.url), .tier = tracker.tier}); - - return ret; -} - -QList TorrentInfo::urlSeeds() const -{ - if (!isValid()) return {}; - - const std::vector &nativeWebSeeds = m_nativeInfo->web_seeds(); - - QList urlSeeds; - urlSeeds.reserve(static_cast(nativeWebSeeds.size())); - - for (const lt::web_seed_entry &webSeed : nativeWebSeeds) - { -#if LIBTORRENT_VERSION_NUM < 20100 - if (webSeed.type == lt::web_seed_entry::url_seed) - urlSeeds.append(QUrl(QString::fromStdString(webSeed.url))); -#else - urlSeeds.append(QUrl(QString::fromStdString(webSeed.url))); -#endif - } - - return urlSeeds; -} - -QByteArray TorrentInfo::metadata() const +QByteArray TorrentInfo::rawData() const { if (!isValid()) return {}; #ifdef QBT_USES_LIBTORRENT2 @@ -366,16 +239,7 @@ QList TorrentInfo::pieceHashes() const TorrentInfo::PieceRange TorrentInfo::filePieces(const Path &filePath) const { - if (!isValid()) // if we do not check here the debug message will be printed, which would be not correct - return {}; - - const int index = fileIndex(filePath); - if (index == -1) - { - qDebug() << "Filename" << filePath.toString() << "was not found in torrent" << name(); - return {}; - } - return filePieces(index); + return filePieces(fileIndex(filePath)); } TorrentInfo::PieceRange TorrentInfo::filePieces(const int fileIndex) const @@ -384,10 +248,7 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(const int fileIndex) const return {}; if ((fileIndex < 0) || (fileIndex >= filesCount())) - { - qDebug() << "File index (" << fileIndex << ") is out of range for torrent" << name(); return {}; - } const lt::file_storage &files = m_nativeInfo->orig_files(); const auto fileSize = files.file_size(m_nativeIndexes[fileIndex]); diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index 4afdac491..02f5f78d8 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -1,6 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. - * Copyright (C) 2015 Vladimir Golovnev + * Copyright (C) 2015-2024 Vladimir Golovnev * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,7 +34,6 @@ #include #include -#include "base/3rdparty/expected.hpp" #include "base/indexrange.h" #include "base/pathfwd.h" @@ -50,26 +49,17 @@ namespace BitTorrent class TorrentInfo { - Q_DECLARE_TR_FUNCTIONS(TorrentInfo) - public: TorrentInfo() = default; TorrentInfo(const TorrentInfo &other) = default; explicit TorrentInfo(const lt::torrent_info &nativeInfo); - static nonstd::expected load(const QByteArray &data) noexcept; - static nonstd::expected loadFromFile(const Path &path) noexcept; - nonstd::expected saveToFile(const Path &path) const; - TorrentInfo &operator=(const TorrentInfo &other); bool isValid() const; InfoHash infoHash() const; QString name() const; - QDateTime creationDate() const; - QString creator() const; - QString comment() const; bool isPrivate() const; qlonglong totalSize() const; int filesCount() const; @@ -80,9 +70,6 @@ namespace BitTorrent PathList filePaths() const; qlonglong fileSize(int index) const; qlonglong fileOffset(int index) const; - QList trackers() const; - QList urlSeeds() const; - QByteArray metadata() const; PathList filesForPiece(int pieceIndex) const; QList fileIndicesForPiece(int pieceIndex) const; QList pieceHashes() const; @@ -93,6 +80,8 @@ namespace BitTorrent PieceRange filePieces(const Path &filePath) const; PieceRange filePieces(int fileIndex) const; + QByteArray rawData() const; + bool matchesInfoHash(const InfoHash &otherInfoHash) const; std::shared_ptr nativeInfo() const; diff --git a/src/gui/addnewtorrentdialog.cpp b/src/gui/addnewtorrentdialog.cpp index 5b2cadd33..11b083c3e 100644 --- a/src/gui/addnewtorrentdialog.cpp +++ b/src/gui/addnewtorrentdialog.cpp @@ -897,11 +897,11 @@ void AddNewTorrentDialog::setupTreeview() // Set dialog title setWindowTitle(torrentDescr.name()); - const auto &torrentInfo = *torrentDescr.info(); - // Set torrent information - m_ui->labelCommentData->setText(Utils::Misc::parseHtmlLinks(torrentInfo.comment().toHtmlEscaped())); - m_ui->labelDateData->setText(!torrentInfo.creationDate().isNull() ? QLocale().toString(torrentInfo.creationDate(), QLocale::ShortFormat) : tr("Not available")); + m_ui->labelCommentData->setText(Utils::Misc::parseHtmlLinks(torrentDescr.comment().toHtmlEscaped())); + m_ui->labelDateData->setText(!torrentDescr.creationDate().isNull() ? QLocale().toString(torrentDescr.creationDate(), QLocale::ShortFormat) : tr("Not available")); + + const auto &torrentInfo = *torrentDescr.info(); BitTorrent::AddTorrentParams &addTorrentParams = m_currentContext->torrentParams; if (addTorrentParams.filePaths.isEmpty())