Skip to content

Commit

Permalink
Temp
Browse files Browse the repository at this point in the history
  • Loading branch information
glassez committed Dec 27, 2024
1 parent 2fafd8a commit bf34329
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 58 deletions.
132 changes: 77 additions & 55 deletions src/base/bittorrent/sessionimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <libtorrent/session_stats.hpp>
#include <libtorrent/session_status.hpp>
#include <libtorrent/torrent_info.hpp>
#include <libtorrent/write_resume_data.hpp>

#include <QDateTime>
#include <QDeadlineTimer>
Expand Down Expand Up @@ -326,6 +327,18 @@ namespace

return torrentFilePath;
}

lt::entry LTWriteTorrentFile(lt::add_torrent_params ltAddTorrentParams, lt::error_code &ec)
try
{
ec.clear();
return lt::write_torrent_file(ltAddTorrentParams);
}
catch (const lt::system_error &err)
{
ec = err.code();
return {};
}
}

struct BitTorrent::SessionImpl::ResumeSessionContext final : public QObject
Expand Down Expand Up @@ -829,8 +842,12 @@ bool SessionImpl::isStoreTorrentFileEnabled() const

void SessionImpl::setStoreTorrentFileEnabled(const bool enabled)
{
if (enabled != m_isStoreTorrentFileEnabled)
m_isStoreTorrentFileEnabled = enabled;
if (enabled == m_isStoreTorrentFileEnabled)
return;

m_isStoreTorrentFileEnabled = enabled;
if (!m_isStoreTorrentFileEnabled)
m_needStoreFileTorrents.clear();
}

bool SessionImpl::isDeleteStoredTorrentFileOnRemoveEnabled() const
Expand All @@ -846,7 +863,10 @@ void SessionImpl::setDeleteStoredTorrentFileOnRemoveEnabled(const bool enabled)

Path SessionImpl::torrentFileStoreDirectory() const
{
return m_torrentFileStoreDirectory;
const Path torrentFileStoreDirectory = m_torrentFileStoreDirectory;
return torrentFileStoreDirectory.isEmpty()
? specialFolderLocation(SpecialFolder::Downloads) / Path(u"Torrent Files"_s)
: torrentFileStoreDirectory;
}

void SessionImpl::setTorrentFileStoreDirectory(const Path &path)
Expand Down Expand Up @@ -2507,6 +2527,22 @@ bool SessionImpl::removeTorrent(const TorrentID &id, const TorrentRemoveOption d
// Remove it from torrent resume directory
m_resumeDataStorage->remove(torrentID);

m_needStoreFileTorrents.remove(torrent);
if (std::holds_alternative<Path>(torrent->storedTorrentInfo()))
{
const auto storedTorrentFilePath = std::get<Path>(torrent->storedTorrentInfo());
if (const auto result = Utils::Fs::removeFile(storedTorrentFilePath))
{
LogMsg(tr("Removed stored .torrent file. Torrent: \"%1\". File: \"%2\".")
.arg(torrent->name(), storedTorrentFilePath.toString()));
}
else
{
LogMsg(tr("Failed to remove stored .torrent file. Torrent: \"%1\". File: \"%2\". Reason: \"%3\".")
.arg(torrent->name(), storedTorrentFilePath.toString(), result.error()));
}
}

LogMsg(tr("Torrent removed. Torrent: \"%1\"").arg(torrentName));
delete torrent;
return true;
Expand Down Expand Up @@ -3121,31 +3157,6 @@ bool SessionImpl::downloadMetadata(const TorrentDescriptor &torrentDescr)
return true;
}

nonstd::expected<Path, QString> SessionImpl::createTorrentFile(const Torrent *torrent, const Path &folderPath)
{
if (!folderPath.exists() && !Utils::Fs::mkpath(folderPath))
return nonstd::make_unexpected(tr("Unable to create folder. Path: \"%1\".").arg(folderPath.toString()));

const Path torrentFilePath = generateTorrentFilePath(folderPath, torrent->name());
if (const auto result = torrent->exportToFile(torrentFilePath); !result)
return nonstd::make_unexpected(result.error());

return torrentFilePath;
}

nonstd::expected<Path, QString> SessionImpl::createTorrentFile(const TorrentDescriptor &torrentDescr, const Path &folderPath)
{
if (!folderPath.exists() && !Utils::Fs::mkpath(folderPath))
return nonstd::make_unexpected(tr("Unable to create folder. Path: \"%1\".").arg(folderPath.toString()));

const Path torrentFilePath = generateTorrentFilePath(folderPath, torrentDescr.name());
const auto saveResult = torrentDescr.saveToFile(torrentFilePath);
if (saveResult)
return torrentFilePath;

return nonstd::make_unexpected(saveResult.error());
}

void SessionImpl::generateResumeData()
{
for (TorrentImpl *const torrent : asConst(m_torrents))
Expand Down Expand Up @@ -5065,14 +5076,9 @@ void SessionImpl::updateSeedingLimitTimer()
}
}

void SessionImpl::storeTorrentFile(TorrentImpl *torrent)
void SessionImpl::storeTorrentFile(TorrentImpl *torrent, [[maybe_unused]] const lt::add_torrent_params &resumeData)
{
if (!isStoreTorrentFileEnabled())
return;

const Path storeDir = torrentFileStoreDirectory();
if (storeDir.isEmpty())
return;
const QString errorMessage = tr("Failed to store .torrent file. Torrent: \"%1\". Destination: \"%2\". Reason: \"%3\".");

const std::variant<QString, Path> storedTorrentInfo = torrent->storedTorrentInfo();
if (!std::holds_alternative<QString>(storedTorrentInfo))
Expand All @@ -5082,28 +5088,49 @@ void SessionImpl::storeTorrentFile(TorrentImpl *torrent)
if (originalMagnetURI.isEmpty())
return;

const auto parseResult = TorrentDescriptor::parse(originalMagnetURI);
if (!parseResult)
const Path storeDir = torrentFileStoreDirectory();

lt::error_code ec;
lt::add_torrent_params ltAddTorrentParams = lt::parse_magnet_uri(originalMagnetURI.toStdString(), ec);
if (ec)
{
LogMsg(errorMessage.arg(torrent->name(), storeDir.toString(), QString::fromStdString(ec.message())), Log::WARNING);
return;
}

ltAddTorrentParams.ti = torrent->info().nativeInfo();
#ifdef QBT_USES_LIBTORRENT2
ltAddTorrentParams.merkle_trees = resumeData.merkle_trees;
ltAddTorrentParams.merkle_tree_mask = resumeData.merkle_tree_mask;
#endif

const lt::entry torrentEntry = LTWriteTorrentFile(ltAddTorrentParams, ec);
if (ec)
{
LogMsg(tr("Failed to store .torrent file. Torrent: \"%1\". Destination: \"%2\". Reason: \"%3\".")
.arg(torrent->name(), storeDir.toString(), parseResult.error()), Log::WARNING);
#ifdef QBT_USES_LIBTORRENT2
if ((ec != lt::errors::torrent_missing_piece_layer) && (ec != lt::errors::torrent_invalid_piece_layer))
#endif
LogMsg(errorMessage.arg(torrent->name(), storeDir.toString(), QString::fromStdString(ec.message())), Log::WARNING);
return;
}

TorrentDescriptor torrentDescr = parseResult.value();
torrentDescr.setTorrentInfo(torrent->info());
if (!storeDir.exists() && !Utils::Fs::mkpath(storeDir))
{
LogMsg(errorMessage.arg(torrent->name(), storeDir.toString(), tr("Unable to create folder")), Log::WARNING);
return;
}

if (const auto result = createTorrentFile(torrentDescr, storeDir))
const Path torrentFilePath = generateTorrentFilePath(storeDir, torrent->name());
if (const auto result = Utils::IO::saveToFile(torrentFilePath, torrentEntry))
{
const Path torrentFilePath = result.value();
torrent->setStoredTorrentInfo(torrentFilePath);
m_needStoreFileTorrents.remove(torrent);
LogMsg(tr("Stored .torrent file. Torrent: \"%1\". Destination: \"%2\".")
.arg(torrent->name(), torrentFilePath.toString()));
}
else
{
LogMsg(tr("Failed to store .torrent file. Torrent: \"%1\". Destination: \"%2\". Reason: \"%3\".")
.arg(torrent->name(), result.value().toString(), result.error()), Log::WARNING);
LogMsg(errorMessage.arg(torrent->name(), storeDir.toString(), result.error()), Log::WARNING);
}
}

Expand Down Expand Up @@ -5219,6 +5246,9 @@ void SessionImpl::handleTorrentResumeDataReady(TorrentImpl *const torrent, const
m_resumeDataStorage->remove(iter.value());
m_changedTorrentIDs.erase(iter);
}

if (m_needStoreFileTorrents.contains(torrent))
storeTorrentFile(torrent, data.ltAddTorrentParams);
}

void SessionImpl::handleTorrentInfoHashChanged(TorrentImpl *torrent, const InfoHash &prevInfoHash)
Expand Down Expand Up @@ -5823,14 +5853,7 @@ void SessionImpl::dispatchTorrentAlert(const lt::torrent_alert *alert)

if (torrent)
{
const bool needStoreTorentFile = (alert->type() == lt::save_resume_data_alert::alert_type)
&& m_needStoreFileTorrents.contains(torrent);

torrent->handleAlert(alert);

if (needStoreTorentFile)
storeTorrentFile(torrent);

return;
}

Expand All @@ -5857,12 +5880,11 @@ TorrentImpl *SessionImpl::createTorrent(const lt::torrent_handle &nativeHandle,
torrent->requestResumeData(lt::torrent_handle::save_info_dict);

const TorrentDescriptor torrentDescr = m_addingTorrents.take(torrent->id());
if (const Path copyDir = torrentFileStoreDirectory();
isStoreTorrentFileEnabled() && !copyDir.isEmpty())
if (isStoreTorrentFileEnabled())
{
if (torrentDescr.hasCompleteMetadata())
{
const auto storeTorrent = [&torrentDescr, &copyDir]() -> nonstd::expected<Path, QString>
const auto storeTorrent = [&torrentDescr, copyDir = torrentFileStoreDirectory()]() -> nonstd::expected<Path, QString>
{
if (!copyDir.exists() && !Utils::Fs::mkpath(copyDir))
return nonstd::make_unexpected(tr("Unable to create folder. Path: \"%1\".").arg(copyDir.toString()));
Expand Down
4 changes: 1 addition & 3 deletions src/base/bittorrent/sessionimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,9 +562,7 @@ namespace BitTorrent

void updateSeedingLimitTimer();

void storeTorrentFile(TorrentImpl *torrent);
nonstd::expected<Path, QString> createTorrentFile(const Torrent *torrent, const Path &folderPath);
nonstd::expected<Path, QString> createTorrentFile(const TorrentDescriptor &torrentDescr, const Path &folderPath);
void storeTorrentFile(TorrentImpl *torrent, const lt::add_torrent_params &resumeData);

void handleAlert(const lt::alert *alert);
void dispatchTorrentAlert(const lt::torrent_alert *alert);
Expand Down

0 comments on commit bf34329

Please sign in to comment.