[gegl] bin: add commandline interactions for setting/querying metadata
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] bin: add commandline interactions for setting/querying metadata
- Date: Wed, 24 Apr 2019 23:46:06 +0000 (UTC)
commit b1946b66afa44492941235f89c72d260591819d9
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Apr 24 23:38:25 2019 +0200
bin: add commandline interactions for setting/querying metadata
In collection view mode, the command foo=bar sets the key on the file foo to
bar, while foo@bar sets the attribute, which is associated with the entry in
the folder (which follows the file - but multiple entries can share a file).
The command info which in editing mode provides information about the selected
node now prints out the meta data associated with the selected file.
bin/ui-core.c | 320 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
bin/ui.h | 14 ++-
2 files changed, 291 insertions(+), 43 deletions(-)
---
diff --git a/bin/ui-core.c b/bin/ui-core.c
index 9e067e896..54c0c48cd 100644
--- a/bin/ui-core.c
+++ b/bin/ui-core.c
@@ -3739,6 +3739,26 @@ static GeglNode *node_find_by_id (GeState *o, GeglNode *iter,
return NULL;
}
+static char *get_item_path (GeState *o)
+{
+ char *path = NULL;
+ if (o->is_dir)
+ {
+ path = meta_child_no_path (o, NULL, o->entry_no);
+ if (g_file_test (path, G_FILE_TEST_IS_DIR))
+ {
+ g_free (path);
+ path = NULL;
+ }
+ }
+ else
+ {
+ path = g_strdup (o->path);
+ }
+ return path;
+}
+
+
void
ui_run_command (MrgEvent *event, void *data1, void *data_2)
{
@@ -3775,8 +3795,37 @@ ui_run_command (MrgEvent *event, void *data1, void *data_2)
{
- if (strchr (*arg, '='))
+ if (strstr (*arg, "@") && o->is_dir)
+ {
+ char *path = get_item_path (o);
+ char *key = g_strdup (*arg);
+ char *value = strstr (key, "@") + 1;
+ value[-1]='\0';
+
+ meta_set_attribute (o, NULL, o->entry_no, key, value[0]==0?NULL:value);
+
+ g_free (key);
+ g_free (path);
+ }
+ else if (strchr (*arg, '='))
{
+ if (o->is_dir)
+ {
+ char *path = get_item_path (o);
+ if (path)
+ {
+ char *key = g_strdup (*arg);
+ char *value = strchr (key, '=') + 1;
+ value[-1]='\0';
+
+ meta_set_key (o, path, key, value[0]==0?NULL:value);
+
+ g_free (key);
+ g_free (path);
+ }
+ }
+ else
+ {
GType target_type = 0;
GParamSpec *pspec = NULL;
GParamSpec **pspecs = NULL;
@@ -3996,6 +4045,7 @@ ui_run_command (MrgEvent *event, void *data1, void *data_2)
}
}
g_free (key);
+ }
}
else
{
@@ -5488,6 +5538,7 @@ static void load_path_inner (GeState *o,
g_free (foo);
}
+
if (is_xml_fragment (meta))
o->gegl = gegl_node_new_from_xml (meta, containing_path);
else
@@ -6398,6 +6449,7 @@ cmd_node_defaults (COMMAND_ARGS)
+
int cmd_info (COMMAND_ARGS); /* "info", 0, "", "dump information about active node"*/
int
@@ -6408,6 +6460,36 @@ cmd_info (COMMAND_ARGS)
GeglOperation *operation;
GeglRectangle extent;
+ if (o->is_dir)
+ {
+ char *path = get_item_path (o);
+ char **attributes = NULL;
+ char **keys = NULL;
+ if (!path)
+ return -1;
+
+ attributes = meta_list_attributes (o, path, o->entry_no);
+ for (char **a = attributes; a && *a; a++)
+ {
+ const char *value = meta_get_attribute (o, path, o->entry_no, *a);
+ printf ("%s@%s\n", *a, value);
+ }
+ if (attributes) g_free (attributes);
+
+ keys = meta_list_keys (o, path);
+ for (char **a = keys; a && *a; a++)
+ {
+ const char *value = meta_get_key (o, path, *a);
+ printf ("%s=%s\n", *a, value);
+ }
+ if (keys) g_free (keys);
+ printf ("\n");
+
+ g_free (path);
+
+ return 0;
+ }
+
if (!node)
{
printf ("no active node\n");
@@ -6563,25 +6645,6 @@ cmd_toggle (COMMAND_ARGS)
return 0;
}
-static char *get_item_path (GeState *o)
-{
- char *path = NULL;
- if (o->is_dir)
- {
- path = meta_child_no_path (o, NULL, o->entry_no);
- if (g_file_test (path, G_FILE_TEST_IS_DIR))
- {
- g_free (path);
- path = NULL;
- }
- }
- else
- {
- path = g_strdup (o->path);
- }
- return path;
-}
-
char *get_item_dir (GeState *o)
{
char *path = NULL;
@@ -7655,12 +7718,68 @@ cmd_todo (COMMAND_ARGS)
return 0;
}
+static void
+_meta_unset_key (GeState *state,const char *path, const char *key)
+{
+ gchar *metadata_path = ui_get_metadata_path (path);
+ gchar *contents = NULL;
+
+ g_file_get_contents (metadata_path, &contents, NULL, NULL);
+ if (contents)
+ {
+ char *line = contents;
+
+ while (*line)
+ {
+ if (0==memcmp (line, key, strlen (key)) &&
+ line[strlen(key)]=='=')
+ {
+ char *start = &line[strlen(key)+1];
+ char *end = start;
+
+ for (end = start; *end != '\n' && *end != '\0'; end++);
+ if (*end == 0)
+ {
+ *line = 0;
+ }
+ else
+ {
+ memmove (line, end + 1, strlen (end));
+ }
+ goto prepped;
+ }
+
+ while (*line && *line != '\n')
+ {
+ line++;
+ }
+ if (*line == '\n')
+ line++;
+ }
+
+ prepped:
+ g_file_set_contents (metadata_path, contents, -1, NULL);
+
+ g_free (contents);
+ }
+
+ g_free (metadata_path);
+}
+
void
meta_set_key (GeState *state,const char *path, const char *key, const char *value)
{
- gchar *metadata_path = ui_get_metadata_path (path);
+ gchar *metadata_path;
gchar *contents = NULL;
char *alloc_value = NULL;
+
+ if (value == NULL)
+ {
+ _meta_unset_key (state, path, key);
+ return;
+ }
+
+ metadata_path = ui_get_metadata_path (path);
if (strchr (value, '\n'))
{
const char *src;
@@ -7734,8 +7853,6 @@ meta_set_key (GeState *state,const char *path, const char *key, const char *valu
g_mkdir_with_parents (dirname, 0777);
g_free (dirname);
-
- fprintf (stderr, "%s!%s!!!\n\n", metadata_path, str);
g_file_set_contents (metadata_path, str, -1, NULL);
g_free (str);
}
@@ -7772,7 +7889,6 @@ store_index (GeState *state, const char *path)
struct stat stat_buf;
char *dirname;
char *index_path = NULL;
- fprintf (stderr, "!%s %s\n", path, state->path);
lstat (path, &stat_buf);
if (S_ISREG (stat_buf.st_mode))
{
@@ -8086,6 +8202,35 @@ meta_swap_children (GeState *o,const char *path,
o->index_dirty ++;
}
+static void
+_meta_unset_attribute (GeState *state,
+ const char *path,
+ int value_no,
+ const char *attribute)
+{
+ GList *iter;
+ int no;
+ for (iter = state->index, no = 0; iter; iter=iter->next, no++)
+ {
+ IndexItem *item = iter->data;
+ if (no == value_no)
+ {
+ for (int ano = 0; ano < INDEX_MAX_ATTRIBUTES; ano++)
+ {
+ if (item->attribute[ano] && !strcmp (item->attribute[ano], attribute))
+ {
+ g_free (item->attribute[ano]);
+ item->attribute[ano] = NULL;
+ if (item->detail[ano])
+ g_free (item->detail[ano]);
+ item->detail[ano] = NULL;
+ state->index_dirty ++;
+ }
+ }
+ }
+ }
+}
+
void
meta_set_attribute (GeState *state,
@@ -8097,7 +8242,12 @@ meta_set_attribute (GeState *state,
{
GList *iter;
int no;
- fprintf (stderr, "----%s %i %s %s\n", path, value_no, attribute, detail);
+ if (detail == NULL)
+ {
+ _meta_unset_attribute (state, path, value_no, attribute);
+ return;
+ }
+
for (iter = state->index, no = 0; iter; iter=iter->next, no++)
{
IndexItem *item = iter->data;
@@ -8171,6 +8321,8 @@ meta_get_attribute (GeState *state,
return NULL;
}
+
+
int
meta_has_attribute (GeState *state,
const char *path,
@@ -8196,35 +8348,127 @@ meta_has_attribute (GeState *state,
return 0;
}
-void
-meta_unset_attribute (GeState *state,
+char **
+meta_list_keys (GeState *state,
+ const char *path)
+{
+ int count = 0;
+ int tot_len = 0;
+ int array_byte_size = 0;
+ char **pasp = NULL;
+ char *pasp_data = NULL;
+ gchar *metadata_path = ui_get_metadata_path (path);
+ gchar *contents = NULL;
+ g_file_get_contents (metadata_path, &contents, NULL, NULL);
+ if (contents)
+ {
+ char *line = contents;
+ while (*line)
+ {
+ if (strchr (line, '='))
+ {
+ char *key = g_strdup (line);
+ count++;
+ *strchr (key, '=') = 0;
+ tot_len += strlen (key);
+ g_free (key);
+ }
+
+ while (*line && *line != '\n')
+ {
+ line++;
+ }
+ if (*line == '\n')
+ line++;
+ }
+
+ array_byte_size = (count + 1) * sizeof (char *);
+ pasp = g_malloc0 ( array_byte_size + count + tot_len);
+ pasp_data = &(((char*)(pasp))[array_byte_size]);
+ count = 0;
+
+ line = contents;
+ while (*line)
+ {
+ if (strchr (line, '='))
+ {
+ char *key = g_strdup (line);
+ *strchr (key, '=') = 0;
+
+ pasp[count++] = pasp_data;
+ strcpy (pasp_data, key);
+ pasp_data += strlen (key) + 1;
+
+ g_free (key);
+ }
+
+ while (*line && *line != '\n')
+ {
+ line++;
+ }
+ if (*line == '\n')
+ line++;
+ }
+
+ g_free (contents);
+ }
+ return pasp;
+}
+
+char **
+meta_list_attributes (GeState *state,
const char *path,
- int value_no,
- const char *attribute)
+ int item_no)
{
GList *iter;
+ int count = 0;
+ int tot_len = 0;
int no;
+ int array_byte_size = 0;
+ char **pasp = NULL;
+ char *pasp_data = NULL;
+
for (iter = state->index, no = 0; iter; iter=iter->next, no++)
{
IndexItem *item = iter->data;
- if (no == value_no)
+ if (no == item_no)
+ for (int ano = 0; ano < INDEX_MAX_ATTRIBUTES; ano++)
{
+ if (item->attribute[ano])
+ {
+ count++;
+ tot_len += strlen (item->attribute[ano]);
+ }
+ }
+ }
+
+ if (count == 0)
+ return NULL;
+
+ array_byte_size = (count + 1) * sizeof (char *);
+ pasp = g_malloc0 ( array_byte_size + count + tot_len);
+ pasp_data = &(((char*)(pasp))[array_byte_size]);
+ no = 0;
+ count = 0;
+
+ for (iter = state->index, no = 0; iter; iter=iter->next, no++)
+ {
+ IndexItem *item = iter->data;
+ if (no == item_no)
for (int ano = 0; ano < INDEX_MAX_ATTRIBUTES; ano++)
{
- if (item->attribute[ano] && !strcmp (item->attribute[ano], attribute))
+ if (item->attribute[ano])
{
- g_free (item->attribute[ano]);
- item->attribute[ano] = NULL;
- if (item->detail[ano])
- g_free (item->detail[ano]);
- item->detail[ano] = NULL;
- state->index_dirty ++;
+ pasp[count] = pasp_data;
+ strcpy (pasp[count++], item->attribute[ano]);
+ pasp_data += strlen (item->attribute[ano]) + 1;
}
}
- }
}
+ return pasp;
}
+
#if 1
static int
index_contains (GeState *state,
diff --git a/bin/ui.h b/bin/ui.h
index bdde74eaa..1815f7f15 100644
--- a/bin/ui.h
+++ b/bin/ui.h
@@ -175,6 +175,10 @@ void meta_set_key (GeState *state,
const char *key,
const char *value);
+void meta_unset_key (GeState *state,
+ const char *path,
+ const char *key);
+
const char *meta_get_key (GeState *state, const char *path, const char *key);
void meta_set_key_int (GeState *state, const char *path, const char *key, int value);
@@ -182,6 +186,9 @@ int meta_get_key_int (GeState *state, const char *path, const char *k
void meta_set_key_float (GeState *state, const char *path, const char *key, float value);
float meta_get_key_float (GeState *state, const char *path, const char *key);
+char **meta_list_keys (GeState *state, const char *path);
+char **meta_list_attributes (GeState *state, const char *path, int item_no);
+
int
meta_get_attribute_int (GeState *state,
const char *path,
@@ -218,6 +225,8 @@ meta_set_attribute_int (GeState *state,
* the display order should be a second list of
*/
+/* passing NULL for detail unsets the attribute
+ */
void
meta_set_attribute (GeState *state,
const char *path,
@@ -234,11 +243,6 @@ meta_has_attribute (GeState *state,
const char *path,
int child_no,
const char *attribute);
-void
-meta_unset_attribute (GeState *state,
- const char *path,
- int child_no,
- const char *attribute);
/* for now - not supporting multivalue on attribute/details */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]