From 6c3a3fefa23689f640e71d474a7a132fc21f6e94 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 10 Dec 2009 12:52:59 +0000 Subject: [PATCH] 2009-12-10 Tatsuhiro Tsujikawa Print Magnet URI in -S output. * src/AnnounceList.cc * src/bittorrent_helper.cc * src/bittorrent_helper.h * test/BittorrentHelperTest.cc --- ChangeLog | 8 ++++++++ src/AnnounceList.cc | 2 +- src/bittorrent_helper.cc | 40 +++++++++++++++++++++++++++++++++++- src/bittorrent_helper.h | 4 ++++ test/BittorrentHelperTest.cc | 21 ++++++++++++++++--- 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 35238c6d..581fa0f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-12-10 Tatsuhiro Tsujikawa + + Print Magnet URI in -S output. + * src/AnnounceList.cc + * src/bittorrent_helper.cc + * src/bittorrent_helper.h + * test/BittorrentHelperTest.cc + 2009-12-10 Tatsuhiro Tsujikawa Added --bt-prioritize-piece option to aria2rpc. diff --git a/src/AnnounceList.cc b/src/AnnounceList.cc index 67260a98..2e0c01dd 100644 --- a/src/AnnounceList.cc +++ b/src/AnnounceList.cc @@ -73,7 +73,7 @@ void AnnounceList::reconfigure(const BDE& announceList) elemItr != elemList.listEnd(); ++elemItr) { const BDE& data = *elemItr; if(data.isString()) { - urls.push_back(util::trim(data.s())); + urls.push_back(data.s()); } } if(!urls.empty()) { diff --git a/src/bittorrent_helper.cc b/src/bittorrent_helper.cc index ac381b2e..2b076c89 100644 --- a/src/bittorrent_helper.cc +++ b/src/bittorrent_helper.cc @@ -304,12 +304,22 @@ static void extractAnnounce(BDE& torrent, const BDE& rootDict) const BDE& announceList = rootDict[C_ANNOUNCE_LIST]; if(announceList.isList()) { torrent[ANNOUNCE_LIST] = announceList; + BDE& tiers = torrent[ANNOUNCE_LIST]; + for(BDE::List::iterator tieriter = tiers.listBegin(); + tieriter != tiers.listEnd(); ++tieriter) { + for(BDE::List::iterator uriiter = (*tieriter).listBegin(); + uriiter != (*tieriter).listEnd(); ++uriiter) { + if((*uriiter).isString()) { + *uriiter = util::trim((*uriiter).s()); + } + } + } } else { const BDE& announce = rootDict[C_ANNOUNCE]; BDE announceList = BDE::list(); if(announce.isString()) { announceList << BDE::list(); - announceList[0] << announce; + announceList[0] << util::trim(announce.s()); } torrent[ANNOUNCE_LIST] = announceList; } @@ -582,6 +592,7 @@ void print(std::ostream& o, const SharedHandle& dctx) } } o << "Name: " << torrentAttrs[NAME].s() << "\n"; + o << "Magnet URI: " << torrent2Magnet(torrentAttrs) << "\n"; util::toStream(dctx->getFileEntries().begin(), dctx->getFileEntries().end(), o); } @@ -925,6 +936,33 @@ std::string metadata2Torrent(const std::string& metadata, const BDE& attrs) return torrent; } +std::string torrent2Magnet(const BDE& attrs) +{ + std::string uri = "magnet:?"; + if(attrs.containsKey(INFO_HASH)) { + uri += "xt=urn:btih:"; + uri += util::toHex(attrs[INFO_HASH].s()); + } else { + return A2STR::NIL; + } + if(attrs.containsKey(NAME)) { + uri += "&dn="; + uri += util::urlencode(attrs[NAME].s()); + } + if(attrs.containsKey(ANNOUNCE_LIST)) { + const BDE& tiers = attrs[ANNOUNCE_LIST]; + for(BDE::List::const_iterator tieriter = tiers.listBegin(); + tieriter != tiers.listEnd(); ++tieriter) { + for(BDE::List::const_iterator uriiter = (*tieriter).listBegin(); + uriiter != (*tieriter).listEnd(); ++uriiter) { + uri += "&tr="; + uri += util::urlencode((*uriiter).s()); + } + } + } + return uri; +} + } // namespace bittorrent } // namespace aria2 diff --git a/src/bittorrent_helper.h b/src/bittorrent_helper.h index 6893cb6b..a27427ae 100644 --- a/src/bittorrent_helper.h +++ b/src/bittorrent_helper.h @@ -235,6 +235,10 @@ void generateRandomKey(unsigned char* key); // data. std::string metadata2Torrent(const std::string& metadata, const BDE& attrs); +// Constructs BitTorrent Magnet URI using attrs. attrs must be a +// BDE::dict. +std::string torrent2Magnet(const BDE& attrs); + } // namespace bittorrent } // namespace aria2 diff --git a/test/BittorrentHelperTest.cc b/test/BittorrentHelperTest.cc index a3d660a5..a2b9c3c5 100644 --- a/test/BittorrentHelperTest.cc +++ b/test/BittorrentHelperTest.cc @@ -62,6 +62,7 @@ class BittorrentHelperTest:public CppUnit::TestFixture { CPPUNIT_TEST(testParseMagnet); CPPUNIT_TEST(testParseMagnet_base32); CPPUNIT_TEST(testMetadata2Torrent); + CPPUNIT_TEST(testTorrent2Magnet); CPPUNIT_TEST_SUITE_END(); public: void setUp() { @@ -104,6 +105,7 @@ public: void testParseMagnet(); void testParseMagnet_base32(); void testMetadata2Torrent(); + void testTorrent2Magnet(); }; @@ -252,7 +254,7 @@ void BittorrentHelperTest::testGetAnnounceTier() { const BDE& tier = announceList[0]; CPPUNIT_ASSERT_EQUAL((size_t)1, tier.size()); CPPUNIT_ASSERT_EQUAL(std::string("http://aria.rednoah.com/announce.php"), - util::trim(tier[0].s())); + tier[0].s()); } @@ -267,8 +269,7 @@ void BittorrentHelperTest::testGetAnnounceTierAnnounceList() { const BDE& tier1 = announceList[0]; CPPUNIT_ASSERT_EQUAL((size_t)1, tier1.size()); - CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"), - util::trim(tier1[0].s())); + CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"), tier1[0].s()); const BDE& tier2 = announceList[1]; CPPUNIT_ASSERT_EQUAL((size_t)1, tier2.size()); @@ -756,6 +757,20 @@ void BittorrentHelperTest::testMetadata2Torrent() metadata2Torrent(metadata, attrs)); } +void BittorrentHelperTest::testTorrent2Magnet() +{ + SharedHandle dctx(new DownloadContext()); + load("test.torrent", dctx); + + CPPUNIT_ASSERT_EQUAL + (std::string("magnet:?xt=urn:btih:248d0a1cd08284299de78d5c1ed359bb46717d8c" + "&dn=aria2-test" + "&tr=http%3A%2F%2Ftracker1" + "&tr=http%3A%2F%2Ftracker2" + "&tr=http%3A%2F%2Ftracker3"), + torrent2Magnet(dctx->getAttribute(BITTORRENT))); +} + } // namespace bittorrent } // namespace aria2