[tracker] tracker-search: Added some love



commit dd33b109937c36d908274b8bfce843b587bdda62
Author: Martyn Russell <martyn lanedo com>
Date:   Mon Sep 7 19:59:42 2009 +0100

    tracker-search: Added some love
    
    - Now we have -r to use search terms in OR not AND
    - Now we have options:
      - To list all music files
      - To list all music artists
      - To list all music albums

 src/tracker-utils/tracker-search.c |  392 ++++++++++++++++++++++++++++++-----
 1 files changed, 336 insertions(+), 56 deletions(-)
---
diff --git a/src/tracker-utils/tracker-search.c b/src/tracker-utils/tracker-search.c
index e2d15c0..2427363 100644
--- a/src/tracker-utils/tracker-search.c
+++ b/src/tracker-utils/tracker-search.c
@@ -35,7 +35,11 @@
 static gint	      limit = 512;
 static gint	      offset;
 static gchar	    **terms;
+static gboolean       or_operator;
 static gboolean       detailed;
+static gboolean       music_albums;
+static gboolean       music_artists;
+static gboolean       music_files;
 
 static GOptionEntry   entries[] = {
 	{ "limit", 'l', 0, G_OPTION_ARG_INT, &limit,
@@ -46,8 +50,24 @@ static GOptionEntry   entries[] = {
 	  N_("Offset the results"),
 	  N_("0")
 	},
+	{ "or-operator", 'r', 0, G_OPTION_ARG_NONE, &or_operator,
+	  N_("Use OR for search terms instead of AND (the default)"),
+	  NULL
+	},
 	{ "detailed", 'd', 0, G_OPTION_ARG_NONE, &detailed,
-	  N_("Show more detailed results with service and mime type"),
+	  N_("Show more detailed results (only applies to general search)"),
+	  NULL
+	},
+	{ "music-albums", 'a', 0, G_OPTION_ARG_NONE, &music_albums,
+	  N_("List all music albums"),
+	  NULL
+	},
+	{ "music-artists", 's', 0, G_OPTION_ARG_NONE, &music_artists,
+	  N_("List all music albums"),
+	  NULL
+	},
+	{ "music-files", 'u', 0, G_OPTION_ARG_NONE, &music_files,
+	  N_("List all music files"),
 	  NULL
 	},
 	{ G_OPTION_REMAINING, 0, 0,
@@ -59,19 +79,21 @@ static GOptionEntry   entries[] = {
 };
 
 static void
-get_meta_table_data (gpointer value, gpointer user_data)
+search_results_foreach (gpointer value, 
+			gpointer user_data)
 {
-	gboolean pdetailed = GPOINTER_TO_INT (user_data);
-	gchar **meta;
+	gchar **metadata;
 	gchar **p;
-	gint	i;
+	gboolean detailed;
+	gint i;
 
-	meta = value;
+	metadata = value;
+	detailed = GPOINTER_TO_INT (user_data);
 
-	for (p = meta, i = 0; *p; p++, i++) {
+	for (p = metadata, i = 0; *p; p++, i++) {
 		if (i == 0) {
 			g_print ("  %s", *p);
-		} else if (pdetailed) {
+		} else if (detailed) {
 			g_print (", %s", *p);
 		}
 	}
@@ -79,16 +101,278 @@ get_meta_table_data (gpointer value, gpointer user_data)
 	g_print ("\n");
 }
 
+static void
+get_music_files_foreach (gpointer value,
+			 gpointer user_data)
+{
+	gchar **data = value;
+
+	g_print ("  '%s'\n", data[0]);
+}
+
+static gboolean
+get_music_files (TrackerClient *client,
+		 gint           search_offset,
+		 gint           search_limit)
+{
+	GError *error = NULL;
+	GPtrArray *results;
+	gchar *query;
+
+	query = g_strdup_printf ("SELECT ?song "
+				 "WHERE { "
+				 "  ?song a nmm:MusicPiece "
+				 "}"
+				 "OFFSET %d "
+				 "LIMIT %d",
+				 search_offset, 
+				 search_limit);
+
+	results = tracker_resources_sparql_query (client, query, &error);
+	g_free (query);
+
+	if (error) {
+		g_printerr ("%s, %s\n",
+			    _("Could not get search results"),
+			    error->message);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	if (!results) {
+		g_print ("%s\n",
+			 _("No files were found"));
+	} else {
+		g_print (tracker_dngettext (NULL,
+					    _("Result: %d"), 
+					    _("Results: %d"),
+					    results->len),
+			 results->len);
+		g_print ("\n");
+
+		g_ptr_array_foreach (results, 
+				     get_music_files_foreach, 
+				     NULL);
+		g_ptr_array_free (results, TRUE);
+	}
+
+	return TRUE;
+}
+
+static void
+get_music_artists_foreach (gpointer value,
+			   gpointer user_data)
+{
+	gchar **data = value;
+
+	g_print ("  '%s'\n", data[1]);
+}
+
+static gboolean
+get_music_artists (TrackerClient *client,
+		   gint           search_offset,
+		   gint           search_limit)
+{
+	GError *error = NULL;
+	GPtrArray *results;
+	gchar *query;
+
+	query = g_strdup_printf ("SELECT ?artist ?title "
+				 "WHERE {"
+				 "  ?artist a nmm:Artist ;"
+				 "  nmm:artistName ?title"
+                                 "}"
+				 "GROUP BY ?artist "
+				 "OFFSET %d "
+				 "LIMIT %d",
+				 search_offset, 
+				 search_limit);
+
+	results = tracker_resources_sparql_query (client, query, &error);
+	g_free (query);
+
+	if (error) {
+		g_printerr ("%s, %s\n",
+			    _("Could not get search results"),
+			    error->message);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	if (!results) {
+		g_print ("%s\n",
+			 _("No artists were found"));
+	} else {
+		g_print (tracker_dngettext (NULL,
+					    _("Result: %d"), 
+					    _("Results: %d"),
+					    results->len),
+			 results->len);
+		g_print ("\n");
+
+		g_ptr_array_foreach (results, 
+				     get_music_artists_foreach, 
+				     NULL);
+		g_ptr_array_free (results, TRUE);
+	}
+
+	return TRUE;
+}
+
+static void
+get_music_albums_foreach (gpointer value,
+			  gpointer user_data)
+{
+	gchar **data = value;
+
+	g_print ("  "); /*'%s', ", data[1]);*/
+	g_print (tracker_dngettext (NULL,
+				    _("%d Song"), 
+				    _("%d Songs"),
+				    atoi (data[2])),
+		 atoi (data[2]));
+
+	g_print (", ");
+	g_print (tracker_dngettext (NULL,
+				    _("%d Second"), 
+				    _("%d Seconds"),
+				    atoi (data[3])),
+		 atoi (data[3]));
+	g_print (", ");
+	g_print (_("Album '%s'"), data[1]);
+	g_print ("\n");
+}
+
+static gboolean
+get_music_albums (TrackerClient *client,
+		  gint           search_offset,
+		  gint           search_limit)
+{
+	GError *error = NULL;
+	GPtrArray *results;
+	gchar *query;
+
+	query = g_strdup_printf ("SELECT ?album ?title COUNT(?song) "
+				 "AS songs "
+				 "SUM(?length) AS totallength "
+				 "WHERE {"
+				 "  ?album a nmm:MusicAlbum ;"
+				 "  nie:title ?title ."
+				 "  ?song nmm:musicAlbum ?album ;"
+				 "  nmm:length ?length"
+                                 "}"
+				 "GROUP BY ?album "
+				 "OFFSET %d "
+				 "LIMIT %d",
+				 search_offset, 
+				 search_limit);
+
+	results = tracker_resources_sparql_query (client, query, &error);
+	g_free (query);
+
+	if (error) {
+		g_printerr ("%s, %s\n",
+			    _("Could not get search results"),
+			    error->message);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	if (!results) {
+		g_print ("%s\n",
+			 _("No music was found"));
+	} else {
+		g_print (tracker_dngettext (NULL,
+					    _("Result: %d"), 
+					    _("Results: %d"),
+					    results->len),
+			 results->len);
+		g_print ("\n");
+
+		g_ptr_array_foreach (results, 
+				     get_music_albums_foreach, 
+				     NULL);
+		g_ptr_array_free (results, TRUE);
+	}
+
+	return TRUE;
+}
+
+static gboolean
+get_all_by_search (TrackerClient *client, 
+		   GStrv          search_words,
+		   gint           search_offset,
+		   gint           search_limit,
+		   gboolean       use_or_operator,
+		   gboolean       detailed_results)
+{
+	GError *error = NULL;
+	GPtrArray *results;
+	gchar *search_words_joined;
+	gchar *query;
+
+	if (use_or_operator) {
+		search_words_joined = g_strjoinv (" OR ", search_words);
+	} else {
+		search_words_joined = g_strjoinv (" ", search_words);
+	}
+
+	if (detailed_results) {
+		query = g_strdup_printf ("SELECT ?s ?type ?mimeType WHERE { ?s fts:match \"%s\" ; rdf:type ?type . "
+					 "OPTIONAL { ?s nie:mimeType ?mimeType } } OFFSET %d LIMIT %d",
+					 search_words_joined, 
+					 search_offset, 
+					 search_limit);
+	} else {
+		query = g_strdup_printf ("SELECT ?s WHERE { ?s fts:match \"%s\" } OFFSET %d LIMIT %d",
+					 search_words_joined, 
+					 search_offset, 
+					 search_limit);
+	}
+
+	g_free (search_words_joined);
+
+	results = tracker_resources_sparql_query (client, query, &error);
+	g_free (query);
+
+	if (error) {
+		g_printerr ("%s, %s\n",
+			    _("Could not get search results"),
+			    error->message);
+		g_error_free (error);
+
+		return FALSE;
+	}
+
+	if (!results) {
+		g_print ("%s\n",
+			 _("No results were found matching your query"));
+	} else {
+		g_print (tracker_dngettext (NULL,
+					    _("Result: %d"), 
+					    _("Results: %d"),
+					    results->len),
+			 results->len);
+		g_print ("\n");
+
+		g_ptr_array_foreach (results, 
+				     search_results_foreach, 
+				     GINT_TO_POINTER (detailed_results));
+		g_ptr_array_free (results, TRUE);
+	}
+
+	return TRUE;
+}
 
 int
 main (int argc, char **argv)
 {
-	TrackerClient	*client;
-	GOptionContext	*context;
-	GError		*error = NULL;
-	gchar		*search, *temp, *query;
-	gchar		*summary;
-	GPtrArray	*array;
+	TrackerClient *client;
+	GOptionContext *context;
+	gchar *summary;
 
 	setlocale (LC_ALL, "");
 
@@ -96,25 +380,29 @@ main (int argc, char **argv)
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
-	/* Translators: this messagge will apper immediately after the	*/
-	/* usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE>	*/
-	context = g_option_context_new (_("- Search files for certain terms"));
+	/* Translators: this messagge will apper immediately after the
+	 * usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE>
+	 */
+	context = g_option_context_new (_("- Search for terms in all data"));
 
-	/* Translators: this message will appear after the usage string */
-	/* and before the list of options.				*/
-	summary = g_strconcat (_("Specifying multiple terms apply an AND "
-				 "operator to the search performed"),
+	/* Translators: this message will appear after the usage string
+	 * and before the list of options.
+	 */
+	summary = g_strconcat (_("Applies an AND operator to all terms separated "
+				 "by a space (see --or-operator)"),
+			       "\n",
 			       "\n",
 			       _("This means if you search for 'foo' and 'bar', "
-				 "they must BOTH exist"),
+				 "they must BOTH exist (unless you use --or-operator)"),
 			       NULL);
 	g_option_context_set_summary (context, summary);
 	g_option_context_add_main_entries (context, entries, NULL);
 	g_option_context_parse (context, &argc, &argv, NULL);
 
 	g_free (summary);
-
-	if (!terms) {
+	
+	if (!music_albums && !music_artists && !music_files &&
+	    !terms) {
 		gchar *help;
 
 		g_printerr ("%s\n\n",
@@ -142,49 +430,41 @@ main (int argc, char **argv)
 		limit = 512;
 	}
 
-	temp = g_strjoinv (" ", terms);
-	search = g_strdup (temp); /* replace with escape function */
-	g_free (temp);
+	if (music_albums) {
+		gboolean success;
 
-	if (detailed) {
-		query = g_strdup_printf ("SELECT ?s ?type ?mimeType WHERE { ?s fts:match \"%s\" ; rdf:type ?type . "
-					 "OPTIONAL { ?s nie:mimeType ?mimeType } } OFFSET %d LIMIT %d",
-					 search, offset, limit);
-	} else {
-		query = g_strdup_printf ("SELECT ?s WHERE { ?s fts:match \"%s\" } OFFSET %d LIMIT %d",
-					 search, offset, limit);
+		success = get_music_albums (client, offset, limit);
+		tracker_disconnect (client);
+
+		return success ? EXIT_SUCCESS : EXIT_FAILURE;
 	}
 
-	array = tracker_resources_sparql_query (client, query, &error);
+	if (music_artists) {
+		gboolean success;
 
-	g_free (search);
+		success = get_music_artists (client, offset, limit);
+		tracker_disconnect (client);
 
-	if (error) {
-		g_printerr ("%s, %s\n",
-			    _("Could not get find detailed results by text"),
-			    error->message);
+		return success ? EXIT_SUCCESS : EXIT_FAILURE;
+	}
 
-		g_error_free (error);
+	if (music_files) {
+		gboolean success;
+
+		success = get_music_files (client, offset, limit);
 		tracker_disconnect (client);
 
-		return EXIT_FAILURE;
+		return success ? EXIT_SUCCESS : EXIT_FAILURE;
 	}
 
-	if (!array) {
-		g_print ("%s\n",
-			 _("No results found matching your query"));
-	} else {
-		g_print (tracker_dngettext (NULL,
-					    _("Result: %d"), 
-					    _("Results: %d"),
-					    array->len),
-			 array->len);
-		g_print ("\n");
-			g_ptr_array_foreach (array, get_meta_table_data, 
-					     GINT_TO_POINTER (detailed));
-		g_ptr_array_free (array, TRUE);
+	if (terms) {
+		gboolean success;
+		
+		success = get_all_by_search (client, terms, offset, limit, or_operator, detailed);
+		tracker_disconnect (client);
+
+		return success ? EXIT_SUCCESS : EXIT_FAILURE;
 	}
 
-	tracker_disconnect (client);
 	return EXIT_SUCCESS;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]