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>
Removed parse(std::istream&) and parse(const std::string&) from

View File

@ -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

View File

@ -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>

View File

@ -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'

View File

@ -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());

View File

@ -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

View File

@ -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