From 2f8ff5fc79e394b95bafdb5931f2cdddb8a7ae1c Mon Sep 17 00:00:00 2001 From: Niklas Halle Date: Wed, 26 Aug 2020 11:20:44 +0200 Subject: Extended extra field of annotations to be an list of text-annotation pairs as well Fixed CMake Boost findings --- CMakeLists.txt | 3 +-- README.md | 5 +++-- include/Handler.hpp | 11 ++++++++++- include/Response.hpp | 8 +++++++- src/Response.cpp | 9 ++++++++- src/SimpleHandlers.cpp | 5 ++++- src/main.cpp | 23 +++++++++++++++-------- 7 files changed, 48 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b68be2f..12319e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,7 @@ IF (CMAKE_VERSION VERSION_LESS "3.7.0") set(CMAKE_INCLUDE_CURRENT_DIR ON) ENDIF () -find_package(Boost REQUIRED COMPONENTS system) -find_package(Boost REQUIRED COMPONENTS date_time) +find_package(Boost REQUIRED COMPONENTS system date_time) add_executable(${PROJECT_NAME} # Headers diff --git a/README.md b/README.md index 3f8e291..13cdd32 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ The `annotation` object: | Field | Type | Required? | Description | |-------|------|-----------|-------------| | `type` | string | yes | A part of the answer | -| `extra` | string | no | Extra content specific to the annotation type | +| `extra` | array of `reply`-objects | no | Extra content specific to the annotation type | The currently specified annotation types are enumerated below: @@ -60,7 +60,8 @@ The text should be printed as strikethrough. No extra content. The text should be printed as underline. No extra content. ##### `command` -The text should be printed as a command, meaning how did bridge will recognize it (e.g. prefix with '/'). No extra content. +The text should be printed as a command how did bridge will recognize it (e.g. prefix with '/'). +Extra content: the description of the command. ##### `link` The text should be formatted as a link. Extra content: the alt text for the uri - the uri should be the text itself, so that clients ignoring this annotation still show the real uri. \ No newline at end of file diff --git a/include/Handler.hpp b/include/Handler.hpp index 3d4b830..3aed302 100644 --- a/include/Handler.hpp +++ b/include/Handler.hpp @@ -1,5 +1,9 @@ #pragma once +#include +#include +#include + #include "crow.h" namespace Handler { @@ -8,12 +12,17 @@ namespace Handler { void *payload)> handler_function; struct CommandHandler { + ~CommandHandler() { + delete description; + } + [[nodiscard]] json exec(std::string const &arguments, std::string const &session) const { return func(arguments, session, payload); } handler_function func{nullptr}; - std::string description; + // handler takes ownership of the description, using it after passing is unsafe + std::queue *description{nullptr}; void *payload{nullptr}; }; diff --git a/include/Response.hpp b/include/Response.hpp index 53043c8..82edb53 100644 --- a/include/Response.hpp +++ b/include/Response.hpp @@ -8,13 +8,19 @@ namespace Response { using Reply::AnnotationType; typedef crow::json::wvalue json; + // create a full response of just plain text json simple_response(std::string const &text, std::string const &session = "null", bool success = true); + // "nested" annotations: the extra field is again an array of text-annotation pairs + json create_annotation(AnnotationType annotation, std::vector &&extra); + // construct an extra field with no special annotations in the extra json create_annotation(AnnotationType annotation = AnnotationType::none, std::string const &extra = ""); + // text with no special annotation json create_text(std::string const &text); - + // text with annotations json create_text(std::string const &text, std::vector &&annotations); + // create a response from multiple texts json create_response(std::vector &&reply, std::string const &session = "null", bool success = true); } \ No newline at end of file diff --git a/src/Response.cpp b/src/Response.cpp index 050a537..d7006c9 100644 --- a/src/Response.cpp +++ b/src/Response.cpp @@ -10,7 +10,14 @@ Response::json Response::simple_response(std::string const &text, std::string co Response::json Response::create_annotation(Reply::AnnotationType annotationType, std::string const &extra) { json annotation(crow::json::type::Object); annotation["type"] = Reply::GetStringAnnotationType(annotationType); - annotation["extra"] = extra; + annotation["extra"] = create_text(extra); + return annotation; +} + +Response::json Response::create_annotation(Reply::AnnotationType annotationType, std::vector &&extra) { + json annotation(crow::json::type::Object); + annotation["type"] = Reply::GetStringAnnotationType(annotationType); + annotation["extra"] = std::move(extra); return annotation; } diff --git a/src/SimpleHandlers.cpp b/src/SimpleHandlers.cpp index 033da53..c9d0fcf 100644 --- a/src/SimpleHandlers.cpp +++ b/src/SimpleHandlers.cpp @@ -40,7 +40,10 @@ Handler::json Handler::helpHandler(std::string const &arguments, std::string con reply_vec.emplace_back(create_text("- ")); reply_vec.emplace_back(create_text(itor.first, std::move(commandAnnotations))); - reply_vec.emplace_back(create_text(" " + itor.second.description + "\n")); + while (!itor.second.description->empty()) { + reply_vec.emplace_back(std::move(itor.second.description->back())); + itor.second.description->pop(); + } } reply_vec.emplace_back(create_text( diff --git a/src/main.cpp b/src/main.cpp index 72fd9a0..59fd6a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,10 @@ +#include +#include +#include #include -#include #include #include "crow.h" -#include "sqdb.hpp" #include "Handler.hpp" #include "Response.hpp" @@ -18,17 +19,23 @@ int main() { crow::SimpleApp app; + auto createPlainDescriptionFromText = [] (std::string const &text) -> std::queue* { + auto reply_queue = new std::queue; + reply_queue->emplace(Response::create_text(text)); + return reply_queue; + }; + // command --> handler std::unordered_map commands{ - {"wiki", {.func = Handler::wikiHandler, .description = "Send you to wikipedia"}}, - {"stop", {.func = Handler::stopHandler, .description = "Stops the bot", .payload = &app}}, - {"mensa", {.func = Handler::mensaHandler, .description = "{adlershof, nord, sued} Shows the daily menu of the mensa at various places."}}, - {"klinger", {.func = Handler::klingerHandler, .description = "Greats in french. Bonjour!"}}, - {"relation", {.func = Handler::relationShipHandler, .description = "[name1] [name2] Shows the result of an odd astrological religious pseudo-algorithm, based on the fact how much blessing a relationship receives by the glorious N."}}, + {"wiki", {.func = Handler::wikiHandler, .description = createPlainDescriptionFromText("Sends you to Wikipedia!")}}, + {"stop", {.func = Handler::stopHandler, .description = createPlainDescriptionFromText("Stops the bot"), .payload = &app}}, + {"mensa", {.func = Handler::mensaHandler, .description = createPlainDescriptionFromText("{adlershof, nord, sued} Shows the daily menu of the mensa at various places.")}}, + {"klinger", {.func = Handler::klingerHandler, .description = createPlainDescriptionFromText("Greats in french. Bonjour!")}}, + {"relation", {.func = Handler::relationShipHandler, .description = createPlainDescriptionFromText("[name1] [name2] Shows the result of an odd astrological religious pseudo-algorithm, based on the fact how much blessing a relationship receives by the glorious N.")}}, }; commands.insert({"help", - {.func = Handler::helpHandler, .description = "This is my holy manual.", .payload = &commands}}); + {.func = Handler::helpHandler, .description = createPlainDescriptionFromText("This is my holy manual."), .payload = &commands}}); CROW_ROUTE(app, "/") .methods("POST"_method) -- cgit v1.2.3-54-g00ecf