15#include <unordered_map>
23bool shouldStop(
const export_ports::ExportRequest &request) {
24 if (request.waitIfPaused) {
25 request.waitIfPaused();
27 return request.shouldCancel && request.shouldCancel();
30export_ports::ExportResult canceledResult(
31 const export_ports::ExportRequest &request) {
32 return {
false, export_ports::ExportStatus::Canceled, request.format,
33 request.outputPath, {},
"Canceled"};
36std::string dedupeKey(
const export_ports::ExportObjectRequest &item) {
37 return item.annualId +
"|" + item.objectId +
"|" +
38 std::to_string(
static_cast<int>(item.format));
41export_ports::AnalysisExportFormat
42analysisFormatFromString(
const std::string &value) {
44 return export_ports::AnalysisExportFormat::Xlsx;
45 if (value ==
"jpg" || value ==
"jpeg")
46 return export_ports::AnalysisExportFormat::Jpg;
48 return export_ports::AnalysisExportFormat::Png;
49 return export_ports::AnalysisExportFormat::Csv;
52std::vector<export_ports::ExportObjectRequest>
53expandObjectRequests(
const core::domain::catalog::WorkspaceCatalog &state,
54 const export_ports::ExportRequest &request) {
55 std::vector<export_ports::ExportObjectRequest> out;
56 std::unordered_map<std::string, std::shared_ptr<core::domain::Analysis>>
58 for (
const auto &analysis : state.
analyses()) {
59 if (!analysis || analysis->id().empty())
61 analysisById.emplace(analysis->id(), analysis);
64 std::set<std::string> seen;
65 for (
const auto &item : request.objectRequests) {
66 if (item.type == export_ports::ExportObjectType::Analysis) {
67 if (!item.objectId.empty()) {
68 const std::string key = dedupeKey(item);
69 if (seen.find(key) != seen.end())
77 for (
const auto &annual : state.
annuals()) {
78 if (!annual || annual->id() != item.objectId)
80 for (
const auto &analysisId : annual->analysisIds()) {
81 const auto it = analysisById.find(analysisId);
82 if (it == analysisById.end() || !it->second)
84 export_ports::ExportObjectRequest expanded;
85 expanded.type = export_ports::ExportObjectType::Analysis;
86 expanded.objectId = analysisId;
87 expanded.annualId = annual->id();
88 expanded.name = it->second->name();
89 expanded.format = analysisFormatFromString(it->second->exportFormat());
90 const std::string key = dedupeKey(expanded);
91 if (seen.find(key) != seen.end())
94 out.push_back(std::move(expanded));
106 std::shared_ptr<core::ports::archive::IArchive> archive,
107 std::shared_ptr<core::ports::xlsx_writer::IXlsxWriter> xlsxWriter,
111 : archive_(std::move(archive)), xlsxWriter_(std::move(xlsxWriter)),
112 imageRenderer_(std::move(imageRenderer)) {}
114export_ports::ExportResult
117 export_ports::ExportRequest request)
const {
118 if (shouldStop(request)) {
119 return canceledResult(request);
127 const export_ports::ExportRequest &request)
const {
128 if (!request.objectRequests.empty()) {
129 auto normalized = request;
130 normalized.objectRequests = expandObjectRequests(state, request);
131 if (shouldStop(normalized)) {
132 return canceledResult(normalized);
134 if (normalized.progressCallback) {
135 normalized.progressCallback(0.05,
"Preparing export");
136 if (shouldStop(normalized)) {
137 return canceledResult(normalized);
139 normalized.progressCallback(0.20,
"Resolving export objects");
143 if (normalized.progressCallback) {
144 normalized.progressCallback(result.success ? 1.0 : 0.95,
145 result.success ?
"Finished" :
"Failed");
150 switch (request.format) {
151 case export_ports::ExportFormat::Csv:
152 if (shouldStop(request)) {
153 return canceledResult(request);
156 case export_ports::ExportFormat::Xlsx:
157 if (shouldStop(request)) {
158 return canceledResult(request);
163 return export_ports::ExportResult{
165 export_ports::ExportStatus::UnsupportedFormat,
Declares CSV export for the property/contract-type matrix.
Defines private constants shared by core export implementations.
Declares the export entry point used by the application shell.
Declares object export execution helpers.
Maps workspace port snapshots into internal catalog state.
Declares XLSX export for the property/contract-type matrix.
Exports the property/contract matrix to CSV.
core::ports::exporting::ExportResult exportData(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request) const
Exports the property/contract matrix to a CSV file.
ExportService(std::shared_ptr< core::ports::archive::IArchive > archive={}, std::shared_ptr< core::ports::xlsx_writer::IXlsxWriter > xlsxWriter={}, std::shared_ptr< core::ports::analysis_rendering::IAnalysisRenderer > imageRenderer={})
core::ports::exporting::ExportResult runExport(const core::ports::workspace::WorkspaceSnapshot &workspace, core::ports::exporting::ExportRequest request) const override
Dispatches an export request to the appropriate exporter implementation.
core::ports::exporting::ExportResult exportData(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request) const
Exports the property/contract matrix to XLSX.
core::ports::exporting::ExportResult exportData(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request) const
Exports the property/contract matrix to an XLSX file.
const AnnualList & annuals() const noexcept
Returns all annuals in the catalog.
const AnalysisList & analyses() const noexcept
Returns all analyses in the catalog.
Renders analysis results to image artifacts.
constexpr std::string_view kMessageUnsupportedFormat
constexpr std::string_view kErrorUnsupportedFormat
core::ports::exporting::ExportResult exportObjectRequests(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request, const std::shared_ptr< core::ports::archive::IArchive > &archive, const std::shared_ptr< core::ports::xlsx_writer::IXlsxWriter > &xlsxWriter, const std::shared_ptr< core::ports::analysis_rendering::IAnalysisRenderer > &imageRenderer)
Export selected workspace objects according to an export request.
core::domain::catalog::WorkspaceCatalog toWorkspaceCatalog(const core::ports::workspace::WorkspaceSnapshot &snapshot)