CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
configurable_xmp_path_strategy.cpp
Go to the documentation of this file.
1
9#include <spdlog/spdlog.h>
10#include <exiv2/exiv2.hpp>
11#include <filesystem>
12
14
15ConfigurableXmpPathStrategy::ConfigurableXmpPathStrategy(const std::string& base_xmp_dir, std::unique_ptr<IXmpProvider> xmp_provider)
16 : m_base_xmp_dir(base_xmp_dir)
17 , m_xmp_provider(std::move(xmp_provider))
18{
19 if (!m_xmp_provider) {
20 spdlog::error("ConfigurableXmpPathStrategy: Constructor received a null IXmpProvider.");
21 throw std::invalid_argument("ConfigurableXmpPathStrategy: IXmpProvider cannot be null.");
22 }
23
24 if (!std::filesystem::exists(m_base_xmp_dir)) {
25 try {
26 std::filesystem::create_directories(m_base_xmp_dir);
27 spdlog::info("ConfigurableXmpPathStrategy: Created configured base XMP directory: {}", m_base_xmp_dir);
28 } catch (const std::exception& e) {
29 spdlog::error("ConfigurableXmpPathStrategy: Failed to create configured base XMP directory '{}': {}", m_base_xmp_dir, e.what());
30 }
31 }
32 spdlog::debug("ConfigurableXmpPathStrategy: Initialized with base XMP directory: {} and IXmpProvider.", m_base_xmp_dir);
33}
34
35std::string ConfigurableXmpPathStrategy::getXmpPathForImage(std::string_view source_image_path) const
36{
37 if (source_image_path.empty()) {
38 spdlog::error("ConfigurableXmpPathStrategy::getXmpPathForImage: Source image path is empty.");
39 return {};
40 }
41
42 std::filesystem::path image_path_obj(source_image_path);
43
44 // Calculate relative path
45 // NOTE: Assumes 'source_image_path' is absolute.
46 std::filesystem::path relative_path = image_path_obj.lexically_relative(image_path_obj.root_path());
47
48 // Construct target path in configured directory, mirroring structure
49 std::filesystem::path xmp_final_path = m_base_xmp_dir / relative_path;
50 xmp_final_path += ".xmp";
51
52 spdlog::debug("ConfigurableXmpPathStrategy::getXmpPathForImage: Mapped '{}' to XMP path: '{}'", source_image_path, xmp_final_path.string());
53 return xmp_final_path.string();
54}
55
56std::string ConfigurableXmpPathStrategy::getImagePathFromXmp(std::string_view xmp_path) const
57{
58 if (xmp_path.empty()) {
59 spdlog::error("ConfigurableXmpPathStrategy::getImagePathFromXmp: XMP path is empty.");
60 return {};
61 }
62
63 spdlog::debug("ConfigurableXmpPathStrategy::getImagePathFromXmp: Attempting to read original image path from XMP: {}", xmp_path);
64
65 // Read the XMP packet to find the stored path
66 std::string xmp_packet = m_xmp_provider->readXmp(xmp_path);
67 if (xmp_packet.empty()) {
68 spdlog::warn("ConfigurableXmpPathStrategy::getImagePathFromXmp: IXmpProvider returned an empty XMP packet for file: {}", xmp_path);
69 return {};
70 }
71
72 Exiv2::XmpData xmp_data;
73 try {
74 if (Exiv2::XmpParser::decode(xmp_data, xmp_packet.c_str()) != 0) {
75 spdlog::error("ConfigurableXmpPathStrategy::getImagePathFromXmp: Failed to decode XMP packet from file: {}", xmp_path);
76 return {};
77 }
78
79 // Extract the stored source path
80 std::string source_image_path_from_xmp = xmp_data["Xmp.cm.sourceImagePath"].toString();
81
82 if (source_image_path_from_xmp.empty()) {
83 spdlog::warn("ConfigurableXmpPathStrategy::getImagePathFromXmp: XMP packet in file '{}' does not contain the 'Xmp.cm.sourceImagePath' key.", xmp_path);
84 } else {
85 spdlog::debug("ConfigurableXmpPathStrategy::getImagePathFromXmp: Found source image path in XMP: '{}'", source_image_path_from_xmp);
86 }
87
88 return source_image_path_from_xmp;
89
90 } catch (const Exiv2::Error& e) {
91 spdlog::error("ConfigurableXmpPathStrategy::getImagePathFromXmp: Exiv2 error during parsing XMP file '{}': {}", xmp_path, e.what());
92 return {};
93 } catch (const std::exception& e) {
94 spdlog::error("ConfigurableXmpPathStrategy::getImagePathFromXmp: General error during parsing XMP file '{}': {}", xmp_path, e.what());
95 return {};
96 }
97}
98
99} // namespace CaptureMoment::Core::Serializer
std::string getImagePathFromXmp(std::string_view xmp_path) const override
Calculates the source image path associated with a given XMP file path.
std::string getXmpPathForImage(std::string_view source_image_path) const override
Calculates the XMP file path associated with a given source image path.
ConfigurableXmpPathStrategy(const std::string &base_xmp_dir, std::unique_ptr< IXmpProvider > xmp_provider)
Constructs a ConfigurableXmpPathStrategy.
Declaration of ConfigurableXmpPathStrategy class.
CaptureMoment — footer