diff --git a/libi2pd_client/TorrentsRPC.cpp b/libi2pd_client/TorrentsRPC.cpp index 9389b162..0e5b59ab 100644 --- a/libi2pd_client/TorrentsRPC.cpp +++ b/libi2pd_client/TorrentsRPC.cpp @@ -66,6 +66,8 @@ namespace torrents std::string HandleTorrentStop (boost::json::object&& jsonRequest); std::string HandleTorrentStart (boost::json::object&& jsonRequest); std::string HandleSessionGet (boost::json::object&& jsonRequest); // for transmission-rpc library + std::string HandleSessionStats (boost::json::object&& jsonRequest); + private: std::shared_ptr m_Tunnel; @@ -74,6 +76,7 @@ namespace torrents std::string JSONRPCHandler::SuccessResponse (int64_t id, boost::json::object&& arguments) { boost::json::object response; + response["jsonrpc"] = "2.0"; response["result"] = "success"; response["arguments"] = arguments; if (id) response["id"] = id; @@ -141,6 +144,8 @@ namespace torrents return HandleTorrentStart (std::move (jsonRequest)); else if (method == "session-get") return HandleSessionGet (std::move (jsonRequest)); + else if (method == "session-stats") + return HandleSessionStats (std::move (jsonRequest)); else { LogPrint (eLogInfo, "TorrentsRPC: Method not found ", method); @@ -239,7 +244,6 @@ namespace torrents auto fields = arguments.at ("fields").as_array (); boost::json::object response; - response["jsonrpc"] = "2.0"; boost::json::array torrents; for (auto id: torrentIds) { @@ -554,6 +558,37 @@ namespace torrents return SuccessResponse (GetTag (jsonRequest), std::move (response)); } + std::string JSONRPCHandler::HandleSessionStats (boost::json::object&& jsonRequest) + { + boost::json::object response, stats; + auto torrents = m_Tunnel->GetTorrents (); + size_t downloaded = 0, uploaded = 0; + uint64_t downloadRate = 0, uploadRate = 0; + int numStoppedTorrents = 0; + for (auto it: torrents) + { + downloaded += it->GetDownloaded (); + uploaded += it->GetUploaded (); + downloadRate += it->GetDownloadRate (); + uploadRate += it->GetUploadRate (); + if (it->IsStopped ()) + numStoppedTorrents++; + } + stats["downloadedBytes"] = downloaded; + stats["uploadedBytes"] = uploaded; + stats["downloadSpeed"] = downloadRate; + stats["uploadSpeed"] = uploadRate; + stats["sessionCount"] = 1; + stats["filesAdded"] = 0; // TODO: + stats["secondsActive"] = 0; // TODO: + response["torrentCount"] = torrents.size (); + response["pausedTorrentCount"] = numStoppedTorrents; + response["activeTorrentCount"] = torrents.size () - numStoppedTorrents; + response["current-stats"] = stats; + response["cumulative-stats"] = stats; + return SuccessResponse (GetTag (jsonRequest), std::move (response)); + } + #endif TorrentsRPCSession::TorrentsRPCSession (TorrentsRPCServer& server, boost::asio::ip::tcp::socket&& s): diff --git a/libi2pd_client/TorrentsTunnel.cpp b/libi2pd_client/TorrentsTunnel.cpp index 3847fd58..86ef115c 100644 --- a/libi2pd_client/TorrentsTunnel.cpp +++ b/libi2pd_client/TorrentsTunnel.cpp @@ -317,6 +317,15 @@ namespace torrents return ids; } + std::list > TorrentsTunnel:: GetTorrents () const + { + std::list > torrents; + std::lock_guard l(m_TorrentsMutex); + for (const auto& it: m_Torrents) + torrents.push_back (it.second); + return torrents; + } + std::pair, int> TorrentsTunnel::AddTorrent (std::string_view torrentFileContent) { auto torrent = std::make_shared (torrentFileContent); diff --git a/libi2pd_client/TorrentsTunnel.h b/libi2pd_client/TorrentsTunnel.h index 1c4a942b..9a9a070f 100644 --- a/libi2pd_client/TorrentsTunnel.h +++ b/libi2pd_client/TorrentsTunnel.h @@ -98,6 +98,7 @@ namespace torrents std::shared_ptr FindTorrent (const Torrent::InfoHash& infoHash) const; std::shared_ptr FindTorrentByID (int id) const; std::vector GetTorrentIDs () const; + std::list > GetTorrents () const; std::pair, int> AddTorrent (std::string_view torrentFileContent); // retrun (torrent, id) std::pair, int> AddMagnet (std::string_view magnet); // return (torrent, id) void UpdateTorrentInfo (std::shared_ptr torrent, std::string_view info); // magnet