#ifndef _TR_TORRENTS_HPP_ #define _TR_TORRENTS_HPP_ #include #include #include #include #include namespace tr { namespace session { namespace torrents { 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); } auto torrents = session.get_torrents(); auto response_object = nlohmann::json::object(); auto torrents_json = nlohmann::json::array(); for (auto &torrent : torrents) { if (torrent.is_valid()) { torrents_json.push_back(tr::torrent::to_json(torrent)); } } response_object["torrents"] = torrents_json; http_response.set_status(http::ok); http_response.set_body(response_object); *resp << http_response; } template void del(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); } 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("info_hash") == request_object.end()) { return respond(http::bad_request); } auto obj = request_object.at("info_hash"); if (!obj.is_string()) { return respond(http::bad_request); } int options = 0; if (request_object.find("remove_files") != request_object.end()) { bool remove_files = false; auto obj = request_object.at("remove_files"); if (obj.is_boolean()) remove_files = request_object.at("remove_files"); else if (obj.is_string()) { std::string p = obj; remove_files = p == "true"; } options = remove_files; } const auto handle = session.find_torrent(util::sha1::string(obj)); if (handle.is_valid()) { session.remove_torrent(handle, options); } else { return respond(http::bad_request); } respond(http::no_content); } template void post(settings opts, 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); } 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); } auto magnet_uri_itr = request_object.find("magnet_uri"); auto url_itr = request_object.end(); if (magnet_uri_itr == request_object.end() && url_itr == request_object.end()) { return respond(http::bad_request); } if (magnet_uri_itr != request_object.end() && url_itr != request_object.end()) { return respond(http::bad_request); } libtorrent::add_torrent_params params; if (magnet_uri_itr != request_object.end()) { std::string uri = request_object.at("magnet_uri"); boost::system::error_code ec; libtorrent::parse_magnet_uri(uri, params, ec); if (ec) { return respond(http::bad_request); } } if (request_object.find("save_path") != request_object.end()) { boost::filesystem::path save_path = request_object.at("save_path"); if (save_path.is_relative()) params.save_path = (opts.root_dir / save_path).string(); else return respond(http::bad_request); } else params.save_path = boost::filesystem::path(opts.root_dir / opts.default_download_dir).string(); params.flags &= ~libtorrent::add_torrent_params::flag_paused; if (request_object.find("paused") != request_object.end()) { bool paused = false; 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 (paused) params.flags |= libtorrent::add_torrent_params::flag_paused; } if (request_object.find("up_speed") != request_object.end()) { int up_limit = 0; auto obj = request_object.at("up_speed"); if (obj.is_string()) { std::string i = obj; up_limit = std::stoi(i); } else if (obj.is_number()) { up_limit = obj; } params.upload_limit = up_limit; } if (request_object.find("down_speed") != request_object.end()) { int down_limit = 0; auto obj = request_object.at("down_speed"); if (obj.is_string()) { std::string i = obj; down_limit = std::stoi(i); } else if (obj.is_number()) { down_limit = obj; } params.download_limit = down_limit; } if (request_object.find("name") != request_object.end()) { auto obj = request_object.at("name"); if (obj.is_string()) params.name = obj; } std::stringstream ss; ss << params.info_hash; session.async_add_torrent(params); http_response.add_header({"Location", "/session/torrents/" + ss.str()}); return respond(http::created); } } } } #endif