273 lines
8.6 KiB
C++
273 lines
8.6 KiB
C++
#include "RestQueryHandler.h"
|
|
|
|
using namespace Rest;
|
|
using namespace Logging;
|
|
using namespace Downloader;
|
|
using namespace JasonPP;
|
|
|
|
void RestQueryHandler::PreInit()
|
|
{
|
|
log = new Logger("RestQueryHandler");
|
|
|
|
return;
|
|
}
|
|
|
|
bool RestQueryHandler::ProcessQuery(const std::string clientAdress, const Json& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
log->SetAdditionalInformation(std::string("@") + clientAdress);
|
|
|
|
if (!ValidateField("request", JDType::STRING, request, responseBody))
|
|
{
|
|
responseCode = BAD_REQUEST;
|
|
return false;
|
|
}
|
|
JsonBlock requestBody = request.AsJson;
|
|
std::string requestName = requestBody.Get("request").AsString;
|
|
|
|
|
|
|
|
if (requestName == "kill_yourself") return KillYourself(requestBody, responseBody, responseCode);
|
|
else if (requestName == "queue_download") return QueueDownload(requestBody, responseBody, responseCode);
|
|
else if (requestName == "fetch_queue") return FetchQueue(requestBody, responseBody, responseCode);
|
|
else if (requestName == "clear_download_cache") return ClearDownloadCache(requestBody, responseBody, responseCode);
|
|
else if (requestName == "foo") return Example_Foo(requestBody, responseBody, responseCode);
|
|
else if (requestName == "show_console") return ShowConsole(requestBody, responseBody, responseCode);
|
|
else if (requestName == "hide_console") return HideConsole(requestBody, responseBody, responseCode);
|
|
else if (requestName == "get_os_name") return GetOSName(requestBody, responseBody, responseCode);
|
|
else if (requestName == "fetch_logs") return FetchLogs(requestBody, responseBody, responseCode);
|
|
|
|
|
|
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(NOT_FOUND, "The requested request was not found."));
|
|
responseCode = NOT_FOUND;
|
|
return false;
|
|
}
|
|
|
|
void RestQueryHandler::PostExit()
|
|
{
|
|
delete log;
|
|
log = nullptr;
|
|
|
|
return;
|
|
}
|
|
|
|
bool RestQueryHandler::Example_Foo(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("message") = "Bar!";
|
|
std::cout << "Bar!" << std::endl;
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::QueueDownload(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
if ((!ValidateField("video_url", JDType::STRING, request, responseBody)) ||
|
|
(!ValidateField("mode", JDType::STRING, request, responseBody)))
|
|
{
|
|
responseCode = BAD_REQUEST;
|
|
return false;
|
|
}
|
|
|
|
std::string modeParam = request.Get("mode").AsString;
|
|
std::string videoUrl = request.Get("video_url").AsString;
|
|
DOWNLOAD_MODE mode;
|
|
if (modeParam == "video") mode = DOWNLOAD_MODE::VIDEO;
|
|
else if (modeParam == "audio") mode = DOWNLOAD_MODE::AUDIO;
|
|
else
|
|
{
|
|
responseCode = BAD_REQUEST;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(BAD_REQUEST, "Parameter 'mode' is of wrong value. Should be either 'video' or 'audio'."));
|
|
return false;
|
|
}
|
|
|
|
log->cout << "Queued video \"" << videoUrl << "\"...";
|
|
log->Flush();
|
|
|
|
std::string tubId = DownloadManager::QueueDownload(videoUrl, mode);
|
|
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("message") = "Download queued!";
|
|
responseBody.Set("queue_position") = (long long int)DownloadManager::GetQueueLength();
|
|
responseBody.Set("tubio_id") = tubId;
|
|
responseBody.Set("queue") = DownloadManager::GetQueueAsJson();
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::FetchQueue(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
log->cout << "Asking for queue...";
|
|
log->Flush();
|
|
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("queue") = DownloadManager::GetQueueAsJson();
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::ClearDownloadCache(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
log->cout << "Clearing download cache...";
|
|
log->Flush();
|
|
|
|
bool wait = !DownloadManager::ClearDownloadCache();
|
|
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
|
|
if (wait)
|
|
{
|
|
responseBody.Set("status") = "OK_WAIT";
|
|
responseBody.Set("message") = "Download cache cannot be cleared right now because there are active downloads, but will be cleared as soon as those have finished!";
|
|
}
|
|
else
|
|
{
|
|
responseBody.Set("message") = "Download cache has been cleared!";
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::KillYourself(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
XGControl::keepServerRunning = false;
|
|
|
|
log->cout << "Shutting down server upon client request...";
|
|
log->Flush();
|
|
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("message") = "Goodbye! :3";
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::HideConsole(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
if (ConsoleManager::IsSupported())
|
|
{
|
|
log->cout << "Hiding console...";
|
|
log->Flush();
|
|
|
|
bool didAnythingChange = ConsoleManager::HideConsole();
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("message") = (didAnythingChange) ? "Console is now hidden!" : "Console was already hidden!";
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
responseCode = NOT_IMPLEMENTED;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(NOT_IMPLEMENTED));
|
|
responseBody.Set("message") = "This feature is currently only supported on Windows! Make sure to compile with preprocessor directive _WIN!";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool RestQueryHandler::ShowConsole(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
if (ConsoleManager::IsSupported())
|
|
{
|
|
log->cout << "Showing console...";
|
|
log->Flush();
|
|
|
|
bool didAnythingChange = ConsoleManager::ShowConsole();
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("message") = (didAnythingChange) ? "Console is now shown!" : "Console was already shown!";
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
responseCode = NOT_IMPLEMENTED;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(NOT_IMPLEMENTED));
|
|
responseBody.Set("message") = "This feature is currently only supported on Windows! Make sure to compile with preprocessor directive _WIN!";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool RestQueryHandler::GetOSName(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
log->cout << "Asking for server OS name...";
|
|
log->Flush();
|
|
|
|
std::string osName = "other";
|
|
#ifdef _WIN
|
|
osName = "Windows";
|
|
#elif __APPLE__ || __MACH__
|
|
osName = "Mac OSX";
|
|
#elif __linux__
|
|
osName = "Linux";
|
|
#elif __FreeBSD__
|
|
osName = "FreeBSD";
|
|
#elif __unix || __unix__
|
|
osName = "Unix";
|
|
#endif
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("os_name") = osName;
|
|
return true;
|
|
}
|
|
|
|
bool RestQueryHandler::FetchLogs(const JsonBlock& request, JsonBlock& responseBody, HTTP_STATUS_CODE& responseCode)
|
|
{
|
|
log->cout << "Fetching logs...";
|
|
log->Flush();
|
|
|
|
responseCode = OK;
|
|
responseBody.CloneFrom(RestResponseTemplates::GetByCode(OK));
|
|
responseBody.Set("logs") = LogHistory::GetCompleteLogHistoryAsJson();
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool RestQueryHandler::ValidateField(const std::string name, const JasonPP::JDType type, const JasonPP::Json& checkThat, JasonPP::JsonBlock& putErrorResponseHere)
|
|
{
|
|
if (checkThat.GetDataType() != JDType::JSON)
|
|
{
|
|
putErrorResponseHere = RestResponseTemplates::GetByCode(BAD_REQUEST, "The request body must be a json struct! No json array or similar...");
|
|
return false;
|
|
}
|
|
|
|
const JsonBlock& cachedJson = checkThat.AsJson;
|
|
|
|
if (cachedJson.DoesShorthandExist(name))
|
|
{
|
|
const JsonData& cached = cachedJson.ShorthandGet(name);
|
|
|
|
if ((cached.GetDataType() == type) ||
|
|
((cached.IsOfNumericType()) && (type == JDType::INT)) ||
|
|
((cached.IsOfNumericType()) && (type == JDType::FLOAT)))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
std::stringstream ss;
|
|
ss << "Mandatory value \"" << name << "\" is of wrong type (" << JsonDataType2String(cached.GetDataType()) << ")" << std::endl;
|
|
ss << "Should be of type " << JsonDataType2String(type) << "! (Integers can be casted to floats)";
|
|
|
|
putErrorResponseHere.CloneFrom(RestResponseTemplates::GetByCode(BAD_REQUEST, ss.str()));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
putErrorResponseHere.CloneFrom(RestResponseTemplates::GetByCode(BAD_REQUEST, std::string("Missing mandatory value '" + name + "'")));
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Logger* RestQueryHandler::log;
|