Allow to save downloaded metadata as torrent file

This commit is contained in:
Vladimir Golovnev (Glassez)
2020-02-19 13:19:51 +03:00
committed by sledgehammer999
parent 5fdd069f66
commit 703330c40d
8 changed files with 110 additions and 63 deletions

View File

@@ -3831,13 +3831,18 @@ void Session::handleTorrentMetadataReceived(TorrentHandle *const torrent)
torrent->saveResumeData();
// Save metadata
const QDir resumeDataDir(m_resumeFolderPath);
QString torrentFile = resumeDataDir.absoluteFilePath(QString("%1.torrent").arg(torrent->hash()));
if (torrent->saveTorrentFile(torrentFile)) {
const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash())};
try {
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
// Copy the torrent file to the export folder
if (!torrentExportDirectory().isEmpty())
exportTorrentFile(torrent);
}
catch (const RuntimeError &err) {
LogMsg(tr("Couldn't save torrent metadata file '%1'. Reason: %2")
.arg(torrentFileName, err.message()), Log::CRITICAL);
}
emit torrentMetadataLoaded(torrent);
}
@@ -4352,15 +4357,17 @@ void Session::createTorrentHandle(const lt::torrent_handle &nativeHandle)
// The following is useless for newly added magnet
if (!fromMagnetUri) {
// Backup torrent file
const QDir resumeDataDir(m_resumeFolderPath);
const QString newFile = resumeDataDir.absoluteFilePath(QString("%1.torrent").arg(torrent->hash()));
if (torrent->saveTorrentFile(newFile)) {
const QDir resumeDataDir {m_resumeFolderPath};
const QString torrentFileName {QString {"%1.torrent"}.arg(torrent->hash())};
try {
torrent->info().saveToFile(resumeDataDir.absoluteFilePath(torrentFileName));
// Copy the torrent file to the export folder
if (!torrentExportDirectory().isEmpty())
exportTorrentFile(torrent);
}
else {
LogMsg(tr("Couldn't save '%1.torrent'").arg(torrent->hash()), Log::CRITICAL);
catch (const RuntimeError &err) {
LogMsg(tr("Couldn't save torrent metadata file '%1'. Reason: %2")
.arg(torrentFileName, err.message()), Log::CRITICAL);
}
}

View File

@@ -38,15 +38,16 @@
#include <libtorrent/address.hpp>
#include <libtorrent/alert_types.hpp>
#include <libtorrent/bencode.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/magnet_uri.hpp>
#include <libtorrent/time.hpp>
#include <libtorrent/version.hpp>
#if (LIBTORRENT_VERSION_NUM >= 10200)
#include <libtorrent/storage_defs.hpp>
#include <libtorrent/write_resume_data.hpp>
#else
#include <libtorrent/storage.hpp>
#endif
#include <QBitArray>
@@ -1533,29 +1534,6 @@ void TorrentHandle::renameFile(const int index, const QString &name)
m_nativeHandle.rename_file(LTFileIndex {index}, Utils::Fs::toNativePath(name).toStdString());
}
bool TorrentHandle::saveTorrentFile(const QString &path)
{
if (!m_torrentInfo.isValid()) return false;
#if (LIBTORRENT_VERSION_NUM < 10200)
const lt::create_torrent torrentCreator = lt::create_torrent(*(m_torrentInfo.nativeInfo()), true);
#else
const lt::create_torrent torrentCreator = lt::create_torrent(*(m_torrentInfo.nativeInfo()));
#endif
const lt::entry torrentEntry = torrentCreator.generate();
QByteArray out;
out.reserve(1024 * 1024); // most torrent file sizes are under 1 MB
lt::bencode(std::back_inserter(out), torrentEntry);
if (out.isEmpty())
return false;
QFile torrentFile(path);
if (torrentFile.open(QIODevice::WriteOnly))
return (torrentFile.write(out) == out.size());
return false;
}
void TorrentHandle::handleStateUpdate(const lt::torrent_status &nativeStatus)
{
updateStatus(nativeStatus);

View File

@@ -319,7 +319,6 @@ namespace BitTorrent
void forceDHTAnnounce();
void forceRecheck();
void renameFile(int index, const QString &name);
bool saveTorrentFile(const QString &path);
void prioritizeFiles(const QVector<DownloadPriority> &priorities);
void setRatioLimit(qreal limit);
void setSeedingTimeLimit(int limit);

View File

@@ -32,6 +32,8 @@
#include <boost/optional.hpp>
#endif
#include <libtorrent/bencode.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/error_code.hpp>
#include <QByteArray>
@@ -42,6 +44,7 @@
#include <QStringList>
#include <QUrl>
#include "base/exceptions.h"
#include "base/global.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
@@ -151,6 +154,27 @@ TorrentInfo TorrentInfo::loadFromFile(const QString &path, QString *error) noexc
return load(data, error);
}
void TorrentInfo::saveToFile(const QString &path) const
{
if (!isValid())
throw RuntimeError {tr("Invalid metadata.")};
#if (LIBTORRENT_VERSION_NUM < 10200)
const lt::create_torrent torrentCreator = lt::create_torrent(*(nativeInfo()), true);
#else
const lt::create_torrent torrentCreator = lt::create_torrent(*(nativeInfo()));
#endif
const lt::entry torrentEntry = torrentCreator.generate();
QByteArray out;
out.reserve(1024 * 1024); // most torrent file sizes are under 1 MB
lt::bencode(std::back_inserter(out), torrentEntry);
QFile torrentFile{path};
if (!torrentFile.open(QIODevice::WriteOnly) || (torrentFile.write(out) != out.size()))
throw RuntimeError {torrentFile.errorString()};
}
bool TorrentInfo::isValid() const
{
return (m_nativeInfo && m_nativeInfo->is_valid() && (m_nativeInfo->num_files() > 0));

View File

@@ -66,6 +66,7 @@ namespace BitTorrent
static TorrentInfo load(const QByteArray &data, QString *error = nullptr) noexcept;
static TorrentInfo loadFromFile(const QString &path, QString *error = nullptr) noexcept;
void saveToFile(const QString &path) const;
TorrentInfo &operator=(const TorrentInfo &other);