You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.1 KiB
208 lines
6.1 KiB
#ifndef _TR_TORRENTS_HPP_ |
|
#define _TR_TORRENTS_HPP_ |
|
#include <boost/filesystem.hpp> |
|
#include <http.hpp> |
|
#include <libtorrent/magnet_uri.hpp> |
|
#include <util.hpp> |
|
|
|
namespace tr { |
|
namespace session { |
|
namespace torrents { |
|
template <class torrent_session, class request, class response> |
|
void get(torrent_session &session, response resp, request req) { |
|
auto http_response = http::response(); |
|
if (session.is_valid()) { |
|
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()) { |
|
const auto hash = torrent.info_hash().to_string(); |
|
const auto status = torrent.status( |
|
torrent.query_name | |
|
torrent.query_save_path); |
|
torrents_json.push_back({{"hash", hash}, |
|
{"paused", status.paused}, |
|
{"seeding", status.is_seeding}, |
|
{"state", status.state}, |
|
{"priority", status.priority}, |
|
{"name", status.name}}); |
|
} |
|
} |
|
response_object["torrents"] = torrents_json; |
|
http_response.set_status(http::ok); |
|
http_response.set_body(response_object); |
|
} else { |
|
auto response_code = http::code(http::service_unavailable); |
|
http_response.set_body({{"code", response_code.first}, {"status", response_code.second}}); |
|
http_response.set_status(response_code.first); |
|
} |
|
*resp << http_response; |
|
} |
|
|
|
template <class torrent_session, class request, class response> |
|
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; |
|
} |
|
|
|
std::string sha1_hash_in = obj; |
|
libtorrent::sha1_hash sha1_hash; |
|
std::stringstream ss; |
|
ss << sha1_hash_in; |
|
ss >> sha1_hash; |
|
auto handle = session.find_torrent(sha1_hash); |
|
|
|
if (handle.is_valid()) { |
|
session.remove_torrent(handle, options); |
|
} else { |
|
return respond(http::bad_request); |
|
} |
|
|
|
respond(http::no_content); |
|
} |
|
|
|
template <class settings, class torrent_session, class request, class response> |
|
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); |
|
} |
|
|
|
if (request_object.find("magnet_uri") == request_object.end()) { |
|
return respond(http::bad_request); |
|
} |
|
|
|
std::string uri = request_object.at("magnet_uri"); |
|
boost::system::error_code ec; |
|
libtorrent::add_torrent_params params; |
|
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
|
|
|