#ifndef _TR_TORRENT_HPP_ #define _TR_TORRENT_HPP_ #include #include #include #include namespace tr { namespace torrent { template static nlohmann::json to_json(torrent_t torrent) { const auto status = torrent.status( torrent.query_name | torrent.query_save_path); return {{"info_hash", util::sha1::string(torrent.info_hash())}, {"paused", status.paused}, {"seeding", status.is_seeding}, {"state", status.state}, {"priority", status.priority}, {"up_limit", torrent.upload_limit()}, {"down_limit", torrent.download_limit()}, {"name", status.name}}; } } namespace session { namespace torrents { namespace id { template void get(torrent_session &session, response resp, request req) { auto http_response = http::response(); const auto respond = [&](http::status status) { const auto response_code = http::code(status); http_response.set_body({{"code", response_code.first}, {"status", response_code.second}}); http_response.set_status(response_code.first); *resp << http_response; }; if (!session.is_valid()) { return respond(http::service_unavailable); } const auto hash = req->path.substr(18, req->path.size() - 18); //TODO hacky const auto torrent = session.find_torrent(util::sha1::info_hash(hash)); if (!torrent.is_valid()) { return respond(http::bad_request); } http_response.set_body(torrent::to_json(torrent)); http_response.set_status(http::ok); *resp << http_response; } template void patch(torrent_session &session, response resp, request req) { auto http_response = http::response(); const auto respond = [&](http::status status) { const auto response_code = http::code(status); http_response.set_body({{"code", response_code.first}, {"status", response_code.second}}); http_response.set_status(response_code.first); *resp << http_response; }; if (!session.is_valid()) { return respond(http::service_unavailable); } const auto hash = req->path.substr(18, req->path.size() - 18); #ifndef _TR_TESTING_ auto torrent = session.find_torrent(util::sha1::info_hash(hash)); #else auto &torrent = session.find_torrent(util::sha1::info_hash(hash)); #endif if (!torrent.is_valid()) { return respond(http::bad_request); } auto request_object = util::json::parse(req->content); if (request_object.is_null()) { return respond(http::bad_request); } if (!request_object.is_object()) { return respond(http::bad_request); } if (request_object.find("paused") != request_object.end()) { bool paused = false; const auto obj = request_object.at("paused"); if (obj.is_boolean()) paused = request_object.at("paused"); else if (obj.is_string()) { std::string p = obj; paused = (p == "true"); } if (torrent.status().paused != paused) { if (paused) torrent.pause(); else { torrent.resume(); } } } respond(http::accepted); } } } } } #endif