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
pull/1/head
Tatsuhiro Tsujikawa 2010-01-31 08:05:21 +00:00
parent 100ad4e18a
commit a4870cacb4
7 changed files with 242 additions and 7 deletions

View File

@ -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> 2010-01-29 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Removed parse(std::istream&) and parse(const std::string&) from Removed parse(std::istream&) and parse(const std::string&) from

View File

@ -2,12 +2,12 @@
.\" Title: aria2c .\" Title: aria2c
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
.\" Date: 01/18/2010 .\" Date: 01/31/2010
.\" Manual: Aria2 Manual .\" Manual: Aria2 Manual
.\" Source: Aria2 1.8.1 .\" Source: Aria2 1.8.1
.\" Language: English .\" 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 .\" * Define some portability stuff
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -2155,7 +2155,7 @@ How many times the server is used\&. Currently this value is only used by Adapti
.PP .PP
last_updated last_updated
.RS 4 .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 .RE
.PP .PP
status status
@ -2299,6 +2299,44 @@ Returns the list of files\&. The element of list is the same struct used in
\fBaria2\&.getFiles\fR \fBaria2\&.getFiles\fR
method\&. method\&.
.RE .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 .sp
\fBaria2\&.getUris\fR \fIgid\fR \fBaria2\&.getUris\fR \fIgid\fR
.sp .sp

View File

@ -2661,7 +2661,7 @@ last_updated
<dd> <dd>
<p> <p>
Last contact time in GMT with this server, specified in the seconds 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> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
@ -2911,6 +2911,71 @@ files
used in <strong>aria2.getFiles</strong> method. used in <strong>aria2.getFiles</strong> method.
</p> </p>
</dd> </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> </dl></div>
<div class="paragraph"><p><strong>aria2.getUris</strong> <em>gid</em></p></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> <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="footnotes"><hr /></div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2010-01-18 23:42:25 JST Last updated 2010-01-31 17:04:00 JST
</div> </div>
</div> </div>
</body> </body>

View File

@ -1101,7 +1101,7 @@ counter::
last_updated:: last_updated::
Last contact time in GMT with this server, specified in the seconds 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:: status::
ERROR is set when server cannot be reached or out-of-service or 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 Returns the list of files. The element of list is the same struct
used in *aria2.getFiles* method. 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' *aria2.getUris* 'gid'
This method returns URIs used in the download denoted by 'gid'. 'gid' This method returns URIs used in the download denoted by 'gid'. 'gid'

View File

@ -119,6 +119,13 @@ const std::string KEY_SESSION_ID = "sessionId";
const std::string KEY_FILES = "files"; const std::string KEY_FILES = "files";
const std::string KEY_DIR = "dir"; const std::string KEY_DIR = "dir";
const std::string KEY_URIS = "uris"; 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) static BDE createGIDResponse(int32_t gid)
@ -371,12 +378,47 @@ void gatherProgressCommon
} }
#ifdef ENABLE_BITTORRENT #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 static void gatherProgressBitTorrent
(BDE& entryDict, const BDE& torrentAttrs, const BtObject& btObject) (BDE& entryDict, const BDE& torrentAttrs, const BtObject& btObject)
{ {
const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s(); const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
entryDict[KEY_INFO_HASH] = util::toHex(infoHash); entryDict[KEY_INFO_HASH] = util::toHex(infoHash);
BDE btDict = BDE::dict();
gatherBitTorrentMetadata(btDict, torrentAttrs);
entryDict[KEY_BITTORRENT] = btDict;
if(!btObject.isNull()) { if(!btObject.isNull()) {
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage; SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
assert(!peerStorage.isNull()); assert(!peerStorage.isNull());

View File

@ -378,6 +378,12 @@ void gatherStoppedDownload
void gatherProgressCommon void gatherProgressCommon
(BDE& entryDict, const SharedHandle<RequestGroup>& group); (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 xmlrpc
} // namespace aria2 } // namespace aria2

View File

@ -27,6 +27,7 @@
# include "PeerStorage.h" # include "PeerStorage.h"
# include "BtProgressInfoFile.h" # include "BtProgressInfoFile.h"
# include "BtAnnounce.h" # include "BtAnnounce.h"
# include "bittorrent_helper.h"
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
namespace aria2 { namespace aria2 {
@ -68,6 +69,9 @@ class XmlRpcMethodTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testNoSuchMethod); CPPUNIT_TEST(testNoSuchMethod);
CPPUNIT_TEST(testGatherStoppedDownload); CPPUNIT_TEST(testGatherStoppedDownload);
CPPUNIT_TEST(testGatherProgressCommon); CPPUNIT_TEST(testGatherProgressCommon);
#ifdef ENABLE_BITTORRENT
CPPUNIT_TEST(testGatherBitTorrentMetadata);
#endif // ENABLE_BITTORRENT
CPPUNIT_TEST(testChangePosition); CPPUNIT_TEST(testChangePosition);
CPPUNIT_TEST(testChangePosition_fail); CPPUNIT_TEST(testChangePosition_fail);
CPPUNIT_TEST(testGetSessionInfo); CPPUNIT_TEST(testGetSessionInfo);
@ -125,6 +129,9 @@ public:
void testNoSuchMethod(); void testNoSuchMethod();
void testGatherStoppedDownload(); void testGatherStoppedDownload();
void testGatherProgressCommon(); void testGatherProgressCommon();
#ifdef ENABLE_BITTORRENT
void testGatherBitTorrentMetadata();
#endif // ENABLE_BITTORRENT
void testChangePosition(); void testChangePosition();
void testChangePosition_fail(); void testChangePosition_fail();
void testGetSessionInfo(); void testGetSessionInfo();
@ -708,6 +715,38 @@ void XmlRpcMethodTest::testGatherProgressCommon()
CPPUNIT_ASSERT_EQUAL(std::string("/tmp"), entry["dir"].s()); 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() void XmlRpcMethodTest::testChangePosition()
{ {
_e->_requestGroupMan->addReservedGroup _e->_requestGroupMan->addReservedGroup