mirror of https://github.com/aria2/aria2
				
				
				
			Merge branch 'bt-load-saved-metadata'
						commit
						e3b6460d07
					
				| 
						 | 
				
			
			@ -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>`
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue