Browse Source

2009-12-10 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Print Magnet URI in -S output.
	* src/AnnounceList.cc
	* src/bittorrent_helper.cc
	* src/bittorrent_helper.h
	* test/BittorrentHelperTest.cc
Tatsuhiro Tsujikawa 16 năm trước cách đây
mục cha
commit
6c3a3fefa2
5 tập tin đã thay đổi với 70 bổ sung5 xóa
  1. 8 0
      ChangeLog
  2. 1 1
      src/AnnounceList.cc
  3. 39 1
      src/bittorrent_helper.cc
  4. 4 0
      src/bittorrent_helper.h
  5. 18 3
      test/BittorrentHelperTest.cc

+ 8 - 0
ChangeLog

@@ -1,3 +1,11 @@
+2009-12-10  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	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  <t-tujikawa@users.sourceforge.net>
 
 	Added --bt-prioritize-piece option to aria2rpc.

+ 1 - 1
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()) {

+ 39 - 1
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<DownloadContext>& 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

+ 4 - 0
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

+ 18 - 3
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<DownloadContext> 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