[goobox] async metadata functions



commit 582dac34e545fe193d33fb0cdabcee8766bd8e04
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Jun 4 22:34:12 2011 +0200

    async metadata functions

 src/album-info.c     |    3 +-
 src/album-info.h     |    4 +-
 src/dlg-properties.c |   56 ++++----
 src/goo-player.c     |  401 ++++++++++----------------------------------------
 src/metadata.c       |  318 +++++++++++++++++++++++++++++++++++++++-
 src/metadata.h       |   24 +++-
 6 files changed, 442 insertions(+), 364 deletions(-)
---
diff --git a/src/album-info.c b/src/album-info.c
index 7effa35..6e461cc 100644
--- a/src/album-info.c
+++ b/src/album-info.c
@@ -79,10 +79,11 @@ album_info_get_type (void)
 }
 
 
-void
+AlbumInfo *
 album_info_ref (AlbumInfo *album)
 {
 	album->ref++;
+	return album;
 }
 
 
diff --git a/src/album-info.h b/src/album-info.h
index 8515893..947b25f 100644
--- a/src/album-info.h
+++ b/src/album-info.h
@@ -50,7 +50,7 @@ typedef struct {
 
 GType           album_info_get_type         (void);
 AlbumInfo *     album_info_new              (void);
-void            album_info_ref              (AlbumInfo  *album);
+AlbumInfo *     album_info_ref              (AlbumInfo  *album);
 void            album_info_unref            (AlbumInfo  *album);
 AlbumInfo *     album_info_copy             (AlbumInfo  *album);
 void            album_info_set_id           (AlbumInfo  *album,
@@ -61,7 +61,7 @@ void            album_info_set_artist       (AlbumInfo  *album,
 					     const char *artist,
 					     const char *artist_id);
 void            album_info_set_genre        (AlbumInfo  *album,
-					     const char *genre);				 
+					     const char *genre);
 void            album_info_set_asin         (AlbumInfo  *album,
 					     const char *asin);
 void            album_info_set_release_date (AlbumInfo  *album,
diff --git a/src/dlg-properties.c b/src/dlg-properties.c
index 7cf0d2a..37b770d 100644
--- a/src/dlg-properties.c
+++ b/src/dlg-properties.c
@@ -48,6 +48,7 @@ typedef struct {
 	GtkTreeViewColumn *author_column;
 	GList             *albums;
 	int                n_albums, current_album;
+	GCancellable      *cancellable;
 } DialogData;
 
 
@@ -56,7 +57,8 @@ dialog_destroy_cb (GtkWidget  *widget,
 		   DialogData *data)
 {
 	data->window->properties_dialog = NULL;
-	g_object_unref (G_OBJECT (data->builder));
+	g_object_unref (data->cancellable);
+	g_object_unref (data->builder);
 	g_free (data);
 }
 
@@ -224,33 +226,14 @@ remove_incompatible_albums (GList     *albums,
 
 
 static void
-search_cb (GtkWidget  *widget,
-	   DialogData *data)
+search_album_by_title_ready_cb (GObject      *source_object,
+			        GAsyncResult *result,
+				gpointer      user_data)
 {
-	MbReleaseFilter  filter;
-	MbQuery          query;
-	MbResultList     list;
-
-	gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("info_icon")), GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON);
-	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("info_label")), _("Searching disc info..."));
-	gtk_widget_show (GET_WIDGET ("info_box"));
-	gtk_widget_hide (GET_WIDGET ("navigation_box"));
+	DialogData *data = user_data;
+	GError     *error = NULL;
 
-	/*
-	metadata_search_album_by_title (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("title_entry"))),
-					data->cancellable,
-					G_CALLBACK (search_album_by_title_ready_cb),
-					data);
-	*/
-
-	filter = mb_release_filter_new ();
-	mb_release_filter_title (filter, gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("title_entry"))));
-
-	query = mb_query_new (NULL, NULL);
-	list = mb_query_get_releases (query, filter);
-
-	data->albums = get_album_list (list);
-	get_track_info_for_album_list (data->albums);
+	data->albums = metadata_search_album_by_title_finish (result, &error);
 	data->albums = remove_incompatible_albums (data->albums, goo_window_get_album (data->window));
 	data->n_albums = g_list_length (data->albums);
 
@@ -262,10 +245,24 @@ search_cb (GtkWidget  *widget,
 	}
 	else
 		show_album (data, 0);
+}
+
 
-	mb_result_list_free (list);
-	mb_query_free (query);
-	mb_release_filter_free (filter);
+static void
+search_cb (GtkWidget  *widget,
+	   DialogData *data)
+{
+
+
+	gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("info_icon")), GTK_STOCK_FIND, GTK_ICON_SIZE_BUTTON);
+	gtk_label_set_text (GTK_LABEL (GET_WIDGET ("info_label")), _("Searching disc info..."));
+	gtk_widget_show (GET_WIDGET ("info_box"));
+	gtk_widget_hide (GET_WIDGET ("navigation_box"));
+
+	metadata_search_album_by_title (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("title_entry"))),
+					data->cancellable,
+					search_album_by_title_ready_cb,
+					data);
 }
 
 
@@ -463,6 +460,7 @@ dlg_properties (GooWindow *window)
 	data = g_new0 (DialogData, 1);
 	data->window = window;
 	data->builder = _gtk_builder_new_from_file ("properties.ui", "");
+	data->cancellable = g_cancellable_new ();
 
 	/* Get the widgets. */
 
diff --git a/src/goo-player.c b/src/goo-player.c
index 6de4a9a..23d03fd 100644
--- a/src/goo-player.c
+++ b/src/goo-player.c
@@ -25,8 +25,6 @@
 #include <string.h>
 #include <glib/gi18n.h>
 #include <gst/gst.h>
-#include <discid/discid.h>
-#include <musicbrainz3/mb_c.h>
 #include "goo-player.h"
 #include "goo-marshal.h"
 #include "glib-utils.h"
@@ -68,12 +66,9 @@ struct _GooPlayerPrivate {
 	guint            update_state_id;
 	guint            update_progress_id;
 
-	GThread         *thread;
 	GMutex          *yes_or_no;
-	guint            check_id;
 	gboolean         exiting;
-
-	char            *rdf;
+	GCancellable    *cancellable;
 	GList           *albums;
 };
 
@@ -342,7 +337,6 @@ goo_player_init (GooPlayer *self)
 	self->priv->is_busy = FALSE;
 	self->priv->hibernate = FALSE;
 	self->priv->yes_or_no = g_mutex_new ();
-	self->priv->check_id = 0;
 	self->priv->exiting = FALSE,
 	self->priv->discid = NULL;
 	self->priv->album = album_info_new ();
@@ -350,6 +344,7 @@ goo_player_init (GooPlayer *self)
 	self->priv->volume_value = 1.0;
 	self->priv->update_progress_id = 0;
 	self->priv->albums = NULL;
+	self->priv->cancellable = g_cancellable_new ();
 }
 
 
@@ -374,14 +369,17 @@ goo_player_finalize (GObject *object)
 		g_signal_handler_disconnect (self->priv->drive, self->priv->medium_removed_event);
 	g_object_unref (self->priv->drive);
 
-	if (self->priv->check_id != 0)
-		g_source_remove (self->priv->check_id);
+	if (self->priv->update_progress_id != 0) {
+		g_source_remove (self->priv->update_progress_id);
+		self->priv->update_progress_id = 0;
+	}
 
 	destroy_pipeline (self, FALSE);
 	g_mutex_free (self->priv->yes_or_no);
 	destroy_pipeline (self, FALSE);
 	g_free (self->priv->discid);
 	album_info_unref (self->priv->album);
+	g_object_unref (self->priv->cancellable);
 
 	G_OBJECT_CLASS (goo_player_parent_class)->finalize (object);
 }
@@ -459,146 +457,69 @@ goo_player_set_album (GooPlayer *self,
 }
 
 
-#if 0
-
-
-static void
-set_cd_metadata_from_rdf (GooPlayer *self,
-			  char      *rdf)
+gboolean
+goo_player_is_audio_cd (GooPlayer *self)
 {
-	musicbrainz_t  mb;
-	GList         *albums;
-
-	if (rdf == NULL)
-		return;
-
-	mb = mb_New ();
-	mb_UseUTF8 (mb, TRUE);
-	mb_SetResultRDF (mb, rdf);
-
-	albums = get_album_list (mb);
-	if (albums != NULL) {
-		AlbumInfo *first_album = albums->data;
-
-		/* FIXME: ask the user which album to use if the query
-		 * returned more than one album. */
+	return self->priv->audio_cd;
+}
 
-		goo_player_set_album (self, first_album);
-		album_list_free (albums);
-	}
 
-	mb_Delete (mb);
+void
+goo_player_hibernate (GooPlayer *self,
+		      gboolean   hibernate)
+{
+	self->priv->hibernate = hibernate;
 }
 
 
-static char *
-get_cached_rdf_path (GooPlayer *self)
+gboolean
+goo_player_is_hibernate (GooPlayer *self)
 {
-	if (self->priv->discid != NULL)
-		return gth_user_dir_get_file (GTH_DIR_CACHE, "goobox", self->priv->discid, NULL);
-	else
-		return NULL;
+	return self->priv->hibernate;
 }
 
 
-static void
-save_rdf_to_cache (GooPlayer  *player,
-	           const char *rdf)
+void
+goo_player_update (GooPlayer *self)
 {
-	char   *path;
-	char   *dir;
-	GError *error = NULL;
+	BraseroMedium *medium;
 
-	if (rdf == NULL)
+	if (self->priv->hibernate)
 		return;
 
-	path = get_cached_rdf_path (player);
-	if (path == NULL)
-		return;
+	self->priv->audio_cd = FALSE;
 
-	if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-		g_free (path);
-    		return;
+	medium = brasero_drive_get_medium (self->priv->drive);
+	if (medium == NULL) {
+		goo_player_stop (self);
+		goo_player_set_state (self, GOO_PLAYER_STATE_NO_DISC, TRUE);
+		goo_player_empty_list (self);
+		action_done (self, GOO_PLAYER_ACTION_LIST);
 	}
-
-	dir = g_path_get_dirname (path);
-	g_mkdir_with_parents (dir, 0700);
-
-	if (! g_file_set_contents (path, rdf, strlen (rdf), &error)) {
-		debug (DEBUG_INFO, "%s\n", error->message);
-		g_clear_error (&error);
+	else if ((BRASERO_MEDIUM_IS (brasero_medium_get_status (medium), BRASERO_MEDIUM_CD | BRASERO_MEDIUM_HAS_AUDIO))) {
+		self->priv->audio_cd = TRUE;
+		goo_player_set_state (self, GOO_PLAYER_STATE_STOPPED, TRUE);
+		goo_player_list (self);
 	}
-
-	g_free (dir);
-	g_free (path);
-}
-
-
-static char *
-read_cached_rdf (GooPlayer *self)
-{
-	char   *path;
-	char   *rdf = NULL;
-	GError *error = NULL;
-
-	path = get_cached_rdf_path (self);
-	if (path == NULL)
-		return NULL;
-
-	if (! g_file_get_contents (path, &rdf, NULL, &error)) {
-		debug (DEBUG_INFO, "%s\n", error->message);
-		g_clear_error (&error);
-		rdf = NULL;
+	else {
+		goo_player_stop (self);
+		goo_player_set_state (self, GOO_PLAYER_STATE_DATA_DISC, TRUE);
+		goo_player_empty_list (self);
+		action_done (self, GOO_PLAYER_ACTION_LIST);
 	}
-
-	g_free (path);
-
-	return rdf;
 }
 
 
-#endif
-
-
-static int
-check_get_cd_metadata (gpointer data)
+static void
+album_info_from_disc_id_ready_cb (GObject      *source_object,
+				  GAsyncResult *result,
+				  gpointer      user_data)
 {
-	GooPlayer *player = data;
-	gboolean   done, exiting;
+	GooPlayer *player = user_data;
 	GList     *albums;
+	GError    *error = NULL;
 
-	/* Remove the check. */
-
-        g_source_remove (player->priv->check_id);
-        player->priv->check_id = 0;
-
-	/**/
-
-	g_mutex_lock (player->priv->yes_or_no);
-	done = player->priv->thread == NULL;
-	exiting = player->priv->exiting;
-        g_mutex_unlock (player->priv->yes_or_no);
-
-	if (exiting) {
-		goo_player_set_is_busy (player, FALSE);
-		destroy_pipeline (player, FALSE);
-		return FALSE;
-	}
-
-	if (! done) {
-		player->priv->check_id = g_timeout_add (REFRESH_RATE,
-						        check_get_cd_metadata,
-					 	        player);
-		return FALSE;
-	}
-
-	/**/
-
-	g_mutex_lock (player->priv->yes_or_no);
-	albums = player->priv->albums;
-	player->priv->albums = NULL;
-	g_mutex_unlock (player->priv->yes_or_no);
-
+	albums = metadata_get_album_info_from_disc_id_finish (result, &error);
 	if (albums != NULL) {
 		AlbumInfo *first_album = albums->data;
 
@@ -610,214 +531,46 @@ check_get_cd_metadata (gpointer data)
 
 		album_list_free (albums);
 	}
-
-	return FALSE;
-}
-
-
-static void *
-get_cd_metadata (void *thread_data)
-{
-	GooPlayer       *player = thread_data;
-	MbReleaseFilter  filter;
-	MbQuery          query;
-	MbResultList     list;
-
-	filter = mb_release_filter_new ();
-	mb_release_filter_disc_id (filter, player->priv->discid);
-	mb_release_filter_limit (filter, 1);
-
-	query = mb_query_new (NULL, NULL);
-	list = mb_query_get_releases (query, filter);
-
-	g_mutex_lock (player->priv->yes_or_no);
-	album_list_free (player->priv->albums);
-	player->priv->albums = get_album_list (list);
-	player->priv->thread = NULL;
-	g_mutex_unlock (player->priv->yes_or_no);
-
-	mb_result_list_free (list);
-	mb_query_free (query);
-	mb_release_filter_free (filter);
-
-	g_thread_exit (NULL);
-
-	return NULL;
 }
 
 
-static int
-check_get_cd_tracks (gpointer data)
+static void
+get_cd_info_from_device_ready_cb (GObject      *source_object,
+				  GAsyncResult *result,
+				  gpointer      user_data)
 {
-	GooPlayer *player = data;
-	gboolean   done;
-	gboolean   exiting;
-
-	/* Remove the check. */
-
-        g_source_remove (player->priv->check_id);
-        player->priv->check_id = 0;
-
-	/**/
-
-	g_mutex_lock (player->priv->yes_or_no);
-	done = player->priv->thread == NULL;
-	exiting = player->priv->exiting;
-        g_mutex_unlock (player->priv->yes_or_no);
-
-	if (exiting) {
-		goo_player_set_is_busy (player, FALSE);
-		destroy_pipeline (player, TRUE);
-		return FALSE;
-	}
+	GooPlayer *player = user_data;
+	AlbumInfo *album;
+	GError    *error = NULL;
 
-	if (! done) {
-		player->priv->check_id = g_timeout_add (REFRESH_RATE,
-							check_get_cd_tracks,
-							player);
-		return FALSE;
+	if (metadata_get_cd_info_from_device_finish (result,
+						     &player->priv->discid,
+						     &album,
+						     &error))
+	{
+		album_info_set_tracks (player->priv->album, album->tracks);
 	}
 
-	/**/
-
 	goo_player_set_is_busy (player, FALSE);
 	gst_element_set_state (player->priv->pipeline, GST_STATE_NULL);
 	goo_player_set_state (player, GOO_PLAYER_STATE_STOPPED, TRUE);
-
 	action_done (player, GOO_PLAYER_ACTION_LIST);
 	destroy_pipeline (player, TRUE);
 
-	/**/
+	if (player->priv->discid == NULL)
+		return;
 
 	if (album_info_load_from_cache (player->priv->album, player->priv->discid)) {
 		action_done (player, GOO_PLAYER_ACTION_METADATA);
-		return FALSE;
+		return;
 	}
 
-	/*
 	metadata_get_album_info_from_disc_id (player->priv->discid,
-					      data->cancellable,
-					      G_CALLBACK (album_info_from_disc_id_ready_cb),
-					      data);
-	*/
-
-	g_mutex_lock (player->priv->yes_or_no);
-	player->priv->thread = g_thread_create (get_cd_metadata, player, FALSE, NULL);
-	g_mutex_unlock (player->priv->yes_or_no);
-
-	player->priv->check_id = g_timeout_add (REFRESH_RATE, check_get_cd_metadata, player);
+					      player->priv->cancellable,
+					      album_info_from_disc_id_ready_cb,
+					      player);
 
-	return FALSE;
-}
-
-
-static void *
-get_cd_tracks (void *thread_data)
-{
-	GooPlayer *player = thread_data;
-	GList     *tracks = NULL;
-	DiscId    *disc;
-
-	if (player->priv->pipeline != NULL)
-		gst_element_set_state (player->priv->pipeline, GST_STATE_PAUSED);
-
-	g_free (player->priv->discid);
-	player->priv->discid = NULL;
-
-	disc = discid_new ();
-	if (discid_read (disc, goo_player_get_device (player))) {
-		int first_track;
-		int last_track;
-		int i;
-
-		player->priv->discid = g_strdup (discid_get_id (disc));
-		debug (DEBUG_INFO, "==> [MB] DISC ID: %s\n", player->priv->discid);
-
-		first_track = discid_get_first_track_num (disc);
-		debug (DEBUG_INFO, "==> [MB] FIRST TRACK: %d\n", first_track);
-
-		last_track = discid_get_last_track_num (disc);
-		debug (DEBUG_INFO, "==> [MB] LAST TRACK: %d\n", last_track);
-
-		for (i = first_track; i <= last_track; i++) {
-			gint64 from_sector;
-			gint64 n_sectors;
-
-			from_sector = discid_get_track_offset (disc, i);
-			n_sectors = discid_get_track_length (disc, i);
-
-			debug (DEBUG_INFO, "==> [MB] Track %d: [%"G_GINT64_FORMAT", %"G_GINT64_FORMAT"]\n", i, from_sector, from_sector + n_sectors);
-
-			tracks = g_list_prepend (tracks, track_info_new (i - first_track, from_sector, from_sector + n_sectors));
-		}
-	}
-
-	discid_free (disc);
-
-	tracks = g_list_reverse (tracks);
-	album_info_set_tracks (player->priv->album, tracks);
-	track_list_free (tracks);
-
-	g_mutex_lock (player->priv->yes_or_no);
-	player->priv->thread = NULL;
-	g_mutex_unlock (player->priv->yes_or_no);
-
-	g_thread_exit (NULL);
-
-	return NULL;
-}
-
-
-gboolean
-goo_player_is_audio_cd (GooPlayer *self)
-{
-	return self->priv->audio_cd;
-}
-
-
-void
-goo_player_hibernate (GooPlayer *self,
-		      gboolean   hibernate)
-{
-	self->priv->hibernate = hibernate;
-}
-
-
-gboolean
-goo_player_is_hibernate (GooPlayer *self)
-{
-	return self->priv->hibernate;
-}
-
-
-void
-goo_player_update (GooPlayer *self)
-{
-	BraseroMedium *medium;
-
-	if (self->priv->hibernate)
-		return;
-
-	self->priv->audio_cd = FALSE;
-
-	medium = brasero_drive_get_medium (self->priv->drive);
-	if (medium == NULL) {
-		goo_player_stop (self);
-		goo_player_set_state (self, GOO_PLAYER_STATE_NO_DISC, TRUE);
-		goo_player_empty_list (self);
-		action_done (self, GOO_PLAYER_ACTION_LIST);
-	}
-	else if ((BRASERO_MEDIUM_IS (brasero_medium_get_status (medium), BRASERO_MEDIUM_CD | BRASERO_MEDIUM_HAS_AUDIO))) {
-		self->priv->audio_cd = TRUE;
-		goo_player_set_state (self, GOO_PLAYER_STATE_STOPPED, TRUE);
-		goo_player_list (self);
-	}
-	else {
-		goo_player_stop (self);
-		goo_player_set_state (self, GOO_PLAYER_STATE_DATA_DISC, TRUE);
-		goo_player_empty_list (self);
-		action_done (self, GOO_PLAYER_ACTION_LIST);
-	}
+	album_info_unref (album);
 }
 
 
@@ -835,18 +588,16 @@ goo_player_list (GooPlayer *player)
 	goo_player_set_is_busy (player, TRUE);
 	create_pipeline (player);
 
-	/* FIXME
-	metadata_read_cd_info_from_device (goo_player_get_device (player),
-					   data->cancellable,
-					   G_CALLBACK (cd_info_from_device_ready_cb),
-					   data);
-	*/
+	if (player->priv->pipeline != NULL)
+		gst_element_set_state (player->priv->pipeline, GST_STATE_PAUSED);
 
-	g_mutex_lock (player->priv->yes_or_no);
-	player->priv->thread = g_thread_create (get_cd_tracks, player, FALSE, NULL);
-	g_mutex_unlock (player->priv->yes_or_no);
+	g_free (player->priv->discid);
+	player->priv->discid = NULL;
 
-	player->priv->check_id = g_timeout_add (REFRESH_RATE, check_get_cd_tracks, player);
+	metadata_get_cd_info_from_device (goo_player_get_device (player),
+					  player->priv->cancellable,
+					  get_cd_info_from_device_ready_cb,
+					  player);
 }
 
 
diff --git a/src/metadata.c b/src/metadata.c
index 47d0f5d..358c262 100644
--- a/src/metadata.c
+++ b/src/metadata.c
@@ -3,7 +3,7 @@
 /*
  *  Goo
  *
- *  Copyright (C) 2007 Free Software Foundation, Inc.
+ *  Copyright (C) 2007-2011 Free Software Foundation, Inc.
  *
  *  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
@@ -23,10 +23,11 @@
 #include <config.h>
 #include <stdio.h>
 #include <string.h>
+#include <discid/discid.h>
 #include <musicbrainz3/mb_c.h>
+#include "album-info.h"
 #include "glib-utils.h"
 #include "metadata.h"
-#include "album-info.h"
 
 
 static TrackInfo *
@@ -123,7 +124,7 @@ get_album_info (MbRelease release)
 }
 
 
-GList *
+static GList *
 get_album_list (MbResultList list)
 {
 	GList *albums = NULL;
@@ -144,7 +145,7 @@ get_album_list (MbResultList list)
 }
 
 
-void
+static void
 get_track_info_for_album_list (GList *albums)
 {
 	GList *scan;
@@ -182,3 +183,312 @@ get_track_info_for_album_list (GList *albums)
 		mb_track_filter_free (filter);
 	}
 }
+
+
+/* -- metadata_get_cd_info_from_device -- */
+
+
+typedef struct {
+	char      *device;
+	char      *disc_id;
+	AlbumInfo *album_info;
+} GetCDInfoData;
+
+
+static void
+get_cd_info_data_free (GetCDInfoData *data)
+{
+	g_free (data->device);
+	g_free (data->disc_id);
+	album_info_unref (data->album_info);
+	g_free (data);
+}
+
+
+static void
+get_cd_info_from_device_thread (GSimpleAsyncResult *result,
+				GObject            *object,
+				GCancellable       *cancellable)
+{
+	GetCDInfoData *data;
+	GList         *tracks;
+	DiscId        *disc;
+
+	data = g_simple_async_result_get_op_res_gpointer (result);
+
+	data->album_info = album_info_new ();
+	tracks = NULL;
+	disc = discid_new ();
+	if (discid_read (disc, data->disc_id)) {
+		int first_track;
+		int last_track;
+		int i;
+
+		data->disc_id = g_strdup (discid_get_id (disc));
+		debug (DEBUG_INFO, "==> [MB] DISC ID: %s\n", data->disc_id);
+
+		first_track = discid_get_first_track_num (disc);
+		debug (DEBUG_INFO, "==> [MB] FIRST TRACK: %d\n", first_track);
+
+		last_track = discid_get_last_track_num (disc);
+		debug (DEBUG_INFO, "==> [MB] LAST TRACK: %d\n", last_track);
+
+		for (i = first_track; i <= last_track; i++) {
+			gint64 from_sector;
+			gint64 n_sectors;
+
+			from_sector = discid_get_track_offset (disc, i);
+			n_sectors = discid_get_track_length (disc, i);
+
+			debug (DEBUG_INFO, "==> [MB] Track %d: [%"G_GINT64_FORMAT", %"G_GINT64_FORMAT"]\n", i, from_sector, from_sector + n_sectors);
+
+			tracks = g_list_prepend (tracks, track_info_new (i - first_track, from_sector, from_sector + n_sectors));
+		}
+	}
+	tracks = g_list_reverse (tracks);
+	album_info_set_tracks (data->album_info, tracks);
+
+	track_list_free (tracks);
+	discid_free (disc);
+}
+
+
+void
+metadata_get_cd_info_from_device (const char          *device,
+				  GCancellable        *cancellable,
+				  GAsyncReadyCallback  callback,
+				  gpointer             user_data)
+{
+	GetCDInfoData      *data;
+	GSimpleAsyncResult *result;
+
+	result = g_simple_async_result_new (NULL,
+	                                    callback,
+	                                    user_data,
+	                                    metadata_get_cd_info_from_device);
+
+	data = g_new0 (GetCDInfoData, 1);
+	data->device = g_strdup (device);
+	g_simple_async_result_set_op_res_gpointer (result,
+                                                   data,
+                                                   (GDestroyNotify) get_cd_info_data_free);
+
+	g_simple_async_result_run_in_thread (result,
+					     get_cd_info_from_device_thread,
+					     G_PRIORITY_DEFAULT,
+					     cancellable);
+
+	g_object_unref (result);
+}
+
+
+gboolean
+metadata_get_cd_info_from_device_finish (GAsyncResult  *result,
+					 char         **disc_id,
+					 AlbumInfo    **album_info,
+					 GError       **error)
+{
+	GSimpleAsyncResult *simple;
+	GetCDInfoData      *data;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, metadata_get_cd_info_from_device), FALSE);
+
+        simple = G_SIMPLE_ASYNC_RESULT (result);
+
+        if (g_simple_async_result_propagate_error (simple, error))
+                return FALSE;
+
+        data = g_simple_async_result_get_op_res_gpointer (simple);
+        if (disc_id != NULL)
+        	*disc_id = g_strdup (data->disc_id);
+        if (album_info != NULL)
+        	*album_info = album_info_ref (data->album_info);
+
+        return TRUE;
+}
+
+
+/* -- metadata_get_album_info_from_disc_id -- */
+
+
+typedef struct {
+	char  *disc_id;
+	GList *albums;
+} AlbumFromIDData;
+
+
+static void
+album_from_id_data_free (AlbumFromIDData *data)
+{
+	g_free (data->disc_id);
+	album_list_free (data->albums);
+	g_free (data);
+}
+
+
+static void
+get_album_info_from_disc_id_thread (GSimpleAsyncResult *result,
+				    GObject            *object,
+				    GCancellable       *cancellable)
+{
+	AlbumFromIDData *data;
+	MbReleaseFilter  filter;
+	MbQuery          query;
+	MbResultList     list;
+
+	data = g_simple_async_result_get_op_res_gpointer (result);
+
+	filter = mb_release_filter_new ();
+	mb_release_filter_disc_id (filter, data->disc_id);
+
+	query = mb_query_new (NULL, NULL);
+	list = mb_query_get_releases (query, filter);
+	data->albums = get_album_list (list);
+
+	mb_result_list_free (list);
+	mb_query_free (query);
+	mb_release_filter_free (filter);
+}
+
+
+void
+metadata_get_album_info_from_disc_id (const char          *disc_id,
+				      GCancellable        *cancellable,
+				      GAsyncReadyCallback  callback,
+				      gpointer             user_data)
+{
+	AlbumFromIDData    *data;
+	GSimpleAsyncResult *result;
+
+	result = g_simple_async_result_new (NULL,
+	                                    callback,
+	                                    user_data,
+	                                    metadata_get_album_info_from_disc_id);
+
+	data = g_new0 (AlbumFromIDData, 1);
+	data->disc_id = g_strdup (disc_id);
+	g_simple_async_result_set_op_res_gpointer (result,
+                                                   data,
+                                                   (GDestroyNotify) album_from_id_data_free);
+
+	g_simple_async_result_run_in_thread (result,
+					     get_album_info_from_disc_id_thread,
+					     G_PRIORITY_DEFAULT,
+					     cancellable);
+
+	g_object_unref (result);
+}
+
+
+GList *
+metadata_get_album_info_from_disc_id_finish (GAsyncResult  *result,
+					     GError       **error)
+{
+	GSimpleAsyncResult *simple;
+	AlbumFromIDData    *data;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, metadata_get_album_info_from_disc_id), NULL);
+
+        simple = G_SIMPLE_ASYNC_RESULT (result);
+
+        if (g_simple_async_result_propagate_error (simple, error))
+                return NULL;
+
+        data = g_simple_async_result_get_op_res_gpointer (simple);
+
+        return album_list_dup (data->albums);
+}
+
+
+/* -- metadata_search_album_by_title -- */
+
+
+typedef struct {
+	char  *title;
+	GList *albums;
+} SearchByTitleData;
+
+
+static void
+search_by_tile_data_free (SearchByTitleData *data)
+{
+	g_free (data->title);
+	album_list_free (data->albums);
+	g_free (data);
+}
+
+
+static void
+search_album_by_title_thread (GSimpleAsyncResult *result,
+			      GObject            *object,
+			      GCancellable       *cancellable)
+{
+	SearchByTitleData *data;
+	MbReleaseFilter    filter;
+	MbQuery            query;
+	MbResultList       list;
+
+	data = g_simple_async_result_get_op_res_gpointer (result);
+
+	filter = mb_release_filter_new ();
+	mb_release_filter_title (filter, data->title);
+
+	query = mb_query_new (NULL, NULL);
+	list = mb_query_get_releases (query, filter);
+
+	data->albums = get_album_list (list);
+	get_track_info_for_album_list (data->albums);
+
+	mb_result_list_free (list);
+	mb_query_free (query);
+	mb_release_filter_free (filter);
+}
+
+
+void
+metadata_search_album_by_title (const char          *title,
+				GCancellable        *cancellable,
+				GAsyncReadyCallback  callback,
+				gpointer             user_data)
+{
+	SearchByTitleData  *data;
+	GSimpleAsyncResult *result;
+
+	result = g_simple_async_result_new (NULL,
+	                                    callback,
+	                                    user_data,
+	                                    metadata_search_album_by_title);
+
+	data = g_new0 (SearchByTitleData, 1);
+	data->title = g_strdup (title);
+	g_simple_async_result_set_op_res_gpointer (result,
+                                                   data,
+                                                   (GDestroyNotify) search_by_tile_data_free);
+
+	g_simple_async_result_run_in_thread (result,
+					     search_album_by_title_thread,
+					     G_PRIORITY_DEFAULT,
+					     cancellable);
+
+	g_object_unref (result);
+}
+
+
+GList *
+metadata_search_album_by_title_finish (GAsyncResult  *result,
+				       GError       **error)
+{
+	GSimpleAsyncResult *simple;
+	AlbumFromIDData    *data;
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, metadata_search_album_by_title), NULL);
+
+        simple = G_SIMPLE_ASYNC_RESULT (result);
+
+        if (g_simple_async_result_propagate_error (simple, error))
+                return NULL;
+
+        data = g_simple_async_result_get_op_res_gpointer (simple);
+
+        return album_list_dup (data->albums);
+}
diff --git a/src/metadata.h b/src/metadata.h
index 45526aa..af331fa 100644
--- a/src/metadata.h
+++ b/src/metadata.h
@@ -24,9 +24,27 @@
 #define METADATA_H
 
 #include <glib.h>
-#include <musicbrainz3/mb_c.h>
+#include "album-info.h"
 
-GList * get_album_list (MbResultList list);
-void    get_track_info_for_album_list (GList *albums);
+void      metadata_get_cd_info_from_device            (const char           *device,
+					               GCancellable         *cancellable,
+					               GAsyncReadyCallback   callback,
+					               gpointer              user_data);
+gboolean  metadata_get_cd_info_from_device_finish     (GAsyncResult         *result,
+						       char                **disc_id,
+						       AlbumInfo           **album_info,
+                				       GError              **error);
+void      metadata_get_album_info_from_disc_id        (const char           *disc_id,
+						       GCancellable         *cancellable,
+						       GAsyncReadyCallback   callback,
+						       gpointer              user_data);
+GList *   metadata_get_album_info_from_disc_id_finish (GAsyncResult         *result,
+						       GError              **error);
+void      metadata_search_album_by_title              (const char           *title,
+						       GCancellable         *cancellable,
+						       GAsyncReadyCallback   callback,
+						       gpointer              user_data);
+GList *   metadata_search_album_by_title_finish       (GAsyncResult         *result,
+						       GError              **error);
 
 #endif /* METADATA_H */



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