|
|
|
|
#ifndef _TR_TORRENTS_HPP_
|
|
|
|
|
#define _TR_TORRENTS_HPP_
|
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
|
#include <http.hpp>
|
|
|
|
|
#include <libtorrent/magnet_uri.hpp>
|
|
|
|
|
#include <torrent.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();
|
|
|
|
|
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 response_object = nlohmann::json::object();
|
|
|
|
|
|
|
|
|
|
auto torrents = session.get_torrents();
|
|
|
|
|
auto torrents_json = nlohmann::json::array();
|
|
|
|
|
for (auto &torrent : torrents) {
|
|
|
|
|
if (torrent.is_valid()) {
|
|
|
|
|
torrents_json.push_back(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 <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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto handle = session.find_torrent(util::sha1::info_hash(obj));
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
session.async_add_torrent(params);
|
|
|
|
|
|
|
|
|
|
http_response.add_header({"Location", "/session/torrents/" + util::sha1::string(params.info_hash)});
|
|
|
|
|
return respond(http::created);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|