[tracker/writeback-taglib] tracker-writeback: Add taglib based module



commit ab84b817bc9edcd233abd921e4889d98c2ac3753
Author: Adrien Bustany <abustany gnome org>
Date:   Wed Apr 14 14:18:07 2010 -0400

    tracker-writeback: Add taglib based module
    
    The taglib based module allows doing writeback to a wide variety of audio
    formats. Currently, the modules writebacks the following rdf properties:
    - nie:title
    - nmm:artist (fetching nmm:artistName)
    - nmm:musicAlbum (fetching dc:title)
    - rdfs:comment
    - nmm:genre
    - nmm:trackerNumber.
    
    The supported file formats are MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio,
    WavPack, Ogg FLAC, Ogg Vorbis and Speex.

 configure.ac                                     |   24 ++
 src/tracker-writeback/Makefile.am                |   10 +
 src/tracker-writeback/tracker-writeback-taglib.c |  294 ++++++++++++++++++++++
 3 files changed, 328 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5a3e67f..783dfb9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,7 @@ EDS_REQUIRED=2.25.5
 LIBSTREAMANALYZER_REQUIRED=0.7.0
 GEE_REQUIRED=0.3
 ID3LIB_REQUIRED=3.8.3
+TAGLIB_REQUIRED=1.6
 GNOME_KEYRING_REQUIRED=2.26
 LIBGRSS_REQUIRED=0.3
 
@@ -283,6 +284,28 @@ CFLAGS="$OLD_CFLAGS"
 LIBS="$OLD_LIBS"
 
 ####################################################################
+# Taglib for audio writeback support
+####################################################################
+
+AC_ARG_ENABLE(taglib,
+              AS_HELP_STRING([--enable-taglib],
+                             [enable writeback for audio files [[default=auto]]]),,
+              [enable_taglib=auto])
+
+if test "x$enable_taglib" != "xno" ; then
+	PKG_CHECK_MODULES(TAGLIB,
+                      [taglib_c >= $TAGLIB_REQUIRED],
+                      [have_taglib=yes],
+                      [have_taglib=no])
+	AC_SUBST(TAGLIB_CFLAGS)
+	AC_SUBST(TAGLIB_LIBS)
+else
+	have_taglib="no  (disabled)"
+fi
+
+AM_CONDITIONAL(HAVE_TAGLIB, test "x$have_taglib" = "xyes")
+
+####################################################################
 # Stream Analyzer
 ####################################################################
 
@@ -1815,6 +1838,7 @@ Plugins:
 Writeback:
 
 	MP3:                                    $have_id3lib
+	Audio files using Taglib:               $have_taglib
 	XMP:                                    $have_exempi
 
 Warning:
diff --git a/src/tracker-writeback/Makefile.am b/src/tracker-writeback/Makefile.am
index 5c02c8c..38c11e5 100644
--- a/src/tracker-writeback/Makefile.am
+++ b/src/tracker-writeback/Makefile.am
@@ -17,6 +17,7 @@ INCLUDES = 								\
 	$(GMODULE_CFLAGS) 						\
 	$(DBUS_CFLAGS)							\
 	$(ID3LIB_CFLAGS)						\
+	$(TAGLIB_CFLAGS)						\
 	$(EXEMPI_CFLAGS)						\
 	$(TOTEM_PL_PARSER_CFLAGS)
 
@@ -30,6 +31,15 @@ modules_LTLIBRARIES =
 #libwriteback_mp3_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) $(ID3LIB_LIBS)
 #endif
 
+# Audio files (MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack,
+# Ogg FLAC, Ogg Vorbis and Speex)
+if HAVE_TAGLIB
+modules_LTLIBRARIES += libwriteback-taglib.la
+libwriteback_taglib_la_SOURCES = tracker-writeback-taglib.c
+libwriteback_taglib_la_LDFLAGS = $(module_flags)
+libwriteback_taglib_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) $(TAGLIB_LIBS)
+endif
+
 # XMP
 if HAVE_EXEMPI
 modules_LTLIBRARIES += libwriteback-xmp.la
diff --git a/src/tracker-writeback/tracker-writeback-taglib.c b/src/tracker-writeback/tracker-writeback-taglib.c
new file mode 100644
index 0000000..751531b
--- /dev/null
+++ b/src/tracker-writeback/tracker-writeback-taglib.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2010, Adrien Bustany <abustany gnome org>
+ *
+ * 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 <glib-object.h>
+#include <taglib/tag_c.h>
+#include <stdlib.h>
+
+#include <libtracker-common/tracker-ontologies.h>
+
+#include "tracker-writeback-file.h"
+
+#define TRACKER_TYPE_WRITEBACK_TAGLIB (tracker_writeback_taglib_get_type ())
+
+typedef struct TrackerWritebackTaglib TrackerWritebackTaglib;
+typedef struct TrackerWritebackTaglibClass TrackerWritebackTaglibClass;
+
+struct TrackerWritebackTaglib {
+	TrackerWritebackFile parent_instance;
+};
+
+struct TrackerWritebackTaglibClass {
+	TrackerWritebackFileClass parent_class;
+};
+
+static GType                tracker_writeback_taglib_get_type         (void) G_GNUC_CONST;
+static gboolean             writeback_taglib_update_file_metadata     (TrackerWritebackFile *wbf,
+                                                                       GFile                *file,
+                                                                       GPtrArray            *values,
+                                                                       TrackerClient        *client);
+static const gchar * const *writeback_taglib_content_types            (TrackerWritebackFile *wbf);
+static gchar*               writeback_taglib_get_artist_name (TrackerClient *client,
+                                                              const gchar *urn);
+static gchar*               writeback_taglib_get_album_name  (TrackerClient *client,
+                                                              const gchar *urn);
+
+G_DEFINE_DYNAMIC_TYPE (TrackerWritebackTaglib, tracker_writeback_taglib, TRACKER_TYPE_WRITEBACK_FILE);
+
+static void
+tracker_writeback_taglib_class_init (TrackerWritebackTaglibClass *klass)
+{
+	TrackerWritebackFileClass *writeback_file_class = TRACKER_WRITEBACK_FILE_CLASS (klass);
+
+	writeback_file_class->update_file_metadata = writeback_taglib_update_file_metadata;
+	writeback_file_class->content_types = writeback_taglib_content_types;
+}
+
+static void
+tracker_writeback_taglib_class_finalize (TrackerWritebackTaglibClass *klass)
+{
+}
+
+static void
+tracker_writeback_taglib_init (TrackerWritebackTaglib *wbt)
+{
+}
+
+static const gchar * const *
+writeback_taglib_content_types (TrackerWritebackFile *wbf)
+{
+	static const gchar *content_types [] = {
+		"audio/x-mpc",
+		"audio/x-musepack",
+		"audio/mpc",
+		"audio/musepack",
+		"audio/mpeg",
+		"audio/x-mpeg",
+		"audio/mp3",
+		"audio/x-mp3",
+		"audio/mpeg3",
+		"audio/x-mpeg3",
+		"audio/mpg",
+		"audio/x-mpg",
+		"audio/x-mpegaudio",
+		"audio/flac",
+		"audio/mp4",
+		"audio/asf",
+		"application/asx",
+		"video/x-ms-asf-plugin",
+		"application/x-mplayer2",
+		"video/x-ms-asf",
+		"application/vnd.ms-asf",
+		"video/x-ms-asf-plugin",
+		"video/x-ms-wm",
+		"video/x-ms-wmx",
+		"audio/aiff",
+		"audio/x-aiff",
+		"sound/aiff",
+		"audio/rmf",
+		"audio/x-rmf",
+		"audio/x-pn-aiff",
+		"audio/x-gsm",
+		"audio/mid",
+		"audio/x-midi",
+		"audio/vnd.qcelp",
+		"audio/wav",
+		"audio/x-wav",
+		"audio/wave",
+		"audio/x-pn-wav",
+		"audio/tta",
+		"audio/x-tta",
+		"audio/ogg",
+		"application/ogg",
+		"audio/x-ogg",
+		"application/x-ogg",
+		"audio/x-speex",
+		NULL
+	};
+
+	return content_types;
+}
+
+static gboolean
+writeback_taglib_update_file_metadata (TrackerWritebackFile *writeback_file,
+                                       GFile                *file,
+                                       GPtrArray            *values,
+                                       TrackerClient        *client)
+{
+	TagLib_File *taglib_file;
+	TagLib_Tag *tag;
+	guint n;
+
+	taglib_file = taglib_file_new (g_file_get_path (file));
+
+	if (!taglib_file || !taglib_file_is_valid (taglib_file)) {
+		return FALSE;
+	}
+
+	tag = taglib_file_tag (taglib_file);
+
+	for (n = 0; n < values->len; n++) {
+		const GStrv row = g_ptr_array_index (values, n);
+
+		if (g_strcmp0 (row[2], TRACKER_NIE_PREFIX "title") == 0) {
+			taglib_tag_set_title (tag, row[3]);
+		}
+
+		if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "artist") == 0) {
+			gchar *artist_name = writeback_taglib_get_artist_name (client, row[3]);
+
+			if (artist_name) {
+				taglib_tag_set_artist (tag, artist_name);
+				g_free (artist_name);
+			}
+		}
+
+		if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "musicAlbum") == 0) {
+			gchar *album_name = writeback_taglib_get_album_name (client, row[3]);
+
+			if (album_name) {
+				taglib_tag_set_album (tag, album_name);
+				g_free (album_name);
+			}
+		}
+
+		if (g_strcmp0 (row[2], TRACKER_RDFS_PREFIX "comment") == 0) {
+			taglib_tag_set_comment (tag, row[3]);
+		}
+
+		if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "genre") == 0) {
+			taglib_tag_set_genre (tag, row[3]);
+		}
+
+		if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "trackNumber") == 0) {
+			taglib_tag_set_track (tag, atoi (row[3]));
+		}
+	}
+
+	taglib_file_save (taglib_file);
+	taglib_file_free (taglib_file);
+
+	return TRUE;
+}
+
+static gchar*
+writeback_taglib_get_artist_name (TrackerClient  *client,
+                                  const gchar    *urn)
+{
+	static const gchar *artist_name_query =
+		"SELECT ?artistName WHERE {<%s> nmm:artistName ?artistName}";
+	gchar *query;
+	GPtrArray *query_results;
+	GError *error = NULL;
+	gchar *artist_name;
+
+	artist_name = NULL;
+
+	query = g_strdup_printf (artist_name_query, urn);
+	GError *inner_error = NULL;
+
+	query_results = tracker_resources_sparql_query (client,
+	                                                query,
+	                                                &inner_error);
+
+	if (error || query_results->len != 1) {
+		g_warning ("Couldn't find artist name for artist with urn '%s', %s",
+		           urn,
+		           error ? error->message : "no such artist was found");
+
+		if (error) {
+			g_error_free (error);
+		}
+	} else {
+		gchar **data;
+
+		data = g_ptr_array_index (query_results, 0);
+		artist_name = g_strdup (data[0]);
+	}
+
+	g_free (query);
+	g_ptr_array_foreach (query_results, (GFunc) g_strfreev, NULL);
+	g_ptr_array_free (query_results, TRUE);
+
+	return artist_name;
+}
+
+static gchar*
+writeback_taglib_get_album_name (TrackerClient  *client,
+                                 const gchar    *urn)
+{
+	static const gchar *album_name_query =
+		"SELECT ?albumName WHERE {<%s> dc:title ?albumName}";
+	gchar *query;
+	GPtrArray *query_results;
+	GError *error = NULL;
+	gchar *album_name;
+
+	album_name = NULL;
+
+	query = g_strdup_printf (album_name_query, urn);
+	GError *inner_error = NULL;
+
+	query_results = tracker_resources_sparql_query (client,
+	                                                query,
+	                                                &inner_error);
+
+	if (error || query_results->len != 1) {
+		g_warning ("Couldn't find album name for album with urn '%s', %s",
+		           urn,
+		           error ? error->message : "no such album was found");
+
+		if (error) {
+			g_error_free (error);
+		}
+	} else {
+		gchar **data;
+
+		data = g_ptr_array_index (query_results, 0);
+		album_name = g_strdup (data[0]);
+	}
+
+	g_free (query);
+	g_ptr_array_foreach (query_results, (GFunc) g_strfreev, NULL);
+	g_ptr_array_free (query_results, TRUE);
+
+	return album_name;
+}
+
+TrackerWriteback *
+writeback_module_create (GTypeModule *module)
+{
+	tracker_writeback_taglib_register_type (module);
+
+	return g_object_new (TRACKER_TYPE_WRITEBACK_TAGLIB, NULL);
+}
+
+const gchar * const *
+writeback_module_get_rdf_types (void)
+{
+	static const gchar *rdftypes[] = {
+		TRACKER_NFO_PREFIX "Audio",
+		NULL
+	};
+
+	return rdftypes;
+}



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