[maemo-commits] [maemo-commits] r16308 - in projects/haf/branches/hildon-thumbnail/daemonize: . thumbs

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Wed Oct 1 13:27:42 EEST 2008
Author: pvanhoof
Date: 2008-10-01 13:27:38 +0300 (Wed, 01 Oct 2008)
New Revision: 16308

Added:
   projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.c
   projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.h
Modified:
   projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog
   projects/haf/branches/hildon-thumbnail/daemonize/thumbs/
   projects/haf/branches/hildon-thumbnail/daemonize/thumbs/Makefile.am
Log:
2008-10-01  Philip Van Hoof  <pvanhoof at gnome.org>

	* thumbs/hildon-albumart-factory.c
	* thumbs/Makefile.am
	* thumbs/hildon-albumart-factory.h: Added a client C API for album art
	requesting



Modified: projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog	2008-10-01 08:57:32 UTC (rev 16307)
+++ projects/haf/branches/hildon-thumbnail/daemonize/ChangeLog	2008-10-01 10:27:38 UTC (rev 16308)
@@ -1,3 +1,15 @@
+2008-10-01  Philip Van Hoof  <pvanhoof at gnome.org>
+
+	* thumbs/hildon-albumart-factory.c
+	* thumbs/Makefile.am
+	* thumbs/hildon-albumart-factory.h: Added a client C API for album art
+	requesting
+
+2008-10-01  Philip Van Hoof  <pvanhoof at gnome.org>
+
+	* daemon/albumart.c: Heuristics for cover art
+	* albumart-providers/googleimages/google-images-art-downloader.vala: URI encoding
+
 2008-09-30  Philip Van Hoof  <pvanhoof at gnome.org>
 
 	* daemon/albumart-manager.c


Property changes on: projects/haf/branches/hildon-thumbnail/daemonize/thumbs
___________________________________________________________________
Name: svn:ignore
   - pixbuf-io-loader.c
thumbnailer-client.h
Makefile.in
hildon-thumb-gdk-pixbuf
hildon-thumber-register
.libs
.deps
Makefile


   + pixbuf-io-loader.c
thumbnailer-client.h
albumart-client.h
Makefile.in
hildon-thumb-gdk-pixbuf
hildon-thumber-register
.libs
.deps
Makefile




Modified: projects/haf/branches/hildon-thumbnail/daemonize/thumbs/Makefile.am
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/thumbs/Makefile.am	2008-10-01 08:57:32 UTC (rev 16307)
+++ projects/haf/branches/hildon-thumbnail/daemonize/thumbs/Makefile.am	2008-10-01 10:27:38 UTC (rev 16308)
@@ -39,12 +39,13 @@
 libhildonthumbnail_la_LDFLAGS = -version-info 0:4:0
 libhildonthumbnail_la_SOURCES = hildon-thumbnail-factory.c \
 	hildon-thumbnail-factory.h thumbnailer-client.h \
-	pixbuf-io-loader.c
+	pixbuf-io-loader.c hildon-albumart-factory.c \
+	hildon-albumart-factory.h albumart-client.h
 
 %-client.h: $(top_srcdir)/daemon/%.xml
 	$(DBUSBINDINGTOOL) --mode=glib-client --output=$@ --prefix=$(subst -,_,$*) $^
 
-BUILT_SOURCES = thumbnailer-client.h
+BUILT_SOURCES = thumbnailer-client.h albumart-client.h
 
 libhildonthumbnaildir=$(includedir)/hildon-thumbnail
 libhildonthumbnail_HEADERS = hildon-thumbnail-factory.h hildon-thumber-common.h

Added: projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.c
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.c	2008-10-01 08:57:32 UTC (rev 16307)
+++ projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.c	2008-10-01 10:27:38 UTC (rev 16308)
@@ -0,0 +1,473 @@
+/*
+ * This file is part of hildon-albumart package
+ *
+ * Copyright (C) 2005 Nokia Corporation.  All Rights reserved.
+ *
+ * Contact: Marius Vollmer <marius.vollmer at nokia.com>
+ * Author: Philip Van Hoof <pvanhoof at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "hildon-albumart-factory.h"
+#include "albumart-client.h"
+#include "utils.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <glib/gfileutils.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gio/gio.h>
+
+
+#define ALBUMARTER_SERVICE      "com.nokia.albumart"
+#define ALBUMARTER_PATH         "/com/nokia/albumart/Requester"
+#define ALBUMARTER_INTERFACE    "com.nokia.albumart.Requester"
+
+
+typedef struct {
+	gchar *uri, *album, *artist;
+	HildonAlbumartFactoryFinishedCallback callback;
+	gpointer user_data;
+	gboolean canceled;
+	guint handle_id;
+
+} ThumbsItem;
+
+
+#ifndef gdk_pixbuf_new_from_stream_at_scale
+/* It's implemented in pixbuf-io-loader.c in this case */
+GdkPixbuf* gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, gint width,
+			gint height, gboolean preserve_aspect_ratio,
+			GCancellable *cancellable, GError **error);
+#endif
+
+#ifndef gdk_pixbuf_new_from_stream
+/* It's implemented in pixbuf-io-loader.c in this case */
+GdkPixbuf * gdk_pixbuf_new_from_stream (GInputStream  *stream,
+			    GCancellable  *cancellable,
+			    GError       **error);
+#endif 
+
+#define THUMBS_ITEM(handle) (ThumbsItem*)(handle)
+#define THUMBS_HANDLE(item) (HildonAlbumartFactoryHandle)(item)
+#define HILDON_ALBUMART_APPLICATION "hildon-albumart"
+#define FACTORY_ERROR g_quark_from_static_string (HILDON_ALBUMART_APPLICATION)
+
+static void init (void);
+
+static gboolean show_debug = FALSE, had_init = FALSE;
+static DBusGProxy *proxy;
+static DBusGConnection *connection;
+static GHashTable *tasks;
+
+typedef struct {
+	gchar *file;
+	guint64 mtime;
+	guint64 size;
+} ThumbsCacheFile;
+
+static void thumb_item_free(ThumbsItem* item)
+{
+	g_free(item->uri);
+	g_free(item->artist);
+	g_free(item->album);
+	g_free(item);
+}
+
+static void
+create_pixbuf_and_callback (ThumbsItem *item, gchar *path)
+{
+		GFile *filei = NULL;
+		GInputStream *stream = NULL;
+		GdkPixbuf *pixbuf = NULL;
+		GError *error = NULL;
+
+		/* Open the original albumart as a stream */
+		filei = g_file_new_for_path (path);
+		stream = G_INPUT_STREAM (g_file_read (filei, NULL, &error));
+
+		if (error)
+			goto error_handler;
+
+		/* Read the stream as a pixbuf at the requested exact scale */
+		pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
+
+		error_handler:
+
+		/* Callback user function, passing the pixbuf and error */
+
+		item->callback (item, item->user_data, pixbuf, error);
+
+		/* Cleanup */
+		if (filei)
+			g_object_unref (filei);
+
+		if (stream) {
+			g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
+			g_object_unref (stream);
+		}
+
+		if (error)
+			g_error_free (error);
+
+		if (pixbuf)
+			gdk_pixbuf_unref (pixbuf);
+}
+
+static void
+on_task_finished (DBusGProxy *proxy,
+		  guint       handle,
+		  gpointer    user_data)
+{
+	gchar *key = g_strdup_printf ("%d", handle);
+	ThumbsItem *item = g_hash_table_lookup (tasks, key);
+
+	if (item) {
+		GError *error = NULL;
+		gchar *path;
+
+		/* Get the large small and cropped path for the original
+		 * URI */
+
+		hildon_thumbnail_util_get_albumart_path (item->artist, 
+												 item->album, 
+												 item->uri, &path);
+
+		create_pixbuf_and_callback (item, path);
+
+		error_handler:
+
+		g_free (path);
+
+		/* Remove the key from the hash, which means that we declare it 
+		 * handled. */
+		g_hash_table_remove (tasks, key);
+	}
+
+	g_free (key);
+
+}
+
+static void 
+read_cache_dir(gchar *path, GPtrArray *files)
+{
+	GDir *dir;
+	const gchar *file;
+
+	dir = g_dir_open(path, 0, NULL);
+
+	if(dir) {
+		while((file = g_dir_read_name(dir)) != NULL) {
+			gchar *file_path;
+			ThumbsCacheFile *item;
+			GFile *filei;
+			GFileInfo *info;
+			GError *error = NULL;
+			guint64 mtime, size;
+
+			file_path = g_build_filename (path, file, NULL);
+
+			if(file[0] == '.' || !g_file_test(file_path, G_FILE_TEST_IS_REGULAR)) {
+				g_free (file_path);
+				continue;
+			}
+
+			filei = g_file_new_for_path (file_path);
+
+			info = g_file_query_info (filei, G_FILE_ATTRIBUTE_TIME_MODIFIED ","
+						  G_FILE_ATTRIBUTE_STANDARD_SIZE,
+						  G_FILE_QUERY_INFO_NONE,
+						  NULL, &error);
+
+			if (error) {
+				g_error_free (error);
+				g_object_unref (filei);
+				g_free (file_path);
+				continue;
+			}
+
+			mtime = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+			size = g_file_info_get_size (info);
+
+			g_object_unref (filei);
+			g_object_unref (info);
+
+			item = g_new(ThumbsCacheFile, 1);
+			item->file = file_path;
+			item->mtime = mtime;
+			item->size = size;
+
+			g_ptr_array_add(files, item);
+		}
+
+		g_dir_close(dir);
+	}
+}
+
+static void
+cache_file_free(ThumbsCacheFile *item)
+{
+	g_free (item->file);
+	g_free (item);
+}
+
+static gint 
+cache_file_compare(gconstpointer a, gconstpointer b)
+{
+	ThumbsCacheFile *f1 = *(ThumbsCacheFile**)a,
+			        *f2 = *(ThumbsCacheFile**)b;
+
+	/* Sort in descending order */
+	if(f2->mtime == f1->mtime) {
+		return 0;
+	} else if(f2->mtime < f1->mtime) {
+		return -1;
+	} else {
+		return 1;
+	}
+}
+
+
+
+void 
+hildon_albumart_factory_clean_cache(gint max_size, time_t min_mtime)
+{
+	GPtrArray *files;
+	int i, size = 0;
+	gchar *a_dir =  g_build_filename (g_get_home_dir (), ".album_art", NULL);
+
+	init ();
+
+	files = g_ptr_array_new();
+
+	read_cache_dir (a_dir, files);
+
+	g_ptr_array_sort (files, cache_file_compare);
+
+	for(i = 0; i < files->len; i++) {
+		ThumbsCacheFile *item = g_ptr_array_index (files, i);
+
+		size += item->size;
+		if ((max_size >= 0 && size >= max_size) || item->mtime < min_mtime) {
+			unlink (item->file);
+		}
+	}
+
+	g_ptr_array_foreach (files, (GFunc)cache_file_free, NULL);
+	g_ptr_array_free (files, TRUE);
+
+	g_free (a_dir);
+}
+
+static void 
+on_got_handle (DBusGProxy *proxy, guint OUT_handle, GError *error, gpointer userdata)
+{
+	ThumbsItem *item = userdata;
+	gchar *key = g_strdup_printf ("%d", OUT_handle);
+	item->handle_id = OUT_handle;
+
+	/* Register the item as being handled */
+	g_hash_table_replace (tasks, key, item);
+}
+
+typedef struct {
+	gchar *path;
+	ThumbsItem *item;
+} ThumbsItemAndPaths;
+
+static void
+free_thumbsitem_and_paths (ThumbsItemAndPaths *info) 
+{
+	g_free (info->path);
+	thumb_item_free (info->item);
+	g_slice_free (ThumbsItemAndPaths, info);
+}
+
+static gboolean
+have_all_cb (gpointer user_data)
+{
+	ThumbsItemAndPaths *info = user_data;
+	ThumbsItem *item = info->item;
+
+	create_pixbuf_and_callback (item, info->path);
+
+	return FALSE;
+}
+
+HildonAlbumartFactoryHandle hildon_albumart_factory_load(
+				const gchar *uri, const gchar *artist,
+				const gchar *album,
+				HildonAlbumartFactoryFinishedCallback callback,
+				gpointer user_data)
+{
+	gchar *path;
+	GError *error = NULL;
+	ThumbsItem *item;
+	gboolean have_all = FALSE;
+
+	hildon_thumbnail_util_get_albumart_path (artist, album, uri, &path);
+
+	have_all = g_file_test (path, G_FILE_TEST_EXISTS);
+
+	item = g_new (ThumbsItem, 1);
+
+	item->uri = g_strdup(uri);
+	item->album = g_strdup(album);
+	item->artist = g_strdup(artist);
+	item->callback = callback;
+	item->user_data = user_data;
+	item->canceled = FALSE;
+	item->handle_id = 0;
+
+	if (have_all) {
+		ThumbsItemAndPaths *info = g_slice_new (ThumbsItemAndPaths);
+
+		info->item = item;
+		info->path = path;
+
+		g_idle_add_full (G_PRIORITY_DEFAULT, have_all_cb, info,
+						 (GDestroyNotify) free_thumbsitem_and_paths);
+
+		return;
+	}
+
+	g_free (path);
+
+	if (!have_all) {
+
+		init ();
+
+		com_nokia_albumart_Requester_queue_async (proxy, artist, 
+												  album, 
+												  uri, 0, 
+												  on_got_handle,
+												  item);
+
+	}
+
+	return THUMBS_HANDLE (item);
+}
+
+
+static void 
+on_cancelled (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+	ThumbsItem *item = userdata;
+	gchar *key = g_strdup_printf ("%d", item->handle_id);
+
+	/* Unregister the item */
+	g_hash_table_remove (tasks, key);
+	g_free (key);
+}
+
+void hildon_albumart_factory_cancel(HildonAlbumartFactoryHandle handle)
+{
+	ThumbsItem *item = THUMBS_ITEM (handle);
+
+	init();
+
+	if (item->handle_id == 0)
+		return;
+
+	/* We don't do real canceling, we just do unqueing */
+
+	com_nokia_albumart_Requester_unqueue_async (proxy, 
+												item->handle_id,
+												on_cancelled, item);
+
+}
+
+void hildon_albumart_factory_wait()
+{
+	init();
+
+	while(g_hash_table_size (tasks) != 0) {
+		g_main_context_iteration(NULL, TRUE);
+	}
+}
+
+static void file_opp_reply  (DBusGProxy *proxy, GError *error, gpointer userdata)
+{
+}
+
+void hildon_albumart_factory_remove(const gchar *artist, const gchar *album, const gchar *uri)
+{
+
+	init();
+
+	com_nokia_albumart_Requester_delete_async (proxy, 
+											   artist, 
+											   album, 
+											   uri, 
+											   file_opp_reply, NULL);
+
+}
+
+void hildon_albumart_factory_set_debug(gboolean debug)
+{
+	init ();
+
+	show_debug = debug;
+}
+
+
+
+static void init (void) {
+	if (!had_init) {
+		GError *error = NULL;
+
+		tasks = g_hash_table_new_full (g_str_hash, g_str_equal,
+					       (GDestroyNotify) g_free,
+					       (GDestroyNotify) thumb_item_free);
+
+		connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+		if (error) {
+			g_critical ("Can't initialize HildonAlbumarter: %s\n", error->message);
+			g_error_free (error);
+			g_hash_table_unref (tasks);
+			tasks = NULL;
+			connection = NULL;
+			had_init = FALSE;
+			abort ();
+			return;
+		}
+
+		proxy = dbus_g_proxy_new_for_name (connection, 
+					   ALBUMARTER_SERVICE,
+					   ALBUMARTER_PATH,
+					   ALBUMARTER_INTERFACE);
+
+		dbus_g_proxy_add_signal (proxy, "Finished", 
+					G_TYPE_UINT, G_TYPE_INVALID);
+
+		dbus_g_proxy_connect_signal (proxy, "Finished",
+				     G_CALLBACK (on_task_finished),
+				     NULL,
+				     NULL);
+	}
+	had_init = TRUE;
+}
+

Added: projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.h
===================================================================
--- projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.h	2008-10-01 08:57:32 UTC (rev 16307)
+++ projects/haf/branches/hildon-thumbnail/daemonize/thumbs/hildon-albumart-factory.h	2008-10-01 10:27:38 UTC (rev 16308)
@@ -0,0 +1,117 @@
+/*
+ * This file is part of hildon-albumart package
+ *
+ * Copyright (C) 2005 Nokia Corporation.  All Rights reserved.
+ *
+ * Contact: Marius Vollmer <marius.vollmer at nokia.com>
+ * Author: Philip Van Hoof <pvanhoof at gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __LIBHILDONALBUMARTFACTORY_H__
+#define __LIBHILDONALBUMARTFACTORY_H__
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <glib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+typedef gpointer HildonAlbumartFactoryHandle;
+
+/**
+ * HildonAlbumartFactoryFinishedCallback:
+ * @handle: Handle of the albumart that was completed
+ * @user_data: User-supplied data when callback was registered
+ * @albumart: A pixbuf containing the albumart or %NULL. If application wishes to keep
+ *      the structure, it must call g_object_ref() on it. The library does not cache
+ *      returned pixbufs.
+ *      The pixbuf may contain various options, which are prefixed with
+ *      HILDON_ALBUMART_OPTION_PREFIX. The various options may be "Noimage" if there
+ *      is no image but only metadata, "Title", "Artist" etc. To get the options,
+ *      use gdk_pixbuf_get_option(albumart, HILDON_ALBUMART_OPTION_PREFIX "Option").
+ * @error: The error or %NULL if there was none. Freed after callback returns.
+ *
+ * Called when the albumarting process finishes or there is an error
+ */
+typedef void (*HildonAlbumartFactoryFinishedCallback)(HildonAlbumartFactoryHandle handle,
+    gpointer user_data, GdkPixbuf *albumart, GError *error);
+
+/**
+ * hildon_albumart_factory_load:
+ * @uri: Albumart will be created for this URI
+ * @mime_type: MIME type of the resource the URI points to
+ * @width: Desired albumart width
+ * @height: Desired albumart height
+ * @callback: Function to call when albumart creation finished or there was an error
+ * @user_data: Optional data passed to the callback
+ *
+ * This function requests for the library to create a albumart, or load if from cache
+ * if possible. The process is asynchronous, the function returns immediately. Right now
+ * most processing is done in the idle callback and albumarting in a separate process.
+ * If the process fails, the callback is called with the error.
+ *
+ * Returns: A #HildonAlbumartFactoryHandle if request succeeded or %NULL if there was
+ *  a critical error
+ */
+HildonAlbumartFactoryHandle hildon_albumart_factory_load(
+            const gchar *artist, const gchar *album, const gchar *uri,
+            HildonAlbumartFactoryFinishedCallback callback,
+            gpointer user_data);
+
+
+
+/**
+ * hildon_albumart_factory_cancel:
+ * @handle: Handle to cancel
+ *
+ * Removes specified albumart request from the queue
+ */
+void hildon_albumart_factory_cancel(HildonAlbumartFactoryHandle handle);
+
+/**
+ * hildon_albumart_factory_remove:
+ * @uri: URI of the file that was deleted
+ *
+ * Call to indicate the a file was removed and the albumart cache should be updated
+ */
+void hildon_albumart_factory_remove(const gchar *artist, const gchar *album, const gchar *uri);
+
+/**
+ * hildon_albumart_factory_wait:
+ *
+ * Wait until all albumarting processes have finished
+ */
+void hildon_albumart_factory_wait();
+
+/**
+ * hildon_albumart_factory_clean_cache:
+ * @max_size: Maximum size of cache in bytes. Set to -1 to disable. 0 deletes all entries.
+ * @min_mtime: Minimum creation time of albumarts. (usually now() - 30 days)
+ *      Set to 0 to disable.
+ *
+ * Clean the albumart cache, deletes oldest entries first (based on albumart
+ * creation date)
+ */
+void hildon_albumart_factory_clean_cache(gint max_size, time_t min_mtime);
+
+
+G_END_DECLS
+
+#endif


More information about the maemo-commits mailing list