From c45ff588d1d50b9701c54f1df1f9487127bb7aeb Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 8 May 2009 12:23:04 +0000 Subject: [PATCH] 2009-05-08 Tatsuhiro Tsujikawa Added addTorrentFile xml-rpc command which receives uploaded torrent file and add download for it. * src/RequestGroupMan.cc * src/XmlRpcMethodFactory.cc * src/XmlRpcMethodImpl.cc * src/XmlRpcMethodImpl.h * src/download_helper.cc * src/download_helper.h --- ChangeLog | 11 +++++++++++ src/RequestGroupMan.cc | 1 + src/XmlRpcMethodFactory.cc | 2 ++ src/XmlRpcMethodImpl.cc | 36 ++++++++++++++++++++++++++++++++---- src/XmlRpcMethodImpl.h | 5 +++++ src/download_helper.cc | 15 +++++++++++---- src/download_helper.h | 9 ++++++--- 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1aeaac51..006481fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-05-08 Tatsuhiro Tsujikawa + + Added addTorrentFile xml-rpc command which receives uploaded + torrent file and add download for it. + * src/RequestGroupMan.cc + * src/XmlRpcMethodFactory.cc + * src/XmlRpcMethodImpl.cc + * src/XmlRpcMethodImpl.h + * src/download_helper.cc + * src/download_helper.h + 2009-05-08 Tatsuhiro Tsujikawa Added remove xml-rpc command which removes specified download. diff --git a/src/RequestGroupMan.cc b/src/RequestGroupMan.cc index 4084bdbe..923dd1c0 100644 --- a/src/RequestGroupMan.cc +++ b/src/RequestGroupMan.cc @@ -346,6 +346,7 @@ void RequestGroupMan::fillRequestGroupFromReserver(DownloadEngine* e) e->addCommand(commands); } catch(RecoverableException& ex) { _logger->error(EX_EXCEPTION_CAUGHT, ex); + groupToAdd->releaseRuntimeResource(e); _downloadResults.push_back(groupToAdd->createDownloadResult()); } } diff --git a/src/XmlRpcMethodFactory.cc b/src/XmlRpcMethodFactory.cc index 57e801a3..87d8849b 100644 --- a/src/XmlRpcMethodFactory.cc +++ b/src/XmlRpcMethodFactory.cc @@ -46,6 +46,8 @@ XmlRpcMethodFactory::create(const std::string& methodName) { if(methodName == "aria2.addURI") { return SharedHandle(new AddURIXmlRpcMethod()); + } else if(methodName == "aria2.addTorrent") { + return SharedHandle(new AddTorrentFileXmlRpcMethod()); } else if(methodName == "aria2.remove") { return SharedHandle(new RemoveXmlRpcMethod()); } else { diff --git a/src/XmlRpcMethodImpl.cc b/src/XmlRpcMethodImpl.cc index c4c09d19..3859ff99 100644 --- a/src/XmlRpcMethodImpl.cc +++ b/src/XmlRpcMethodImpl.cc @@ -54,6 +54,14 @@ namespace aria2 { namespace xmlrpc { +static BDE createGIDResponse(int32_t gid) +{ + BDE resParams = BDE::list(); + resParams << BDE("OK"); + resParams << BDE(Util::itos(gid)); + return resParams; +} + BDE AddURIXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e) { const BDE& params = req._params; @@ -80,15 +88,35 @@ BDE AddURIXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e) if(!result.empty()) { e->_requestGroupMan->addReservedGroup(result.front()); - BDE resParams = BDE::list(); - resParams << BDE("OK"); - resParams << BDE(Util::itos(result.front()->getGID())); - return resParams; + return createGIDResponse(result.front()->getGID()); } else { throw DlAbortEx("No URI to download."); } } +BDE AddTorrentFileXmlRpcMethod::process +(const XmlRpcRequest& req, DownloadEngine* e) +{ + const BDE& params = req._params; + assert(params.isList()); + if(params.empty() || !params[0].isString()) { + throw DlAbortEx("Torrent data is not provided."); + } + + // TODO should accect uris from xml rpc request + std::deque > result; + createRequestGroupForBitTorrent(result, *e->option, + std::deque(), + params[0].s()); + + if(!result.empty()) { + e->_requestGroupMan->addReservedGroup(result.front()); + return createGIDResponse(result.front()->getGID()); + } else { + throw DlAbortEx("No Torrent to download."); + } +} + BDE RemoveXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e) { const BDE& params = req._params; diff --git a/src/XmlRpcMethodImpl.h b/src/XmlRpcMethodImpl.h index ef9352a4..e3159d79 100644 --- a/src/XmlRpcMethodImpl.h +++ b/src/XmlRpcMethodImpl.h @@ -51,6 +51,11 @@ protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); }; +class AddTorrentFileXmlRpcMethod:public XmlRpcMethod { +protected: + virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); +}; + class FailXmlRpcMethod:public XmlRpcMethod { protected: virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e); diff --git a/src/download_helper.cc b/src/download_helper.cc index ae03d0d3..588b3742 100644 --- a/src/download_helper.cc +++ b/src/download_helper.cc @@ -132,12 +132,17 @@ SharedHandle createBtRequestGroup(const std::string& torrentFilePath, const Option& op, const std::deque& auxUris, - const Option& requestOption) + const Option& requestOption, + const std::string& torrentData = "") { SharedHandle rg(new RequestGroup(&op, auxUris)); SharedHandle btContext(new DefaultBtContext()); btContext->setDir(requestOption.get(PREF_DIR)); - btContext->load(torrentFilePath);// may throw exception + if(torrentData.empty()) { + btContext->load(torrentFilePath);// may throw exception + } else { + btContext->loadFromMemory(torrentData, "default"); // may throw exception + } if(op.defined(PREF_PEER_ID_PREFIX)) { btContext->setPeerIdPrefix(op.get(PREF_PEER_ID_PREFIX)); } @@ -158,7 +163,8 @@ createBtRequestGroup(const std::string& torrentFilePath, void createRequestGroupForBitTorrent (std::deque >& result, const Option& op, - const std::deque& uris) + const std::deque& uris, + const std::string& torrentData) { std::deque nargs; if(op.get(PREF_PARAMETERIZED_URI) == V_TRUE) { @@ -171,7 +177,8 @@ void createRequestGroupForBitTorrent std::deque auxUris; splitURI(auxUris, nargs.begin(), nargs.end(), numSplit); SharedHandle rg = - createBtRequestGroup(op.get(PREF_TORRENT_FILE), op, auxUris, op); + createBtRequestGroup(op.get(PREF_TORRENT_FILE), op, auxUris, op, + torrentData); rg->setNumConcurrentCommand(numSplit); result.push_back(rg); } diff --git a/src/download_helper.h b/src/download_helper.h index 51551df4..3921441b 100644 --- a/src/download_helper.h +++ b/src/download_helper.h @@ -51,11 +51,14 @@ class Option; const std::vector& listRequestOptions(); #ifdef ENABLE_BITTORRENT -// Create RequestGroup object using torrent file specified by torrent-file -// option. In this function, force-sequential is ignored. +// Create RequestGroup object using torrent file specified by +// torrent-file option. If torrentData is specified, then it is used +// as a content of torrent file in stead. In this function, +// force-sequential is ignored. void createRequestGroupForBitTorrent (std::deque >& result, const Option& op, - const std::deque& uris); + const std::deque& uris, + const std::string& torrentData = ""); #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK