tracker r2914 - in trunk: . src/libtracker-common src/tracker-extract



Author: pvanhoof
Date: Wed Feb 11 10:16:03 2009
New Revision: 2914
URL: http://svn.gnome.org/viewvc/tracker?rev=2914&view=rev

Log:
2009-02-11  Philip Van Hoof  <philip codeminded be>

	* src/tracker-extract/tracker-extract-mp3.c
	* src/tracker-extract/tracker-extract-gstreamer-helix.c
	* src/tracker-extract/tracker-extract-gstreamer.c
	* src/tracker-extract/Makefile.am
	* src/libtracker-common/Makefile.am
	* src/tracker-extract/tracker-extract-albumart.c
	* src/tracker-extract/tracker-extract-albumart.h
	* src/libtracker-common/tracker-albumart.c
	* src/libtracker-common/tracker-albumart.h
	* src/tracker-extract/tracker-albumart.c
	* src/tracker-extract/tracker-albumart.h: Made a library for the album-art
	code, because other processes (tracker-indexer and trackerd) will soon
	have to perform album-art use-cases and requests too (not only the 
	tracker-extract will have to do it anymore)



Added:
   trunk/src/libtracker-common/tracker-albumart.c
   trunk/src/libtracker-common/tracker-albumart.h
   trunk/src/tracker-extract/tracker-extract-albumart.c
      - copied, changed from r2913, /trunk/src/tracker-extract/tracker-albumart.c
   trunk/src/tracker-extract/tracker-extract-albumart.h
      - copied, changed from r2913, /trunk/src/tracker-extract/tracker-albumart.h
Removed:
   trunk/src/tracker-extract/tracker-albumart.c
   trunk/src/tracker-extract/tracker-albumart.h
Modified:
   trunk/ChangeLog
   trunk/src/libtracker-common/Makefile.am
   trunk/src/tracker-extract/Makefile.am
   trunk/src/tracker-extract/tracker-extract-gstreamer-helix.c
   trunk/src/tracker-extract/tracker-extract-gstreamer.c
   trunk/src/tracker-extract/tracker-extract-mp3.c

Modified: trunk/src/libtracker-common/Makefile.am
==============================================================================
--- trunk/src/libtracker-common/Makefile.am	(original)
+++ trunk/src/libtracker-common/Makefile.am	Wed Feb 11 10:16:03 2009
@@ -5,13 +5,14 @@
 	-DG_LOG_DOMAIN=\"Tracker\"			\
 	-DTRACKER_COMPILATION				\
 	-I$(top_srcdir)/src				\
-	$(WARN_CFLAGS)							\
+	$(WARN_CFLAGS)					\
 	$(HAL_CFLAGS)					\
 	$(DBUS_CFLAGS)					\
 	$(UNAC_CFLAGS)					\
 	$(PANGO_CFLAGS)					\
 	$(GIO_CFLAGS)					\
-	$(GLIB2_CFLAGS)
+	$(GLIB2_CFLAGS)					\
+	$(GDKPIXBUF_CFLAGS)
 
 libtracker_commondir = $(libdir)/tracker
 libtracker_commonincludedir=$(includedir)/tracker-1.0/libtracker-common/
@@ -48,7 +49,8 @@
 	tracker-service.c				\
 	tracker-type-utils.c				\
 	tracker-utils.c					\
-	tracker-thumbnailer.c
+	tracker-thumbnailer.c				\
+	tracker-albumart.c
 
 noinst_HEADERS =					\
 	$(hal_headers)					\
@@ -57,7 +59,8 @@
 	tracker-log.h					\
 	tracker-nfs-lock.h				\
 	tracker-os-dependant.h				\
-	tracker-thumbnailer.h
+	tracker-thumbnailer.h				\
+	tracker-albumart.h
 
 libtracker_commoninclude_HEADERS =			\
 	tracker-common.h				\
@@ -80,7 +83,8 @@
 	$(UNAC_LIBS)					\
 	$(PANGO_LIBS)					\
 	$(GIO_LIBS)					\
-	$(GLIB2_LIBS)
+	$(GLIB2_LIBS)					\
+	$(GDKPIXBUF_LIBS)
 
 
 tracker-marshal.h: tracker-marshal.list

Added: trunk/src/libtracker-common/tracker-albumart.c
==============================================================================
--- (empty file)
+++ trunk/src/libtracker-common/tracker-albumart.c	Wed Feb 11 10:16:03 2009
@@ -0,0 +1,643 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * 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 "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#ifdef HAVE_GDKPIXBUF
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#endif
+#include <dbus/dbus-glib-bindings.h>
+
+#include <libtracker-common/tracker-common.h>
+
+
+#include "tracker-albumart.h"
+
+#define ALBUMARTER_SERVICE      "com.nokia.albumart"
+#define ALBUMARTER_PATH         "/com/nokia/albumart/Requester"
+#define ALBUMARTER_INTERFACE    "com.nokia.albumart.Requester"
+
+#define THUMBNAILER_SERVICE      "org.freedesktop.thumbnailer"
+#define THUMBNAILER_PATH         "/org/freedesktop/thumbnailer/Generic"
+#define THUMBNAILER_INTERFACE    "org.freedesktop.thumbnailer.Generic"
+
+typedef struct {
+	gchar *art_path;
+	gchar *local_uri;
+} GetFileInfo;
+
+static gchar *
+my_compute_checksum_for_data (GChecksumType  checksum_type,
+                              const guchar  *data,
+                              gsize          length)
+{
+  GChecksum *checksum;
+  gchar *retval;
+
+  checksum = g_checksum_new (checksum_type);
+  if (!checksum)
+    return NULL;
+
+  g_checksum_update (checksum, data, length);
+  retval = g_strdup (g_checksum_get_string (checksum));
+  g_checksum_free (checksum);
+
+  return retval;
+}
+
+#ifndef HAVE_STRCASESTR
+
+static gchar *
+strcasestr (const gchar *haystack, 
+	    const gchar *needle)
+{
+	gchar *p;
+	gchar *startn = NULL;
+	gchar *np = NULL;
+
+	for (p = (gchar *) haystack; *p; p++) {
+		if (np) {
+			if (toupper (*p) == toupper (*np)) {
+				if (!*++np) {
+					return startn;
+				}
+			} else {
+				np = 0;
+			}
+		} else if (toupper (*p) == toupper (*needle)) {
+			np = (gchar *) needle + 1;
+			startn = p;
+		}
+	}
+
+	return NULL;
+}
+
+#endif /* HAVE_STRCASESTR */
+
+/* NOTE: This function was stolen from GLib 2.18.x. Since upstream and
+ * the Maemo branch don't have this in circulation yet, we have copied
+ * it here. This can be removed an replaced with
+ * g_file_make_directory_with_parents() when we get it. -mr
+ */
+static gboolean
+make_directory_with_parents (GFile         *file,
+			     GCancellable  *cancellable,
+			     GError       **error)
+{
+  gboolean result;
+  GFile *parent_file, *work_file;
+  GList *list = NULL, *l;
+  GError *my_error = NULL;
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
+
+  result = g_file_make_directory (file, cancellable, &my_error);
+  if (result || my_error->code != G_IO_ERROR_NOT_FOUND)
+    {
+      if (my_error)
+        g_propagate_error (error, my_error);
+      return result;
+    }
+
+  work_file = file;
+
+  while (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
+    {
+      g_clear_error (&my_error);
+
+      parent_file = g_file_get_parent (work_file);
+      if (parent_file == NULL)
+        break;
+      result = g_file_make_directory (parent_file, cancellable, &my_error);
+
+      if (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
+        list = g_list_prepend (list, parent_file);
+
+      work_file = parent_file;
+    }
+
+  for (l = list; result && l; l = l->next)
+    {
+      result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
+    }
+
+  /* Clean up */
+  while (list != NULL)
+    {
+      g_object_unref ((GFile *) list->data);
+      list = g_list_remove (list, list->data);
+    }
+
+  if (!result)
+    {
+      g_propagate_error (error, my_error);
+      return result;
+    }
+
+  return g_file_make_directory (file, cancellable, error);
+}
+
+
+
+static gchar*
+strip_characters (const gchar *original)
+{
+	const gchar *foo = "()[]<>{}_! #$^&*+=|\\/\"'?~";
+	guint osize = strlen (original);
+	gchar *retval = (gchar *) g_malloc0 (sizeof (gchar *) * osize + 1);
+	guint i = 0, y = 0;
+
+	while (i < osize) {
+
+		/* Remove (anything) */
+
+		if (original[i] == '(') {
+			gchar *loc = strchr (original+i, ')');
+			if (loc) {
+				i = loc - original + 1;
+				continue;
+			}
+		}
+
+		/* Remove [anything] */
+
+		if (original[i] == '[') {
+			gchar *loc = strchr (original+i, ']');
+			if (loc) {
+				i = loc - original + 1;
+				continue;
+			}
+		}
+
+		/* Remove {anything} */
+
+		if (original[i] == '{') {
+			gchar *loc = strchr (original+i, '}');
+			if (loc) {
+				i = loc - original + 1;
+				continue;
+			}
+		}
+
+		/* Remove <anything> */
+
+		if (original[i] == '<') {
+			gchar *loc = strchr (original+i, '>');
+			if (loc) {
+				i = loc - original + 1;
+				continue;
+			}
+		}
+
+		/* Remove double whitespaces */
+
+		if ((y > 0) &&
+		    (original[i] == ' ' || original[i] == '\t') &&
+		    (retval[y-1] == ' ' || retval[y-1] == '\t')) {
+			i++;
+			continue;
+		}
+
+		/* Remove strange characters */
+
+		if (!strchr (foo, original[i])) {
+			retval[y] = original[i]!='\t'?original[i]:' ';
+			y++;
+		}
+
+		i++;
+	}
+
+	retval[y] = 0;
+
+	return retval;
+}
+
+
+void
+tracker_albumart_copy_to_local (const gchar *filename, const gchar *local_uri)
+{
+#ifdef HAVE_HAL
+	TrackerHal *hal;
+#endif
+	GList *removable_roots, *l;
+	gboolean on_removable_device = FALSE;
+	guint flen;
+
+	if (!filename)
+		return;
+
+	if (!local_uri)
+		return;
+
+	flen = strlen (filename);
+
+	/* Determining if we are on a removable device */
+
+#ifdef HAVE_HAL
+	hal = tracker_hal_new ();
+	removable_roots = tracker_hal_get_removable_device_roots (hal);
+	g_object_unref (hal);
+#else
+	removable_roots = g_list_append (removable_roots, "/media");
+	removable_roots = g_list_append (removable_roots, "/mnt");
+#endif
+
+	for (l = removable_roots; l; l = l->next) {
+		guint len;
+		
+		len = strlen (l->data);
+
+		if (flen >= len && strncmp (filename, l->data, len)) {
+			on_removable_device = TRUE;
+			break;
+		}
+	}
+
+#ifdef HAVE_HAL
+	g_list_foreach (removable_roots, (GFunc) g_free, NULL);
+#endif
+
+	g_list_free (removable_roots);
+
+	if (on_removable_device) {
+		GFile *local_file, *from;
+
+		from = g_file_new_for_path (filename);
+		local_file = g_file_new_for_uri (local_uri);
+
+		/* We don't try to overwrite, but we also ignore all errors.
+		 * Such an error could be that the removable device is 
+		 * read-only. Well that's fine then ... ignore */
+
+		if (!g_file_query_exists (local_file, NULL)) {
+			GFile *dirf;
+
+			dirf = g_file_get_parent (local_file);
+			make_directory_with_parents (dirf, NULL, NULL);
+			g_object_unref (dirf);
+
+			g_file_copy_async (from, local_file, 0, 0, 
+					   NULL, NULL, NULL, NULL, NULL);
+		}
+
+		g_object_unref (local_file);
+		g_object_unref (from);
+	}
+}
+
+gboolean 
+tracker_albumart_heuristic (const gchar *artist_,  
+			    const gchar *album_, 
+			    const gchar *tracks_str, 
+			    const gchar *filename,
+			    const gchar *local_uri,
+			    gboolean    *copied)
+{
+	GFile *file;
+	GDir *dir;
+	struct stat st;
+	gchar *target = NULL;
+	gchar *basename;
+	const gchar *name;
+	gboolean retval;
+	gint tracks;
+	gint count;
+	gchar *artist = NULL;
+	gchar *album = NULL;
+
+	/* Copy from local album art (.mediaartlocal) to spec */
+
+	if (local_uri) {
+	  GFile *local_file;
+
+	  local_file = g_file_new_for_uri (local_uri);
+
+	  if (g_file_query_exists (local_file, NULL)) {
+
+		tracker_albumart_get_path (artist, album, 
+					   "album", NULL, 
+					   &target, NULL);
+
+		file = g_file_new_for_path (target);
+
+		g_file_copy_async (local_file, file, 0, 0, 
+				   NULL, NULL, NULL, NULL, NULL);
+
+		g_object_unref (file);
+		g_object_unref (local_file);
+
+		*copied = TRUE;
+		g_free (target);
+
+		return TRUE;
+	  }
+	  g_object_unref (local_file);
+	}
+
+	*copied = FALSE;
+
+	file = g_file_new_for_path (filename);
+	basename = g_file_get_basename (file);
+	g_object_unref (file);
+
+	if (!basename) {
+		return FALSE;
+	}
+
+	dir = g_dir_open (basename, 0, NULL);
+
+	if (!dir) {
+		g_free (basename);
+		return FALSE;
+	}
+
+	retval = FALSE;
+	file = NULL;
+
+	g_stat (basename, &st);
+	count = st.st_nlink;
+	
+	if (tracks_str) {
+		tracks = atoi (tracks_str);
+	} else {
+		tracks = -1;
+	}
+
+	if (artist_)
+		artist = strip_characters (artist_);
+	if (album_)
+		album = strip_characters (album_);
+
+	/* If amount of files and amount of tracks in the album somewhat match */
+
+	if ((tracks != -1 && tracks < count + 3 && tracks > count - 3) || 
+	    (tracks == -1 && count > 8 && count < 50)) {
+		gchar *found = NULL;
+
+		/* Try to find cover art in the directory */
+
+		for (name = g_dir_read_name (dir); name; name = g_dir_read_name (dir)) {
+			if ((artist && strcasestr (name, artist)) || 
+			    (album && strcasestr (name, album))   || 
+			    (strcasestr (name, "cover"))) {
+				GError *error = NULL;
+				
+				if (g_str_has_suffix (name, "jpeg") || 
+				    g_str_has_suffix (name, "jpg")) {
+					GFile *file_found;
+					
+					if (!target) {
+						tracker_albumart_get_path (artist, album, 
+									   "album", NULL, 
+									   &target, NULL);
+					}
+					
+					if (!file) {
+						file = g_file_new_for_path (target);
+					}
+					
+					found = g_build_filename (basename, name, NULL);
+					file_found = g_file_new_for_path (found);
+					
+					g_file_copy (file_found, file, 0, NULL, NULL, NULL, &error);
+					
+					if (!error) {
+						retval = TRUE;
+					} else {
+						g_error_free (error);
+						retval = FALSE;
+					}
+					
+					g_free (found);
+					g_object_unref (file_found);
+				} else {
+#ifdef HAVE_GDKPIXBUF
+					GdkPixbuf *pixbuf;
+					
+					found = g_build_filename (basename, name, NULL);
+					pixbuf = gdk_pixbuf_new_from_file (found, &error);
+					
+					if (error) {
+						g_error_free (error);
+						retval = FALSE;
+					} else {
+						if (!target) {
+							tracker_albumart_get_path (artist, 
+										   album, 
+										   "album", 
+										   NULL, 
+										   &target, 
+										   NULL);
+						}
+						
+						gdk_pixbuf_save (pixbuf, target, "jpeg", &error, NULL);
+						
+						if (!error) {
+							retval = TRUE;
+						} else {
+							g_error_free (error);
+							retval = FALSE;
+						}
+					}
+					
+					g_free (found);
+#else  /* HAVE_GDKPIXBUF */
+					retval = FALSE;
+#endif /* HAVE_GDKPIXBUF */
+				}
+
+				if (retval)
+					break;
+			}
+		}
+		
+	}
+	
+	g_dir_close (dir);
+	
+	if (file) {
+		g_object_unref (file);
+	}
+
+	g_free (target);
+	g_free (basename);
+	g_free (artist);
+	g_free (album);
+
+	return retval;
+}
+
+static DBusGProxy*
+get_albumart_requester (void)
+{
+	static DBusGProxy *albart_proxy = NULL;
+
+	if (!albart_proxy) {
+		GError          *error = NULL;
+		DBusGConnection *connection;
+
+		connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+		if (!error) {
+			albart_proxy = dbus_g_proxy_new_for_name (connection,
+								  ALBUMARTER_SERVICE,
+								  ALBUMARTER_PATH,
+								  ALBUMARTER_INTERFACE);
+		} else {
+			g_error_free (error);
+		}
+	}
+
+	return albart_proxy;
+}
+
+
+static void
+tracker_albumart_queue_cb (DBusGProxy     *proxy,
+			   DBusGProxyCall *call,
+			   gpointer	    user_data)
+{
+	GError      *error = NULL;
+	guint        handle;
+	GetFileInfo *info = user_data;
+
+	dbus_g_proxy_end_call (proxy, call, &error,
+			       G_TYPE_UINT, &handle,
+			       G_TYPE_INVALID);
+
+	if (g_file_test (info->art_path, G_FILE_TEST_EXISTS)) {
+
+		gchar * asuri = g_filename_to_uri (info->art_path, NULL, NULL);
+		tracker_thumbnailer_get_file_thumbnail (asuri, "image/jpeg");
+		g_free (asuri);
+
+		tracker_albumart_copy_to_local (info->art_path, info->local_uri);
+	}
+
+	g_free (info->art_path);
+	g_free (info->local_uri);
+
+	g_slice_free (GetFileInfo, info);
+
+	if (error) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+}
+
+void
+tracker_albumart_get_path (const gchar  *a, 
+			   const gchar  *b, 
+			   const gchar  *prefix, 
+			   const gchar  *uri,
+			   gchar       **path,
+			   gchar       **local)
+{
+	gchar *art_filename;
+	gchar *dir;
+	gchar *down1, *down2;
+	gchar *str1 = NULL, *str2 = NULL;
+	gchar *f_a = NULL, *f_b = NULL;
+
+	/* http://live.gnome.org/MediaArtStorageSpec */
+
+	*path = NULL;
+
+	if (!a && !b) {
+		return;
+	}
+
+	if (!a) 
+		f_a = g_strdup (" ");
+	else
+		f_a = strip_characters (a);
+
+	if (!b)
+		f_b = g_strdup (" ");
+	else
+		f_b = strip_characters (b);
+
+	down1 = g_utf8_strdown (f_a, -1);
+	down2 = g_utf8_strdown (f_b, -1);
+
+	g_free (f_a);
+	g_free (f_b);
+
+	dir = g_build_filename (g_get_user_cache_dir (), "media-art", NULL);
+
+	if (!g_file_test (dir, G_FILE_TEST_EXISTS)) {
+		g_mkdir_with_parents (dir, 0770);
+	}
+
+	str1 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down1, strlen (down1));
+	str2 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down2, strlen (down2));
+
+	g_free (down1);
+	g_free (down2);
+
+	art_filename = g_strdup_printf ("%s-%s-%s.jpeg", prefix?prefix:"album", str1, str2);
+
+	*path = g_build_filename (dir, art_filename, NULL);
+	g_free (dir);
+	g_free (art_filename);
+	g_free (str1);
+	g_free (str2);
+}
+
+void
+tracker_albumart_request_download (gchar *album, 
+				   gchar *artist, 
+				   gchar *local_uri, 
+				   gchar *art_path)
+{
+	GetFileInfo *info;
+
+	info = g_slice_new (GetFileInfo);
+
+	info->local_uri = g_strdup (local_uri);
+	info->art_path = g_strdup (art_path);
+
+	dbus_g_proxy_begin_call (get_albumart_requester (),
+				 "Queue",
+				 tracker_albumart_queue_cb,
+				 info, NULL,
+				 G_TYPE_STRING, artist,
+				 G_TYPE_STRING, album,
+				 G_TYPE_STRING, "album",
+				 G_TYPE_UINT, 0,
+				 G_TYPE_INVALID);
+}

Added: trunk/src/libtracker-common/tracker-albumart.h
==============================================================================
--- (empty file)
+++ trunk/src/libtracker-common/tracker-albumart.h	Wed Feb 11 10:16:03 2009
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ * 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>
+ */
+
+#ifndef __TRACKER_ALBUMART_H__
+#define __TRACKER_ALBUMART_H__
+
+G_BEGIN_DECLS
+
+gboolean tracker_albumart_heuristic        (const gchar *artist_,  
+					    const gchar *album_, 
+					    const gchar *tracks_str, 
+					    const gchar *filename,
+					    const gchar *local_uri,
+					    gboolean    *copied);
+void     tracker_albumart_copy_to_local    (const gchar *filename, 
+					    const gchar *local_uri);
+void     tracker_albumart_get_path         (const gchar  *a, 
+					    const gchar  *b, 
+					    const gchar  *prefix, 
+					    const gchar  *uri,
+					    gchar       **path,
+					    gchar       **local);
+void     tracker_albumart_request_download (gchar *album, 
+					    gchar *artist, 
+					    gchar *local_uri, 
+					    gchar *art_path);
+
+G_END_DECLS
+
+#endif /* __TRACKER_THUMBNAILER_H__ */

Modified: trunk/src/tracker-extract/Makefile.am
==============================================================================
--- trunk/src/tracker-extract/Makefile.am	(original)
+++ trunk/src/tracker-extract/Makefile.am	Wed Feb 11 10:16:03 2009
@@ -96,8 +96,8 @@
 albumart_libs = 
 albumart_flags = 
 albumart_sources =							\
-	tracker-albumart.c						\
-	tracker-albumart.h
+	tracker-extract-albumart.c						\
+	tracker-extract-albumart.h
 
 if HAVE_GDKPIXBUF
 albumart_flags += $(DBUS_CFLAGS)
@@ -234,4 +234,4 @@
 BUILT_SOURCES = 							\
 	$(dbus_sources)
 
-CLEANFILES = $(BUILT_SOURCES)
\ No newline at end of file
+CLEANFILES = $(BUILT_SOURCES)

Copied: trunk/src/tracker-extract/tracker-extract-albumart.c (from r2913, /trunk/src/tracker-extract/tracker-albumart.c)
==============================================================================
--- /trunk/src/tracker-extract/tracker-albumart.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-albumart.c	Wed Feb 11 10:16:03 2009
@@ -37,593 +37,11 @@
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #endif
 
-#include <dbus/dbus-glib-bindings.h>
-
 #include <libtracker-common/tracker-common.h>
 #include <libtracker-common/tracker-thumbnailer.h>
 
-#include "tracker-albumart.h"
-
-#define ALBUMARTER_SERVICE      "com.nokia.albumart"
-#define ALBUMARTER_PATH         "/com/nokia/albumart/Requester"
-#define ALBUMARTER_INTERFACE    "com.nokia.albumart.Requester"
-
-#define THUMBNAILER_SERVICE      "org.freedesktop.thumbnailer"
-#define THUMBNAILER_PATH         "/org/freedesktop/thumbnailer/Generic"
-#define THUMBNAILER_INTERFACE    "org.freedesktop.thumbnailer.Generic"
-
-
-static void get_albumart_path (const gchar  *a, 
-			       const gchar  *b, 
-			       const gchar  *prefix, 
-			       const gchar  *uri,
-			       gchar       **path,
-			       gchar       **local);
-
-static gchar *
-my_compute_checksum_for_data (GChecksumType  checksum_type,
-                              const guchar  *data,
-                              gsize          length)
-{
-  GChecksum *checksum;
-  gchar *retval;
-
-  checksum = g_checksum_new (checksum_type);
-  if (!checksum)
-    return NULL;
-
-  g_checksum_update (checksum, data, length);
-  retval = g_strdup (g_checksum_get_string (checksum));
-  g_checksum_free (checksum);
-
-  return retval;
-}
-
-#ifndef HAVE_STRCASESTR
-
-static gchar *
-strcasestr (const gchar *haystack, 
-	    const gchar *needle)
-{
-	gchar *p;
-	gchar *startn = NULL;
-	gchar *np = NULL;
-
-	for (p = (gchar *) haystack; *p; p++) {
-		if (np) {
-			if (toupper (*p) == toupper (*np)) {
-				if (!*++np) {
-					return startn;
-				}
-			} else {
-				np = 0;
-			}
-		} else if (toupper (*p) == toupper (*needle)) {
-			np = (gchar *) needle + 1;
-			startn = p;
-		}
-	}
-
-	return NULL;
-}
-
-#endif /* HAVE_STRCASESTR */
-
-/* NOTE: This function was stolen from GLib 2.18.x. Since upstream and
- * the Maemo branch don't have this in circulation yet, we have copied
- * it here. This can be removed an replaced with
- * g_file_make_directory_with_parents() when we get it. -mr
- */
-static gboolean
-make_directory_with_parents (GFile         *file,
-			     GCancellable  *cancellable,
-			     GError       **error)
-{
-  gboolean result;
-  GFile *parent_file, *work_file;
-  GList *list = NULL, *l;
-  GError *my_error = NULL;
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return FALSE;
-
-  result = g_file_make_directory (file, cancellable, &my_error);
-  if (result || my_error->code != G_IO_ERROR_NOT_FOUND)
-    {
-      if (my_error)
-        g_propagate_error (error, my_error);
-      return result;
-    }
-
-  work_file = file;
-
-  while (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
-    {
-      g_clear_error (&my_error);
-
-      parent_file = g_file_get_parent (work_file);
-      if (parent_file == NULL)
-        break;
-      result = g_file_make_directory (parent_file, cancellable, &my_error);
-
-      if (!result && my_error->code == G_IO_ERROR_NOT_FOUND)
-        list = g_list_prepend (list, parent_file);
-
-      work_file = parent_file;
-    }
-
-  for (l = list; result && l; l = l->next)
-    {
-      result = g_file_make_directory ((GFile *) l->data, cancellable, &my_error);
-    }
-
-  /* Clean up */
-  while (list != NULL)
-    {
-      g_object_unref ((GFile *) list->data);
-      list = g_list_remove (list, list->data);
-    }
-
-  if (!result)
-    {
-      g_propagate_error (error, my_error);
-      return result;
-    }
-
-  return g_file_make_directory (file, cancellable, error);
-}
-
-
-
-static gchar*
-strip_characters (const gchar *original)
-{
-	const gchar *foo = "()[]<>{}_! #$^&*+=|\\/\"'?~";
-	guint osize = strlen (original);
-	gchar *retval = (gchar *) g_malloc0 (sizeof (gchar *) * osize + 1);
-	guint i = 0, y = 0;
-
-	while (i < osize) {
-
-		/* Remove (anything) */
-
-		if (original[i] == '(') {
-			gchar *loc = strchr (original+i, ')');
-			if (loc) {
-				i = loc - original + 1;
-				continue;
-			}
-		}
-
-		/* Remove [anything] */
-
-		if (original[i] == '[') {
-			gchar *loc = strchr (original+i, ']');
-			if (loc) {
-				i = loc - original + 1;
-				continue;
-			}
-		}
-
-		/* Remove {anything} */
-
-		if (original[i] == '{') {
-			gchar *loc = strchr (original+i, '}');
-			if (loc) {
-				i = loc - original + 1;
-				continue;
-			}
-		}
-
-		/* Remove <anything> */
-
-		if (original[i] == '<') {
-			gchar *loc = strchr (original+i, '>');
-			if (loc) {
-				i = loc - original + 1;
-				continue;
-			}
-		}
-
-		/* Remove double whitespaces */
-
-		if ((y > 0) &&
-		    (original[i] == ' ' || original[i] == '\t') &&
-		    (retval[y-1] == ' ' || retval[y-1] == '\t')) {
-			i++;
-			continue;
-		}
-
-		/* Remove strange characters */
-
-		if (!strchr (foo, original[i])) {
-			retval[y] = original[i]!='\t'?original[i]:' ';
-			y++;
-		}
-
-		i++;
-	}
-
-	retval[y] = 0;
-
-	return retval;
-}
-
-
-static void
-perhaps_copy_to_local (const gchar *filename, const gchar *local_uri)
-{
-#ifdef HAVE_HAL
-	TrackerHal *hal;
-#endif
-	GList *removable_roots, *l;
-	gboolean on_removable_device = FALSE;
-	guint flen;
-
-	if (!filename)
-		return;
-
-	if (!local_uri)
-		return;
-
-	flen = strlen (filename);
-
-	/* Determining if we are on a removable device */
-
-#ifdef HAVE_HAL
-	hal = tracker_hal_new ();
-	removable_roots = tracker_hal_get_removable_device_roots (hal);
-	g_object_unref (hal);
-#else
-	removable_roots = g_list_append (removable_roots, "/media");
-	removable_roots = g_list_append (removable_roots, "/mnt");
-#endif
-
-	for (l = removable_roots; l; l = l->next) {
-		guint len;
-		
-		len = strlen (l->data);
-
-		if (flen >= len && strncmp (filename, l->data, len)) {
-			on_removable_device = TRUE;
-			break;
-		}
-	}
-
-#ifdef HAVE_HAL
-	g_list_foreach (removable_roots, (GFunc) g_free, NULL);
-#endif
-
-	g_list_free (removable_roots);
-
-	if (on_removable_device) {
-		GFile *local_file, *from;
-
-		from = g_file_new_for_path (filename);
-		local_file = g_file_new_for_uri (local_uri);
-
-		/* We don't try to overwrite, but we also ignore all errors.
-		 * Such an error could be that the removable device is 
-		 * read-only. Well that's fine then ... ignore */
-
-		if (!g_file_query_exists (local_file, NULL)) {
-			GFile *dirf;
-
-			dirf = g_file_get_parent (local_file);
-			make_directory_with_parents (dirf, NULL, NULL);
-			g_object_unref (dirf);
-
-			g_file_copy_async (from, local_file, 0, 0, 
-					   NULL, NULL, NULL, NULL, NULL);
-		}
-
-		g_object_unref (local_file);
-		g_object_unref (from);
-	}
-}
-
-static gboolean 
-heuristic_albumart (const gchar *artist_,  
-		    const gchar *album_, 
-		    const gchar *tracks_str, 
-		    const gchar *filename,
-		    const gchar *local_uri,
-		    gboolean    *copied)
-{
-	GFile *file;
-	GDir *dir;
-	struct stat st;
-	gchar *target = NULL;
-	gchar *basename;
-	const gchar *name;
-	gboolean retval;
-	gint tracks;
-	gint count;
-	gchar *artist = NULL;
-	gchar *album = NULL;
-
-	/* Copy from local album art (.mediaartlocal) to spec */
-
-	if (local_uri) {
-	  GFile *local_file;
-
-	  local_file = g_file_new_for_uri (local_uri);
-
-	  if (g_file_query_exists (local_file, NULL)) {
+#include "tracker-extract-albumart.h"
 
-		get_albumart_path (artist, album, 
-				   "album", NULL, 
-				   &target, NULL);
-
-		file = g_file_new_for_path (target);
-
-		g_file_copy_async (local_file, file, 0, 0, 
-				   NULL, NULL, NULL, NULL, NULL);
-
-		g_object_unref (file);
-		g_object_unref (local_file);
-
-		*copied = TRUE;
-		g_free (target);
-
-		return TRUE;
-	  }
-	  g_object_unref (local_file);
-	}
-
-	*copied = FALSE;
-
-	file = g_file_new_for_path (filename);
-	basename = g_file_get_basename (file);
-	g_object_unref (file);
-
-	if (!basename) {
-		return FALSE;
-	}
-
-	dir = g_dir_open (basename, 0, NULL);
-
-	if (!dir) {
-		g_free (basename);
-		return FALSE;
-	}
-
-	retval = FALSE;
-	file = NULL;
-
-	g_stat (basename, &st);
-	count = st.st_nlink;
-	
-	if (tracks_str) {
-		tracks = atoi (tracks_str);
-	} else {
-		tracks = -1;
-	}
-
-	if (artist_)
-		artist = strip_characters (artist_);
-	if (album_)
-		album = strip_characters (album_);
-
-	/* If amount of files and amount of tracks in the album somewhat match */
-
-	if ((tracks != -1 && tracks < count + 3 && tracks > count - 3) || 
-	    (tracks == -1 && count > 8 && count < 50)) {
-		gchar *found = NULL;
-
-		/* Try to find cover art in the directory */
-
-		for (name = g_dir_read_name (dir); name; name = g_dir_read_name (dir)) {
-			if ((artist && strcasestr (name, artist)) || 
-			    (album && strcasestr (name, album))   || 
-			    (strcasestr (name, "cover"))) {
-				GError *error = NULL;
-				
-				if (g_str_has_suffix (name, "jpeg") || 
-				    g_str_has_suffix (name, "jpg")) {
-					GFile *file_found;
-					
-					if (!target) {
-						get_albumart_path (artist, album, 
-								   "album", NULL, 
-								   &target, NULL);
-					}
-					
-					if (!file) {
-						file = g_file_new_for_path (target);
-					}
-					
-					found = g_build_filename (basename, name, NULL);
-					file_found = g_file_new_for_path (found);
-					
-					g_file_copy (file_found, file, 0, NULL, NULL, NULL, &error);
-					
-					if (!error) {
-						retval = TRUE;
-					} else {
-						g_error_free (error);
-						retval = FALSE;
-					}
-					
-					g_free (found);
-					g_object_unref (file_found);
-				} else {
-#ifdef HAVE_GDKPIXBUF
-					GdkPixbuf *pixbuf;
-					
-					found = g_build_filename (basename, name, NULL);
-					pixbuf = gdk_pixbuf_new_from_file (found, &error);
-					
-					if (error) {
-						g_error_free (error);
-						retval = FALSE;
-					} else {
-						if (!target) {
-							get_albumart_path (artist, 
-									   album, 
-									   "album", 
-									   NULL, 
-									   &target, 
-									   NULL);
-						}
-						
-						gdk_pixbuf_save (pixbuf, target, "jpeg", &error, NULL);
-						
-						if (!error) {
-							retval = TRUE;
-						} else {
-							g_error_free (error);
-							retval = FALSE;
-						}
-					}
-					
-					g_free (found);
-#else  /* HAVE_GDKPIXBUF */
-					retval = FALSE;
-#endif /* HAVE_GDKPIXBUF */
-				}
-
-				if (retval)
-					break;
-			}
-		}
-		
-	}
-	
-	g_dir_close (dir);
-	
-	if (file) {
-		g_object_unref (file);
-	}
-
-	g_free (target);
-	g_free (basename);
-	g_free (artist);
-	g_free (album);
-
-	return retval;
-}
-
-static DBusGProxy*
-get_albumart_requester (void)
-{
-	static DBusGProxy *albart_proxy = NULL;
-
-	if (!albart_proxy) {
-		GError          *error = NULL;
-		DBusGConnection *connection;
-
-		connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
-		if (!error) {
-			albart_proxy = dbus_g_proxy_new_for_name (connection,
-								  ALBUMARTER_SERVICE,
-								  ALBUMARTER_PATH,
-								  ALBUMARTER_INTERFACE);
-		} else {
-			g_error_free (error);
-		}
-	}
-
-	return albart_proxy;
-}
-
-typedef struct {
-	gchar *art_path, *local_uri;
-} GetFileInfo;
-
-
-static void
-get_file_albumart_queue_cb (DBusGProxy     *proxy,
-			    DBusGProxyCall *call,
-			    gpointer	    user_data)
-{
-	GError      *error = NULL;
-	guint        handle;
-	GetFileInfo *info = user_data;
-
-	dbus_g_proxy_end_call (proxy, call, &error,
-			       G_TYPE_UINT, &handle,
-			       G_TYPE_INVALID);
-
-	if (g_file_test (info->art_path, G_FILE_TEST_EXISTS)) {
-
-		gchar * asuri = g_filename_to_uri (info->art_path, NULL, NULL);
-		tracker_thumbnailer_get_file_thumbnail (asuri, "image/jpeg");
-		g_free (asuri);
-
-		perhaps_copy_to_local (info->art_path, info->local_uri);
-	}
-
-	g_free (info->art_path);
-	g_free (info->local_uri);
-
-	g_slice_free (GetFileInfo, info);
-
-	if (error) {
-		g_warning ("%s", error->message);
-		g_error_free (error);
-	}
-}
-
-static void
-get_albumart_path (const gchar  *a, 
-		   const gchar  *b, 
-		   const gchar  *prefix, 
-		   const gchar  *uri,
-		   gchar       **path,
-		   gchar       **local)
-{
-	gchar *art_filename;
-	gchar *dir;
-	gchar *down1, *down2;
-	gchar *str1 = NULL, *str2 = NULL;
-	gchar *f_a = NULL, *f_b = NULL;
-
-	/* http://live.gnome.org/MediaArtStorageSpec */
-
-	*path = NULL;
-
-	if (!a && !b) {
-		return;
-	}
-
-	if (!a) 
-		f_a = g_strdup (" ");
-	else
-		f_a = strip_characters (a);
-
-	if (!b)
-		f_b = g_strdup (" ");
-	else
-		f_b = strip_characters (b);
-
-	down1 = g_utf8_strdown (f_a, -1);
-	down2 = g_utf8_strdown (f_b, -1);
-
-	g_free (f_a);
-	g_free (f_b);
-
-	dir = g_build_filename (g_get_user_cache_dir (), "media-art", NULL);
-
-	if (!g_file_test (dir, G_FILE_TEST_EXISTS)) {
-		g_mkdir_with_parents (dir, 0770);
-	}
-
-	str1 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down1, strlen (down1));
-	str2 = my_compute_checksum_for_data (G_CHECKSUM_MD5, (const guchar *) down2, strlen (down2));
-
-	g_free (down1);
-	g_free (down2);
-
-	art_filename = g_strdup_printf ("%s-%s-%s.jpeg", prefix?prefix:"album", str1, str2);
-
-	*path = g_build_filename (dir, art_filename, NULL);
-	g_free (dir);
-	g_free (art_filename);
-	g_free (str1);
-	g_free (str2);
-}
 
 
 #ifdef HAVE_GDKPIXBUF
@@ -647,7 +65,7 @@
 		return FALSE;
 	}
 
-	get_albumart_path (artist, album, "album", NULL, &filename, NULL);
+	tracker_albumart_get_path (artist, album, "album", NULL, &filename, NULL);
 
 	loader = gdk_pixbuf_loader_new ();
 
@@ -708,8 +126,8 @@
 	else
 		filename_uri = g_filename_to_uri (filename, NULL, NULL);
 
-	get_albumart_path (artist, album, "album", filename_uri, 
-			   &art_path, &local_uri);
+	tracker_albumart_get_path (artist, album, "album", filename_uri, 
+				   &art_path, &local_uri);
 
 	if (!g_file_test (art_path, G_FILE_TEST_EXISTS)) {
 
@@ -730,28 +148,16 @@
 
 			/* If not, we perform a heuristic on the dir */
 
-			if (!heuristic_albumart (artist, album, trackercnt_str, filename, local_uri, &lcopied)) {
-				GetFileInfo *info;
+			if (!tracker_albumart_heuristic (artist, album, trackercnt_str, filename, local_uri, &lcopied)) {
 
 				/* If the heuristic failed, we request the download 
 				 * of the media-art to the media-art downloaders */
 
 				lcopied = TRUE;
-
-				info = g_slice_new (GetFileInfo);
-
-				info->local_uri = g_strdup (local_uri);
-				info->art_path = g_strdup (art_path);
-
-				dbus_g_proxy_begin_call (get_albumart_requester (),
-					 "Queue",
-					 get_file_albumart_queue_cb,
-					 info, NULL,
-					 G_TYPE_STRING, artist,
-					 G_TYPE_STRING, album,
-					 G_TYPE_STRING, "album",
-					 G_TYPE_UINT, 0,
-					 G_TYPE_INVALID);
+				tracker_albumart_request_download (artist,
+								   album,
+								   local_uri,
+								   art_path);
 			}
 #ifdef HAVE_GDKPIXBUF
 
@@ -771,7 +177,7 @@
 		}
 
 		if (!lcopied && g_file_test (art_path, G_FILE_TEST_EXISTS))
-			perhaps_copy_to_local (art_path, local_uri);
+			tracker_albumart_copy_to_local (art_path, local_uri);
 	}
 
 	g_free (art_path);

Copied: trunk/src/tracker-extract/tracker-extract-albumart.h (from r2913, /trunk/src/tracker-extract/tracker-albumart.h)
==============================================================================
--- /trunk/src/tracker-extract/tracker-albumart.h	(original)
+++ trunk/src/tracker-extract/tracker-extract-albumart.h	Wed Feb 11 10:16:03 2009
@@ -22,6 +22,8 @@
 
 #include <glib.h>
 
+#include <libtracker-common/tracker-albumart.h>
+
 G_BEGIN_DECLS
 
 gboolean tracker_process_albumart (const unsigned char *buffer,

Modified: trunk/src/tracker-extract/tracker-extract-gstreamer-helix.c
==============================================================================
--- trunk/src/tracker-extract/tracker-extract-gstreamer-helix.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-gstreamer-helix.c	Wed Feb 11 10:16:03 2009
@@ -34,7 +34,7 @@
 #include <gst/tag/tag.h>
 
 #include "tracker-main.h"
-#include "tracker-albumart.h"
+#include "tracker-extract-albumart.h"
 
 typedef enum {
 	EXTRACT_MIME_UNDEFINED=0,

Modified: trunk/src/tracker-extract/tracker-extract-gstreamer.c
==============================================================================
--- trunk/src/tracker-extract/tracker-extract-gstreamer.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-gstreamer.c	Wed Feb 11 10:16:03 2009
@@ -65,7 +65,7 @@
 #include <libtracker-common/tracker-type-utils.h>
 
 #include "tracker-main.h"
-#include "tracker-albumart.h"
+#include "tracker-extract-albumart.h"
 
 /*
  * Some fluendo plugins use non-standard tag names currently which cause

Modified: trunk/src/tracker-extract/tracker-extract-mp3.c
==============================================================================
--- trunk/src/tracker-extract/tracker-extract-mp3.c	(original)
+++ trunk/src/tracker-extract/tracker-extract-mp3.c	Wed Feb 11 10:16:03 2009
@@ -40,7 +40,7 @@
 #endif /* G_OS_WIN32 */
 
 #include "tracker-main.h"
-#include "tracker-albumart.h"
+#include "tracker-extract-albumart.h"
 #include "tracker-escape.h"
 
 /* FIXME The max file read is not a good idea as basic 



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