[tracker/collation-gconf-locale: 11/13] tracker-miner-applications: Re-extract desktop files when locale change detected



commit 0072638b6ce5045bf2e8e79618b683d4c8b54067
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Tue Nov 16 17:09:36 2010 +0100

    tracker-miner-applications: Re-extract desktop files when locale change detected

 src/miners/fs/Makefile.am                          |    2 +
 src/miners/fs/tracker-miner-applications-locale.c  |  137 ++++++++++++++++
 src/miners/fs/tracker-miner-applications-locale.h  |   29 ++++
 src/miners/fs/tracker-miner-applications-meego.cpp |   17 ++-
 src/miners/fs/tracker-miner-applications-meego.h   |    6 +-
 src/miners/fs/tracker-miner-applications.c         |  171 +++++++++++++++++---
 6 files changed, 333 insertions(+), 29 deletions(-)
---
diff --git a/src/miners/fs/Makefile.am b/src/miners/fs/Makefile.am
index 5cc14ba..9e2644d 100644
--- a/src/miners/fs/Makefile.am
+++ b/src/miners/fs/Makefile.am
@@ -19,6 +19,8 @@ tracker_miner_fs_SOURCES =                             \
 	tracker-main.c                                 \
 	tracker-miner-applications.c                   \
 	tracker-miner-applications.h                   \
+	tracker-miner-applications-locale.c            \
+	tracker-miner-applications-locale.h            \
 	tracker-miner-files.c                          \
 	tracker-miner-files.h                          \
 	tracker-miner-files-index.c                    \
diff --git a/src/miners/fs/tracker-miner-applications-locale.c b/src/miners/fs/tracker-miner-applications-locale.c
new file mode 100644
index 0000000..39c537c
--- /dev/null
+++ b/src/miners/fs/tracker-miner-applications-locale.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2010 Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+#include <string.h>
+
+#include <libtracker-common/tracker-locale.h>
+
+#include "tracker-miner-applications-locale.h"
+#ifdef HAVE_MEEGOTOUCH
+#include "tracker-miner-applications-meego.h"
+#endif
+
+#define TRACKER_MINER_APPLICATIONS_LOCALE_FILE "miner-applications-locale.txt"
+
+static gchar *
+miner_applications_locale_get_previous (const gchar *locale_file)
+{
+	gchar *locale = NULL;
+
+	if (G_LIKELY (g_file_test (locale_file, G_FILE_TEST_EXISTS))) {
+		gchar *contents;
+
+		/* Check locale is correct */
+		if (G_LIKELY (g_file_get_contents (locale_file, &contents, NULL, NULL))) {
+			if (contents && strlen (contents) == 0) {
+				g_critical ("  Empty locale file found at '%s'", locale_file);
+				g_free (contents);
+			} else {
+				/* Re-use contents */
+				locale = contents;
+			}
+		} else {
+			g_critical ("  Could not get content of file '%s'", locale_file);
+		}
+	} else {
+		g_critical ("  Could not find locale file:'%s'", locale_file);
+	}
+
+	return locale;
+}
+
+static void
+miner_applications_locale_set_current (const gchar *locale_file,
+                                       const gchar *locale)
+{
+	GError *error = NULL;
+	gchar  *str;
+
+	g_message ("  Creating locale file '%s'", locale_file);
+
+	str = g_strdup_printf ("%s", locale ? locale : "");
+
+	if (!g_file_set_contents (locale_file, str, -1, &error)) {
+		g_message ("  Could not set file contents, %s",
+		           error ? error->message : "no error given");
+		g_clear_error (&error);
+	}
+
+	g_free (str);
+}
+
+gboolean
+tracker_miner_applications_locale_changed (void)
+{
+	gchar *previous_locale;
+	gchar *current_locale;
+	gboolean changed;
+	gchar *data_dir;
+	gchar *filename;
+
+	/* Locate previous locale file */
+	data_dir = g_build_filename (g_get_user_cache_dir (),
+	                             "tracker",
+	                             NULL);
+	filename = g_build_filename (data_dir, TRACKER_MINER_APPLICATIONS_LOCALE_FILE, NULL);
+
+	/* Get current tracker LANG locale */
+	current_locale = tracker_locale_get (TRACKER_LOCALE_LANGUAGE);
+
+#ifdef HAVE_MEEGOTOUCH
+	/* If we have meegotouch enabled, sanity check to compare with our
+	 * tracker locale */
+	{
+		/* Get also current meegotouch locale, which should be EQUAL to
+		 * the tracker locale */
+		gchar *current_mlocale;
+
+		current_mlocale = tracker_miner_applications_meego_get_locale ();
+
+		if (g_strcmp0 (current_locale, current_mlocale) != 0) {
+			g_critical ("Wrong locale settings (tracker locale '%s' vs MLocale '%s')",
+			            current_locale, current_mlocale);
+		}
+
+		g_free (current_mlocale);
+	}
+#endif
+
+	/* Get previous locale */
+	previous_locale = miner_applications_locale_get_previous (filename);
+
+	/* Note that having both to NULL is actually valid, they would default
+	 * to the unicode collation without locale-specific stuff. */
+	if (g_strcmp0 (previous_locale, current_locale) != 0) {
+		g_message ("Locale change detected from '%s' to '%s'...",
+		           previous_locale, current_locale);
+		/* Store the new one now */
+		miner_applications_locale_set_current (filename, current_locale);
+		changed = TRUE;
+	} else {
+		g_message ("Current and previous locales match: '%s'", previous_locale);
+		changed = FALSE;
+	}
+
+	g_free (previous_locale);
+	g_free (current_locale);
+	g_free (filename);
+	g_free (data_dir);
+	return changed;
+}
diff --git a/src/miners/fs/tracker-miner-applications-locale.h b/src/miners/fs/tracker-miner-applications-locale.h
new file mode 100644
index 0000000..1f514e2
--- /dev/null
+++ b/src/miners/fs/tracker-miner-applications-locale.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __TRACKER_MINER_FS_APPLICATIONS_LOCALE_H__
+#define __TRACKER_MINER_FS_APPLICATIONS_LOCALE_H__
+
+G_BEGIN_DECLS
+
+gboolean tracker_miner_applications_locale_changed (void);
+
+G_END_DECLS
+
+#endif /* __TRACKER_MINER_FS_APPLICATIONS_LOCALE_H__ */
diff --git a/src/miners/fs/tracker-miner-applications-meego.cpp b/src/miners/fs/tracker-miner-applications-meego.cpp
index c4c777f..30a7af3 100644
--- a/src/miners/fs/tracker-miner-applications-meego.cpp
+++ b/src/miners/fs/tracker-miner-applications-meego.cpp
@@ -30,14 +30,14 @@
  * localized strings using catalog and string ids. QApplication and
  * MLocale are needed for loading the translation catalogs. The
  * returned string is a multi-string one which has parts of different
- * lenght separated by '\x9C' unicode escape sequences.
+ * length separated by '\x9C' unicode escape sequences.
  *
  * FIXME: This is insane, try to get rid of at least some of the extra
  * layers here.
  */
 gchar *
-tracker_miner_applications_meego_translate (const gchar *catalogue,
-					    const gchar *id)
+tracker_miner_applications_meego_translate (const gchar  *catalogue,
+                                            const gchar  *id)
 {
 	char *argv[] = { "dummy", NULL };
 	int argc = 1;
@@ -52,7 +52,7 @@ tracker_miner_applications_meego_translate (const gchar *catalogue,
 	locale.installTrCatalog (catalogue);
 	MLocale::setDefault (locale);
 
-	gchar *ret = g_strdup (qtTrId (id). toUtf8 ().data ());
+	gchar *ret = g_strdup (qtTrId (id).toUtf8 ().data ());
 
 	/* We only want the first string of the multi-string, so if
 	 * the separator character is found (encoded as C2:9C in UTF-8),
@@ -64,3 +64,12 @@ tracker_miner_applications_meego_translate (const gchar *catalogue,
 
 	return ret;
 }
+
+gchar *
+tracker_miner_applications_meego_get_locale (void)
+{
+	/* Get the system default locale */
+	MLocale locale;
+
+	return g_strdup (locale.name ().toAscii ().data ());
+}
diff --git a/src/miners/fs/tracker-miner-applications-meego.h b/src/miners/fs/tracker-miner-applications-meego.h
index 8f36523..d3688ee 100644
--- a/src/miners/fs/tracker-miner-applications-meego.h
+++ b/src/miners/fs/tracker-miner-applications-meego.h
@@ -22,8 +22,10 @@
 
 G_BEGIN_DECLS
 
-gchar* tracker_miner_applications_meego_translate (const gchar *catalogue,
-                                                   const gchar *id);
+gchar *tracker_miner_applications_meego_translate (const gchar  *catalogue,
+                                                   const gchar  *id);
+
+gchar *tracker_miner_applications_meego_get_locale (void);
 
 G_END_DECLS
 
diff --git a/src/miners/fs/tracker-miner-applications.c b/src/miners/fs/tracker-miner-applications.c
index 26f49c1..bcd03eb 100644
--- a/src/miners/fs/tracker-miner-applications.c
+++ b/src/miners/fs/tracker-miner-applications.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ * Copyright (C) 2008-2010 Nokia <ivan frade nokia com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
@@ -21,8 +21,10 @@
 
 #include <libtracker-common/tracker-utils.h>
 #include <libtracker-common/tracker-ontologies.h>
+#include <libtracker-common/tracker-locale.h>
 
 #include "tracker-miner-applications.h"
+#include "tracker-miner-applications-locale.h"
 
 #ifdef HAVE_MEEGOTOUCH
 #include "tracker-miner-applications-meego.h"
@@ -127,12 +129,18 @@ insert_data_from_desktop_file (TrackerSparqlBuilder *sparql,
                                const gchar          *metadata_key,
                                GKeyFile             *desktop_file,
                                const gchar          *key,
-                               gboolean              use_locale)
+                               const gchar          *locale)
 {
 	gchar *str;
 
-	if (use_locale) {
-		str = g_key_file_get_locale_string (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL, NULL);
+	if (locale) {
+		/* Try to get the key with our desired LANG locale... */
+		str = g_key_file_get_locale_string (desktop_file, GROUP_DESKTOP_ENTRY, key, locale, NULL);
+		/* If our desired locale failed, use the list of LANG locales prepared by GLib
+		 * (will return untranslated string if none of the locales available) */
+		if (!str) {
+			str = g_key_file_get_locale_string (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL, NULL);
+		}
 	} else {
 		str = g_key_file_get_string (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL);
 	}
@@ -290,6 +298,7 @@ process_desktop_file (ProcessApplicationData  *data,
 	gsize cats_len;
 	gboolean is_software = TRUE;
 	const gchar *parent_urn;
+	gchar *lang;
 #ifdef HAVE_MEEGOTOUCH
 	gchar *logical_id = NULL;
 	gchar *translation_catalog = NULL;
@@ -301,11 +310,16 @@ process_desktop_file (ProcessApplicationData  *data,
 
 	path = g_file_get_path (data->file);
 
-	/* Try to get the categories with locale, then without if that fails */
-	cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", NULL, &cats_len, NULL);
+	/* Retrieve LANG locale setup */
+	lang = tracker_locale_get (TRACKER_LOCALE_LANGUAGE);
 
-	if (!cats)
-		cats = g_key_file_get_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", &cats_len, NULL);
+	/* Try to get the categories with our desired LANG locale... */
+	cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", lang, &cats_len, NULL);
+	if (!cats) {
+		/* If our desired locale failed, use the list of LANG locales prepared by GLib
+		 * (will return untranslated string if none of the locales available) */
+		cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", NULL, &cats_len, NULL);
+	}
 
 	/* NOTE: We sanitize categories later on when iterating them */
 
@@ -323,12 +337,13 @@ process_desktop_file (ProcessApplicationData  *data,
 #endif /* HAVE_MEEGOTOUCH */
 
 	if (!name) {
-		/* Try to get the name with locale, then without if that fails */
-		name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL, NULL);
-	}
-
-	if (!name) {
-		name = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL);
+		/* Try to get the name with our desired LANG locale... */
+		name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", lang, NULL);
+		if (!name) {
+			/* If our desired locale failed, use the list of LANG locales prepared by GLib
+			 * (will return untranslated string if none of the locales available) */
+			name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL, NULL);
+		}
 	}
 
 	/* Sanitize name */
@@ -505,12 +520,18 @@ process_desktop_file (ProcessApplicationData  *data,
 		if (is_software) {
 			gchar *icon;
 
-			insert_data_from_desktop_file (sparql, uri,
-			                               TRACKER_NIE_PREFIX "comment", key_file,
-			                               "Comment", TRUE);
-			insert_data_from_desktop_file (sparql, uri,
-			                               TRACKER_NFO_PREFIX "softwareCmdLine", key_file,
-			                               "Exec", TRUE);
+			insert_data_from_desktop_file (sparql,
+			                               uri,
+			                               TRACKER_NIE_PREFIX "comment",
+			                               key_file,
+			                               "Comment",
+			                               lang);
+			insert_data_from_desktop_file (sparql,
+			                               uri,
+			                               TRACKER_NFO_PREFIX "softwareCmdLine",
+			                               key_file,
+			                               "Exec",
+			                               lang);
 
 			icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);
 
@@ -614,6 +635,7 @@ process_desktop_file (ProcessApplicationData  *data,
 	g_free (uri);
 	g_free (path);
 	g_free (name);
+	g_free (lang);
 }
 
 static void
@@ -724,10 +746,113 @@ miner_applications_process_file_attributes (TrackerMinerFS       *fs,
 	return FALSE;
 }
 
+/* If a reset is requested, we will remove from the store all items previously
+ * inserted by the tracker-miner-applications, this is:
+ *  (a) all elements which are nfo:softwareIcon of a given nfo:Software
+ *  (b) all nfo:Software in our graph (includes both applications and maemo applets)
+ *  (c) all elements which are nfo:softwareCategoryIcon of a given nfo:SoftwareCategory
+ *  (d) all nfo:SoftwareCategory in our graph
+ */
+static void
+miner_applications_reset (TrackerMiner *miner)
+{
+	GError *error = NULL;
+	TrackerSparqlBuilder *sparql;
+
+	sparql = tracker_sparql_builder_new_update ();
+
+	/* (a) all elements which are nfo:softwareIcon of a given nfo:Software */
+	tracker_sparql_builder_delete_open (sparql, TRACKER_MINER_FS_GRAPH_URN);
+	tracker_sparql_builder_subject_variable (sparql, "icon");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "rdfs:Resource");
+	tracker_sparql_builder_delete_close (sparql);
+
+	tracker_sparql_builder_where_open (sparql);
+	tracker_sparql_builder_subject_variable (sparql, "software");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "nfo:Software");
+	tracker_sparql_builder_subject_variable (sparql, "icon");
+	tracker_sparql_builder_predicate (sparql, "nfo:softwareIcon");
+	tracker_sparql_builder_object_variable (sparql, "software");
+	tracker_sparql_builder_where_close (sparql);
+
+	/* (b) all nfo:Software in our graph (includes both applications and maemo applets) */
+	tracker_sparql_builder_delete_open (sparql, TRACKER_MINER_FS_GRAPH_URN);
+	tracker_sparql_builder_subject_variable (sparql, "software");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "rdfs:Resource");
+	tracker_sparql_builder_delete_close (sparql);
+
+	tracker_sparql_builder_where_open (sparql);
+	tracker_sparql_builder_subject_variable (sparql, "software");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "nfo:Software");
+	tracker_sparql_builder_where_close (sparql);
+
+	/* (c) all elements which are nfo:softwareCategoryIcon of a given nfo:SoftwareCategory */
+	tracker_sparql_builder_delete_open (sparql, TRACKER_MINER_FS_GRAPH_URN);
+	tracker_sparql_builder_subject_variable (sparql, "icon");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "rdfs:Resource");
+	tracker_sparql_builder_delete_close (sparql);
+
+	tracker_sparql_builder_where_open (sparql);
+	tracker_sparql_builder_subject_variable (sparql, "category");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory");
+	tracker_sparql_builder_subject_variable (sparql, "icon");
+	tracker_sparql_builder_predicate (sparql, "nfo:softwareCategoryIcon");
+	tracker_sparql_builder_object_variable (sparql, "category");
+	tracker_sparql_builder_where_close (sparql);
+
+	/* (d) all nfo:SoftwareCategory in our graph */
+	tracker_sparql_builder_delete_open (sparql, TRACKER_MINER_FS_GRAPH_URN);
+	tracker_sparql_builder_subject_variable (sparql, "category");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "rdfs:Resource");
+	tracker_sparql_builder_delete_close (sparql);
+
+	tracker_sparql_builder_where_open (sparql);
+	tracker_sparql_builder_subject_variable (sparql, "category");
+	tracker_sparql_builder_predicate (sparql, "a");
+	tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory");
+	tracker_sparql_builder_where_close (sparql);
+
+	/* Execute a sync update, we don't want the apps miner to start before
+	 * we finish this. */
+	tracker_sparql_connection_update (tracker_miner_get_connection (miner),
+	                                  tracker_sparql_builder_get_result (sparql),
+	                                  G_PRIORITY_HIGH,
+	                                  NULL,
+	                                  &error);
+
+	if (error) {
+		/* Some error happened performing the query, not good */
+		g_critical ("Couldn't remove previously created items: %s",
+		            error ? error->message : "unknown error");
+		g_error_free (error);
+	}
+
+	g_object_unref (sparql);
+}
+
 TrackerMiner *
 tracker_miner_applications_new (void)
 {
-	return g_object_new (TRACKER_TYPE_MINER_APPLICATIONS,
-	                     "name", "Applications",
-	                     NULL);
+	TrackerMiner *miner;
+
+	miner = g_object_new (TRACKER_TYPE_MINER_APPLICATIONS,
+	                      "name", "Applications",
+	                      NULL);
+
+	/* Before returning the newly created miner, check if we need
+	 * to reset it */
+	if (tracker_miner_applications_locale_changed ()) {
+		g_message ("Locale change detected, so resetting miner to "
+		           "remove all previously created items...");
+		miner_applications_reset (miner);
+	}
+
+	return miner;
 }



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