|
|
@ -156,31 +156,6 @@ namespace |
|
|
|
return QString::fromUtf8(str.data(), static_cast<int>(str.size())); |
|
|
|
return QString::fromUtf8(str.data(), static_cast<int>(str.size())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template <typename Entry> |
|
|
|
|
|
|
|
QSet<QString> entryListToSetImpl(const Entry &entry) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Q_ASSERT(entry.type() == Entry::list_t); |
|
|
|
|
|
|
|
QSet<QString> output; |
|
|
|
|
|
|
|
for (int i = 0; i < entry.list_size(); ++i) { |
|
|
|
|
|
|
|
const QString tag = fromLTString(entry.list_string_value_at(i)); |
|
|
|
|
|
|
|
if (Session::isValidTag(tag)) |
|
|
|
|
|
|
|
output.insert(tag); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
qWarning() << QString("Dropping invalid stored tag: %1").arg(tag); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return output; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isList(const lt::bdecode_node &entry) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return entry.type() == lt::bdecode_node::list_t; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QSet<QString> entryListToSet(const lt::bdecode_node &entry) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return entryListToSetImpl(entry); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QString normalizePath(const QString &path) |
|
|
|
QString normalizePath(const QString &path) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QString tmp = Utils::Fs::toUniformPath(path.trimmed()); |
|
|
|
QString tmp = Utils::Fs::toUniformPath(path.trimmed()); |
|
|
@ -2028,6 +2003,11 @@ bool Session::addTorrent_impl(CreateTorrentParams params, const MagnetUri &magne |
|
|
|
p.upload_limit = params.uploadLimit; |
|
|
|
p.upload_limit = params.uploadLimit; |
|
|
|
p.download_limit = params.downloadLimit; |
|
|
|
p.download_limit = params.downloadLimit; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if (LIBTORRENT_VERSION_NUM >= 10200) |
|
|
|
|
|
|
|
if (params.addedTime.isValid()) |
|
|
|
|
|
|
|
p.added_time = params.addedTime.toSecsSinceEpoch(); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// Preallocation mode
|
|
|
|
// Preallocation mode
|
|
|
|
p.storage_mode = isPreallocationEnabled() |
|
|
|
p.storage_mode = isPreallocationEnabled() |
|
|
|
? lt::storage_mode_allocate : lt::storage_mode_sparse; |
|
|
|
? lt::storage_mode_allocate : lt::storage_mode_sparse; |
|
|
@ -3662,13 +3642,13 @@ void Session::startUpTorrents() |
|
|
|
QStringList fastresumes = resumeDataDir.entryList( |
|
|
|
QStringList fastresumes = resumeDataDir.entryList( |
|
|
|
QStringList(QLatin1String("*.fastresume")), QDir::Files, QDir::Unsorted); |
|
|
|
QStringList(QLatin1String("*.fastresume")), QDir::Files, QDir::Unsorted); |
|
|
|
|
|
|
|
|
|
|
|
typedef struct |
|
|
|
struct TorrentResumeData |
|
|
|
{ |
|
|
|
{ |
|
|
|
QString hash; |
|
|
|
QString hash; |
|
|
|
MagnetUri magnetUri; |
|
|
|
MagnetUri magnetUri; |
|
|
|
CreateTorrentParams addTorrentData; |
|
|
|
CreateTorrentParams addTorrentData; |
|
|
|
QByteArray data; |
|
|
|
QByteArray data; |
|
|
|
} TorrentResumeData; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
int resumedTorrentsCount = 0; |
|
|
|
int resumedTorrentsCount = 0; |
|
|
|
const auto startupTorrent = [this, &resumeDataDir, &resumedTorrentsCount](const TorrentResumeData ¶ms) |
|
|
|
const auto startupTorrent = [this, &resumeDataDir, &resumedTorrentsCount](const TorrentResumeData ¶ms) |
|
|
@ -4422,49 +4402,59 @@ namespace |
|
|
|
|
|
|
|
|
|
|
|
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &queuePos, MagnetUri &magnetUri) |
|
|
|
bool loadTorrentResumeData(const QByteArray &data, CreateTorrentParams &torrentParams, int &queuePos, MagnetUri &magnetUri) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
lt::error_code ec; |
|
|
|
|
|
|
|
lt::bdecode_node root; |
|
|
|
|
|
|
|
lt::bdecode(data.constData(), (data.constData() + data.size()), root, ec); |
|
|
|
|
|
|
|
if (ec || (root.type() != lt::bdecode_node::dict_t)) return false; |
|
|
|
|
|
|
|
|
|
|
|
torrentParams = CreateTorrentParams(); |
|
|
|
torrentParams = CreateTorrentParams(); |
|
|
|
|
|
|
|
|
|
|
|
torrentParams.restored = true; |
|
|
|
torrentParams.restored = true; |
|
|
|
torrentParams.skipChecking = false; |
|
|
|
torrentParams.skipChecking = false; |
|
|
|
|
|
|
|
torrentParams.name = fromLTString(root.dict_find_string_value("qBt-name")); |
|
|
|
lt::error_code ec; |
|
|
|
|
|
|
|
lt::bdecode_node fast; |
|
|
|
|
|
|
|
lt::bdecode(data.constData(), data.constData() + data.size(), fast, ec); |
|
|
|
|
|
|
|
if (ec || (fast.type() != lt::bdecode_node::dict_t)) return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
torrentParams.savePath = Profile::instance().fromPortablePath( |
|
|
|
torrentParams.savePath = Profile::instance().fromPortablePath( |
|
|
|
Utils::Fs::toUniformPath(fromLTString(fast.dict_find_string_value("qBt-savePath")))); |
|
|
|
Utils::Fs::toUniformPath(fromLTString(root.dict_find_string_value("qBt-savePath")))); |
|
|
|
|
|
|
|
torrentParams.disableTempPath = root.dict_find_int_value("qBt-tempPathDisabled"); |
|
|
|
LTString ratioLimitString = fast.dict_find_string_value("qBt-ratioLimit"); |
|
|
|
torrentParams.sequential = root.dict_find_int_value("qBt-sequential"); |
|
|
|
|
|
|
|
torrentParams.hasSeedStatus = root.dict_find_int_value("qBt-seedStatus"); |
|
|
|
|
|
|
|
torrentParams.firstLastPiecePriority = root.dict_find_int_value("qBt-firstLastPiecePriority"); |
|
|
|
|
|
|
|
torrentParams.hasRootFolder = root.dict_find_int_value("qBt-hasRootFolder"); |
|
|
|
|
|
|
|
torrentParams.seedingTimeLimit = root.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const bool isAutoManaged = root.dict_find_int_value("auto_managed"); |
|
|
|
|
|
|
|
const bool isPaused = root.dict_find_int_value("paused"); |
|
|
|
|
|
|
|
torrentParams.paused = root.dict_find_int_value("qBt-paused", (isPaused && !isAutoManaged)); |
|
|
|
|
|
|
|
torrentParams.forced = root.dict_find_int_value("qBt-forced", (!isPaused && !isAutoManaged)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const LTString ratioLimitString = root.dict_find_string_value("qBt-ratioLimit"); |
|
|
|
if (ratioLimitString.empty()) |
|
|
|
if (ratioLimitString.empty()) |
|
|
|
torrentParams.ratioLimit = fast.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0; |
|
|
|
torrentParams.ratioLimit = root.dict_find_int_value("qBt-ratioLimit", TorrentHandle::USE_GLOBAL_RATIO * 1000) / 1000.0; |
|
|
|
else |
|
|
|
else |
|
|
|
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble(); |
|
|
|
torrentParams.ratioLimit = fromLTString(ratioLimitString).toDouble(); |
|
|
|
torrentParams.seedingTimeLimit = fast.dict_find_int_value("qBt-seedingTimeLimit", TorrentHandle::USE_GLOBAL_SEEDING_TIME); |
|
|
|
|
|
|
|
// **************************************************************************************
|
|
|
|
// **************************************************************************************
|
|
|
|
// Workaround to convert legacy label to category
|
|
|
|
// Workaround to convert legacy label to category
|
|
|
|
// TODO: Should be removed in future
|
|
|
|
// TODO: Should be removed in future
|
|
|
|
torrentParams.category = fromLTString(fast.dict_find_string_value("qBt-label")); |
|
|
|
torrentParams.category = fromLTString(root.dict_find_string_value("qBt-label")); |
|
|
|
if (torrentParams.category.isEmpty()) |
|
|
|
if (torrentParams.category.isEmpty()) |
|
|
|
// **************************************************************************************
|
|
|
|
// **************************************************************************************
|
|
|
|
torrentParams.category = fromLTString(fast.dict_find_string_value("qBt-category")); |
|
|
|
torrentParams.category = fromLTString(root.dict_find_string_value("qBt-category")); |
|
|
|
// auto because the return type depends on the #if above.
|
|
|
|
|
|
|
|
const auto tagsEntry = fast.dict_find_list("qBt-tags"); |
|
|
|
const lt::bdecode_node tagsNode = root.dict_find("qBt-tags"); |
|
|
|
if (isList(tagsEntry)) |
|
|
|
if (tagsNode.type() == lt::bdecode_node::list_t) { |
|
|
|
torrentParams.tags = entryListToSet(tagsEntry); |
|
|
|
for (int i = 0; i < tagsNode.list_size(); ++i) { |
|
|
|
torrentParams.name = fromLTString(fast.dict_find_string_value("qBt-name")); |
|
|
|
const QString tag = fromLTString(tagsNode.list_string_value_at(i)); |
|
|
|
torrentParams.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus"); |
|
|
|
if (Session::isValidTag(tag)) |
|
|
|
torrentParams.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled"); |
|
|
|
torrentParams.tags << tag; |
|
|
|
torrentParams.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
magnetUri = MagnetUri(fromLTString(fast.dict_find_string_value("qBt-magnetUri"))); |
|
|
|
|
|
|
|
const bool isAutoManaged = fast.dict_find_int_value("auto_managed"); |
|
|
|
const lt::bdecode_node addedTimeNode = root.dict_find("qBt-addedTime"); |
|
|
|
const bool isPaused = fast.dict_find_int_value("paused"); |
|
|
|
if (addedTimeNode.type() == lt::bdecode_node::int_t) |
|
|
|
torrentParams.paused = fast.dict_find_int_value("qBt-paused", (isPaused && !isAutoManaged)); |
|
|
|
torrentParams.addedTime = QDateTime::fromSecsSinceEpoch(addedTimeNode.int_value()); |
|
|
|
torrentParams.forced = fast.dict_find_int_value("qBt-forced", (!isPaused && !isAutoManaged)); |
|
|
|
|
|
|
|
torrentParams.firstLastPiecePriority = fast.dict_find_int_value("qBt-firstLastPiecePriority"); |
|
|
|
queuePos = root.dict_find_int_value("qBt-queuePosition"); |
|
|
|
torrentParams.sequential = fast.dict_find_int_value("qBt-sequential"); |
|
|
|
magnetUri = MagnetUri(fromLTString(root.dict_find_string_value("qBt-magnetUri"))); |
|
|
|
|
|
|
|
|
|
|
|
queuePos = fast.dict_find_int_value("qBt-queuePosition"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|