[tracker] All miner SPARQL Update queries need FROM or INTO to avoid writeback



commit 9940fb32bf4cc816fde237a5bbbf2eecae2d993a
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Nov 12 11:55:16 2009 +0100

    All miner SPARQL Update queries need FROM or INTO to avoid writeback
    
    When INTO or FROM are passed, graph in tracker_writeback_check wont be NULL.
    A NULL graph means 'default graph' or 'something that came from the user'.
    We only want to do writeback for things that came from the user. This is how
    we distinguish between content from the miner and content from the user.

 src/libtracker-common/tracker-sparql-builder.vala |    7 +-
 src/libtracker-data/tracker-data-update.c         |   38 +++---
 src/libtracker-miner/tracker-miner-fs.c           |   14 +-
 src/plugins/evolution/tracker-evolution-plugin.c  |   31 +++--
 src/plugins/kmail/tracker-kmail-registrar.c       |    9 +-
 src/tracker-extract/tracker-extract.c             |    2 +-
 src/tracker-miner-fs/tracker-miner-applications.c |    8 +-
 src/tracker-miner-fs/tracker-miner-files.c        |   39 +++---
 src/tracker-writeback/tracker-writeback-mp3.c     |  159 +++++++++++++++++++++
 9 files changed, 241 insertions(+), 66 deletions(-)
---
diff --git a/src/libtracker-common/tracker-sparql-builder.vala b/src/libtracker-common/tracker-sparql-builder.vala
index 7c8761d..c0d5e6d 100644
--- a/src/libtracker-common/tracker-sparql-builder.vala
+++ b/src/libtracker-common/tracker-sparql-builder.vala
@@ -54,11 +54,14 @@ public class Tracker.SparqlBuilder : Object {
 		str.append ("DROP GRAPH <%s>\n".printf (iri));
 	}
 
-	public void insert_open ()
+	public void insert_open (string? graph)
 		requires (state == State.UPDATE)
 	{
 		states += State.INSERT;
-		str.append ("INSERT {\n");
+		if (graph != null)
+			str.append ("INSERT INTO <%s> {\n".printf (graph));
+		else
+			str.append ("INSERT {\n");
 	}
 
 	public void insert_close ()
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 9ef0132..fe6ee76 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -1563,10 +1563,10 @@ tracker_data_update_enable_volume (const gchar *udi,
 	mount_path_file = g_file_new_for_path (mount_path);
 	mount_path_uri = g_file_get_uri (mount_path_file);
 
-	delete_q = g_strdup_printf ("DELETE { <%s> tracker:mountPoint ?d } WHERE { <%s> tracker:mountPoint ?d }", 
-				    removable_device_urn, removable_device_urn);
-	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:mountPoint <%s> }", 
-				 removable_device_urn, mount_path_uri);
+	delete_q = g_strdup_printf ("DELETE FROM <%s> { <%s> tracker:mountPoint ?d } WHERE { <%s> tracker:mountPoint ?d }", 
+	                            removable_device_urn, removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT INTO <%s> { <%s> a tracker:Volume; tracker:mountPoint <%s> }", 
+	                         removable_device_urn, removable_device_urn, mount_path_uri);
 
 	tracker_data_update_sparql (delete_q, &error);
 
@@ -1586,10 +1586,10 @@ tracker_data_update_enable_volume (const gchar *udi,
 	g_free (set_q);
 	g_free (delete_q);
 
-	delete_q = g_strdup_printf ("DELETE { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
-				    removable_device_urn, removable_device_urn);
-	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:isMounted true }", 
-				 removable_device_urn);
+	delete_q = g_strdup_printf ("DELETE FROM <%s> { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
+	                            removable_device_urn, removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT INTO <%s> { <%s> a tracker:Volume; tracker:isMounted true }", 
+	                         removable_device_urn, removable_device_urn);
 
 	tracker_data_update_sparql (delete_q, &error);
 
@@ -1625,9 +1625,10 @@ tracker_data_update_reset_volume (const gchar *uri)
 
 	mnow = time (NULL);
 	now_as_string = tracker_date_to_string (mnow);
-	delete_q = g_strdup_printf ("DELETE { <%s> tracker:unmountDate ?d } WHERE { <%s> tracker:unmountDate ?d }", uri, uri);
-	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:unmountDate \"%s\" }", 
-				 uri, now_as_string);
+	delete_q = g_strdup_printf ("DELETE FROM <%s> { <%s> tracker:unmountDate ?d } WHERE { <%s> tracker:unmountDate ?d }", 
+	                            uri, uri, uri);
+	set_q = g_strdup_printf ("INSERT INTO <%s> { <%s> a tracker:Volume; tracker:unmountDate \"%s\" }", 
+	                         uri, uri, now_as_string);
 
 	tracker_data_update_sparql (delete_q, &error);
 
@@ -1665,10 +1666,10 @@ tracker_data_update_disable_volume (const gchar *udi)
 
 	tracker_data_update_reset_volume (removable_device_urn);
 
-	delete_q = g_strdup_printf ("DELETE { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
-				    removable_device_urn, removable_device_urn);
-	set_q = g_strdup_printf ("INSERT { <%s> a tracker:Volume; tracker:isMounted false }", 
-				 removable_device_urn);
+	delete_q = g_strdup_printf ("DELETE FROM <%s> { <%s> tracker:isMounted ?d } WHERE { <%s> tracker:isMounted ?d }", 
+	                            removable_device_urn, removable_device_urn, removable_device_urn);
+	set_q = g_strdup_printf ("INSERT INTO <%s> { <%s> a tracker:Volume; tracker:isMounted false }", 
+	                         removable_device_urn, removable_device_urn);
 
 	tracker_data_update_sparql (delete_q, &error);
 
@@ -1713,8 +1714,11 @@ tracker_data_update_disable_all_volumes (void)
 	tracker_db_statement_execute (stmt, NULL);
 	g_object_unref (stmt);
 
-	delete_q = g_strdup_printf ("DELETE { ?o tracker:isMounted ?d } WHERE { ?o tracker:isMounted ?d  FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
-	set_q = g_strdup_printf ("INSERT { ?o a tracker:Volume; tracker:isMounted false } WHERE { ?o a tracker:Volume FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
+	/* The INTO and FROM uris are not really right, but it should be harmless:
+	 * we just want graph to be != NULL in tracker-store/tracker-writeback.c */
+
+	delete_q = g_strdup_printf ("DELETE FROM <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> { ?o tracker:isMounted ?d } WHERE { ?o tracker:isMounted ?d  FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
+	set_q = g_strdup_printf ("INSERT INTO <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> { ?o a tracker:Volume; tracker:isMounted false } WHERE { ?o a tracker:Volume FILTER (?o != <"TRACKER_NON_REMOVABLE_MEDIA_DATASOURCE_URN"> ) }");
 
 	tracker_data_update_sparql (delete_q, &error);
 
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index d3bd1db..00259df 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -999,14 +999,14 @@ item_remove (TrackerMinerFS *fs,
 
 	/* Delete all children */
 	g_string_append_printf (sparql,
-				"DELETE { ?u a rdfs:Resource } "
+				"DELETE FROM <%s> { ?u a rdfs:Resource } "
 				"WHERE { ?u nfo:belongsToContainer ?p . FILTER (fn:starts-with (?p, \"%s\")) } ",
-				slash_uri);
+				uri, slash_uri);
 
 	/* Delete resource itself */
 	g_string_append_printf (sparql,
-				"DELETE { <%s> a rdfs:Resource }",
-				uri);
+				"DELETE FROM <%s> { <%s> a rdfs:Resource }",
+				uri, uri);
 
 	data = process_data_new (file, NULL, NULL);
 	fs->private->processing_pool = g_list_prepend (fs->private->processing_pool, data);
@@ -1144,10 +1144,10 @@ item_move (TrackerMinerFS *fs,
 	sparql = g_string_new ("");
 
 	g_string_append_printf (sparql,
-				"DELETE { <%s> nfo:fileName ?o } WHERE { <%s> nfo:fileName ?o }",
-				source_uri, source_uri);
+				"DELETE FROM <%s> { <%s> nfo:fileName ?o } WHERE { <%s> nfo:fileName ?o }",
+				source_uri, source_uri, source_uri);
 
-	g_string_append (sparql, " INSERT {");
+	g_string_append_printf (sparql, " INSERT INTO <%s> {", uri);
 
 	escaped_filename = g_strescape (g_file_info_get_display_name (file_info), NULL);
 
diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c
index eb39a8d..f474f7f 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.c
+++ b/src/plugins/evolution/tracker-evolution-plugin.c
@@ -340,9 +340,9 @@ send_sparql_commit (TrackerEvolutionPlugin *self, gboolean update)
 	if (priv->client) {
 		if (update) {
 			gchar *date_s = tracker_date_to_string (time (NULL));
-			gchar *update = g_strdup_printf ("DELETE { <" DATASOURCE_URN "> nie:contentLastModified ?d } "
+			gchar *update = g_strdup_printf ("DELETE FROM <"DATASOURCE_URN"> { <" DATASOURCE_URN "> nie:contentLastModified ?d } "
 			                                 "WHERE { <" DATASOURCE_URN "> a nie:InformationElement ; nie:contentLastModified ?d } \n"
-			                                 "INSERT { <" DATASOURCE_URN "> nie:contentLastModified \"%s\" }",
+			                                 "INSERT INTO <"DATASOURCE_URN"> { <" DATASOURCE_URN "> nie:contentLastModified \"%s\" }",
 			                                 date_s);
 
 			send_sparql_update (self, update);
@@ -652,7 +652,7 @@ on_folder_summary_changed (CamelFolder *folder,
 
 			tracker_sparql_builder_drop_graph (sparql, uri);
 
-			tracker_sparql_builder_insert_open (sparql);
+			tracker_sparql_builder_insert_open (sparql, uri);
 
 			process_fields (sparql, uid, flags, sent, subject, 
 			                from, to, cc, size, folder, uri);
@@ -717,21 +717,26 @@ on_folder_summary_changed (CamelFolder *folder,
 	/* the uid_removed member contains the removed-from-the-summary items */
 
 	if (changes->uid_removed && changes->uid_removed->len > 0) {
-		GString *sparql = g_string_new ("DELETE { \n");
+
+		/* The FROM uri is not exactly right here, but we just want 
+		 * graph != NULL in tracker-store/tracker-writeback.c */
+
+		GString *sparql = g_string_new ("");
 
 		for (i = 0; i< changes->uid_removed->len; i++) {
 
 			/* This is not a path but a URI, don't use the OS's 
 			 * directory separator here */
 
-			g_string_append_printf (sparql, "\t<%s%s/%s> a rdfs:Resource . \n", 
+			g_string_append_printf (sparql, "DELETE FROM <%s%s/%s> { <%s%s/%s> a rdfs:Resource }\n ", 
+			                        em_uri, 
+			                        camel_folder_get_full_name (folder),
+			                        (char*) changes->uid_removed->pdata[i],
 			                        em_uri, 
 			                        camel_folder_get_full_name (folder),
 			                        (char*) changes->uid_removed->pdata[i]);
 		}
 
-		g_string_append_c (sparql, '}');
-
 		send_sparql_update (info->self, sparql->str);
 		g_string_free (sparql, TRUE);
 	}
@@ -954,7 +959,7 @@ introduce_walk_folders_in_folder (TrackerEvolutionPlugin *self,
 
 					tracker_sparql_builder_drop_graph (sparql, uri);
 
-					tracker_sparql_builder_insert_open (sparql);
+					tracker_sparql_builder_insert_open (sparql, uri);
 
 					process_fields (sparql, uid, flags, sent, 
 					                subject, from, to, cc, size, 
@@ -1191,10 +1196,14 @@ introduce_store_deal_with_deleted (TrackerEvolutionPlugin *self,
 		}
 
 		if (count > 0) {
-			GString *sparql = g_string_new ("DELETE { \n");
+			/* The FROM uri is not exactly right here, but we just want 
+			 * graph != NULL in tracker-store/tracker-writeback.c */
+
+			GString *sparql = g_string_new ("");
 
 			for (i = 0; i < subjects_a->len; i++) {
-				g_string_append_printf (sparql, "\t<%s> a rdfs:Resource . \n", 
+				g_string_append_printf (sparql, "DELETE FROM <%s> { <%s> a rdfs:Resource } \n", 
+				                        (gchar *) g_ptr_array_index (subjects_a, i),
 				                        (gchar *) g_ptr_array_index (subjects_a, i));
 			}
 
@@ -1656,7 +1665,7 @@ register_client_second_half (ClientRegistry *info)
 
 	if (info->last_checkout < too_old) {
 
-		send_sparql_update (info->self, "DELETE { ?s a rdfs:Resource } "
+		send_sparql_update (info->self, "DELETE FROM <"DATASOURCE_URN"> { ?s a rdfs:Resource } "
 		                                "WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }");
 		send_sparql_commit (info->self, FALSE);
 
diff --git a/src/plugins/kmail/tracker-kmail-registrar.c b/src/plugins/kmail/tracker-kmail-registrar.c
index cf1afba..b7c478f 100644
--- a/src/plugins/kmail/tracker-kmail-registrar.c
+++ b/src/plugins/kmail/tracker-kmail-registrar.c
@@ -166,7 +166,7 @@ perform_set (TrackerKMailRegistrar *object,
 
 	sparql = tracker_sparql_builder_new_update ();
 
-	tracker_sparql_builder_insert_open (sparql);
+	tracker_sparql_builder_insert_open (sparql, uri);
 
 	tracker_sparql_builder_subject_iri (sparql, DATASOURCE_URN);
 	tracker_sparql_builder_predicate (sparql, "rdf:type");
@@ -359,7 +359,8 @@ static void
 perform_unset (TrackerKMailRegistrar *object, 
 	       const gchar *subject)
 {
-	gchar *sparql = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }", subject);
+	gchar *sparql = g_strdup_printf ("DELETE FROM <%s> { <%s> a rdfs:Resource }", 
+	                                 subject, subject);
 
 	tracker_store_queue_sparql_update (sparql, NULL, NULL, NULL, NULL);
 
@@ -369,8 +370,8 @@ perform_unset (TrackerKMailRegistrar *object,
 static void
 perform_cleanup (TrackerKMailRegistrar *object)
 {
-	tracker_store_queue_sparql_update ("DELETE { ?s a rdfs:Resource } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL, NULL);
-	/* tracker_store_queue_sparql_update ("DELETE { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL, NULL); */
+	tracker_store_queue_sparql_update ("DELETE FROM <"DATASOURCE_URN"> { ?s a rdfs:Resource } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL, NULL);
+	/* tracker_store_queue_sparql_update ("DELETE FROM <"DATASOURCE_URN"> { ?s ?p ?o } WHERE { ?s nie:dataSource <" DATASOURCE_URN "> }", NULL, NULL, NULL, NULL); */
 }
 
 static void
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index 165ddd0..0404114 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -241,7 +241,7 @@ get_file_metadata (TrackerExtract *extract,
 	/* Create hash table to send back */
 	statements = tracker_sparql_builder_new_update ();
 
-	tracker_sparql_builder_insert_open (statements);
+	tracker_sparql_builder_insert_open (statements, uri);
 
 #ifdef HAVE_LIBSTREAMANALYZER
 	if (!priv->force_internal_extractors) {
diff --git a/src/tracker-miner-fs/tracker-miner-applications.c b/src/tracker-miner-fs/tracker-miner-applications.c
index 7dc8e12..27fef50 100644
--- a/src/tracker-miner-fs/tracker-miner-applications.c
+++ b/src/tracker-miner-fs/tracker-miner-applications.c
@@ -242,10 +242,8 @@ miner_applications_process_file_cb (gpointer user_data)
 		gchar *canonical_uri = tracker_uri_printf_escaped (SOFTWARE_CATEGORY_URN_PREFIX "%s", path);
 		gchar *icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);
 
-		tracker_sparql_builder_insert_open (sparql);
-
 		uri = canonical_uri;
-
+		tracker_sparql_builder_insert_open (sparql, uri);
 		tracker_sparql_builder_subject_iri (sparql, uri);
 
 		tracker_sparql_builder_predicate (sparql, "a");
@@ -270,7 +268,7 @@ miner_applications_process_file_cb (gpointer user_data)
 
 	} else if (name && g_ascii_strcasecmp (type, "Application") == 0) {
 		uri = g_file_get_uri (data->file);
-		tracker_sparql_builder_insert_open (sparql);
+		tracker_sparql_builder_insert_open (sparql, uri);
 
 		tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN);
 		tracker_sparql_builder_predicate (sparql, "a");
@@ -289,7 +287,7 @@ miner_applications_process_file_cb (gpointer user_data)
 	} else if (name && g_str_has_suffix (type, "Applet")) {
 		/* The URI of the InformationElement should be a UUID URN */
 		uri = g_file_get_uri (data->file);
-		tracker_sparql_builder_insert_open (sparql);
+		tracker_sparql_builder_insert_open (sparql, uri);
 
 		tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN);
 		tracker_sparql_builder_predicate (sparql, "a");
diff --git a/src/tracker-miner-fs/tracker-miner-files.c b/src/tracker-miner-fs/tracker-miner-files.c
index 9ee6b7e..c3e5339 100644
--- a/src/tracker-miner-fs/tracker-miner-files.c
+++ b/src/tracker-miner-fs/tracker-miner-files.c
@@ -471,48 +471,49 @@ set_up_mount_point (TrackerMinerFiles *miner,
 			uri = g_file_get_uri (file);
 
 			g_string_append_printf (queries,
-			                        "DROP GRAPH <%s>\nINSERT { <%s> a tracker:Volume; tracker:mountPoint <%s> } ",
-			                        removable_device_urn, removable_device_urn, uri);
+			                        "DROP GRAPH <%s>\n "
+			                        "INSERT INTO <%s> { <%s> a tracker:Volume; tracker:mountPoint <%s> } ",
+			                        removable_device_urn, removable_device_urn, removable_device_urn, uri);
 
 			g_object_unref (file);
 			g_free (uri);
 		}
 
 		g_string_append_printf (queries,
-		                        "DELETE { <%s> tracker:isMounted ?unknown } WHERE { <%s> a tracker:Volume; tracker:isMounted ?unknown } ",
-		                        removable_device_urn, removable_device_urn);
+		                        "DELETE FROM <%s> { <%s> tracker:isMounted ?unknown } WHERE { <%s> a tracker:Volume; tracker:isMounted ?unknown } ",
+		                        removable_device_urn, removable_device_urn, removable_device_urn);
 
 		g_string_append_printf (queries,
-		                        "INSERT { <%s> a tracker:Volume; tracker:isMounted true } ",
-		                        removable_device_urn);
+		                        "INSERT INTO <%s> { <%s> a tracker:Volume; tracker:isMounted true } ",
+		                        removable_device_urn, removable_device_urn);
 
 		g_string_append_printf (queries,
-		                        "INSERT { ?do tracker:available true } WHERE { ?do nie:dataSource <%s> } ",
-		                        removable_device_urn);
+		                        "INSERT INTO <%s> { ?do tracker:available true } WHERE { ?do nie:dataSource <%s> } ",
+		                        removable_device_urn, removable_device_urn);
 	} else {
 		gchar *now;
 
 		now = tracker_date_to_string (time (NULL));
 
 		g_string_append_printf (queries,
-		                        "DELETE { <%s> tracker:unmountDate ?unknown } WHERE { <%s> a tracker:Volume; tracker:unmountDate ?unknown } ",
-		                        removable_device_urn, removable_device_urn);
+		                        "DELETE FROM <%s> { <%s> tracker:unmountDate ?unknown } WHERE { <%s> a tracker:Volume; tracker:unmountDate ?unknown } ",
+		                        removable_device_urn, removable_device_urn, removable_device_urn);
 
 		g_string_append_printf (queries,
-		                        "INSERT { <%s> a tracker:Volume; tracker:unmountDate \"%s\" } ",
-		                        removable_device_urn, now);
+		                        "INSERT INTO <%s> { <%s> a tracker:Volume; tracker:unmountDate \"%s\" } ",
+		                        removable_device_urn, removable_device_urn, now);
 
 		g_string_append_printf (queries,
-		                        "DELETE { <%s> tracker:isMounted ?unknown } WHERE { <%s> a tracker:Volume; tracker:isMounted ?unknown } ",
-		                        removable_device_urn, removable_device_urn);
+		                        "DELETE FROM <%s> { <%s> tracker:isMounted ?unknown } WHERE { <%s> a tracker:Volume; tracker:isMounted ?unknown } ",
+		                        removable_device_urn, removable_device_urn, removable_device_urn);
 
 		g_string_append_printf (queries,
-		                        "INSERT { <%s> a tracker:Volume; tracker:isMounted false } ",
-		                        removable_device_urn);
+		                        "INSERT INTO <%s> { <%s> a tracker:Volume; tracker:isMounted false } ",
+		                        removable_device_urn, removable_device_urn);
 
 		g_string_append_printf (queries,
-		                        "DELETE { ?do tracker:available true } WHERE { ?do nie:dataSource <%s> } ",
-		                        removable_device_urn);
+		                        "DELETE FROM <%s> { ?do tracker:available true } WHERE { ?do nie:dataSource <%s> } ",
+		                        removable_device_urn, removable_device_urn);
 		g_free (now);
 	}
 
@@ -1301,7 +1302,7 @@ process_file_cb (GObject      *object,
 	uri = g_file_get_uri (file);
 	mime_type = g_file_info_get_content_type (file_info);
 
-        tracker_sparql_builder_insert_open (sparql);
+        tracker_sparql_builder_insert_open (sparql, uri);
 
         tracker_sparql_builder_subject_iri (sparql, uri);
 	tracker_sparql_builder_predicate (sparql, "a");
diff --git a/src/tracker-writeback/tracker-writeback-mp3.c b/src/tracker-writeback/tracker-writeback-mp3.c
new file mode 100644
index 0000000..09edd2d
--- /dev/null
+++ b/src/tracker-writeback/tracker-writeback-mp3.c
@@ -0,0 +1,159 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008, Nokia
+ *
+ * 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.
+ *
+ * Authors: Philip Van Hoof <philip codeminded be>
+ */
+
+#include <id3.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <libtracker-common/tracker-ontology.h>
+
+#include "tracker-writeback.h"
+
+#define TRACKER_TYPE_WRITEBACK_MP3    (tracker_writeback_mp3_get_type ())
+
+typedef struct TrackerWritebackMP3 TrackerWritebackMP3;
+typedef struct TrackerWritebackMP3Class TrackerWritebackMP3Class;
+
+struct TrackerWritebackMP3 {
+        TrackerWriteback parent_instance;
+};
+
+struct TrackerWritebackMP3Class {
+        TrackerWritebackClass parent_class;
+};
+
+static GType    tracker_writeback_mp3_get_type        (void) G_GNUC_CONST;
+static gboolean tracker_writeback_mp3_update_metadata (TrackerWriteback *writeback,
+                                                         GPtrArray        *values);
+
+G_DEFINE_DYNAMIC_TYPE (TrackerWritebackMP3, tracker_writeback_mp3, TRACKER_TYPE_WRITEBACK);
+
+static void
+tracker_writeback_mp3_class_init (TrackerWritebackMP3Class *klass)
+{
+        TrackerWritebackClass *writeback_class = TRACKER_WRITEBACK_CLASS (klass);
+
+        writeback_class->update_metadata = tracker_writeback_mp3_update_metadata;
+}
+
+static void
+tracker_writeback_mp3_class_finalize (TrackerWritebackMP3Class *klass)
+{
+}
+
+static void
+tracker_writeback_mp3_init (TrackerWritebackMP3 *mp3)
+{
+}
+
+static gboolean
+tracker_writeback_mp3_update_metadata (TrackerWriteback *writeback,
+                                       GPtrArray        *values)
+{
+	guint n;
+	const gchar *uri = NULL;
+	GFile *file = NULL;
+	gchar *path = NULL;
+
+	for (n = 0; n < values->len; n++) {
+		const GStrv row = g_ptr_array_index (values, n);
+
+		if (uri == NULL) {
+			GFileInfo *file_info;
+			const gchar *mime_type;
+
+			uri = row[0];
+			file = g_file_new_for_uri (uri);
+
+			file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+			                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+			                               NULL, NULL);
+
+			if (!file_info) {
+				g_object_unref (file);
+				return FALSE;
+			}
+
+			mime_type = g_file_info_get_content_type (file_info);
+
+			if (g_strcmp0 (mime_type, "audio/mpeg") == 0 ||
+			    g_strcmp0 (mime_type, "audio/x-mp3") == 0) {
+				g_object_unref (file_info);
+				path = g_file_get_path (file);
+			} else {
+				g_object_unref (file);
+				g_object_unref (file_info);
+				return FALSE;
+			}
+		}
+
+		if (g_strcmp0 (row[1], TRACKER_NIE_PREFIX "title") == 0) {
+			ID3Tag *tag = ID3Tag_New ();
+			ID3Frame *frame;
+
+			ID3Tag_Link (tag, path);
+
+ 			frame = ID3Tag_FindFrameWithID (tag, ID3FID_TITLE);
+			if (frame) {
+				ID3Field *field;
+				field = ID3Frame_GetField (frame, ID3FN_TEXT);
+				ID3Field_SetASCII (field, row[2]);
+			} else {
+				ID3Field *field;
+				frame = ID3Frame_NewID (ID3FID_TITLE);
+				field = ID3Frame_GetField (frame, ID3FN_TEXT);
+				ID3Field_SetASCII (field, row[2]);
+				ID3Tag_AddFrame (tag, frame);
+			}
+
+			ID3Tag_Update (tag);
+			// ID3Frame_Delete (frame);
+			ID3Tag_Delete (tag);
+		}
+	}
+
+	if (path)
+		g_free (path);
+
+	if (file)
+		g_object_unref (file);
+
+	return TRUE;
+}
+
+TrackerWriteback *
+writeback_module_create (GTypeModule *module)
+{
+	tracker_writeback_mp3_register_type (module);
+
+	return g_object_new (TRACKER_TYPE_WRITEBACK_MP3, NULL);
+}
+
+const gchar**
+writeback_module_get_rdftypes (void)
+{
+	static const gchar *rdftypes[] = { TRACKER_NFO_PREFIX "Document",
+	                                   TRACKER_NMM_PREFIX "MusicPiece",
+	                                   NULL };
+
+	return rdftypes;
+}



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