[sushi] cover-art: wrap ASIN fetching from MusicBrainz in a separate thread
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sushi] cover-art: wrap ASIN fetching from MusicBrainz in a separate thread
- Date: Tue, 10 May 2011 17:36:20 +0000 (UTC)
commit 686f57ae90c20c87eca3964340c92f07b906ecc4
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Tue May 10 13:34:18 2011 -0400
cover-art: wrap ASIN fetching from MusicBrainz in a separate thread
Those innocent functions actually do I/O over the network and can block
the main thread for a long time. Wrap them in a separate I/O thread with
the help of GIOScheduler.
src/libsushi/sushi-cover-art.c | 165 +++++++++++++++++++++++++++++++++++-----
1 files changed, 145 insertions(+), 20 deletions(-)
---
diff --git a/src/libsushi/sushi-cover-art.c b/src/libsushi/sushi-cover-art.c
index 335f259..8304587 100644
--- a/src/libsushi/sushi-cover-art.c
+++ b/src/libsushi/sushi-cover-art.c
@@ -22,6 +22,11 @@ struct _SushiCoverArtFetcherPrivate {
static void sushi_cover_art_fetcher_set_taglist (SushiCoverArtFetcher *self,
GstTagList *taglist);
+static void sushi_cover_art_fetcher_get_uri_for_track_async (SushiCoverArtFetcher *self,
+ const gchar *artist,
+ const gchar *album,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
static void
sushi_cover_art_fetcher_dispose (GObject *object)
@@ -115,10 +120,62 @@ sushi_cover_art_fetcher_class_init (SushiCoverArtFetcherClass *klass)
g_type_class_add_private (klass, sizeof (SushiCoverArtFetcherPrivate));
}
-static gchar *
-sushi_amazon_cover_uri_get_for_track (const gchar *artist,
- const gchar *album)
+typedef struct {
+ SushiCoverArtFetcher *self;
+ GSimpleAsyncResult *result;
+ gchar *artist;
+ gchar *album;
+} FetchUriJob;
+
+static void
+fetch_uri_job_free (gpointer user_data)
+{
+ FetchUriJob *data = user_data;
+
+ g_clear_object (&data->self);
+ g_clear_object (&data->result);
+ g_free (data->artist);
+ g_free (data->album);
+
+ g_slice_free (FetchUriJob, data);
+}
+
+static FetchUriJob *
+fetch_uri_job_new (SushiCoverArtFetcher *self,
+ const gchar *artist,
+ const gchar *album,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ FetchUriJob *retval;
+
+ retval = g_slice_new0 (FetchUriJob);
+ retval->artist = g_strdup (artist);
+ retval->album = g_strdup (album);
+ retval->self = g_object_ref (self);
+ retval->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+ sushi_cover_art_fetcher_get_uri_for_track_async);
+
+ return retval;
+}
+
+static gboolean
+fetch_uri_job_callback (gpointer user_data)
+{
+ FetchUriJob *job = user_data;
+
+ g_simple_async_result_complete (job->result);
+ fetch_uri_job_free (job);
+
+ return FALSE;
+}
+
+static gboolean
+fetch_uri_job (GIOSchedulerJob *sched_job,
+ GCancellable *cancellable,
+ gpointer user_data)
{
+ FetchUriJob *job = user_data;
MbQuery query;
MbReleaseFilter filter;
MbRelease release;
@@ -129,8 +186,8 @@ sushi_amazon_cover_uri_get_for_track (const gchar *artist,
query = mb_query_new (NULL, NULL);
filter = mb_release_filter_new ();
- filter = mb_release_filter_title (filter, album);
- filter = mb_release_filter_artist_name (filter, artist);
+ filter = mb_release_filter_title (filter, job->album);
+ filter = mb_release_filter_artist_name (filter, job->artist);
results = mb_query_get_releases (query, filter);
results_len = mb_result_list_get_size (results);
@@ -148,10 +205,58 @@ sushi_amazon_cover_uri_get_for_track (const gchar *artist,
}
}
+ if (retval == NULL) {
+ /* FIXME: do we need a better error? */
+ g_simple_async_result_set_error (job->result,
+ G_IO_ERROR,
+ 0, "%s",
+ "Error getting the ASIN from MusicBrainz");
+ } else {
+ g_simple_async_result_set_op_res_gpointer (job->result,
+ retval, NULL);
+ }
+
+ g_io_scheduler_job_send_to_mainloop_async (sched_job,
+ fetch_uri_job_callback,
+ job, NULL);
+
+ return FALSE;
+}
+
+static gchar *
+sushi_cover_art_fetcher_get_uri_for_track_finish (SushiCoverArtFetcher *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ gchar *retval;
+
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
+ error))
+ return NULL;
+
+ retval = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result));
+
return retval;
}
static void
+sushi_cover_art_fetcher_get_uri_for_track_async (SushiCoverArtFetcher *self,
+ const gchar *artist,
+ const gchar *album,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ FetchUriJob *job;
+ SushiCoverArtFetcherPrivate *priv = SUSHI_COVER_ART_FETCHER_GET_PRIVATE (self);
+
+ job = fetch_uri_job_new (self, artist, album, callback, user_data);
+ g_io_scheduler_push_job (fetch_uri_job,
+ job, NULL,
+ G_PRIORITY_DEFAULT, NULL);
+}
+
+static void
pixbuf_from_stream_async_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
@@ -199,10 +304,39 @@ asin_uri_read_cb (GObject *source,
}
static void
+amazon_cover_uri_async_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SushiCoverArtFetcher *self = SUSHI_COVER_ART_FETCHER (source);
+ GError *error = NULL;
+ gchar *asin;
+ GFile *file;
+
+ asin = sushi_cover_art_fetcher_get_uri_for_track_finish
+ (self, res, &error);
+
+ if (error != NULL) {
+ g_print ("Unable to fetch the Amazon cover art uri from MusicBrainz: %s\n",
+ error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ file = g_file_new_for_uri (asin);
+ g_file_read_async (file, G_PRIORITY_DEFAULT,
+ NULL, asin_uri_read_cb,
+ self);
+
+ g_object_unref (file);
+ g_free (asin);
+}
+
+static void
try_fetch_from_amazon (SushiCoverArtFetcher *self)
{
SushiCoverArtFetcherPrivate *priv = SUSHI_COVER_ART_FETCHER_GET_PRIVATE (self);
- gchar *asin;
gchar *artist = NULL;
gchar *album = NULL;
GFile *file;
@@ -218,21 +352,12 @@ try_fetch_from_amazon (SushiCoverArtFetcher *self)
return;
}
- asin = sushi_amazon_cover_uri_get_for_track (artist, album);
+ sushi_cover_art_fetcher_get_uri_for_track_async
+ (self, artist, album,
+ amazon_cover_uri_async_ready_cb, NULL);
- if (asin == NULL) {
- g_free (artist);
- g_free (album);
-
- return;
- }
-
- file = g_file_new_for_uri (asin);
- g_file_read_async (file, G_PRIORITY_DEFAULT,
- NULL, asin_uri_read_cb,
- self);
-
- g_object_unref (file);
+ g_free (artist);
+ g_free (album);
}
/* code taken from Totem */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]