Hey everyone,

tracker-tag and friends were starting to bother me because of their
non-standard options usage; most didn't even have a --help option.
I've patched tracker-tag to use GOptions, which offers the following
benefits: 1) it automatically converts filenames from locale to utf8,
and 2) automatically provides useful help output. This patch also adds
support for tagging multiple files at once, like so:

tracker-tag -a music -a radiohead -r bad music/radiohead/*

which would tag all files in music/radiohead/ with "music" and
"radiohead", and remove any instances of "bad." I know that these
command line utilities aren't really meant to be used for day-to-day
stuff (eventually we'll have a bling-ful barracuda :-P), but I don't
think that means the CLI tools should be left out. Anyways, if this is
useful, let me know and I can patch the other tools too.

Cheers,
Samuel Cormier-Iijima
Index: src/libtracker/tracker-tag.c
===================================================================
RCS file: /cvs/gnome/tracker/src/libtracker/tracker-tag.c,v
retrieving revision 1.7
diff -u -r1.7 tracker-tag.c
--- src/libtracker/tracker-tag.c	2 Sep 2006 18:20:11 -0000	1.7
+++ src/libtracker/tracker-tag.c	10 Sep 2006 17:43:28 -0000
@@ -18,312 +18,200 @@
  */
 
 #include <locale.h>
-#include <sys/param.h>
 #include <stdlib.h>
-#include <string.h>
 #include <glib.h>
-#include <glib-object.h>
 
 #include "../libtracker/tracker.h" 
 
-#define USAGE "usage: \ntracker-tag\t\t\t\t: Gets stats for all tags\ntracker-tag -a File Tag1 [Tag2...]\t: Add Tags to File\ntracker-tag -l File \t\t\t: List all tags on a File\ntracker-tag -r File Tag1 [Tag2...] \t: Remove Tags from File\ntracker-tag -R File  \t\t\t: Remove all tags from File\ntracker-tag -s Tag1 [Tag2...] \t\t: Search files for specified tags. Multiple tags are always ANDed in the search\n"
+static gchar **add = NULL;
+static gchar **delete = NULL;
+static gchar **search = NULL;
+static gchar **files = NULL;
+static gboolean remove_all = FALSE;
+static gboolean list = FALSE;
+
+static GOptionEntry entries[] = {
+	{"add", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &add, "add tags to a file", "tag"},
+	{"remove", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &delete, "remove tags from a file", "tag"},
+	{"remove-all", 'R', 0, G_OPTION_ARG_NONE, &remove_all, "remove all tags from  a file", NULL},
+	{"list", 'l', 0, G_OPTION_ARG_NONE, &list, "list tags", NULL},
+	{"search", 's', 0, G_OPTION_ARG_STRING_ARRAY, &search, "search for files with tags", "tag"},
+	{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &files, "files to tag", NULL},
+	{NULL}
+};
 
 
-/*
-
-tracker-tag -a File Tags\t\t: Add Tags to File\n
-tracker-tag -l File \t\t: List all tags on a File\n
-tracker-tag -r File Tags \t\t: Remove Tags from File\n
-tracker-tag -R File  \t\t: Remove all tags from File\n
-tracker-tag -s Tags  \t\t: Search files for specified tags\n
-*/
-
-static char *
-realpath_in_utf8 (const char *path)
-{
-	char *str_path_tmp = NULL, *str_path = NULL;
-
-	str_path_tmp = realpath (path, NULL);
-
-	if (str_path_tmp) {
-		str_path = g_filename_to_utf8 (str_path_tmp, -1, NULL, NULL, NULL);
-
-		g_free (str_path_tmp);
-	}
-
-	if (!str_path) {
-		g_warning ("realpath_in_utf8(): locale to UTF8 failed!");
-		return NULL;
-	}
-
-	return str_path;
-}
-
 static void
-get_meta_table_data (gpointer key,
-   		     gpointer value,
-		     gpointer user_data)
+get_meta_table_data (gpointer key, gpointer value, gpointer user_data)
 {
-
-	char **meta, **meta_p;
+	char **meta;
+	int i;
 
 	if (!G_VALUE_HOLDS (value, G_TYPE_STRV)) {
-		g_warning ("fatal communication error\n");
+		g_warning ("fatal communication error");
 		return;
 	}
 
-
 	g_print ("%s ", (char *) key);
 
 	meta = g_value_get_boxed (value);
 
-	for (meta_p = meta; *meta_p; meta_p++) {
-		g_print ("(%s)", *meta_p);
-	}
+	for (i = 0; meta[i] != NULL; i++)
+		g_print ("(%s)", meta[i]);
+
 	g_print ("\n");
 }
 
-
 int 
 main (int argc, char **argv) 
 {
-
 	TrackerClient *client = NULL;
-
+	GOptionContext *context = NULL;
+	GError *error = NULL;
 
 	setlocale (LC_ALL, "");
 
-	client =  tracker_connect (FALSE);
+	context = g_option_context_new ("file1 file2 ... - manipulate tags on files");
+	g_option_context_add_main_entries (context, entries, NULL);
+	g_option_context_parse (context, &argc, &argv, &error);
 
-	if (!client) {
-		g_print ("Could not initialise Tracker - exiting...\n");
+	if (error) {
+		g_printerr ("%s\n", error->message);
 		return 1;
 	}
 
-	if  (argc == 1) {
+	if (((add || delete || remove_all) && !files) || (remove_all && (add || delete)) || (search && files)) {
+		g_printerr ("invalid arguments\n");
+		return 1;
+	}
 
-		GHashTable *table = NULL;
-		GError *error = NULL;
 
-		table =	tracker_keywords_get_list (client, SERVICE_FILES, &error);
-		
-		if (error) {
-			g_warning ("An error has occured : %s", error->message);
-			g_error_free (error);
-			return 1;
-		}
+	client = tracker_connect (FALSE);
 
-		if (table) {
-			g_hash_table_foreach (table, get_meta_table_data, NULL);
-			g_hash_table_destroy (table);	
-		}
+	if (!client) {
+		g_printerr ("could not initialise Tracker\n");
+		return 1;
+	}
 
-	} else 	if (strcmp (argv[1], "-a") == 0) {
 
-		if (argc < 4) {
-			g_print (USAGE);
-			return 1;
-		} else {
-
-			int i;
-			char **tags;
-			char *str_path = NULL;
-			GError *error = NULL;
+	if (add || delete || remove_all) {
 
-			str_path = realpath_in_utf8 (argv[2]);
+		int i = 0;
 
-			if (!str_path) {
-				return 1;
+		if (add)
+			for (i = 0; add[i] != NULL; i++) {
+				gchar *tmp = g_locale_to_utf8 (add[i], -1, NULL, NULL, NULL);
+				g_free (add[i]);
+				add[i] = tmp;
 			}
 
-			tags = g_new (char *, (argc-2));
-
-			for (i=0; i < (argc-3); i++) {
-				tags[i] = g_locale_to_utf8 (argv[i+3], -1, NULL, NULL, NULL);
-				g_print ("adding tag %s to %s\n", tags[i], str_path);
+		if (delete)
+			for (i = 0; delete[i] != NULL; i++) {
+				gchar *tmp = g_locale_to_utf8 (delete[i], -1, NULL, NULL, NULL);
+				g_free (delete[i]);
+				delete[i] = tmp;
 			}
-			tags[argc-3] = NULL;
-
-
-			tracker_keywords_add (client,  SERVICE_FILES, str_path, tags, &error);
 
-			g_free (str_path);
 
-			if (error) {
-				g_warning ("An error has occured : %s\n", error->message);
-				g_error_free (error);
-				return 1;
-			} else {
-				char *dir = NULL;
+		for (i = 0; files[i] != NULL; i++) {
 
-				dir = g_filename_to_utf8 (argv[2], -1, NULL, NULL, NULL);
+			if (remove_all) {
+				tracker_keywords_remove_all (client, SERVICE_FILES, files[i], &error);
 
-				g_print ("All tags added to %s\n", dir);
-
-				g_free (dir);
+				if (error)
+					g_printerr ("tracker threw error: %s\n", error->message);
 			}
 
-			g_strfreev (tags);
-		}
-
-	} else if (strcmp (argv[1], "-l") == 0)  {
+			if (add) {
+				tracker_keywords_add (client, SERVICE_FILES, files[i], add, &error);
 
-		if (argc != 3) {
-			g_print (USAGE);
-			return 1;
-		} else {
-			
-			char **tags = NULL;
-			char *str_path = NULL;
-			GError *error = NULL;
+				if (error)
+					g_printerr ("tracker threw error: %s\n", error->message);
+			}
 
-			str_path = realpath_in_utf8 (argv[2]);
+			if (delete) {
+				tracker_keywords_remove (client, SERVICE_FILES, files[i], delete, &error);
 
-			if (!str_path) {
-				return 1;
+				if (error)
+					g_printerr ("tracker threw error: %s\n", error->message);
 			}
 
-			tags = tracker_keywords_get (client, SERVICE_FILES, str_path, &error);
+		}
 
-			g_free (str_path);
+	}
 
-			if (error) {
-				g_warning ("An error has occured : %s", error->message);
-				g_error_free (error);
-				return 1;
-			}
+	if (list && !files) {
 
-			if (!tags) {
-				g_print ("no results were found matching your query\n");
-				return 1;
-			}
+		GHashTable *table = NULL;
 
-			char **p_strarray;
+		table =	tracker_keywords_get_list (client, SERVICE_FILES, &error);
 
-			for (p_strarray = tags; *p_strarray; p_strarray++) {
-				g_print ("%s\n", *p_strarray);
-			}
+		if (error)
+			goto error;
 
-			g_strfreev (tags);
+		if (table) {
+			g_hash_table_foreach (table, get_meta_table_data, NULL);
+			g_hash_table_destroy (table);	
 		}
 
-	} else if (strcmp (argv[1], "-r") == 0)  {
-
-		if (argc < 4) {
-			g_print (USAGE);
-			return 1;
-	
-		} else {
-
-			int i;
-			char **tags;
-			char *str_path = NULL;
-			GError *error = NULL;
+	}
 
-			str_path = realpath_in_utf8 (argv[2]);
+	if (list && files) {
+			
+		int i = 0;
 
-			if (!str_path) {
-				return 1;
-			}
+		for (i = 0; files[i] != NULL; i++) {
 
-			tags = g_new (char *, (argc-2));
+			int j = 0;
+			gchar **tags = tracker_keywords_get (client, SERVICE_FILES, files[i], &error);
 
-			for (i=0; i < (argc-3); i++) {
-				tags[i] = g_locale_to_utf8 (argv[i+3], -1, NULL, NULL, NULL);
-			}
-			tags[argc-3] = NULL;
+			if (error)
+				g_printerr ("tracker threw error: %s\n", error->message);
 
-			tracker_keywords_remove (client,  SERVICE_FILES, str_path, tags, &error);
+			if (!tags)
+				continue;
 
-			g_free (str_path);
+			g_print ("%s:", files[i]);
+			for (j = 0; tags[j] != NULL; j++)
+				g_print (" %s", tags[j]);
+			g_print ("\n");
 
 			g_strfreev (tags);
 
-			if (error) {
-				g_warning ("An error has occured : %s", error->message);
-				g_error_free (error);
-				return 1;
-			}
 		}
 
-	} else if (strcmp (argv[1], "-R") == 0)  {
-
-		if (argc != 3) {
-			g_print (USAGE);
-			return 1;
-	
-		} else {
-
-			char *str_path = NULL;
-			GError *error = NULL;
-
-			str_path = realpath_in_utf8 (argv[2]);
-
-			if (!str_path) {
-				return 1;
-			}
+	}
 
-			tracker_keywords_remove_all (client,  SERVICE_FILES, str_path, &error);
+	if (search) {
 
-			g_free (str_path);
+		int i = 0;
 
-			if (error) {
-				g_warning ("An error has occured : %s", error->message);
-				g_error_free (error);
-				return 1;
-			}
+		for (i = 0; search[i] != NULL; i++) {
+			gchar *tmp = g_locale_to_utf8 (search[i], -1, NULL, NULL, NULL);
+			g_free (search[i]);
+			search[i] = tmp;
 		}
 
-	} else if (strcmp (argv[1], "-s") == 0)  {
-
-		if (argc < 3) {
-			g_print (USAGE);
-			return 1;
-	
-		} else {
-
-			int i;
-			char **tags;
-			GError *error = NULL;
-
-			tags = g_new (char *, (argc-1));
-
-			for (i=0; i < (argc-2); i++) {
-				tags[i] = g_locale_to_utf8 (argv[i+2], -1, NULL, NULL, NULL);
-			}
-			tags[argc-2] = NULL;
-
-			char **results = tracker_keywords_search (client, -1, SERVICE_FILES, tags, 0, 512, &error);
-
-			g_strfreev (tags);
-
-			if (error) {
-				g_warning ("An error has occured : %s", error->message);
-				g_error_free (error);
-				return 1;
-			}
+		gchar **results = tracker_keywords_search (client, -1, SERVICE_FILES, search, 0, 512, &error);
 
-			if (!results) {
-				g_print ("no results were found matching your query\n");
-				return 1;
-			}
+		if (error)
+			goto error;
 
-			char **p_strarray;
+		if (!results)
+			g_print ("no results found matching your query\n");
+		else
+			for (i = 0; results[i] != NULL; i++)
+				g_print ("%s\n", results[i]);
 
-			for (p_strarray = results; *p_strarray; p_strarray++) {
-				g_print ("%s\n", *p_strarray);
-			}
-
-			g_strfreev (results);
-		}
+		g_strfreev (results);
 
-	} else {
-		g_print (USAGE);
-		return 1;
 	}
 
-
 	tracker_disconnect (client);
-
 	return 0;
+
+error:
+	g_printerr ("tracker threw error: %s\n", error->message);
+	tracker_disconnect (client);
+	return 1;	
 }
_______________________________________________
tracker-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/tracker-list

Reply via email to