Skip to content

Commit 412ab63

Browse files
committed
manage XMP sidecar files
1 parent 91396c1 commit 412ab63

File tree

5 files changed

+789
-183
lines changed

5 files changed

+789
-183
lines changed

src/common/exif.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5860,6 +5860,7 @@ gboolean dt_exif_xmp_write(const dt_imgid_t imgid,
58605860
fprintf(fout, "%s", xml_header);
58615861
fprintf(fout, "%s", xmpPacket.c_str());
58625862
fclose(fout);
5863+
dt_diratime_action(filename, "update");
58635864
}
58645865
else
58655866
{

src/control/control.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,90 @@ void dt_control_set_mouse_over_id(const dt_imgid_t imgid)
937937
dt_pthread_mutex_unlock(&dc->global_mutex);
938938
}
939939

940+
time_t dt_diratime_action(const char *dir_path, const char *action)
941+
{
942+
time_t timestamp = 0;
943+
gchar *_dir = g_strdup(dir_path);
944+
size_t name_len = strlen(dir_path);
945+
const char *ext = dir_path + name_len - 4;
946+
if (((!g_strcmp0(action, "update") && (!g_strcmp0(ext, ".xmp") || !g_strcmp0(ext, ".XMP")))
947+
|| !g_strcmp0(action, "delete"))
948+
&& name_len > 4)
949+
{
950+
size_t len = strlen(dir_path);
951+
const char *c = dir_path + len;
952+
while((c > dir_path) && ((*c) != G_DIR_SEPARATOR)) c--;
953+
size_t vers_len = c - dir_path + 1;
954+
g_strlcpy(_dir, dir_path, vers_len + 1);
955+
}
956+
957+
GError *error = NULL;
958+
GFile *_g_dir = g_file_new_for_path(_dir);
959+
GFileInfo *info = g_file_query_info(_g_dir,
960+
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
961+
G_FILE_ATTRIBUTE_STANDARD_TYPE,
962+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
963+
const char *dirname = g_file_info_get_attribute_string(info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
964+
965+
const char *dir_mark = g_strconcat(_dir, dirname, ".dt", NULL);
966+
time_t dir_mark_time = 0;
967+
968+
GFile *_g_dir_mark = g_file_new_for_path(dir_mark);
969+
if (!g_strcmp0(action, "create"))
970+
{
971+
if(!g_file_test(dir_mark, G_FILE_TEST_EXISTS))
972+
{
973+
GFileEnumerator *dir_files = g_file_enumerate_children(_g_dir,
974+
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
975+
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
976+
G_FILE_ATTRIBUTE_STANDARD_TYPE,
977+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
978+
if(dir_files)
979+
{
980+
while((info = g_file_enumerator_next_file(dir_files, NULL, &error)))
981+
{
982+
const char *filename = g_file_info_get_display_name(info);
983+
if(!filename) continue;
984+
const GFileType filetype = g_file_info_get_attribute_uint32(info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
985+
if(filetype == G_FILE_TYPE_REGULAR)
986+
{
987+
name_len = strlen(filename);
988+
ext = filename + name_len - 4;
989+
if ((strcmp(ext, ".xmp") == 0 || strcmp(ext, ".XMP") == 0) && name_len > 4)
990+
{
991+
time_t _timestamp = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
992+
if (_timestamp > dir_mark_time)
993+
dir_mark_time = _timestamp;
994+
}
995+
}
996+
}
997+
}
998+
GFileOutputStream *out = g_file_replace(_g_dir_mark, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);
999+
g_object_unref(out);
1000+
info = g_file_query_info(_g_dir_mark,
1001+
G_FILE_ATTRIBUTE_TIME_MODIFIED,
1002+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
1003+
g_file_set_attribute_uint64(_g_dir_mark, G_FILE_ATTRIBUTE_TIME_MODIFIED, dir_mark_time, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,FALSE,&error);
1004+
g_object_unref(dir_files);
1005+
}
1006+
}
1007+
else if (!g_strcmp0(action, "update") || !g_strcmp0(action, "delete"))
1008+
{
1009+
GFileOutputStream *out = g_file_replace(_g_dir_mark, NULL, FALSE,
1010+
G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);
1011+
g_object_unref(out);
1012+
}
1013+
info = g_file_query_info(_g_dir_mark,
1014+
G_FILE_ATTRIBUTE_TIME_MODIFIED,
1015+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
1016+
timestamp = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
1017+
g_object_unref(info);
1018+
g_object_unref(_g_dir_mark);
1019+
g_object_unref(_g_dir);
1020+
1021+
return timestamp;
1022+
}
1023+
9401024
// clang-format off
9411025
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
9421026
// vim: shiftwidth=2 expandtab tabstop=2 cindent

src/control/control.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ gboolean dt_control_running(void);
260260
dt_imgid_t dt_control_get_mouse_over_id(void);
261261
void dt_control_set_mouse_over_id(const dt_imgid_t value);
262262

263+
/** actions on directory access mark file.
264+
'action' must be one of "create", "update", "delete" */
265+
time_t dt_diratime_action(const char *dir_path, const char *action);
266+
263267
G_END_DECLS
264268

265269
// clang-format off

0 commit comments

Comments
 (0)