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.
 
 
 
 

194 lines
5.7 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);
}
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);
} 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