16 : m_base_xmp_dir(base_xmp_dir)
17 , m_xmp_provider(std::move(xmp_provider))
19 if (!m_xmp_provider) {
20 spdlog::error(
"ConfigurableXmpPathStrategy: Constructor received a null IXmpProvider.");
21 throw std::invalid_argument(
"ConfigurableXmpPathStrategy: IXmpProvider cannot be null.");
24 if (!std::filesystem::exists(m_base_xmp_dir)) {
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());
32 spdlog::debug(
"ConfigurableXmpPathStrategy: Initialized with base XMP directory: {} and IXmpProvider.", m_base_xmp_dir);
37 if (source_image_path.empty()) {
38 spdlog::error(
"ConfigurableXmpPathStrategy::getXmpPathForImage: Source image path is empty.");
42 std::filesystem::path image_path_obj(source_image_path);
46 std::filesystem::path relative_path = image_path_obj.lexically_relative(image_path_obj.root_path());
49 std::filesystem::path xmp_final_path = m_base_xmp_dir / relative_path;
50 xmp_final_path +=
".xmp";
52 spdlog::debug(
"ConfigurableXmpPathStrategy::getXmpPathForImage: Mapped '{}' to XMP path: '{}'", source_image_path, xmp_final_path.string());
53 return xmp_final_path.string();
58 if (xmp_path.empty()) {
59 spdlog::error(
"ConfigurableXmpPathStrategy::getImagePathFromXmp: XMP path is empty.");
63 spdlog::debug(
"ConfigurableXmpPathStrategy::getImagePathFromXmp: Attempting to read original image path from XMP: {}", xmp_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);
72 Exiv2::XmpData xmp_data;
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);
80 std::string source_image_path_from_xmp = xmp_data[
"Xmp.cm.sourceImagePath"].toString();
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);
85 spdlog::debug(
"ConfigurableXmpPathStrategy::getImagePathFromXmp: Found source image path in XMP: '{}'", source_image_path_from_xmp);
88 return source_image_path_from_xmp;
90 }
catch (
const Exiv2::Error& e) {
91 spdlog::error(
"ConfigurableXmpPathStrategy::getImagePathFromXmp: Exiv2 error during parsing XMP file '{}': {}", xmp_path, e.what());
93 }
catch (
const std::exception& e) {
94 spdlog::error(
"ConfigurableXmpPathStrategy::getImagePathFromXmp: General error during parsing XMP file '{}': {}", xmp_path, e.what());