Kaynağa Gözat

Add following to aria2.tellStatus response key as reverse link for followedBy

Tatsuhiro Tsujikawa 9 yıl önce
ebeveyn
işleme
21754fa103

+ 4 - 0
doc/manual-src/en/aria2c.rst

@@ -2548,6 +2548,10 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
     auto-generated downloads. If there are no such downloads, this key will not
     be included in the response.
 
+  ``following``
+    The reverse link for ``followedBy``.  A download included in
+    ``followedBy`` has this object's GID in its ``following`` value.
+
   ``belongsTo``
     GID of a parent download. Some downloads are a part of another
     download.  For example, if a file in a Metalink has BitTorrent

+ 3 - 0
src/BtPostDownloadHandler.cc

@@ -104,6 +104,9 @@ void BtPostDownloadHandler::getNextRequestGroups(
                                   std::vector<std::string>(), "",
                                   torrent.get());
   requestGroup->followedBy(std::begin(newRgs), std::end(newRgs));
+  for (auto& rg : newRgs) {
+    rg->following(requestGroup->getGID());
+  }
   auto mi = createMetadataInfoFromFirstFileEntry(
       requestGroup->getGroupId(), requestGroup->getDownloadContext());
   if (mi) {

+ 3 - 0
src/DownloadResult.h

@@ -79,6 +79,9 @@ struct DownloadResult {
   // RequestGroup.cc::followedByGIDs_.
   std::vector<a2_gid_t> followedBy;
 
+  // The reverse link for followedBy.
+  a2_gid_t following;
+
   std::string bitfield;
 
   std::string infoHash;

+ 3 - 0
src/MetalinkPostDownloadHandler.cc

@@ -104,6 +104,9 @@ void MetalinkPostDownloadHandler::getNextRequestGroups(
     Metalink2RequestGroup().generate(newRgs, diskAdaptor,
                                      requestGroup->getOption(), baseUri);
     requestGroup->followedBy(newRgs.begin(), newRgs.end());
+    for (auto& rg : newRgs) {
+      rg->following(requestGroup->getGID());
+    }
     auto mi = createMetadataInfoFromFirstFileEntry(
         requestGroup->getGroupId(), requestGroup->getDownloadContext());
     if (mi) {

+ 2 - 0
src/RequestGroup.cc

@@ -131,6 +131,7 @@ RequestGroup::RequestGroup(const std::shared_ptr<GroupId>& gid,
       btRuntime_(nullptr),
       peerStorage_(nullptr),
 #endif // ENABLE_BITTORRENT
+      followingGID_(0),
       lastModifiedTime_(Time::null()),
       timeout_(option->getAsInt(PREF_TIMEOUT)),
       state_(STATE_WAITING),
@@ -1120,6 +1121,7 @@ std::shared_ptr<DownloadResult> RequestGroup::createDownloadResult() const
   res->result = result.first;
   res->resultMessage = result.second;
   res->followedBy = followedByGIDs_;
+  res->following = followingGID_;
   res->belongsTo = belongsToGID_;
   res->option = option_;
   res->metadataInfo = metadataInfo_;

+ 8 - 0
src/RequestGroup.h

@@ -125,6 +125,10 @@ private:
   // has the GID of generated RequestGroups. empty list means there is
   // no such RequestGroup.
   std::vector<a2_gid_t> followedByGIDs_;
+  // This is a reverse link against followedByGIDs_.  For example, a
+  // download included in followedByGIDs_ has this download's GID in
+  // followingGID_.
+  a2_gid_t followingGID_;
 
   std::vector<const PreDownloadHandler*> preDownloadHandlers_;
 
@@ -455,6 +459,10 @@ public:
 
   const std::vector<a2_gid_t>& followedBy() const { return followedByGIDs_; }
 
+  void following(a2_gid_t gid) { followingGID_ = gid; }
+
+  a2_gid_t following() const { return followingGID_; }
+
   void belongsTo(a2_gid_t gid) { belongsToGID_ = gid; }
 
   a2_gid_t belongsTo() const { return belongsToGID_; }

+ 11 - 0
src/RpcMethodImpl.cc

@@ -108,6 +108,7 @@ const char KEY_BITFIELD[] = "bitfield";
 const char KEY_PIECE_LENGTH[] = "pieceLength";
 const char KEY_NUM_PIECES[] = "numPieces";
 const char KEY_FOLLOWED_BY[] = "followedBy";
+const char KEY_FOLLOWING[] = "following";
 const char KEY_BELONGS_TO[] = "belongsTo";
 const char KEY_INFO_HASH[] = "infoHash";
 const char KEY_NUM_SEEDERS[] = "numSeeders";
@@ -664,6 +665,11 @@ void gatherProgressCommon(Dict* entryDict,
       entryDict->put(KEY_FOLLOWED_BY, std::move(list));
     }
   }
+  if (requested_key(keys, KEY_FOLLOWING)) {
+    if (group->following()) {
+      entryDict->put(KEY_FOLLOWING, GroupId::toHex(group->following()));
+    }
+  }
   if (requested_key(keys, KEY_BELONGS_TO)) {
     if (group->belongsTo()) {
       entryDict->put(KEY_BELONGS_TO, GroupId::toHex(group->belongsTo()));
@@ -824,6 +830,11 @@ void gatherStoppedDownload(Dict* entryDict,
       entryDict->put(KEY_FOLLOWED_BY, std::move(list));
     }
   }
+  if (requested_key(keys, KEY_FOLLOWING)) {
+    if (ds->following) {
+      entryDict->put(KEY_FOLLOWING, GroupId::toHex(ds->following));
+    }
+  }
   if (requested_key(keys, KEY_BELONGS_TO)) {
     if (ds->belongsTo) {
       entryDict->put(KEY_BELONGS_TO, GroupId::toHex(ds->belongsTo));

+ 3 - 1
src/UTMetadataPostDownloadHandler.cc

@@ -104,11 +104,13 @@ void UTMetadataPostDownloadHandler::getNextRequestGroups(
                                     std::vector<std::string>(), A2STR::NIL,
                                     torrent, false);
     requestGroup->followedBy(newRgs.begin(), newRgs.end());
+    for (auto& rg : newRgs) {
+      rg->following(requestGroup->getGID());
+    }
     if (requestGroup->getMetadataInfo()) {
       setMetadataInfo(newRgs.begin(), newRgs.end(),
                       requestGroup->getMetadataInfo());
     }
-
     auto rgman = requestGroup->getRequestGroupMan();
 
     if (rgman && rgman->getKeepRunning() &&

+ 2 - 0
src/aria2api.cc

@@ -727,6 +727,7 @@ struct RequestGroupDH : public DownloadHandle {
   {
     return group->followedBy();
   }
+  virtual A2Gid getFollowing() CXX11_OVERRIDE { return group->following(); }
   virtual A2Gid getBelongsTo() CXX11_OVERRIDE { return group->belongsTo(); }
   virtual const std::string& getDir() CXX11_OVERRIDE
   {
@@ -828,6 +829,7 @@ struct DownloadResultDH : public DownloadHandle {
   {
     return dr->followedBy;
   }
+  virtual A2Gid getFollowing() CXX11_OVERRIDE { return dr->following; }
   virtual A2Gid getBelongsTo() CXX11_OVERRIDE { return dr->belongsTo; }
   virtual const std::string& getDir() CXX11_OVERRIDE { return dr->dir; }
   virtual std::vector<FileData> getFiles() CXX11_OVERRIDE

+ 6 - 0
src/includes/aria2/aria2.h

@@ -807,6 +807,12 @@ public:
    * downloads, this function returns empty array.
    */
   virtual const std::vector<A2Gid>& getFollowedBy() = 0;
+  /**
+   * Returns the GID of the download which generated this download.
+   * This is a reverse link of
+   * :func:`DownloadHandle::getFollowedBy()`.
+   */
+  virtual A2Gid getFollowing() = 0;
   /**
    * Returns the GID of a parent download. Some downloads are a part
    * of another download. For example, if a file in Metalink has

+ 3 - 0
test/BtPostDownloadHandlerTest.cc

@@ -82,6 +82,9 @@ void BtPostDownloadHandlerTest::testGetNextRequestGroups()
       bittorrent::getInfoHashString(groups.front()->getDownloadContext()));
   CPPUNIT_ASSERT(std::find(rg.followedBy().begin(), rg.followedBy().end(),
                            groups.front()->getGID()) != rg.followedBy().end());
+  for (auto& nrg : groups) {
+    CPPUNIT_ASSERT_EQUAL(rg.getGID(), nrg->following());
+  }
 }
 
 } // namespace aria2

+ 4 - 0
test/MetalinkPostDownloadHandlerTest.cc

@@ -83,6 +83,10 @@ void MetalinkPostDownloadHandlerTest::testGetNextRequestGroups()
 #else
   CPPUNIT_ASSERT_EQUAL((size_t)5, groups.size());
 #endif // ENABLE_BITTORRENT
+
+  for (auto& nrg : groups) {
+    CPPUNIT_ASSERT_EQUAL(rg.getGID(), nrg->following());
+  }
 }
 
 void MetalinkPostDownloadHandlerTest::testGetNextRequestGroups_withBaseUri()

+ 7 - 0
test/RpcMethodTest.cc

@@ -924,6 +924,7 @@ void RpcMethodTest::testGatherStoppedDownload()
   d->sessionTime = 1_s;
   d->result = error_code::FINISHED;
   d->followedBy = followedBy;
+  d->following = 1;
   d->belongsTo = 2;
   auto entry = Dict::g();
   std::vector<std::string> keys;
@@ -934,6 +935,8 @@ void RpcMethodTest::testGatherStoppedDownload()
                        downcast<String>(followedByRes->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(GroupId::toHex(4),
                        downcast<String>(followedByRes->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL(GroupId::toHex(1),
+                       downcast<String>(entry->get("following"))->s());
   CPPUNIT_ASSERT_EQUAL(GroupId::toHex(2),
                        downcast<String>(entry->get("belongsTo"))->s());
 
@@ -960,6 +963,8 @@ void RpcMethodTest::testGatherProgressCommon()
   }
 
   group->followedBy(followedBy.begin(), followedBy.end());
+  auto leader = GroupId::create();
+  group->following(leader->getNumericId());
   auto parent = GroupId::create();
   group->belongsTo(parent->getNumericId());
 
@@ -972,6 +977,8 @@ void RpcMethodTest::testGatherProgressCommon()
                        downcast<String>(followedByRes->get(0))->s());
   CPPUNIT_ASSERT_EQUAL(GroupId::toHex(followedBy[1]->getGID()),
                        downcast<String>(followedByRes->get(1))->s());
+  CPPUNIT_ASSERT_EQUAL(leader->toHex(),
+                       downcast<String>(entry->get("following"))->s());
   CPPUNIT_ASSERT_EQUAL(parent->toHex(),
                        downcast<String>(entry->get("belongsTo"))->s());
   const List* files = downcast<List>(entry->get("files"));

+ 1 - 0
test/UTMetadataPostDownloadHandlerTest.cc

@@ -117,6 +117,7 @@ void UTMetadataPostDownloadHandlerTest::testGetNextRequestGroups()
                            requestGroup_->followedBy().end(),
                            newRg->getGID()) !=
                  requestGroup_->followedBy().end());
+  CPPUNIT_ASSERT_EQUAL(requestGroup_->getGID(), newRg->following());
   CPPUNIT_ASSERT(!trfile.exists());
 
   results.clear();