33 #include <libtorrent/create_torrent.hpp>
34 #include <libtorrent/file_storage.hpp>
35 #include <libtorrent/torrent_info.hpp>
37 #include <QDirIterator>
46 #include "base/version.h"
58 #ifdef QBT_USES_LIBTORRENT2
59 lt::create_flags_t toNativeTorrentFormatFlag(
const BitTorrent::TorrentFormat torrentFormat)
61 switch (torrentFormat)
63 case BitTorrent::TorrentFormat::V1:
64 return lt::create_torrent::v1_only;
65 case BitTorrent::TorrentFormat::Hybrid:
67 case BitTorrent::TorrentFormat::V2:
68 return lt::create_torrent::v2_only;
84 requestInterruption();
96 emit
updateProgress(
static_cast<int>((currentPieceIdx * 100.) / totalPieces));
101 if (isInterruptionRequested())
125 QDirIterator dirIter {
m_params.
inputPath, (QDir::AllDirs | QDir::NoDotAndDotDot), QDirIterator::Subdirectories};
126 while (dirIter.hasNext())
129 dirs += dirIter.filePath();
131 std::sort(dirs.begin(), dirs.end(), naturalLessThan);
133 QStringList fileNames;
134 QHash<QString, qint64> fileSizeMap;
136 for (
const auto &dir :
asConst(dirs))
138 QStringList tmpNames;
140 QDirIterator fileIter(dir, QDir::Files);
141 while (fileIter.hasNext())
145 const QString relFilePath = fileIter.filePath().mid(parentPath.length());
146 tmpNames += relFilePath;
147 fileSizeMap[relFilePath] = fileIter.fileInfo().size();
150 std::sort(tmpNames.begin(), tmpNames.end(), naturalLessThan);
151 fileNames += tmpNames;
160 #ifdef QBT_USES_LIBTORRENT2
170 seed = seed.trimmed();
172 newTorrent.add_url_seed(seed.toStdString());
178 if (tracker.isEmpty())
181 newTorrent.add_tracker(tracker.trimmed().toStdString(), tier);
186 , [
this, &newTorrent](
const lt::piece_index_t n)
194 newTorrent.set_creator(
"qBittorrent " QBT_VERSION);
201 lt::entry entry = newTorrent.generate();
221 catch (
const std::exception &err)
223 emit
creationFailure(tr(
"Create new torrent file failed. Reason: %1.").arg(QString::fromLocal8Bit(err.what())));
227 #ifdef QBT_USES_LIBTORRENT2
233 if (inputPath.isEmpty())
239 #ifdef QBT_USES_LIBTORRENT2
240 return lt::create_torrent {fs, pieceSize, toNativeTorrentFormatFlag(torrentFormat)}.num_pieces();
242 return lt::create_torrent(fs, pieceSize, paddedFileSizeLimit
243 , (isAlignmentOptimized ? lt::create_torrent::optimize_alignment : lt::create_flags_t {})).num_pieces();
static int calculateTotalPieces(const QString &inputPath, const int pieceSize, const bool isAlignmentOptimized, int paddedFileSizeLimit)
TorrentCreatorThread(QObject *parent=nullptr)
void creationSuccess(const QString &path, const QString &branchPath)
void updateProgress(int progress)
void checkInterruptionRequested() const
void create(const TorrentCreatorParams ¶ms)
TorrentCreatorParams m_params
void sendProgressSignal(int currentPieceIdx, int totalPieces)
~TorrentCreatorThread() override
void creationFailure(const QString &msg)
QString message() const noexcept
constexpr std::add_const_t< T > & asConst(T &t) noexcept
constexpr T::underlying_type toUnderlyingType(const T &t) noexcept
QString fileName(const QString &filePath)
QString branchPath(const QString &filePath, QString *removed=nullptr)
QString toNativePath(const QString &path)
nonstd::expected< void, QString > saveToFile(const QString &path, const QByteArray &data)
bool fileFilter(const std::string &f)
bool isAlignmentOptimized