diff --git a/daemon/application.cpp b/daemon/application.cpp index 1b7f47d..a0fa144 100644 --- a/daemon/application.cpp +++ b/daemon/application.cpp @@ -182,6 +182,7 @@ void setup_controllers(drogon::HttpAppFramework& app, kgr::container& container) .registerController(container.service()) .registerController(container.service()) .registerController(container.service()) + .registerController(container.service()) .registerController(container.service()) .registerFilter(container.service()); } diff --git a/daemon/core/application/services/MaintenanceService.cpp b/daemon/core/application/services/MaintenanceService.cpp new file mode 100644 index 0000000..5a8014c --- /dev/null +++ b/daemon/core/application/services/MaintenanceService.cpp @@ -0,0 +1,37 @@ +/* === This file is part of bxt === + * + * SPDX-FileCopyrightText: 2024 Artem Grinev + * SPDX-License-Identifier: AGPL-3.0-or-later + * + */ +#include "MaintenanceService.h" + +#include "core/application/dtos/PackageSectionDTO.h" + +coro::task bxt::Core::Application::MaintenanceService::export_database( + std::set const& sections) { + auto available_sections = co_await m_section_service.get_sections(); + + if (!available_sections.has_value()) { + co_return; + } + + std::set sections_to_export; + + if (sections.empty()) { + sections_to_export = *available_sections | std::ranges::to(); + } else { + for (auto const& section : sections) { + if (std::find(available_sections->begin(), available_sections->end(), section) + != available_sections->end()) { + co_return; + } + } + } + + m_exporter.add_dirty_sections(std::move(sections_to_export)); + + co_await m_exporter.export_to_disk(); + + co_return; +} diff --git a/daemon/core/application/services/MaintenanceService.h b/daemon/core/application/services/MaintenanceService.h new file mode 100644 index 0000000..8b6c75f --- /dev/null +++ b/daemon/core/application/services/MaintenanceService.h @@ -0,0 +1,37 @@ +/* === This file is part of bxt === + * + * SPDX-FileCopyrightText: 2024 Artem Grinev + * SPDX-License-Identifier: AGPL-3.0-or-later + * + */ +#pragma once + +#include "core/application/dtos/PackageSectionDTO.h" +#include "core/application/errors/CrudError.h" +#include "core/application/services/SectionService.h" +#include "infrastructure/PackageService.h" +#include "persistence/box/export/AlpmDBExporter.h" +#include "persistence/box/export/ExporterBase.h" +#include "utilities/errors/Macro.h" + +#include + +namespace bxt::Core::Application { +class MaintenanceService { +public: + BXT_DECLARE_RESULT(CrudError) + + MaintenanceService(Persistence::Box::ExporterBase& exporter, + Application::SectionService& section_service) + : m_exporter(exporter) + , m_section_service(section_service) { + } + + coro::task export_database(std::set const& sections = {}); + +private: + Persistence::Box::ExporterBase& m_exporter; + Application::SectionService& m_section_service; +}; + +} // namespace bxt::Core::Application diff --git a/daemon/di.h b/daemon/di.h index ca8c8ff..5c8e8b0 100644 --- a/daemon/di.h +++ b/daemon/di.h @@ -8,6 +8,7 @@ #include "core/application/services/AuthService.h" #include "core/application/services/CompareService.h" +#include "core/application/services/MaintenanceService.h" #include "core/application/services/PackageService.h" #include "core/application/services/PermissionService.h" #include "core/application/services/SectionService.h" @@ -45,6 +46,7 @@ #include "presentation/web-controllers/AuthController.h" #include "presentation/web-controllers/CompareController.h" #include "presentation/web-controllers/LogController.h" +#include "presentation/web-controllers/MaintenanceController.h" #include "presentation/web-controllers/PackageController.h" #include "presentation/web-controllers/SectionController.h" #include "presentation/web-controllers/UserController.h" @@ -294,6 +296,13 @@ namespace Persistence { } // namespace Box } // namespace Persistence +namespace Core::Application { + struct MaintenanceService + : kgr::single_service> {}; +} // namespace Core::Application + namespace Presentation { struct JwtOptions : kgr::single_service {}; @@ -339,6 +348,11 @@ namespace Presentation { kgr::dependency> {}; + struct MaintenanceController + : kgr::shared_service> {}; + struct JwtFilter : kgr::shared_service< bxt::Presentation::JwtFilter, diff --git a/daemon/presentation/messages/MaintenanceMessages.h b/daemon/presentation/messages/MaintenanceMessages.h new file mode 100644 index 0000000..b8a5dec --- /dev/null +++ b/daemon/presentation/messages/MaintenanceMessages.h @@ -0,0 +1,20 @@ +/* === This file is part of bxt === + * + * SPDX-FileCopyrightText: 2024 Artem Grinev + * SPDX-License-Identifier: AGPL-3.0-or-later + * + */ + +#pragma once + +#include "presentation/messages/SectionMessages.h" + +#include + +namespace bxt::Presentation { + +struct ExportDatabaseRequest { + std::vector sections; +}; + +} // namespace bxt::Presentation diff --git a/daemon/presentation/web-controllers/MaintenanceController.cpp b/daemon/presentation/web-controllers/MaintenanceController.cpp new file mode 100644 index 0000000..b3ae7b8 --- /dev/null +++ b/daemon/presentation/web-controllers/MaintenanceController.cpp @@ -0,0 +1,33 @@ +/* === This file is part of bxt === + * + * SPDX-FileCopyrightText: 2024 Artem Grinev + * SPDX-License-Identifier: AGPL-3.0-or-later + * + */ +#include "MaintenanceController.h" + +#include "core/application/dtos/PackageSectionDTO.h" +#include "presentation/messages/MaintenanceMessages.h" +#include "utilities/drogon/Helpers.h" +#include "utilities/drogon/Macro.h" +namespace bxt::Presentation { + +using namespace drogon; + +Task MaintenanceController::export_database(HttpRequestPtr req) { + BXT_JWT_CHECK_PERMISSIONS("maintenance.export", req); + + auto request = drogon_helpers::get_request_json(req); + + co_await m_service.export_database( + request.value_or({{}}).sections | std::views::transform([](SectionRequest const& section) { + return PackageSectionDTO {.branch = section.branch, + .repository = section.repository, + .architecture = section.architecture}; + }) + | std::ranges::to()); + + co_return {}; +} + +} // namespace bxt::Presentation diff --git a/daemon/presentation/web-controllers/MaintenanceController.h b/daemon/presentation/web-controllers/MaintenanceController.h new file mode 100644 index 0000000..b873d8e --- /dev/null +++ b/daemon/presentation/web-controllers/MaintenanceController.h @@ -0,0 +1,42 @@ +/* === This file is part of bxt === + * + * SPDX-FileCopyrightText: 2024 Artem Grinev + * SPDX-License-Identifier: AGPL-3.0-or-later + * + */ +#pragma once + +#include "core/application/services/MaintenanceService.h" +#include "core/application/services/PermissionService.h" +#include "utilities/drogon/Macro.h" + +#include +#include +#include +#include + +namespace bxt::Presentation { + +class MaintenanceController : public drogon::HttpController { +public: + explicit MaintenanceController(Core::Application::MaintenanceService& service, + Core::Application::PermissionService& permission_service) + : m_service(service) + , m_permission_service(permission_service) { + } + + METHOD_LIST_BEGIN + + BXT_JWT_ADD_METHOD_TO(MaintenanceController::export_database, + "/api/maintenance/export", + drogon::Get); + METHOD_LIST_END + + drogon::Task export_database(drogon::HttpRequestPtr req); + +private: + Core::Application::MaintenanceService& m_service; + Core::Application::PermissionService& m_permission_service; +}; + +} // namespace bxt::Presentation