Merge branch 'bt-load-saved-metadata'

This commit is contained in:
Tatsuhiro Tsujikawa 2017-05-22 22:37:34 +09:00
commit e3b6460d07
6 changed files with 67 additions and 5 deletions

View File

@ -713,6 +713,14 @@ BitTorrent Specific Options
option to ``false``. This option has effect only on BitTorrent download.
Default: ``true``
.. option:: --bt-load-saved-metadata[=true|false]
Before getting torrent metadata from DHT when downloading with
magnet link, first try to read file saved by
:option:`--bt-save-metadata` option. If it is successful, then skip
downloading metadata from DHT.
Default: ``false``
.. option:: --bt-lpd-interface=<INTERFACE>
Use given interface for Local Peer Discovery. If this option is not
@ -2111,6 +2119,7 @@ of URIs. These optional lines must start with white space(s).
* :option:`bt-external-ip <--bt-external-ip>`
* :option:`bt-force-encryption <--bt-force-encryption>`
* :option:`bt-hash-check-seed <--bt-hash-check-seed>`
* :option:`bt-load-saved-metadata <--bt-load-saved-metadata>`
* :option:`bt-max-peers <--bt-max-peers>`
* :option:`bt-metadata-only <--bt-metadata-only>`
* :option:`bt-min-crypto-level <--bt-min-crypto-level>`

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