浏览代码

2009-05-09 Tatsuhiro Tsujikawa <[email protected]>

	Renamed TellActiveStatusXmlRpcMethod as TellActiveXmlRpcMethod.
	Added TellStatusXmlRpcMethod.  Remove command can now remove
	waiting RequestGroup.	
	* src/RequestGroupMan.cc
	* src/RequestGroupMan.h
	* src/XmlRpcMethodFactory.cc
	* src/XmlRpcMethodImpl.cc
	* src/XmlRpcMethodImpl.h
Tatsuhiro Tsujikawa 16 年之前
父节点
当前提交
b2605588b7
共有 6 个文件被更改,包括 232 次插入73 次删除
  1. 11 0
      ChangeLog
  2. 53 6
      src/RequestGroupMan.cc
  3. 6 0
      src/RequestGroupMan.h
  4. 4 2
      src/XmlRpcMethodFactory.cc
  5. 152 64
      src/XmlRpcMethodImpl.cc
  6. 6 1
      src/XmlRpcMethodImpl.h

+ 11 - 0
ChangeLog

@@ -1,3 +1,14 @@
+2009-05-09  Tatsuhiro Tsujikawa  <[email protected]>
+
+	Renamed TellActiveStatusXmlRpcMethod as TellActiveXmlRpcMethod.
+	Added TellStatusXmlRpcMethod.  Remove command can now remove
+	waiting RequestGroup.	
+	* src/RequestGroupMan.cc
+	* src/RequestGroupMan.h
+	* src/XmlRpcMethodFactory.cc
+	* src/XmlRpcMethodImpl.cc
+	* src/XmlRpcMethodImpl.h	
+	
 2009-05-09  Tatsuhiro Tsujikawa  <[email protected]>
 
 	Initialized _peerId

+ 53 - 6
src/RequestGroupMan.cc

@@ -133,16 +133,27 @@ RequestGroupMan::getRequestGroups() const
   return _requestGroups;
 }
 
+template<typename Iterator>
+static Iterator findByGID(Iterator first, Iterator last, int32_t gid)
+{
+  for(; first != last; ++first) {
+    if((*first)->getGID() == gid) {
+      return first;
+    }
+  }
+  return first;
+}
+
 SharedHandle<RequestGroup>
 RequestGroupMan::findRequestGroup(int32_t gid) const
 {
-  for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
-	_requestGroups.begin(); i != _requestGroups.end(); ++i) {
-    if((*i)->getGID() == gid) {
-      return *i;
-    }
+  std::deque<SharedHandle<RequestGroup> >::const_iterator i =
+    findByGID(_requestGroups.begin(), _requestGroups.end(), gid);
+  if(i == _requestGroups.end()) {
+    return SharedHandle<RequestGroup>();
+  } else {
+    return *i;
   }
-  return SharedHandle<RequestGroup>();
 }
 
 const std::deque<SharedHandle<RequestGroup> >&
@@ -151,6 +162,30 @@ RequestGroupMan::getReservedGroups() const
   return _reservedGroups;
 }
 
+SharedHandle<RequestGroup>
+RequestGroupMan::findReservedGroup(int32_t gid) const
+{
+  std::deque<SharedHandle<RequestGroup> >::const_iterator i =
+    findByGID(_reservedGroups.begin(), _reservedGroups.end(), gid);
+  if(i == _reservedGroups.end()) {
+    return SharedHandle<RequestGroup>();
+  } else {
+    return *i;
+  }
+}
+
+bool RequestGroupMan::removeReservedGroup(int32_t gid)
+{
+  std::deque<SharedHandle<RequestGroup> >::iterator i =
+    findByGID(_reservedGroups.begin(), _reservedGroups.end(), gid);
+  if(i == _reservedGroups.end()) {
+    return false;
+  } else {
+    _reservedGroups.erase(i);
+    return true;
+  }
+}
+
 class ProcessStoppedRequestGroup {
 private:
   DownloadEngine* _e;
@@ -605,6 +640,18 @@ RequestGroupMan::getDownloadResults() const
   return _downloadResults;
 }
 
+SharedHandle<DownloadResult>
+RequestGroupMan::findDownloadResult(int32_t gid) const
+{
+  for(std::deque<SharedHandle<DownloadResult> >::const_iterator i =
+	_downloadResults.begin(); i != _downloadResults.end(); ++i) {
+    if((*i)->gid == gid) {
+      return *i;
+    }
+  }
+  return SharedHandle<DownloadResult>();
+}
+
 SharedHandle<ServerStat>
 RequestGroupMan::findServerStat(const std::string& hostname,
 				const std::string& protocol) const

+ 6 - 0
src/RequestGroupMan.h

@@ -116,6 +116,10 @@ public:
 
   const std::deque<SharedHandle<RequestGroup> >& getReservedGroups() const;
 
+  SharedHandle<RequestGroup> findReservedGroup(int32_t gid) const;
+
+  bool removeReservedGroup(int32_t gid);
+
   void showDownloadResults(std::ostream& o) const;
 
   bool isSameFileBeingDownloaded(RequestGroup* requestGroup) const;
@@ -163,6 +167,8 @@ public:
   const std::deque<SharedHandle<DownloadResult> >&
   getDownloadResults() const;
 
+  SharedHandle<DownloadResult> findDownloadResult(int32_t gid) const;
+
   SharedHandle<ServerStat> findServerStat(const std::string& hostname,
 					  const std::string& protocol) const;
 

+ 4 - 2
src/XmlRpcMethodFactory.cc

@@ -50,8 +50,10 @@ XmlRpcMethodFactory::create(const std::string& methodName)
     return SharedHandle<XmlRpcMethod>(new AddTorrentFileXmlRpcMethod());
   } else if(methodName == "aria2.remove") {
     return SharedHandle<XmlRpcMethod>(new RemoveXmlRpcMethod());
-  } else if(methodName == "aria2.tellActiveStatus") {
-    return SharedHandle<XmlRpcMethod>(new TellActiveStatusXmlRpcMethod());
+  } else if(methodName == "aria2.tellStatus") {
+    return SharedHandle<XmlRpcMethod>(new TellStatusXmlRpcMethod());
+  } else if(methodName == "aria2.tellActive") {
+    return SharedHandle<XmlRpcMethod>(new TellActiveXmlRpcMethod());
   } else {
     return SharedHandle<XmlRpcMethod>(new NoSuchMethodXmlRpcMethod());
   }

+ 152 - 64
src/XmlRpcMethodImpl.cc

@@ -145,89 +145,177 @@ BDE RemoveXmlRpcMethod::process(const XmlRpcRequest& req, DownloadEngine* e)
   SharedHandle<RequestGroup> group = e->_requestGroupMan->findRequestGroup(gid);
 
   if(group.isNull()) {
-    throw DlAbortEx
-      (StringFormat("Active Download not found for GID#%d", gid).str());
+    group = e->_requestGroupMan->findReservedGroup(gid);
+    if(group.isNull()) {
+      throw DlAbortEx
+	(StringFormat("Active Download not found for GID#%d", gid).str());
+    }
+    if(group->isDependencyResolved()) {
+      e->_requestGroupMan->removeReservedGroup(gid);
+    } else {
+      throw DlAbortEx
+	(StringFormat("GID#%d cannot be removed now", gid).str());
+    }
+  } else {
+    group->setHaltRequested(true, RequestGroup::USER_REQUEST);
   }
 
-  group->setHaltRequested(true, RequestGroup::USER_REQUEST);
-
   return createGIDResponse(gid);
 }
 
-BDE TellActiveStatusXmlRpcMethod::process
+static void gatherProgressCommon
+(BDE& entryDict, const SharedHandle<RequestGroup>& group)
+{
+  entryDict["gid"] = BDE(Util::itos(group->getGID()));
+  entryDict["totalLength"] = BDE(Util::uitos(group->getTotalLength()));
+  entryDict["completedLength"] = BDE(Util::uitos(group->getCompletedLength()));
+  TransferStat stat = group->calculateStat();
+  entryDict["downloadSpeed"] = BDE(Util::uitos(stat.getDownloadSpeed()));
+  entryDict["uploadSpeed"] = BDE(Util::uitos(stat.getUploadSpeed()));
+    
+  SharedHandle<PieceStorage> ps = group->getPieceStorage();
+  if(!ps.isNull()) {
+    if(ps->getBitfieldLength() > 0) {
+      entryDict["bitfield"] = BDE(Util::toHex(ps->getBitfield(),
+					      ps->getBitfieldLength()));
+    }
+
+    if(!ps->getDiskAdaptor().isNull()) {
+      BDE files = BDE::list();
+      const std::deque<SharedHandle<FileEntry> >& entries =
+	ps->getDiskAdaptor()->getFileEntries();
+      for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
+	    entries.begin(); i != entries.end(); ++i) {
+	files << BDE((*i)->getPath());
+      }
+      entryDict["files"] = files;
+    }
+  }
+
+  entryDict["pieceLength"] = 
+    BDE(Util::uitos(group->getDownloadContext()->getPieceLength()));
+  entryDict["numPieces"] =
+    BDE(Util::uitos(group->getDownloadContext()->getNumPieces()));
+}
+
+static void gatherProgressBitTorrent
+(BDE& entryDict, const SharedHandle<BtContext>& btctx)
+{
+  entryDict["infoHash"] = BDE(btctx->getInfoHashAsString());
+}
+
+static void gatherPeer(BDE& entryDict, const SharedHandle<PeerStorage>& ps)
+{
+  BDE peers = BDE::list();
+
+  std::deque<SharedHandle<Peer> > activePeers;
+  ps->getActivePeers(activePeers);
+  for(std::deque<SharedHandle<Peer> >::const_iterator i =
+	activePeers.begin(); i != activePeers.end(); ++i) {
+    BDE peerEntry = BDE::dict();
+    peerEntry["peerId"] = BDE(Util::torrentUrlencode((*i)->getPeerId(),
+						     PEER_ID_LENGTH));
+    peerEntry["ip"] = BDE((*i)->ipaddr);
+    peerEntry["port"] = BDE(Util::uitos((*i)->port));
+    peerEntry["bitfield"] = BDE(Util::toHex((*i)->getBitfield(),
+					    (*i)->getBitfieldLength()));
+    peers << peerEntry;
+  }
+  entryDict["peers"] = peers;
+}
+
+static void gatherProgress
+(BDE& entryDict, const SharedHandle<RequestGroup>& group, DownloadEngine* e)
+{
+  gatherProgressCommon(entryDict, group);
+
+  SharedHandle<BtContext> btctx =
+    dynamic_pointer_cast<BtContext>(group->getDownloadContext());
+  if(!btctx.isNull()) {
+    gatherProgressBitTorrent(entryDict, btctx);
+
+    SharedHandle<BtRegistry> btreg = e->getBtRegistry();
+    SharedHandle<PeerStorage> ps =
+      btreg->getPeerStorage(btctx->getInfoHashAsString());
+    if(!ps.isNull()) {
+      gatherPeer(entryDict, ps);
+    }
+  }
+}
+
+static void gatherStoppedDownload
+(BDE& entryDict, const SharedHandle<DownloadResult>& ds)
+{
+  entryDict["gid"] = ds->gid;
+  if(ds->result == DownloadResult::IN_PROGRESS) {
+    entryDict["status"] = BDE("removed");
+  } else if(ds->result == DownloadResult::FINISHED) {
+    entryDict["status"] = BDE("complete");
+  } else {
+    entryDict["status"] = BDE("error");
+  }
+}
+
+BDE TellStatusXmlRpcMethod::process
+(const XmlRpcRequest& req, DownloadEngine* e)
+{
+  const BDE& params = req._params;
+  assert(params.isList());
+
+  if(params.empty() || !params[0].isString()) {
+    throw DlAbortEx("GID is not provided.");
+  }
+  
+  int32_t gid = Util::parseInt(params[0].s());
+
+  SharedHandle<RequestGroup> group = e->_requestGroupMan->findRequestGroup(gid);
+
+  BDE entryDict = BDE::dict();
+  if(group.isNull()) {
+    group = e->_requestGroupMan->findReservedGroup(gid);
+    if(group.isNull()) {
+      SharedHandle<DownloadResult> ds =
+	e->_requestGroupMan->findDownloadResult(gid);
+      if(ds.isNull()) {
+	throw DlAbortEx
+	  (StringFormat("No such download for GID#%d", gid).str());
+      }
+      gatherStoppedDownload(entryDict, ds);
+    } else {
+      entryDict["status"] = BDE("waiting");
+      gatherProgress(entryDict, group, e);
+    }
+  } else {
+    entryDict["status"] = BDE("active");
+    gatherProgress(entryDict, group, e);
+  }
+
+  BDE resParams = BDE::list();
+  resParams << entryDict;
+  return resParams;
+}
+
+BDE TellActiveXmlRpcMethod::process
 (const XmlRpcRequest& req, DownloadEngine* e)
 {
-  BDE res = BDE::list();
+  BDE list = BDE::list();
   const std::deque<SharedHandle<RequestGroup> >& groups =
     e->_requestGroupMan->getRequestGroups();
   for(std::deque<SharedHandle<RequestGroup> >::const_iterator i =
 	groups.begin(); i != groups.end(); ++i) {
     BDE entryDict = BDE::dict();
-    entryDict["gid"] = BDE(Util::itos((*i)->getGID()));
-    entryDict["totalLength"] = BDE(Util::uitos((*i)->getTotalLength()));
-    entryDict["completedLength"] = BDE(Util::uitos((*i)->getCompletedLength()));
-    TransferStat stat = (*i)->calculateStat();
-    entryDict["downloadSpeed"] = BDE(Util::uitos(stat.getDownloadSpeed()));
-    entryDict["uploadSpeed"] = BDE(Util::uitos(stat.getUploadSpeed()));
-    
-    SharedHandle<PieceStorage> ps = (*i)->getPieceStorage();
-    if(!ps.isNull()) {
-      if(ps->getBitfieldLength() > 0) {
-	entryDict["bitfield"] = BDE(Util::toHex(ps->getBitfield(),
-						ps->getBitfieldLength()));
-      }
-
-      if(!ps->getDiskAdaptor().isNull()) {
-	BDE files = BDE::list();
-	const std::deque<SharedHandle<FileEntry> >& entries =
-	  ps->getDiskAdaptor()->getFileEntries();
-	for(std::deque<SharedHandle<FileEntry> >::const_iterator i =
-	      entries.begin(); i != entries.end(); ++i) {
-	  files << BDE((*i)->getPath());
-	}
-	entryDict["files"] = files;
-      }
-    }
+    entryDict["status"] = BDE("active");
+    gatherProgressCommon(entryDict, *i);
 
-    entryDict["pieceLength"] = 
-      BDE(Util::uitos((*i)->getDownloadContext()->getPieceLength()));
-    entryDict["numPieces"] =
-      BDE(Util::uitos((*i)->getDownloadContext()->getNumPieces()));
-    
     SharedHandle<BtContext> btctx =
       dynamic_pointer_cast<BtContext>((*i)->getDownloadContext());
     if(!btctx.isNull()) {
-      entryDict["infoHash"] = BDE(btctx->getInfoHashAsString());
-
-      SharedHandle<BtRegistry> btreg = e->getBtRegistry();
-
-      BDE peers = BDE::list();
-      SharedHandle<PeerStorage> ps =
-	btreg->getPeerStorage(btctx->getInfoHashAsString());
-
-      assert(!ps.isNull());
-
-      std::deque<SharedHandle<Peer> > activePeers;
-      ps->getActivePeers(activePeers);
-      for(std::deque<SharedHandle<Peer> >::const_iterator i =
-	    activePeers.begin(); i != activePeers.end(); ++i) {
-	BDE peerEntry = BDE::dict();
-	peerEntry["peerId"] = BDE(Util::torrentUrlencode((*i)->getPeerId(),
-							 PEER_ID_LENGTH));
-	peerEntry["ip"] = BDE((*i)->ipaddr);
-	peerEntry["port"] = BDE(Util::uitos((*i)->port));
-	peerEntry["bitfield"] = BDE(Util::toHex((*i)->getBitfield(),
-						(*i)->getBitfieldLength()));
-	peers << peerEntry;
-      }
-      entryDict["peers"] = peers;
+      gatherProgressBitTorrent(entryDict, btctx);
     }
-
-    res << entryDict;
+    list << entryDict;
   }
-
   BDE resParams = BDE::list();
-  resParams << res;
+  resParams << list;
   return resParams;
 }
 

+ 6 - 1
src/XmlRpcMethodImpl.h

@@ -56,7 +56,12 @@ protected:
   virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
 };
 
-class TellActiveStatusXmlRpcMethod:public XmlRpcMethod {
+class TellStatusXmlRpcMethod:public XmlRpcMethod {
+protected:
+  virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
+};
+
+class TellActiveXmlRpcMethod:public XmlRpcMethod {
 protected:
   virtual BDE process(const XmlRpcRequest& req, DownloadEngine* e);
 };