Skip to Content.
Sympa Menu

cc-devel - [cc-devel] [PATCH] Read XMP Sidecar

cc-devel AT lists.ibiblio.org

Subject: Developer discussion for Creative Commons technology and tools

List archive

Chronological Thread  
  • From: Jason Kivlighn <jkivlighn AT gmail.com>
  • To: jamie <jamiemcc AT blueyonder.co.uk>, tracker-list AT gnome.org, CC Developer Mailing List <cc-devel AT lists.ibiblio.org>
  • Subject: [cc-devel] [PATCH] Read XMP Sidecar
  • Date: Mon, 11 Jun 2007 21:12:15 -0700

Here's a patch to have Tracker read XMP sidecar files. It adds a
configure check for Exempi, enabling reading XMP if found.

One problem I see is how to handle updating the associated file when
it's sidecar file is updated.

Cheers,
Jason
Index: src/trackerd/tracker-metadata.c
===================================================================
--- src/trackerd/tracker-metadata.c	(revision 598)
+++ src/trackerd/tracker-metadata.c	(working copy)
@@ -83,7 +83,8 @@
 			  "application/x-killustrator",
 			  "application/x-kivio",
 			  "application/x-kontour",
-			  "application/x-wpg"
+			  "application/x-wpg",
+			  "application/rdf+xml"
 };
 
 
Index: src/trackerd/tracker-db.c
===================================================================
--- src/trackerd/tracker-db.c	(revision 598)
+++ src/trackerd/tracker-db.c	(working copy)
@@ -26,9 +26,9 @@
 #include "tracker-email.h"
 #include "tracker-metadata.h"
 
-
 extern Tracker *tracker;
 
+#define XMP_MIME_TYPE "application/rdf+xml"
 
 typedef struct {
 	DBConnection	*db_con;
@@ -844,8 +844,9 @@
 
 	GHashTable	*meta_table;
 	const char	*ext;
+	char		*filename, *dirname;
 	char		*str_link_uri, *service_name;
-	gboolean	is_file_indexable, service_has_metadata, is_external_service, service_has_fulltext, service_has_thumbs;
+	gboolean	is_file_indexable, service_has_metadata, is_external_service, service_has_fulltext, service_has_thumbs, is_sidecar;
 
 	const char *uri;
 
@@ -888,15 +889,20 @@
 
 		tracker_add_metadata_to_table  (meta_table, g_strdup ("File:NameDelimited"), g_strdup (uri));
 
-		ext = strrchr (uri, '.');
+		dirname = g_path_get_dirname (uri);
+		filename = g_path_get_basename (uri);
+		ext = strrchr (filename, '.');
 		if (ext) {
 			ext++;
 			tracker_debug ("file extension is %s", ext);
 			tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Ext"), g_strdup (ext));
+			is_sidecar = strcmp("xmp",ext) == 0;
+		} else {
+			is_sidecar = FALSE;
 		}
 
-		tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Path"), g_path_get_dirname (uri));
-		tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Name"), g_path_get_basename (uri));
+		tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Path"), g_strdup(dirname));
+		tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Name"), g_strdup(filename));
 
 		if (str_link_uri) {
 			tracker_add_metadata_to_table  (meta_table, g_strdup ("File:Link"), str_link_uri);
@@ -911,18 +917,43 @@
 		is_file_indexable = (!info->is_directory && (strcmp (info->mime, "unknown") != 0) && (strcmp (info->mime, "symlink") != 0) && tracker_file_is_indexable (info->uri));
 
 		service_has_metadata = (is_external_service ||
-					(is_file_indexable && (tracker_str_in_array (service_name, services_with_metadata) != -1)));
+					(is_file_indexable && (tracker_str_in_array (service_name, services_with_metadata) != -1))) && !is_sidecar;
 		service_has_fulltext = (is_external_service ||
-					(is_file_indexable && (tracker_str_in_array (service_name, services_with_text) != -1)));
+					(is_file_indexable && (tracker_str_in_array (service_name, services_with_text) != -1))) && !is_sidecar;
 		service_has_thumbs = (is_external_service ||
 				      (is_file_indexable && (tracker_str_in_array (service_name, services_with_thumbs) != -1)));
 
+		#ifdef HAVE_EXEMPI
+		/* TODO: How can we update the file when the sidecar file changes? */
+		if ( !info->is_directory && !is_sidecar ) {
+			gchar *basename;
+			if ( ext ) {
+				basename = g_strndup(filename,ext-filename-1);
+			}
+			else {
+				basename = g_strdup(filename);
+			}
 
+			gchar *sidecar_uri = g_build_filename(dirname,g_strconcat(basename,".xmp",NULL),NULL);
+
+			tracker_debug ("looking for xmp sidecar at %s", sidecar_uri);
+			if ( g_file_test( sidecar_uri, G_FILE_TEST_EXISTS) ) {
+				tracker_debug ("xmp sidecar found for %s", sidecar_uri);
+				tracker_metadata_get_embedded (sidecar_uri, XMP_MIME_TYPE, meta_table);
+			}
+
+			g_free(sidecar_uri);
+			g_free(basename);
+		}
+		#endif
+
  		tracker_debug ("file %s has fulltext %d with service %s", info->uri, service_has_fulltext, service_name); 
 		tracker_db_index_service (db_con, info, service_name, meta_table, uri, attachment_service, service_has_metadata, service_has_fulltext, service_has_thumbs);
 
 		g_hash_table_destroy (meta_table);
 
+		g_free(filename);
+		g_free(dirname);
 	} else {
 		tracker_db_index_service (db_con, info, service_name, NULL, uri, NULL, FALSE, FALSE, FALSE);
 
Index: src/tracker-extract/tracker-extract.c
===================================================================
--- src/tracker-extract/tracker-extract.c	(revision 598)
+++ src/tracker-extract/tracker-extract.c	(working copy)
@@ -30,6 +30,11 @@
 
 #define MAX_MEM 128
 
+#ifdef HAVE_EXEMPI
+#include <exempi/xmp.h>
+#include <exempi/xmpconsts.h>
+#endif
+
 typedef enum {
 	IGNORE_METADATA,
 	NO_METADATA,
@@ -59,9 +64,12 @@
 #ifdef HAVE_LIBGSF
 void tracker_extract_msoffice	(gchar *, GHashTable *);
 #endif
+#ifdef HAVE_EXEMPI
+void tracker_extract_xmp	(gchar *, GHashTable *);
+#endif
 void tracker_extract_mp3	(gchar *, GHashTable *);
 #ifdef HAVE_VORBIS
-void tracker_extract_vorbis	(gchar *, GHashTable *);
+void tracker_extract_vorbis    (gchar *, GHashTable *);
 #endif
 void tracker_extract_png	(gchar *, GHashTable *);
 #ifdef HAVE_LIBEXIF
@@ -92,7 +100,10 @@
  	{ "application/msword",				tracker_extract_msoffice	},
  	{ "application/vnd.ms-*",			tracker_extract_msoffice	},
 #endif
-  
+#ifdef HAVE_EXEMPI
+ 	{ "application/rdf+xml",			tracker_extract_xmp		},
+#endif
+
   	/* Video extractors */
 #ifdef HAVE_GSTREAMER
  	{ "video/*",					tracker_extract_gstreamer	},
@@ -183,7 +194,45 @@
 
 }
 
+void
+tracker_read_xmp (gchar *buffer, size_t len, GHashTable *metadata)
+{
+	#ifdef HAVE_EXEMPI
+	xmp_init();
 
+	XmpPtr xmp = xmp_new_empty();
+	xmp_parse(xmp, buffer, len);
+	if (xmp != NULL) {
+		XmpIteratorPtr iter = xmp_iterator_new(xmp, NULL, NULL, XMP_ITER_JUSTLEAFNODES);
+		XmpStringPtr the_schema = xmp_string_new();
+		XmpStringPtr the_path = xmp_string_new();
+		XmpStringPtr the_prop = xmp_string_new();
+	
+		while( xmp_iterator_next(iter, the_schema, the_path, the_prop, NULL) )
+		{
+			const char *schema = xmp_string_cstr(the_schema);
+			const char *name = xmp_string_cstr(the_path);
+			const char *value = xmp_string_cstr(the_prop);
+			if (value != NULL) {
+				if ( strcmp(schema,NS_CC) == 0 ) {
+					if (g_str_has_suffix(name,"license")) {
+						g_hash_table_insert (metadata, g_strdup("File:License"), g_strdup (value));
+					}
+				}
+			}
+		}
+	
+		xmp_string_free(the_prop);
+		xmp_string_free(the_path);
+		xmp_string_free(the_schema);
+		xmp_iterator_free(iter);
+	
+		xmp_free(xmp);
+	}
+	xmp_terminate();
+	#endif
+}
+
 static GHashTable *
 tracker_get_file_metadata (const char *uri, char *mime)
 {
Index: src/tracker-extract/tracker-extract-xmp.c
===================================================================
--- src/tracker-extract/tracker-extract-xmp.c	(revision 0)
+++ src/tracker-extract/tracker-extract-xmp.c	(revision 0)
@@ -0,0 +1,40 @@
+/* Tracker Extract - extracts embedded metadata from files
+ * Copyright (C) 2007, Jason Kivlighn (jkivlighn AT gmail.com)
+ *
+ * This program 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 program 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 program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_EXEMPI
+
+#include <glib.h>
+
+#include "tracker-extract.h"
+
+void tracker_extract_xmp (gchar* filename, GHashTable *metadata)
+{
+	gchar *contents;
+	gsize length;
+	GError *error;
+
+	if ( g_file_get_contents( filename, &contents, &length, &error ) )
+		tracker_read_xmp(contents, length, metadata);
+}
+
+#else
+#warning "Not building XMP metadata extractor."
+#endif  /* HAVE_EXEMPI */
Index: src/tracker-extract/tracker-extract.h
===================================================================
--- src/tracker-extract/tracker-extract.h	(revision 598)
+++ src/tracker-extract/tracker-extract.h	(working copy)
@@ -17,6 +17,13 @@
  * Boston, MA  02110-1301, USA.
  */
 
+#ifndef _TRACKER_EXTRACT_H_
+#define _TRACKER_EXTRACT_H_
+
 #include <glib.h>
 
 gboolean	tracker_spawn (char **argv, int timeout, char **tmp_stdout, int *exit_status);
+
+void 		tracker_read_xmp (gchar *buffer, size_t len, GHashTable *metadata);
+
+#endif
Index: src/tracker-extract/Makefile.am
===================================================================
--- src/tracker-extract/Makefile.am	(revision 598)
+++ src/tracker-extract/Makefile.am	(working copy)
@@ -5,6 +5,7 @@
 	$(LIBGSF_CFLAGS)			\
 	$(LIBGSF_CFLAGS)			\
 	$(GSTREAMER_CFLAGS)			\
+	$(EXEMPI_CFLAGS)			\
 	$(XINE_CFLAGS)
 
 bin_PROGRAMS = tracker-extract
@@ -33,6 +34,7 @@
 	tracker-extract-imagemagick.c		\
 	tracker-extract-mplayer.c		\
 	tracker-extract-totem.c			\
+	tracker-extract-xmp.c			\
 	$(video_sources)
 
 tracker_extract_LDADD = $(GLIB2_LIBS)		\
@@ -41,4 +43,5 @@
 	$(LIBEXIF_LIBS)				\
 	$(LIBGSF_LIBS)				\
 	$(GSTREAMER_LIBS)			\
+	$(EXEMPI_LIBS)				\
 	$(XINE_LIBS)
Index: configure.ac
===================================================================
--- configure.ac	(revision 598)
+++ configure.ac	(working copy)
@@ -607,6 +607,25 @@
 
 #####################################################
 
+##################################################################
+# check for exempi
+##################################################################
+
+EXEMPI_REQUIRED=1.99.0
+
+AC_ARG_ENABLE(xmp, AC_HELP_STRING([--disable-xmp], [Disable XMP extraction]),,[enable_xmp=yes])
+if test "x$enable_xmp" = "xyes"; then
+	PKG_CHECK_MODULES(EXEMPI,[
+		exempi-2.0 >= $EXEMPI_REQUIRED],
+		[have_exempi=yes] , [have_exempi=no])
+	AC_SUBST(EXEMPI_CFLAGS)
+	AC_SUBST(EXEMPI_LIBS)
+else
+	have_exempi="no (disabled)"
+fi
+AM_CONDITIONAL(HAVE_EXEMPI, test "$have_exempi" = "yes")
+test "$have_exempi" = "yes" && AC_DEFINE(HAVE_EXEMPI, [], [Define if we have exempi])
+
 AC_CONFIG_FILES([
 	Makefile
 	tracker.pc
@@ -675,6 +694,7 @@
 	exif (jpeg):				$have_libexif
 	gsf:					$have_libgsf
 	video files:				$videos_are_handled ($videos_handler)
+	embedded/sidecar xmp:			$have_exempi
 
 "
 if test "x$enable_external_sqlite" = "xyes"; then



Archive powered by MHonArc 2.6.24.

Top of Page