Bläddra i källkod

2010-01-31 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Added bittorrent key to the response of tellStatus XML-RPC method.
	The associated value of the key is a struct and contains data
	retrieved from .torrent file, such as name, announce-list,
	comment, etc.
	* doc/aria2c.1.txt
	* src/XmlRpcMethodImpl.cc
	* src/XmlRpcMethodImpl.h
	* test/XmlRpcMethodTest.cc
Tatsuhiro Tsujikawa 15 år sedan
förälder
incheckning
a4870cacb4
7 ändrade filer med 242 tillägg och 7 borttagningar
  1. 11 0
      ChangeLog
  2. 41 3
      doc/aria2c.1
  3. 67 2
      doc/aria2c.1.html
  4. 35 1
      doc/aria2c.1.txt
  5. 43 1
      src/XmlRpcMethodImpl.cc
  6. 6 0
      src/XmlRpcMethodImpl.h
  7. 39 0
      test/XmlRpcMethodTest.cc

+ 11 - 0
ChangeLog

@@ -1,3 +1,14 @@
+2010-01-31  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Added bittorrent key to the response of tellStatus XML-RPC method.
+	The associated value of the key is a struct and contains data
+	retrieved from .torrent file, such as name, announce-list,
+	comment, etc.
+	* doc/aria2c.1.txt
+	* src/XmlRpcMethodImpl.cc
+	* src/XmlRpcMethodImpl.h
+	* test/XmlRpcMethodTest.cc
+
 2010-01-29  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Removed parse(std::istream&) and parse(const std::string&) from

+ 41 - 3
doc/aria2c.1

@@ -2,12 +2,12 @@
 .\"     Title: aria2c
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: 01/18/2010
+.\"      Date: 01/31/2010
 .\"    Manual: Aria2 Manual
 .\"    Source: Aria2 1.8.1
 .\"  Language: English
 .\"
-.TH "ARIA2C" "1" "01/18/2010" "Aria2 1\&.8\&.1" "Aria2 Manual"
+.TH "ARIA2C" "1" "01/31/2010" "Aria2 1\&.8\&.1" "Aria2 Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -2155,7 +2155,7 @@ How many times the server is used\&. Currently this value is only used by Adapti
 .PP
 last_updated
 .RS 4
-Last contact time in GMT with this server, specified in the seconds from the Epoch\&. Required\&.
+Last contact time in GMT with this server, specified in the seconds since the Epoch(00:00:00 on January 1, 1970, UTC)\&. Required\&.
 .RE
 .PP
 status
@@ -2299,6 +2299,44 @@ Returns the list of files\&. The element of list is the same struct used in
 \fBaria2\&.getFiles\fR
 method\&.
 .RE
+.PP
+bittorrent
+.RS 4
+Struct which contains information retrieved from \&.torrent file\&. BitTorrent only\&. It contains following keys\&.
+.PP
+announceList
+.RS 4
+List of lists of announce URI\&. If \&.torrent file contains announce and no announce\-list, announce is converted to announce\-list format\&.
+.RE
+.PP
+comment
+.RS 4
+The comment for the torrent\&. comment\&.utf\-8 is used if available\&.
+.RE
+.PP
+creationDate
+.RS 4
+The creation time of the torrent\&. The value is an integer since the Epoch, measured in seconds\&.
+.RE
+.PP
+mode
+.RS 4
+File mode of the torrent\&. The value is either
+\fIsingle\fR
+or
+\fImulti\fR\&.
+.RE
+.PP
+info
+.RS 4
+Struct which contains data from Info dictionary\&. It contains following keys\&.
+.PP
+name
+.RS 4
+name in info dictionary\&. name\&.utf\-8 is used if available\&.
+.RE
+.RE
+.RE
 .sp
 \fBaria2\&.getUris\fR \fIgid\fR
 .sp

+ 67 - 2
doc/aria2c.1.html

@@ -2661,7 +2661,7 @@ last_updated
 <dd>
 <p>
   Last contact time in GMT with this server, specified in the seconds
-  from the Epoch. Required.
+  since the Epoch(00:00:00 on January 1, 1970, UTC). Required.
 </p>
 </dd>
 <dt class="hdlist1">
@@ -2911,6 +2911,71 @@ files
   used in <strong>aria2.getFiles</strong> method.
 </p>
 </dd>
+<dt class="hdlist1">
+bittorrent
+</dt>
+<dd>
+<p>
+  Struct which contains information retrieved from .torrent
+  file. BitTorrent only. It contains following keys.
+</p>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+announceList
+</dt>
+<dd>
+<p>
+    List of lists of announce URI. If .torrent file contains announce
+    and no announce-list, announce is converted to announce-list
+    format.
+</p>
+</dd>
+<dt class="hdlist1">
+comment
+</dt>
+<dd>
+<p>
+    The comment for the torrent. comment.utf-8 is used if available.
+</p>
+</dd>
+<dt class="hdlist1">
+creationDate
+</dt>
+<dd>
+<p>
+    The creation time of the torrent. The value is an integer since
+    the Epoch, measured in seconds.
+</p>
+</dd>
+<dt class="hdlist1">
+mode
+</dt>
+<dd>
+<p>
+    File mode of the torrent. The value is either <em>single</em> or <em>multi</em>.
+</p>
+</dd>
+<dt class="hdlist1">
+info
+</dt>
+<dd>
+<p>
+    Struct which contains data from Info dictionary. It contains
+    following keys.
+</p>
+<div class="dlist"><dl>
+<dt class="hdlist1">
+name
+</dt>
+<dd>
+<p>
+      name in info dictionary. name.utf-8 is used if available.
+</p>
+</dd>
+</dl></div>
+</dd>
+</dl></div>
+</dd>
 </dl></div>
 <div class="paragraph"><p><strong>aria2.getUris</strong> <em>gid</em></p></div>
 <div class="paragraph"><p>This method returns URIs used in the download denoted by <em>gid</em>.  <em>gid</em>
@@ -3648,7 +3713,7 @@ files in the program, then also delete it here.</p></div>
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2010-01-18 23:42:25 JST
+Last updated 2010-01-31 17:04:00 JST
 </div>
 </div>
 </body>

+ 35 - 1
doc/aria2c.1.txt

@@ -1101,7 +1101,7 @@ counter::
 
 last_updated::
   Last contact time in GMT with this server, specified in the seconds
-  from the Epoch. Required.
+  since the Epoch(00:00:00 on January 1, 1970, UTC). Required.
 
 status::
   ERROR is set when server cannot be reached or out-of-service or
@@ -1280,6 +1280,40 @@ files::
   Returns the list of files. The element of list is the same struct
   used in *aria2.getFiles* method.
 
+
+bittorrent::
+
+  Struct which contains information retrieved from .torrent
+  file. BitTorrent only. It contains following keys.
+
+  announceList;;
+
+    List of lists of announce URI. If .torrent file contains announce
+    and no announce-list, announce is converted to announce-list
+    format.
+
+  comment;;
+
+    The comment for the torrent. comment.utf-8 is used if available.
+
+  creationDate;;
+
+    The creation time of the torrent. The value is an integer since
+    the Epoch, measured in seconds.
+
+  mode;;
+
+    File mode of the torrent. The value is either 'single' or 'multi'.
+
+  info;;
+
+    Struct which contains data from Info dictionary. It contains
+    following keys.
+
+    name:::
+
+      name in info dictionary. name.utf-8 is used if available.
+
 *aria2.getUris* 'gid'
 
 This method returns URIs used in the download denoted by 'gid'.  'gid'

+ 43 - 1
src/XmlRpcMethodImpl.cc

@@ -119,6 +119,13 @@ const std::string KEY_SESSION_ID = "sessionId";
 const std::string KEY_FILES = "files";
 const std::string KEY_DIR = "dir";
 const std::string KEY_URIS = "uris";
+const std::string KEY_BITTORRENT = "bittorrent";
+const std::string KEY_INFO = "info";
+const std::string KEY_NAME = "name";
+const std::string KEY_ANNOUNCE_LIST = "announceList";
+const std::string KEY_COMMENT = "comment";
+const std::string KEY_CREATION_DATE = "creationDate";
+const std::string KEY_MODE = "mode";
 }
 
 static BDE createGIDResponse(int32_t gid)
@@ -371,12 +378,47 @@ void gatherProgressCommon
 }
 
 #ifdef ENABLE_BITTORRENT
+void gatherBitTorrentMetadata(BDE& btDict, const BDE& torrentAttrs)
+{
+  if(torrentAttrs.containsKey(bittorrent::COMMENT)) {
+    btDict[KEY_COMMENT] = torrentAttrs[bittorrent::COMMENT];
+  }
+  if(torrentAttrs.containsKey(bittorrent::CREATION_DATE)) {
+    btDict[KEY_CREATION_DATE] = torrentAttrs[bittorrent::CREATION_DATE];
+  }
+  if(torrentAttrs.containsKey(bittorrent::MODE)) {
+    btDict[KEY_MODE] = torrentAttrs[bittorrent::MODE];
+  }
+  // Copy announceList to avoid modification on entyDict to be
+  // affected original announceList.
+  // TODO Would it be good to add copy() method in BDE?
+  const BDE& announceList = torrentAttrs[bittorrent::ANNOUNCE_LIST];
+  BDE destAnnounceList = BDE::list();
+  for(BDE::List::const_iterator l = announceList.listBegin();
+      l != announceList.listEnd(); ++l) {
+    BDE destAnnounceTier = BDE::list();
+    for(BDE::List::const_iterator t = (*l).listBegin();
+        t != (*l).listEnd(); ++t) {
+      destAnnounceTier <<  (*t);
+    }
+    destAnnounceList << destAnnounceTier;
+  }
+  btDict[KEY_ANNOUNCE_LIST] = destAnnounceList;
+  if(torrentAttrs.containsKey(bittorrent::METADATA)) {
+    BDE infoDict = BDE::dict();
+    infoDict[KEY_NAME] = torrentAttrs[bittorrent::NAME];
+    btDict[KEY_INFO] = infoDict;
+  }
+}
+
 static void gatherProgressBitTorrent
 (BDE& entryDict, const BDE& torrentAttrs, const BtObject& btObject)
 {
   const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
   entryDict[KEY_INFO_HASH] = util::toHex(infoHash);
-
+  BDE btDict = BDE::dict();
+  gatherBitTorrentMetadata(btDict, torrentAttrs);
+  entryDict[KEY_BITTORRENT] = btDict;
   if(!btObject.isNull()) {
     SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
     assert(!peerStorage.isNull());

+ 6 - 0
src/XmlRpcMethodImpl.h

@@ -378,6 +378,12 @@ void gatherStoppedDownload
 void gatherProgressCommon
 (BDE& entryDict, const SharedHandle<RequestGroup>& group);
 
+#ifdef ENABLE_BITTORRENT
+// Helper function to store BitTorrent metadata from torrentAttrs in
+// btDict. btDict must be an BDE::Dict.
+void gatherBitTorrentMetadata(BDE& btDict, const BDE& torrentAttrs);
+#endif // ENABLE_BITTORRENT
+
 } // namespace xmlrpc
 
 } // namespace aria2

+ 39 - 0
test/XmlRpcMethodTest.cc

@@ -27,6 +27,7 @@
 # include "PeerStorage.h"
 # include "BtProgressInfoFile.h"
 # include "BtAnnounce.h"
+# include "bittorrent_helper.h"
 #endif // ENABLE_BITTORRENT
 
 namespace aria2 {
@@ -68,6 +69,9 @@ class XmlRpcMethodTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testNoSuchMethod);
   CPPUNIT_TEST(testGatherStoppedDownload);
   CPPUNIT_TEST(testGatherProgressCommon);
+#ifdef ENABLE_BITTORRENT
+  CPPUNIT_TEST(testGatherBitTorrentMetadata);
+#endif // ENABLE_BITTORRENT
   CPPUNIT_TEST(testChangePosition);
   CPPUNIT_TEST(testChangePosition_fail);
   CPPUNIT_TEST(testGetSessionInfo);
@@ -125,6 +129,9 @@ public:
   void testNoSuchMethod();
   void testGatherStoppedDownload();
   void testGatherProgressCommon();
+#ifdef ENABLE_BITTORRENT
+  void testGatherBitTorrentMetadata();
+#endif // ENABLE_BITTORRENT
   void testChangePosition();
   void testChangePosition_fail();
   void testGetSessionInfo();
@@ -708,6 +715,38 @@ void XmlRpcMethodTest::testGatherProgressCommon()
   CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), entry["dir"].s());
 }
 
+#ifdef ENABLE_BITTORRENT
+void XmlRpcMethodTest::testGatherBitTorrentMetadata()
+{
+  SharedHandle<DownloadContext> dctx(new DownloadContext());
+  bittorrent::load("test.torrent", dctx);
+  BDE btDict = BDE::dict();
+  gatherBitTorrentMetadata(btDict, dctx->getAttribute(bittorrent::BITTORRENT));
+  CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"), btDict["comment"].s());
+  CPPUNIT_ASSERT_EQUAL((int64_t)1123456789, btDict["creationDate"].i());
+  CPPUNIT_ASSERT_EQUAL(std::string("multi"), btDict["mode"].s());
+  CPPUNIT_ASSERT_EQUAL(std::string("aria2-test"), btDict["info"]["name"].s());
+  const BDE& announceList = btDict["announceList"];
+  CPPUNIT_ASSERT_EQUAL((size_t)3, announceList.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker1"), announceList[0][0].s());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker2"), announceList[1][0].s());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://tracker3"), announceList[2][0].s());
+  // Remove some keys
+  BDE modBtAttrs = dctx->getAttribute(bittorrent::BITTORRENT);
+  modBtAttrs.removeKey(bittorrent::COMMENT);
+  modBtAttrs.removeKey(bittorrent::CREATION_DATE);
+  modBtAttrs.removeKey(bittorrent::MODE);
+  modBtAttrs.removeKey(bittorrent::METADATA);
+  btDict = BDE::dict();
+  gatherBitTorrentMetadata(btDict, modBtAttrs);
+  CPPUNIT_ASSERT(!btDict.containsKey("comment"));
+  CPPUNIT_ASSERT(!btDict.containsKey("creationDate"));
+  CPPUNIT_ASSERT(!btDict.containsKey("mode"));
+  CPPUNIT_ASSERT(!btDict.containsKey("info"));
+  CPPUNIT_ASSERT(btDict.containsKey("announceList"));
+}
+#endif // ENABLE_BITTORRENT
+
 void XmlRpcMethodTest::testChangePosition()
 {
   _e->_requestGroupMan->addReservedGroup