diff --git a/.gitmodules b/.gitmodules index 21ed188..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "dependencies/served"] - path = dependencies/served - url = https://github.com/meltwater/served.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e0000d..73a386e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,12 +37,8 @@ include_directories(${Boost_INCLUDE_DIR}) include_directories(${CUPS_INCLUDE_DIR}) include_directories(${Protobuf_INCLUDE_DIRS}) include_directories(${Protobuf_INCLUDE_DIR}) -include_directories(dependencies/served/src) - -OPTION (SERVED_BUILD_TESTS "Build served unit test suite" OFF) -OPTION (SERVED_BUILD_EXAMPLES "Build served examples" OFF) -add_subdirectory(dependencies/served) +add_subdirectory(dependencies/crow) add_subdirectory(dependencies/spdlog) if(USE_SPI) @@ -85,7 +81,7 @@ target_link_libraries(self_o_mat.app ${Boost_LIBRARIES} sfml-window ${OpenCV_LIBS} ${CUPS_LIBRARIES} - served + Crow protobuf spdlog::spdlog ) diff --git a/dependencies/crow/CMakeLists.txt b/dependencies/crow/CMakeLists.txt new file mode 100644 index 0000000..96ceb39 --- /dev/null +++ b/dependencies/crow/CMakeLists.txt @@ -0,0 +1,7 @@ +include(FetchContent) +FetchContent_Declare( + Crow + GIT_REPOSITORY https://github.com/CrowCpp/Crow + GIT_TAG v1.2.0 +) +FetchContent_MakeAvailable(Crow) diff --git a/dependencies/served b/dependencies/served deleted file mode 160000 index 8ef95d7..0000000 --- a/dependencies/served +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8ef95d72692ef1f392fc0a44a6dad4235386ac9d diff --git a/src/api/BoothApi.cpp b/src/api/BoothApi.cpp index 871da3e..4d1235c 100644 --- a/src/api/BoothApi.cpp +++ b/src/api/BoothApi.cpp @@ -11,942 +11,835 @@ using namespace selfomat::logic; std::string BoothApi::TAG = "API"; BoothApi::BoothApi(selfomat::logic::BoothLogic *logic, ICamera *camera, bool show_led_setup) : logic(logic), - camera(camera), - server("0.0.0.0", "9080", - mux, false) { + camera(camera) { this->show_led_setup = show_led_setup; } bool BoothApi::start() { - // Use wrapper to set needed headers - mux.use_wrapper([this](served::response &res, const served::request &req, std::function old) { - for (auto const &h : this->headers) - res.set_header(h.first, h.second); - - if (req.method() == served::OPTIONS) { - served::response::stock_reply(200, res); - } else { - old(); - } + // Register some URLs where the app should be reachable + // there's surely a better way to do this. + CROW_ROUTE(app, "/")([]() { + auto response = crow::response(); + response.set_static_file_info("app/index.html"); + return response; }); + CROW_ROUTE(app, "/app")([]() { + auto response = crow::response(); + response.set_static_file_info("app/index.html"); + return response; + }); + CROW_ROUTE(app, "/tabs/")([](const std::string &path) { + (void)path; + auto response = crow::response(); + response.redirect("/"); + return response; + }); - mux.handle("/camera_settings/aperture") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } - - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - camera->setAperture(update.value()); - - served::response::stock_reply(200, res); - }); - - mux.handle("/camera_settings/iso") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } - - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - camera->setIso(update.value()); - - served::response::stock_reply(200, res); - }); - - mux.handle("/camera_settings/shutter_speed") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } - - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - camera->setShutterSpeed(update.value()); - - served::response::stock_reply(200, res); - }); - - mux.handle("/camera_settings/exposure_correction") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } - - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - camera->setExposureCorrection(update.value()); - - served::response::stock_reply(200, res); - }); - - mux.handle("/camera_settings/exposure_correction_trigger") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } - - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - camera->setExposureCorrectionTrigger(update.value()); - - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/camera_settings/aperture").methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } - mux.handle("/camera_settings/image_format") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + camera->setAperture(update.value()); - camera->setImageFormat(update.value()); - - served::response::stock_reply(200, res); - }); - - mux.handle("/camera_settings") - .get([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } + return crow::response(200); + }); - boost::property_tree::ptree locale; - try { - boost::property_tree::read_json("./i18n/" + req.header("lang") + ".json", locale); - } catch (boost::exception &e) { - boost::property_tree::read_json("./i18n/en.json", locale); - } - CameraSettings currentCameraSettings; - { - auto setting = currentCameraSettings.mutable_aperture(); - setting->set_update_url("/camera_settings/aperture"); - setting->set_name(locale.get("api.camera.aperture")); - - setting->set_currentindex(camera->getAperture()); - auto *choices = camera->getApertureChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + CROW_ROUTE(app, "/camera_settings").methods(crow::HTTPMethod::Get)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } + + boost::property_tree::ptree locale; + try { + boost::property_tree::read_json("./i18n/" + req.get_header_value("lang") + ".json", locale); + } catch (boost::exception &e) { + boost::property_tree::read_json("./i18n/en.json", locale); + } + + CameraSettings currentCameraSettings; { + auto setting = currentCameraSettings.mutable_aperture(); + setting->set_update_url("/camera_settings/aperture"); + setting->set_name(locale.get("api.camera.aperture")); + + setting->set_currentindex(camera->getAperture()); + auto *choices = camera->getApertureChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } - - { - auto setting = currentCameraSettings.mutable_iso(); - setting->set_name("ISO"); - setting->set_update_url("/camera_settings/iso"); - setting->set_currentindex(camera->getIso()); - auto *choices = camera->getIsoChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + } { + auto setting = currentCameraSettings.mutable_iso(); + setting->set_name("ISO"); + setting->set_update_url("/camera_settings/iso"); + setting->set_currentindex(camera->getIso()); + auto *choices = camera->getIsoChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } - - { - auto setting = currentCameraSettings.mutable_shutter_speed(); - setting->set_name(locale.get("api.camera.shutterSpeed")); - setting->set_update_url("/camera_settings/shutter_speed"); - setting->set_currentindex(camera->getShutterSpeed()); - auto *choices = camera->getShutterSpeedChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + } { + auto setting = currentCameraSettings.mutable_shutter_speed(); + setting->set_name(locale.get("api.camera.shutterSpeed")); + setting->set_update_url("/camera_settings/shutter_speed"); + setting->set_currentindex(camera->getShutterSpeed()); + auto *choices = camera->getShutterSpeedChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } - - { - auto setting = currentCameraSettings.mutable_exposure_compensation(); - setting->set_name(locale.get("api.camera.liveBrightness")); - setting->set_update_url("/camera_settings/exposure_correction"); - setting->set_currentindex(camera->getExposureCorrection()); - auto *choices = camera->getExposureCorrectionModeChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + } { + auto setting = currentCameraSettings.mutable_exposure_compensation(); + setting->set_name(locale.get("api.camera.liveBrightness")); + setting->set_update_url("/camera_settings/exposure_correction"); + setting->set_currentindex(camera->getExposureCorrection()); + auto *choices = camera->getExposureCorrectionModeChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } - - { - auto setting = currentCameraSettings.mutable_exposure_compensation_trigger(); - setting->set_name(locale.get("api.camera.captureBrightness")); - setting->set_update_url("/camera_settings/exposure_correction_trigger"); - setting->set_currentindex(camera->getExposureCorrectionTrigger()); - auto *choices = camera->getExposureCorrectionModeChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + } { + auto setting = currentCameraSettings.mutable_exposure_compensation_trigger(); + setting->set_name(locale.get("api.camera.captureBrightness")); + setting->set_update_url("/camera_settings/exposure_correction_trigger"); + setting->set_currentindex(camera->getExposureCorrectionTrigger()); + auto *choices = camera->getExposureCorrectionModeChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } - - { - auto setting = currentCameraSettings.mutable_image_format(); - setting->set_name(locale.get("api.camera.imageFormat")); - setting->set_update_url("/camera_settings/image_format"); - setting->set_currentindex(camera->getImageFormat()); - auto *choices = camera->getImageFormatChoices(); - if (choices != nullptr) { - for (int i = 0; i < choices->size(); i++) { - setting->add_values(choices->at(i)); - } + } { + auto setting = currentCameraSettings.mutable_image_format(); + setting->set_name(locale.get("api.camera.imageFormat")); + setting->set_update_url("/camera_settings/image_format"); + setting->set_currentindex(camera->getImageFormat()); + auto *choices = camera->getImageFormatChoices(); + if (choices != nullptr) { + for (int i = 0; i < choices->size(); i++) { + setting->add_values(choices->at(i)); } } + } { + auto setting = currentCameraSettings.mutable_focus(); + setting->set_name(locale.get("api.camera.autoFocus")); + setting->set_post_url("/focus"); + } - { - auto setting = currentCameraSettings.mutable_focus(); - setting->set_name(locale.get("api.camera.autoFocus")); - setting->set_post_url("/focus"); - } - - auto lensNameSetting = currentCameraSettings.mutable_lens_name(); - lensNameSetting->set_name(locale.get("api.camera.lensName")); - lensNameSetting->set_value(camera->getLensName()); - auto cameraNameSetting = currentCameraSettings.mutable_camera_name(); - cameraNameSetting->set_name(locale.get("api.camera.cameraName")); - cameraNameSetting->set_value(camera->getCameraName()); - - - res << currentCameraSettings.SerializeAsString(); - }); - - mux.handle("/booth_settings/storage/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - logic->setStorageEnabled(update.value(), true); - - LOG_I(TAG, "updated storage enabled to: ", std::to_string(update.value())); - - served::response::stock_reply(200, res); - }); - - mux.handle("/booth_settings/autofocus_before_trigger/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - logic->setAutofocusBeforeTrigger(update.value(), true); - - LOG_I(TAG, "updated autofocus before trigger enabled to: ", std::to_string(update.value())); - - served::response::stock_reply(200, res); - }); - - - - mux.handle("/booth_settings/flash/ittl/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - logic->getSelfomatController()->setFlashMode(update.value()); - logic->getSelfomatController()->commit(); - - LOG_I(TAG, "updated flash mode to: ", std::to_string(update.value())); - - served::response::stock_reply(200, res); - }); - - mux.handle("/booth_settings/printer/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - logic->setPrinterEnabled(update.value(), true); - - LOG_I(TAG, "updated printer enabled to: ", std::to_string(update.value())); - - served::response::stock_reply(200, res); - }); - - mux.handle("/booth_settings/print_confirmation/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - - logic->setPrintConfirmationEnabled(update.value(), true); - - LOG_I(TAG, "updated print confirmation enabled to: ", std::to_string(update.value())); - - served::response::stock_reply(200, res); - }); - - mux.handle("/booth_settings/flash/enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + auto lensNameSetting = currentCameraSettings.mutable_lens_name(); + lensNameSetting->set_name(locale.get("api.camera.lensName")); + lensNameSetting->set_value(camera->getLensName()); + auto cameraNameSetting = currentCameraSettings.mutable_camera_name(); + cameraNameSetting->set_name(locale.get("api.camera.cameraName")); + cameraNameSetting->set_value(camera->getCameraName()); - logic->setFlashEnabled(update.value(), true); - - served::response::stock_reply(200, res); - }); + return crow::response(currentCameraSettings.SerializeAsString()); + }); - mux.handle("/booth_settings/flash/duration") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; + CROW_ROUTE(app, "/booth_settings").methods(crow::HTTPMethod::Get)( + [this](const crow::request &req) { + BoothSettings currentBoothSettings; + + boost::property_tree::ptree locale; + try { + boost::property_tree::read_json("./i18n/" + req.get_header_value("lang") + ".json", locale); + } catch (boost::exception &e) { + boost::property_tree::read_json("./i18n/en.json", locale); + } + + + auto controller = logic->getSelfomatController(); { + auto setting = currentBoothSettings.mutable_language_choice(); + setting->set_name(locale.get("api.booth.languageChoice")); + setting->set_update_url("/booth_settings/language/which"); + setting->set_currentindex(logic->getLanguageChoice()); + for (auto &choice: *logic->getLanguageChoices()) + setting->add_values(choice); + } { + auto setting = currentBoothSettings.mutable_storage_enabled(); + setting->set_name(locale.get("api.booth.storageEnabled")); + setting->set_update_url("/booth_settings/storage/enabled"); + setting->set_currentvalue(logic->getStorageEnabled()); + } { + auto setting = currentBoothSettings.mutable_printer_enabled(); + setting->set_name(locale.get("api.booth.printerEnabled")); + setting->set_update_url("/booth_settings/printer/enabled"); + setting->set_currentvalue(logic->getPrinterEnabled()); + } { + auto setting = currentBoothSettings.mutable_print_confirmation_enabled(); + setting->set_name(locale.get("api.booth.printConfirmationEnabled")); + setting->set_update_url("/booth_settings/print_confirmation/enabled"); + setting->set_currentvalue(logic->getPrintConfirmationEnabled()); + } { + auto setting = currentBoothSettings.mutable_filter_choice(); + setting->set_name(locale.get("api.booth.filterEnabled")); + setting->set_update_url("/booth_settings/filter/which"); + setting->set_currentindex(logic->getFilterChoice()); + for (auto &choice: *logic->getFilterChoices()) + setting->add_values(choice); + } { + auto setting = currentBoothSettings.mutable_filter_gain(); + setting->set_name(locale.get("api.booth.filterGain")); + setting->set_update_url("/booth_settings/filter/gain"); + setting->set_currentvalue(logic->getFilterGain()); + setting->set_minvalue(0.0); + setting->set_maxvalue(1.0); + } { + auto setting = currentBoothSettings.mutable_autofocus_before_trigger(); + setting->set_name(locale.get("api.booth.autofocus_before_trigger")); + setting->set_update_url("/booth_settings/autofocus_before_trigger/enabled"); + setting->set_currentvalue(logic->getAutofocusBeforeTrigger()); + } + + + bool flashAvailable = logic->getFlashAvailable(); + bool flashEnabled = logic->getFlashEnabled(); + + if (flashAvailable) { + { + auto setting = currentBoothSettings.mutable_flash_enabled(); + setting->set_name(locale.get("api.booth.flashEnabled")); + setting->set_update_url("/booth_settings/flash/enabled"); + setting->set_currentvalue(flashEnabled); + } { + auto setting = currentBoothSettings.mutable_flashmode(); + setting->set_name(locale.get("api.booth.iTTLEnabled")); + setting->set_update_url("/booth_settings/flash/ittl/enabled"); + setting->set_currentvalue(logic->getSelfomatController()->getFlashMode()); + } { + auto setting = currentBoothSettings.mutable_flash_duration_micros(); + setting->set_update_url("/booth_settings/flash/duration"); + setting->set_name(locale.get("api.booth.flashDuration")); + setting->set_currentvalue(controller->getFlashDurationMicros()); + setting->set_minvalue(0); + setting->set_maxvalue(40000); + } { + auto setting = currentBoothSettings.mutable_flash_test(); + setting->set_name(locale.get("api.booth.flashTest")); + setting->set_post_url("/flash"); + } + } { + auto setting = currentBoothSettings.mutable_template_upload(); + setting->set_post_url("/template_upload"); + setting->set_name(locale.get("api.booth.templateUpload")); + setting->set_input_accept("image/x-png,image/png"); + } + + + if (logic->getTemplateLoaded()) { + { + auto setting = currentBoothSettings.mutable_template_enabled(); + setting->set_update_url("/booth_settings/template_enabled"); + setting->set_name(locale.get("api.booth.templateEnabled")); + setting->set_currentvalue(logic->getTemplateEnabled()); } + } - SelfomatController *controller = logic->getSelfomatController(); - controller->setFlashDurationMicros(update.value()); - controller->commit(); - - served::response::stock_reply(200, res); - }); - - mux.handle("/booth_settings/max_led_brightness") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + if (this->show_led_setup) { + { + auto setting = currentBoothSettings.mutable_led_mode(); + setting->set_update_url("/booth_settings/led_mode"); + setting->set_name(locale.get("api.booth.ledMode")); + setting->set_currentindex(controller->getLedType()); + + setting->add_values(SelfomatController::LED_TYPE::RGB.humanName); + setting->add_values(SelfomatController::LED_TYPE::RGBW.humanName); + } { + auto setting = currentBoothSettings.mutable_led_count(); + setting->set_update_url("/booth_settings/led_count"); + setting->set_name(locale.get("api.booth.ledCount")); + + + switch (controller->getLedCount()) { + case 12: + setting->set_currentindex(0); + break; + case 16: + setting->set_currentindex(1); + break; + case 24: + setting->set_currentindex(2); + break; + case 32: + setting->set_currentindex(3); + break; + default: + setting->set_currentindex(0); + break; + } - LOG_I(TAG, "updated max led brightness to:", std::to_string(update.value())); + setting->add_values(SelfomatController::LED_COUNT::COUNT_12.humanName); + setting->add_values(SelfomatController::LED_COUNT::COUNT_16.humanName); + setting->add_values(SelfomatController::LED_COUNT::COUNT_24.humanName); + setting->add_values(SelfomatController::LED_COUNT::COUNT_32.humanName); + } + } { + auto setting = currentBoothSettings.mutable_led_offset_clockwise(); + setting->set_post_url("/booth_settings/led_offset_cw"); + setting->set_name(locale.get("api.booth.ledOffset") + " +"); + } { + auto setting = currentBoothSettings.mutable_led_offset_counter_clockwise(); + setting->set_post_url("/booth_settings/led_offset_ccw"); + setting->set_name(locale.get("api.booth.ledOffset") + " -"); + } { + auto setting = currentBoothSettings.mutable_countdown_duration(); + setting->set_update_url("/booth_settings/countdown_duration"); + setting->set_name(locale.get("api.booth.countdownDuration")); + + setting->set_currentindex(controller->getCountDownMillis() / 1000 - 1); + + for (int i = 1; i <= 10; i++) { + setting->add_values(std::to_string(i) + "s"); + } + } { + auto setting = currentBoothSettings.mutable_max_led_brightness(); + setting->set_update_url("/booth_settings/max_led_brightness"); + setting->set_name(locale.get("api.booth.maxLedBrightness")); + setting->set_minvalue(20); + setting->set_maxvalue(255); + setting->set_currentvalue(controller->getMaxLedBrightness()); + } { + auto setting = currentBoothSettings.mutable_update_mode(); + setting->set_name(locale.get("api.booth.updateMode")); + setting->set_post_url("/update"); + setting->set_alert(locale.get("api.booth.updateAlert")); + } { + auto setting = currentBoothSettings.mutable_cups_link(); + setting->set_name(locale.get("api.booth.cupsSetup")); + setting->set_url("http://192.168.4.1:631"); + } { + auto setting = currentBoothSettings.mutable_debug_log_enabled(); + setting->set_update_url("/booth_settings/debug_log_enabled"); + setting->set_name(locale.get("api.booth.debugLogEnabled")); + setting->set_currentvalue(logic->getDebugLogEnabled()); + } { + auto triggerCountSetting = currentBoothSettings.mutable_trigger_counter(); + triggerCountSetting->set_name(locale.get("api.booth.triggerCounter")); + triggerCountSetting->set_value(std::to_string(logic->getTriggerCounter())); + } { + auto setting = currentBoothSettings.mutable_software_version(); + setting->set_name(locale.get("api.booth.software_version")); + setting->set_value("unreleased (Build date + time: " __DATE__ " " __TIME__ ")"); + } + + + return crow::response(currentBoothSettings.SerializeAsString()); + }); + CROW_ROUTE(app, "/camera_settings/iso") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } - SelfomatController *controller = logic->getSelfomatController(); - controller->setMaxLedBrightness(static_cast(update.value())); - controller->commit(); + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - served::response::stock_reply(200, res); - }); + camera->setIso(update.value()); + return crow::response(200); + }); - mux.handle("/booth_settings/template_enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + CROW_ROUTE(app, "/camera_settings/shutter_speed") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } - LOG_I(TAG, "updated template enabled to", std::to_string(update.value())); + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - logic->setTemplateEnabled(update.value(), true); + camera->setShutterSpeed(update.value()); - served::response::stock_reply(200, res); - }); + return crow::response(200); + }); - mux.handle("/booth_settings/debug_log_enabled") - .post([this](served::response &res, const served::request &req) { - BoolUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + CROW_ROUTE(app, "/camera_settings/exposure_correction") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } - LOG_I(TAG, "updated debug log enabled to", std::to_string(update.value())); + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + camera->setExposureCorrection(update.value()); - logic->setDebugLogEnabled(update.value(), true); + return crow::response(200); + }); - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/camera_settings/exposure_correction_trigger") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - mux.handle("/booth_settings/led_offset_cw") - .post([this](served::response &res, const served::request &req) { + camera->setExposureCorrectionTrigger(update.value()); - SelfomatController *controller = logic->getSelfomatController(); - controller->moveOffsetLeft(); - served::response::stock_reply(200, res); - }); + return crow::response(200); + }); - mux.handle("/booth_settings/led_offset_ccw") - .post([this](served::response &res, const served::request &req) { + CROW_ROUTE(app, "/camera_settings/image_format") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } - SelfomatController *controller = logic->getSelfomatController(); - controller->moveOffsetRight(); - served::response::stock_reply(200, res); - }); + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + camera->setImageFormat(update.value()); + return crow::response(200); + }); - mux.handle("/booth_settings/countdown_duration") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - SelfomatController *controller = logic->getSelfomatController(); - controller->setCountDownMillis((update.value() + 1) * 1000); - controller->commit(); + CROW_ROUTE(app, "/booth_settings/storage/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - served::response::stock_reply(200, res); - }); + logic->setStorageEnabled(update.value(), true); - mux.handle("/booth_settings/led_mode") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + LOG_I(TAG, "updated storage enabled to: ", std::to_string(update.value())); + return crow::response(200); + }); - SelfomatController *controller = logic->getSelfomatController(); - switch (update.value()) { - case 0: - controller->setLedType(SelfomatController::LED_TYPE::RGB.controllerValue); - break; - case 1: - controller->setLedType(SelfomatController::LED_TYPE::RGBW.controllerValue); - break; - default: - served::response::stock_reply(400, res); - return; - } - controller->commit(); + CROW_ROUTE(app, "/booth_settings/autofocus_before_trigger/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - served::response::stock_reply(200, res); - }); + logic->setAutofocusBeforeTrigger(update.value(), true); + LOG_I(TAG, "updated autofocus before trigger enabled to: ", std::to_string(update.value())); - mux.handle("/booth_settings/led_count") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + return crow::response(200); + }); - SelfomatController *controller = logic->getSelfomatController(); - switch (update.value()) { - case 0: - controller->setLedCount(SelfomatController::LED_COUNT::COUNT_12.controllerValue); - break; - case 1: - controller->setLedCount(SelfomatController::LED_COUNT::COUNT_16.controllerValue); - break; - case 2: - controller->setLedCount(SelfomatController::LED_COUNT::COUNT_24.controllerValue); - break; - case 3: - controller->setLedCount(SelfomatController::LED_COUNT::COUNT_32.controllerValue); - break; - default: - served::response::stock_reply(400, res); - return; - } - controller->commit(); - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/booth_settings/flash/ittl/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + logic->getSelfomatController()->setFlashMode(update.value()); + logic->getSelfomatController()->commit(); - mux.handle("/trigger") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } + LOG_I(TAG, "updated flash mode to: ", std::to_string(update.value())); - auto controller = logic->getSelfomatController(); - controller->remoteTrigger(); - served::response::stock_reply(200, res); - }); - - mux.handle("/cancel_print") - .post([this](served::response &res, const served::request &req) { - logic->cancelPrint(); - served::response::stock_reply(200, res); - }); - - mux.handle("/focus") - .post([this](served::response &res, const served::request &req) { - if (camera->getState() != STATE_WORKING) { - served::response::stock_reply(503, res); - return; - } + return crow::response(200); + }); - logic->adjustFocus(); - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/booth_settings/printer/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - mux.handle("/flash") - .post([this](served::response &res, const served::request &req) { + logic->setPrinterEnabled(update.value(), true); - SelfomatController *controller = logic->getSelfomatController(); - controller->triggerFlash(); + LOG_I(TAG, "updated printer enabled to: ", std::to_string(update.value())); - served::response::stock_reply(200, res); - }); + return crow::response(200); + }); - mux.handle("/update") - .post([this](served::response &res, const served::request &req) { - logic->stopForUpdate(); - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/booth_settings/print_confirmation/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - mux.handle("/template_upload") - .post([this](served::response &res, const served::request &req) { + logic->setPrintConfirmationEnabled(update.value(), true); - string body = req.body(); + LOG_I(TAG, "updated print confirmation enabled to: ", std::to_string(update.value())); - if (!logic->updateTemplate((void *)body.c_str(), body.size())) { + return crow::response(200); + }); - boost::property_tree::ptree locale; - try { - boost::property_tree::read_json("./i18n/" + req.header("lang") + ".json", locale); - } catch (boost::exception &e) { - boost::property_tree::read_json("./i18n/en.json", locale); + CROW_ROUTE(app, "/booth_settings/flash/enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); } - BoothError error; - error.set_title(locale.get("api.error.noAlphaTitle")); - error.set_message(locale.get("api.error.noAlpha")); - error.set_code(400); + logic->setFlashEnabled(update.value(), true); - res << error.SerializeAsString(); + return crow::response(200); + }); - return; - } - served::response::stock_reply(200, res); - }); + CROW_ROUTE(app, "/booth_settings/flash/duration") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + SelfomatController *controller = logic->getSelfomatController(); + controller->setFlashDurationMicros(update.value()); + controller->commit(); - mux.handle("/booth_settings/language/which") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } + return crow::response(200); + }); - logic->setLanguageChoice(update.value(), true); + CROW_ROUTE(app, "/booth_settings/max_led_brightness") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - served::response::stock_reply(200, res); - }); + LOG_I(TAG, "updated max led brightness to:", std::to_string(update.value())); - mux.handle("/booth_settings/filter/which") - .post([this](served::response &res, const served::request &req) { - IntUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - logic->setFilterChoice(update.value(), true); + SelfomatController *controller = logic->getSelfomatController(); + controller->setMaxLedBrightness(static_cast(update.value())); + controller->commit(); - served::response::stock_reply(200, res); - }); + return crow::response(200); + }); - mux.handle("/booth_settings/filter/gain") - .post([this](served::response &res, const served::request &req) { - FloatUpdate update; - if (!update.ParseFromString(req.body())) { - served::response::stock_reply(400, res); - return; - } - logic->setFilterGain(update.value(), true); + CROW_ROUTE(app, "/booth_settings/template_enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - served::response::stock_reply(200, res); - }); + LOG_I(TAG, "updated template enabled to", std::to_string(update.value())); - mux.handle("/booth_settings") - .get([this](served::response &res, const served::request &req) { - BoothSettings currentBoothSettings; + logic->setTemplateEnabled(update.value(), true); - boost::property_tree::ptree locale; - try { - boost::property_tree::read_json("./i18n/" + req.header("lang") + ".json", locale); - } catch (boost::exception &e) { - boost::property_tree::read_json("./i18n/en.json", locale); - } + return crow::response(200); + }); + CROW_ROUTE(app, "/booth_settings/debug_log_enabled") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + BoolUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + LOG_I(TAG, "updated debug log enabled to", std::to_string(update.value())); - auto controller = logic->getSelfomatController(); - { - auto setting = currentBoothSettings.mutable_language_choice(); - setting->set_name(locale.get("api.booth.languageChoice")); - setting->set_update_url("/booth_settings/language/which"); - setting->set_currentindex(logic->getLanguageChoice()); - for(auto &choice : *logic->getLanguageChoices()) - setting->add_values(choice); - } + logic->setDebugLogEnabled(update.value(), true); - { - auto setting = currentBoothSettings.mutable_storage_enabled(); - setting->set_name(locale.get("api.booth.storageEnabled")); - setting->set_update_url("/booth_settings/storage/enabled"); - setting->set_currentvalue(logic->getStorageEnabled()); - } + return crow::response(200); + }); - { - auto setting = currentBoothSettings.mutable_printer_enabled(); - setting->set_name(locale.get("api.booth.printerEnabled")); - setting->set_update_url("/booth_settings/printer/enabled"); - setting->set_currentvalue(logic->getPrinterEnabled()); - } - { - auto setting = currentBoothSettings.mutable_print_confirmation_enabled(); - setting->set_name(locale.get("api.booth.printConfirmationEnabled")); - setting->set_update_url("/booth_settings/print_confirmation/enabled"); - setting->set_currentvalue(logic->getPrintConfirmationEnabled()); - } + CROW_ROUTE(app, "/booth_settings/led_offset_cw") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + SelfomatController *controller = logic->getSelfomatController(); + controller->moveOffsetLeft(); + return crow::response(200); + }); - { - auto setting = currentBoothSettings.mutable_filter_choice(); - setting->set_name(locale.get("api.booth.filterEnabled")); - setting->set_update_url("/booth_settings/filter/which"); - setting->set_currentindex(logic->getFilterChoice()); - for(auto &choice : *logic->getFilterChoices()) - setting->add_values(choice); - } - { - auto setting = currentBoothSettings.mutable_filter_gain(); - setting->set_name(locale.get("api.booth.filterGain")); - setting->set_update_url("/booth_settings/filter/gain"); - setting->set_currentvalue(logic->getFilterGain()); - setting->set_minvalue(0.0); - setting->set_maxvalue(1.0); - } + CROW_ROUTE(app, "/booth_settings/led_offset_ccw") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + SelfomatController *controller = logic->getSelfomatController(); + controller->moveOffsetRight(); + return crow::response(200); + }); - { - auto setting = currentBoothSettings.mutable_autofocus_before_trigger(); - setting->set_name(locale.get("api.booth.autofocus_before_trigger")); - setting->set_update_url("/booth_settings/autofocus_before_trigger/enabled"); - setting->set_currentvalue(logic->getAutofocusBeforeTrigger()); - } + CROW_ROUTE(app, "/booth_settings/countdown_duration") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + SelfomatController *controller = logic->getSelfomatController(); + controller->setCountDownMillis((update.value() + 1) * 1000); + controller->commit(); - bool flashAvailable = logic->getFlashAvailable(); - bool flashEnabled = logic->getFlashEnabled(); + return crow::response(200); + }); - if (flashAvailable) { - { - auto setting = currentBoothSettings.mutable_flash_enabled(); - setting->set_name(locale.get("api.booth.flashEnabled")); - setting->set_update_url("/booth_settings/flash/enabled"); - setting->set_currentvalue(flashEnabled); + CROW_ROUTE(app, "/booth_settings/led_mode") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); } - { - auto setting = currentBoothSettings.mutable_flashmode(); - setting->set_name(locale.get("api.booth.iTTLEnabled")); - setting->set_update_url("/booth_settings/flash/ittl/enabled"); - setting->set_currentvalue(logic->getSelfomatController()->getFlashMode()); - } - { - auto setting = currentBoothSettings.mutable_flash_duration_micros(); - setting->set_update_url("/booth_settings/flash/duration"); - setting->set_name(locale.get("api.booth.flashDuration")); - setting->set_currentvalue(controller->getFlashDurationMicros()); - setting->set_minvalue(0); - setting->set_maxvalue(40000); + SelfomatController *controller = logic->getSelfomatController(); + switch (update.value()) { + case 0: + controller->setLedType(SelfomatController::LED_TYPE::RGB.controllerValue); + break; + case 1: + controller->setLedType(SelfomatController::LED_TYPE::RGBW.controllerValue); + break; + default: + return crow::response(400); } + controller->commit(); - { - auto setting = currentBoothSettings.mutable_flash_test(); - setting->set_name(locale.get("api.booth.flashTest")); - setting->set_post_url("/flash"); - } - } + return crow::response(200); + }); - { - auto setting = currentBoothSettings.mutable_template_upload(); - setting->set_post_url("/template_upload"); - setting->set_name(locale.get("api.booth.templateUpload")); - setting->set_input_accept("image/x-png,image/png"); - } - - if (logic->getTemplateLoaded()) { - { - auto setting = currentBoothSettings.mutable_template_enabled(); - setting->set_update_url("/booth_settings/template_enabled"); - setting->set_name(locale.get("api.booth.templateEnabled")); - setting->set_currentvalue(logic->getTemplateEnabled()); + CROW_ROUTE(app, "/booth_settings/led_count") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); } - } - - if (this->show_led_setup) { - { - auto setting = currentBoothSettings.mutable_led_mode(); - setting->set_update_url("/booth_settings/led_mode"); - setting->set_name(locale.get("api.booth.ledMode")); - setting->set_currentindex(controller->getLedType()); - - setting->add_values(SelfomatController::LED_TYPE::RGB.humanName); - setting->add_values(SelfomatController::LED_TYPE::RGBW.humanName); - } - - { - auto setting = currentBoothSettings.mutable_led_count(); - setting->set_update_url("/booth_settings/led_count"); - setting->set_name(locale.get("api.booth.ledCount")); - - - switch (controller->getLedCount()) { - case 12: - setting->set_currentindex(0); - break; - case 16: - setting->set_currentindex(1); - break; - case 24: - setting->set_currentindex(2); - break; - case 32: - setting->set_currentindex(3); - break; - default: - setting->set_currentindex(0); - break; - } - setting->add_values(SelfomatController::LED_COUNT::COUNT_12.humanName); - setting->add_values(SelfomatController::LED_COUNT::COUNT_16.humanName); - setting->add_values(SelfomatController::LED_COUNT::COUNT_24.humanName); - setting->add_values(SelfomatController::LED_COUNT::COUNT_32.humanName); + SelfomatController *controller = logic->getSelfomatController(); + switch (update.value()) { + case 0: + controller->setLedCount(SelfomatController::LED_COUNT::COUNT_12.controllerValue); + break; + case 1: + controller->setLedCount(SelfomatController::LED_COUNT::COUNT_16.controllerValue); + break; + case 2: + controller->setLedCount(SelfomatController::LED_COUNT::COUNT_24.controllerValue); + break; + case 3: + controller->setLedCount(SelfomatController::LED_COUNT::COUNT_32.controllerValue); + break; + default: + return crow::response(400); } - } + controller->commit(); + return crow::response(200); + }); - { - auto setting = currentBoothSettings.mutable_led_offset_clockwise(); - setting->set_post_url("/booth_settings/led_offset_cw"); - setting->set_name(locale.get("api.booth.ledOffset") + " +"); - } - - { - auto setting = currentBoothSettings.mutable_led_offset_counter_clockwise(); - setting->set_post_url("/booth_settings/led_offset_ccw"); - setting->set_name(locale.get("api.booth.ledOffset") + " -"); - } - - - { - auto setting = currentBoothSettings.mutable_countdown_duration(); - setting->set_update_url("/booth_settings/countdown_duration"); - setting->set_name(locale.get("api.booth.countdownDuration")); - setting->set_currentindex(controller->getCountDownMillis() / 1000 - 1); - - for (int i = 1; i <= 10; i++) { - setting->add_values(std::to_string(i) + "s"); + CROW_ROUTE(app, "/trigger") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); } - } - - { - auto setting = currentBoothSettings.mutable_max_led_brightness(); - setting->set_update_url("/booth_settings/max_led_brightness"); - setting->set_name(locale.get("api.booth.maxLedBrightness")); - setting->set_minvalue(20); - setting->set_maxvalue(255); - setting->set_currentvalue(controller->getMaxLedBrightness()); - } - - - { - auto setting = currentBoothSettings.mutable_update_mode(); - setting->set_name(locale.get("api.booth.updateMode")); - setting->set_post_url("/update"); - setting->set_alert(locale.get("api.booth.updateAlert")); - } - - { - auto setting = currentBoothSettings.mutable_cups_link(); - setting->set_name(locale.get("api.booth.cupsSetup")); - setting->set_url("http://192.168.4.1:631"); - } - - { - auto setting = currentBoothSettings.mutable_debug_log_enabled(); - setting->set_update_url("/booth_settings/debug_log_enabled"); - setting->set_name(locale.get("api.booth.debugLogEnabled")); - setting->set_currentvalue(logic->getDebugLogEnabled()); - } - - { - auto triggerCountSetting = currentBoothSettings.mutable_trigger_counter(); - triggerCountSetting->set_name(locale.get("api.booth.triggerCounter")); - triggerCountSetting->set_value(std::to_string(logic->getTriggerCounter())); - } - - { - auto setting = currentBoothSettings.mutable_software_version(); - setting->set_name(locale.get("api.booth.software_version")); - setting->set_value("unreleased (Build date + time: " __DATE__ " " __TIME__ ")"); - } - - - res << currentBoothSettings.SerializeAsString(); - }); + auto controller = logic->getSelfomatController(); + controller->remoteTrigger(); + return crow::response(200); + }); + + CROW_ROUTE(app, "/cancel_print") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + logic->cancelPrint(); + return crow::response(200); + }); + + CROW_ROUTE(app, "/focus") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + if (camera->getState() != STATE_WORKING) { + return crow::response(503); + } + logic->adjustFocus(); + return crow::response(200); + }); + + CROW_ROUTE(app, "/flash") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + SelfomatController *controller = logic->getSelfomatController(); + controller->triggerFlash(); + + return crow::response(200); + }); + + CROW_ROUTE(app, "/update") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + logic->stopForUpdate(); + return crow::response(200); + }); + + CROW_ROUTE(app, "/template_upload") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + string body = req.body; + + if (!logic->updateTemplate((void *) body.c_str(), body.size())) { + boost::property_tree::ptree locale; + try { + boost::property_tree::read_json("./i18n/" + req.get_header_value("lang") + ".json", locale); + } catch (boost::exception &e) { + boost::property_tree::read_json("./i18n/en.json", locale); + } + BoothError error; + error.set_title(locale.get("api.error.noAlphaTitle")); + error.set_message(locale.get("api.error.noAlpha")); + error.set_code(400); + return crow::response(error.SerializeAsString()); + } - mux.handle("/stress") - .post([this](served::response &res, const served::request &req) { - auto controller = logic->getSelfomatController(); - controller->setStressTestEnabled(true); - served::response::stock_reply(200, res); - }); + return crow::response(200); + }); - mux.handle("/unstress") - .post([this](served::response &res, const served::request &req) { - auto controller = logic->getSelfomatController(); - controller->setStressTestEnabled(false); - served::response::stock_reply(200, res); - }); - mux.handle("/version") - .get([this](served::response &res, const served::request &req) { - std::string filename = "./version"; + CROW_ROUTE(app, "/booth_settings/language/which") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - ifstream f(filename, ios::in); - string file_contents{istreambuf_iterator(f), istreambuf_iterator()}; + logic->setLanguageChoice(update.value(), true); - res.set_status(200); - res.set_body(file_contents); - }); + return crow::response(200); + }); - mux.handle("/app/assets/i18n/{file}") - .get([this](served::response &res, const served::request &req) { - std::string filename = "./app/assets/i18n/" + req.params["file"]; + CROW_ROUTE(app, "/booth_settings/filter/which") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + IntUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } - res.set_header("Content-Type", "application/json"); + logic->setFilterChoice(update.value(), true); - ifstream f(filename, ios::in); - string file_contents{istreambuf_iterator(f), istreambuf_iterator()}; + return crow::response(200); + }); - res.set_status(200); - res.set_body(file_contents); - }); + CROW_ROUTE(app, "/booth_settings/filter/gain") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + FloatUpdate update; + if (!update.ParseFromString(req.body)) { + return crow::response(400); + } + logic->setFilterGain(update.value(), true); - mux.handle("/app/svg/{file}") - .get([this](served::response &res, const served::request &req) { - std::string filename = "./app/svg/" + req.params["file"]; + return crow::response(200); + }); - res.set_header("Content-Type", "image/svg+xml"); - ifstream f(filename, ios::in); - string file_contents{istreambuf_iterator(f), istreambuf_iterator()}; + CROW_ROUTE(app, "/stress") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + auto controller = logic->getSelfomatController(); + controller->setStressTestEnabled(true); + return crow::response(200); + }); - res.set_status(200); - res.set_body(file_contents); - }); + CROW_ROUTE(app, "/unstress") + .methods(crow::HTTPMethod::Post)( + [this](const crow::request &req) { + auto controller = logic->getSelfomatController(); + controller->setStressTestEnabled(false); + return crow::response(200); + }); - mux.handle("/app/{file}") - .get([this](served::response &res, const served::request &req) { - string file = req.params["file"]; + CROW_ROUTE(app, "/version") + .methods(crow::HTTPMethod::Get)( + [this](const crow::request &req) { + std::string filename = "./version"; - if (file.compare("tabs") == 0) { - res.set_status(301); - res.set_header("Location", "/app/index.html"); - } else { - ifstream f("./app/" + file, ios::in); + ifstream f(filename, ios::in); string file_contents{istreambuf_iterator(f), istreambuf_iterator()}; - res.set_status(200); - res.set_body(file_contents); - } - }); - - mux.handle("/{file}") - .get([this](served::response &res, const served::request &req) { - string file = req.params["file"]; + return crow::response(file_contents); + }); - if (file.compare("app") == 0) { - res.set_status(301); - res.set_header("Location", "/app/index.html"); - } - }); - // Create the server and run with 2 handler thread. - // THIS IS NEEDED BECAUSE BLOCKING=FALSE IS IGNORED BY SERVERD IF THREADS = 1!!!! - server.run(2, false); + // register the fallback handler to serve static files + CROW_ROUTE(app, "/").methods(crow::HTTPMethod::Get)([](std::string file) { + auto response = crow::response(); + response.set_static_file_info("app/" + file); + return response; + }); + CROW_ROUTE(app, "/app/")([](std::string file) { + auto response = crow::response(); + response.set_static_file_info("app/" + file); + return response; + }); LOG_I(TAG, "API started!"); + app.bindaddr("0.0.0.0"); + app.port(9080); + app_handle = app.run_async(); return true; } bool BoothApi::stop() { LOG_I(TAG, "Stopping the API"); - - server.stop(); - + app.stop(); + app_handle.wait(); + LOG_I(TAG, "API stopped"); return true; } diff --git a/src/api/BoothApi.h b/src/api/BoothApi.h index 05426f1..2d345ff 100644 --- a/src/api/BoothApi.h +++ b/src/api/BoothApi.h @@ -7,8 +7,9 @@ #include "../protobuf/api.pb.h" #include "../logic/BoothLogic.h" +#include +#include -#include using namespace selfomat; namespace selfomat { @@ -20,19 +21,11 @@ namespace selfomat { selfomat::logic::BoothLogic *logic; ICamera *camera; - served::multiplexer mux; - served::net::server server; + crow::App app; + std::future app_handle; bool show_led_setup; - const std::map headers = { - {"Access-Control-Allow-Origin", "*"}, - {"Access-Control-Allow-Credentials", "true"}, - {"Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT"}, - {"Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"}, - - }; - public: BoothApi(selfomat::logic::BoothLogic *logic, ICamera *camera, bool show_led_setup);