Add --bt-load-saved-metadata option

Before getting torrent metadata from DHT when downloading with magnet
link, first try to read file saved by --bt-save-metadata option. If it
is successful, then skip downloading metadata from DHT.  By default,
this feature is turned off.
This commit is contained in:
Tatsuhiro Tsujikawa 2017-05-20 13:00:11 +09:00
parent 8785342f85
commit 9deb4210b2
5 changed files with 58 additions and 5 deletions

View File

@ -1527,6 +1527,16 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
op->setChangeOptionForReserved(true);
handlers.push_back(op);
}
{
OptionHandler* op(new BooleanOptionHandler(
PREF_BT_LOAD_SAVED_METADATA, TEXT_BT_LOAD_SAVED_METADATA, A2_V_FALSE,
OptionHandler::OPT_ARG));
op->addTag(TAG_BITTORRENT);
op->setInitialOption(true);
op->setChangeGlobalOption(true);
op->setChangeOptionForReserved(true);
handlers.push_back(op);
}
{
OptionHandler* op(new DefaultOptionHandler(
PREF_BT_LPD_INTERFACE, TEXT_BT_LPD_INTERFACE, NO_DEFAULT_VALUE,

View File

@ -237,23 +237,54 @@ std::shared_ptr<RequestGroup>
createBtMagnetRequestGroup(const std::string& magnetLink,
const std::shared_ptr<Option>& optionTemplate)
{
auto option = util::copy(optionTemplate);
auto gid = getGID(option);
auto rg = std::make_shared<RequestGroup>(gid, option);
auto dctx = std::make_shared<DownloadContext>(METADATA_PIECE_SIZE, 0);
// We only know info hash. Total Length is unknown at this moment.
dctx->markTotalLengthIsUnknown();
rg->setFileAllocationEnabled(false);
rg->setPreLocalFileCheckEnabled(false);
bittorrent::loadMagnet(magnetLink, dctx);
auto torrentAttrs = bittorrent::getTorrentAttrs(dctx);
if (optionTemplate->getAsBool(PREF_BT_LOAD_SAVED_METADATA)) {
// Try to read .torrent file saved by aria2 (see
// UTMetadataPostDownloadHandler and --bt-save-metadata option).
auto torrentFilename =
util::applyDir(optionTemplate->get(PREF_DIR),
util::toHex(torrentAttrs->infoHash) + ".torrent");
bittorrent::ValueBaseBencodeParser parser;
auto torrent = parseFile(parser, torrentFilename);
if (torrent) {
auto rg = createBtRequestGroup(torrentFilename, optionTemplate, {},
torrent.get());
const auto& actualInfoHash =
bittorrent::getTorrentAttrs(rg->getDownloadContext())->infoHash;
if (torrentAttrs->infoHash == actualInfoHash) {
A2_LOG_NOTICE(fmt("BitTorrent metadata was loaded from %s",
torrentFilename.c_str()));
rg->setMetadataInfo(createMetadataInfo(rg->getGroupId(), magnetLink));
return rg;
}
A2_LOG_WARN(
fmt("BitTorrent metadata loaded from %s has unexpected infohash %s\n",
torrentFilename.c_str(), util::toHex(actualInfoHash).c_str()));
}
}
auto option = util::copy(optionTemplate);
bittorrent::adjustAnnounceUri(torrentAttrs, option);
// torrentAttrs->name may contain "/", but we use basename of
// FileEntry::getPath() to print out in-memory download entry.
// Since "/" is treated as separator, we replace it with "-".
dctx->getFirstFileEntry()->setPath(
util::replace(torrentAttrs->name, "/", "-"));
auto gid = getGID(option);
auto rg = std::make_shared<RequestGroup>(gid, option);
rg->setFileAllocationEnabled(false);
rg->setPreLocalFileCheckEnabled(false);
rg->setDownloadContext(dctx);
rg->clearPostDownloadHandler();
rg->addPostDownloadHandler(

View File

@ -563,6 +563,8 @@ PrefPtr PREF_BT_FORCE_ENCRYPTION = makePref("bt-force-encryption");
// values: true | false
PrefPtr PREF_BT_ENABLE_HOOK_AFTER_HASH_CHECK =
makePref("bt-enable-hook-after-hash-check");
// values: true | false
PrefPtr PREF_BT_LOAD_SAVED_METADATA = makePref("bt-load-saved-metadata");
/**
* Metalink related preferences

View File

@ -514,6 +514,8 @@ extern PrefPtr PREF_BT_DETACH_SEED_ONLY;
extern PrefPtr PREF_BT_FORCE_ENCRYPTION;
// values: true | false
extern PrefPtr PREF_BT_ENABLE_HOOK_AFTER_HASH_CHECK;
// values: true | false
extern PrefPtr PREF_BT_LOAD_SAVED_METADATA;
/**
* Metalink related preferences

View File

@ -1117,4 +1117,12 @@
" number of unfinished download result to keep. If\n" \
" that is undesirable, turn this option off.")
#define TEXT_BT_LOAD_SAVED_METADATA \
_(" --bt-load-saved-metadata[=true|false]\n" \
" Before getting torrent metadata from DHT when\n" \
" downloading with magnet link, first try to read\n" \
" file saved by --bt-save-metadata option. If it is\n" \
" successful, then skip downloading metadata from\n" \
" DHT.")
// clang-format on