CaptureMoment 0.1.0
Free and open-source non-destructive photo editor
Loading...
Searching...
No Matches
appdata_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
15AppDataXmpPathStrategy::AppDataXmpPathStrategy(const std::string& app_data_dir)
16 : m_app_data_dir(app_data_dir)
17{
18 // Ensure the base directory exists
19 if (!std::filesystem::exists(m_app_data_dir)) {
20 try {
21 std::filesystem::create_directories(m_app_data_dir);
22 spdlog::info("AppDataXmpPathStrategy: Created AppData base directory: {}", m_app_data_dir);
23 } catch (const std::exception& e) {
24 spdlog::error("AppDataXmpPathStrategy: Failed to create AppData base directory '{}': {}", m_app_data_dir, e.what());
25 }
26 }
27 spdlog::debug("AppDataXmpPathStrategy: Initialized with AppData directory: {}", m_app_data_dir);
28}
29
30std::string AppDataXmpPathStrategy::getXmpPathForImage(std::string_view source_image_path) const
31{
32 if (source_image_path.empty()) {
33 spdlog::error("AppDataXmpPathStrategy::getXmpPathForImage: Source image path is empty.");
34 return {};
35 }
36
37 std::filesystem::path image_path_obj(source_image_path);
38
39 // Calculate the relative path from the root of the filesystem
40 // NOTE: This logic assumes 'source_image_path' is an absolute path.
41 // If it's relative, root_path() might be empty or misleading.
42 std::filesystem::path relative_path = image_path_obj.lexically_relative(image_path_obj.root_path());
43
44 // Construct the target path in AppData
45 // Preserves folder structure: /home/user/pics/img.jpg -> <appdata>/home/user/pics/img.jpg.xmp
46 std::filesystem::path xmp_final_path = m_app_data_dir / relative_path;
47 xmp_final_path += ".xmp";
48
49 spdlog::debug("AppDataXmpPathStrategy::getXmpPathForImage: Mapped '{}' to XMP path: '{}'", source_image_path, xmp_final_path.string());
50 return xmp_final_path.string();
51}
52
53std::string AppDataXmpPathStrategy::getImagePathFromXmp(std::string_view xmp_path) const
54{
55 if (xmp_path.empty()) {
56 spdlog::error("AppDataXmpPathStrategy::getImagePathFromXmp: XMP path is empty.");
57 return {};
58 }
59
60 spdlog::debug("AppDataXmpPathStrategy::getImagePathFromXmp: Attempting to read original image path from XMP: {}", xmp_path);
61
62 // Step 1: Read the XMP packet from the file using the injected provider
63 std::string xmp_packet = m_xmp_provider->readXmp(xmp_path);
64 if (xmp_packet.empty()) {
65 spdlog::warn("AppDataXmpPathStrategy::getImagePathFromXmp: IXmpProvider returned an empty XMP packet for file: {}", xmp_path);
66 return {};
67 }
68
69 // Step 2: Parse the XMP packet to find the source image path
70 Exiv2::XmpData xmp_data;
71 try {
72 // Decode the XMP packet string into the XmpData container
73 if (Exiv2::XmpParser::decode(xmp_data, xmp_packet.c_str()) != 0) {
74 spdlog::error("AppDataXmpPathStrategy::getImagePathFromXmp: Failed to decode XMP packet from file: {}", xmp_path);
75 return {}; // Return an empty string in case of decoding failure
76 }
77
78 // Read the source image path stored in the XMP
79 std::string source_image_path_from_xmp = xmp_data["Xmp.cm.sourceImagePath"].toString(); // Returns an empty string if the key does not exist
80
81 if (source_image_path_from_xmp.empty()) {
82 spdlog::warn("AppDataXmpPathStrategy::getImagePathFromXmp: XMP packet in file '{}' does not contain the 'Xmp.cm.sourceImagePath' key.", xmp_path);
83 } else {
84 spdlog::debug("AppDataXmpPathStrategy::getImagePathFromXmp: Found source image path in XMP: '{}'", source_image_path_from_xmp);
85 }
86
87 return source_image_path_from_xmp;
88
89 } catch (const Exiv2::Error& e) {
90 spdlog::error("Context::AppDataXmpPathStrategy::getImagePathFromXmp: Exiv2 error during parsing XMP file '{}': {}", xmp_path, e.what());
91 return {};
92 } catch (const std::exception& e) {
93 spdlog::error("Context::AppDataXmpPathStrategy::getImagePathFromXmp: General error during parsing XMP file '{}': {}", xmp_path, e.what());
94 return {};
95 }
96}
97
98} // namespace CaptureMoment::Core::Serializer
Declaration of AppDataXmpPathStrategy class.
std::string getXmpPathForImage(std::string_view source_image_path) const override
Calculates the XMP file path associated with a given source image path.
std::string getImagePathFromXmp(std::string_view xmp_path) const override
Calculates the source image path associated with a given XMP file path.
AppDataXmpPathStrategy(const std::string &app_data_dir)
Constructs an AppDataXmpPathStrategy.
CaptureMoment — footer