mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-23 09:49:52 +00:00
parent
8b7fdf0f22
commit
3b38d0de7f
@ -37,7 +37,6 @@
|
||||
|
||||
#include "base/3rdparty/expected.hpp"
|
||||
#include "base/path.h"
|
||||
#include "torrentdescriptor.h"
|
||||
#include "torrentinfo.h"
|
||||
|
||||
class QByteArray;
|
||||
|
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015-2023 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* 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 <libtorrent/create_torrent.hpp>
|
||||
#include <libtorrent/error_code.hpp>
|
||||
#include <libtorrent/version.hpp>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
#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, QString> 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, QString> 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<void, QString> 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<void, QString> 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<TrackerEntry> TorrentInfo::trackers() const
|
||||
{
|
||||
if (!isValid()) return {};
|
||||
|
||||
const std::vector<lt::announce_entry> trackers = m_nativeInfo->trackers();
|
||||
|
||||
QList<TrackerEntry> ret;
|
||||
ret.reserve(static_cast<decltype(ret)::size_type>(trackers.size()));
|
||||
for (const lt::announce_entry &tracker : trackers)
|
||||
ret.append({.url = QString::fromStdString(tracker.url), .tier = tracker.tier});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<QUrl> TorrentInfo::urlSeeds() const
|
||||
{
|
||||
if (!isValid()) return {};
|
||||
|
||||
const std::vector<lt::web_seed_entry> &nativeWebSeeds = m_nativeInfo->web_seeds();
|
||||
|
||||
QList<QUrl> urlSeeds;
|
||||
urlSeeds.reserve(static_cast<decltype(urlSeeds)::size_type>(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<QByteArray> 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]);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2015-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
*
|
||||
* 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 <QCoreApplication>
|
||||
#include <QList>
|
||||
|
||||
#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<TorrentInfo, QString> load(const QByteArray &data) noexcept;
|
||||
static nonstd::expected<TorrentInfo, QString> loadFromFile(const Path &path) noexcept;
|
||||
nonstd::expected<void, QString> 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<TrackerEntry> trackers() const;
|
||||
QList<QUrl> urlSeeds() const;
|
||||
QByteArray metadata() const;
|
||||
PathList filesForPiece(int pieceIndex) const;
|
||||
QList<int> fileIndicesForPiece(int pieceIndex) const;
|
||||
QList<QByteArray> 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<lt::torrent_info> nativeInfo() const;
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user