diff options
-rw-r--r-- | ChangeLog | 30 | ||||
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | libjuicer/Makefile.am | 22 | ||||
-rw-r--r-- | libjuicer/sj-metadata-cdtext.c | 47 | ||||
-rw-r--r-- | libjuicer/sj-metadata-getter.c | 251 | ||||
-rw-r--r-- | libjuicer/sj-metadata-getter.h | 62 | ||||
-rw-r--r-- | libjuicer/sj-metadata-musicbrainz.c | 111 | ||||
-rw-r--r-- | libjuicer/sj-metadata-musicbrainz3.c | 451 | ||||
-rw-r--r-- | libjuicer/sj-metadata-musicbrainz3.h | 55 | ||||
-rw-r--r-- | libjuicer/sj-metadata.c | 24 | ||||
-rw-r--r-- | libjuicer/sj-metadata.h | 9 | ||||
-rw-r--r-- | libjuicer/sj-structures.h | 3 | ||||
-rw-r--r-- | po/ChangeLog | 4 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | src/sj-main.c | 29 | ||||
-rw-r--r-- | tests/mb-test.c | 32 |
16 files changed, 958 insertions, 198 deletions
@@ -1,5 +1,35 @@ 2008-09-03 Bastien Nocera <hadess@hadess.net> + * configure.in: Check for libmusicbrainz3, and require libcdio + * libjuicer/Makefile.am: + + * libjuicer/sj-metadata-getter.c: + * libjuicer/sj-metadata-getter.h: Add a helper object to gather + data from different metadata backends, with fallback support. The + threading is now in the helper object, and not in the metadata + backends themselves. The backends don't have signals anymore, + and are synchronous. + + * libjuicer/sj-metadata-cdtext.c (cdtext_list_albums), + (sj_metadata_cdtext_finalize): + * libjuicer/sj-metadata-musicbrainz.c (mb_list_albums), + (metadata_interface_init): + * libjuicer/sj-metadata.c (sj_metadata_base_init), + (sj_metadata_list_albums): + * libjuicer/sj-metadata.h: + * libjuicer/sj-structures.h: + * src/sj-main.c (metadata_cb), (reread_cd), (set_device), + (http_proxy_setup), (main): + * tests/mb-test.c (source_to_str), (metadata_cb), (main): + Change for the above + + * libjuicer/sj-metadata-musicbrainz3.c: + * libjuicer/sj-metadata-musicbrainz3.h: Add libmusicbrainz3 support + + (Closes: #516447) + +2008-09-03 Bastien Nocera <hadess@hadess.net> + * libjuicer/sj-metadata-musicbrainz.c (lookup_cd): * libjuicer/sj-structures.c (album_details_free): * libjuicer/sj-structures.h: diff --git a/configure.in b/configure.in index dec9e72..633463a 100644 --- a/configure.in +++ b/configure.in @@ -69,7 +69,20 @@ PKG_CHECK_MODULES(MEDIA_PROFILES, gnome-media-profiles >= 2.11.91) AC_SUBST(MEDIA_PROFILES_CFLAGS) AC_SUBST(MEDIA_PROFILES_LIBS) +# Find libcdio +PKG_CHECK_MODULES([CDIO],[libcdio >= 0.70]) +AC_SUBST([CDIO_CFLAGS]) +AC_SUBST([CDIO_LIBS]) + # Find MusicBrainz +PKG_CHECK_MODULES(MUSICBRAINZ3, libmusicbrainz3, [have_mb3=yes], [have_mb3=no]) +AC_SUBST(MUSICBRAINZ3_CFLAGS) +AC_SUBST(MUSICBRAINZ3_LIBS) +AM_CONDITIONAL([HAVE_MB3], [test "$have_mb3" = "yes"]) +if test "$have_mb3" = "yes" ; then + AC_DEFINE([HAVE_MB3], 1, [Whether libmusicbrainz3 is available]) +fi + PKG_CHECK_MODULES(MUSICBRAINZ, libmusicbrainz >= 2.1.3) AC_SUBST(MUSICBRAINZ_CFLAGS) AC_SUBST(MUSICBRAINZ_LIBS) @@ -79,17 +92,6 @@ LIBS="$LIBS $MUSICBRAINZ_LIBS" AC_CHECK_FUNCS(mb_SetProxyCreds) LIBS="$oldlibs" -# Find the optional dependency libcdio -PKG_CHECK_MODULES([CDIO],[libcdio >= 0.70],[have_cdio=yes],[have_cdio=no]) -AC_SUBST([CDIO_CFLAGS]) -AC_SUBST([CDIO_LIBS]) - -if test "$have_cdio" != "yes"; then - AC_MSG_WARN([libcdio not found, cannot get track names from CD-TEXT]) -fi - -AM_CONDITIONAL([HAVE_CDIO],[test "$have_cdio" = "yes"]) - # Find TagLib for the internal copy of id3mux PKG_CHECK_MODULES([TAGLIB],[taglib],[have_taglib=yes],[have_taglib=no]) AC_SUBST([TAGLIB_CFLAGS]) diff --git a/libjuicer/Makefile.am b/libjuicer/Makefile.am index 6519f28..7a26447 100644 --- a/libjuicer/Makefile.am +++ b/libjuicer/Makefile.am @@ -12,6 +12,10 @@ libjuicer_la_SOURCES = \ sj-metadata.c \ sj-metadata-musicbrainz.h \ sj-metadata-musicbrainz.c \ + sj-metadata-cdtext.h \ + sj-metadata-cdtext.c \ + sj-metadata-getter.c \ + sj-metadata-getter.h \ sj-util.h sj-util.c libjuicer_la_CPPFLAGS = \ @@ -21,33 +25,31 @@ libjuicer_la_CPPFLAGS = \ libjuicer_la_CFLAGS = \ $(WARN_CFLAGS) \ $(MUSICBRAINZ_CFLAGS) \ + $(MUSICBRAINZ3_CFLAGS) \ $(GSTREAMER_CFLAGS) \ $(MEDIA_PROFILES_CFLAGS) \ $(BURN_CFLAGS) \ $(UI_CFLAGS) \ + $(CDIO_CFLAGS) \ $(AM_CFLAGS) libjuicer_la_LIBADD = \ $(MUSICBRAINZ_LIBS) \ + $(MUSICBRAINZ3_LIBS) \ $(MEDIA_PROFILES_LIBS) \ $(GSTREAMER_LIBS) \ $(BURN_LIBS) \ - $(UI_LIBS) + $(UI_LIBS) \ + $(CDIO_LIBS) libjuicer_la_LDFLAGS = \ -export-dynamic \ $(AM_LDFLAGS) -if HAVE_CDIO +if HAVE_MB3 libjuicer_la_SOURCES += \ - sj-metadata-cdtext.h \ - sj-metadata-cdtext.c - -libjuicer_la_CFLAGS += \ - $(CDIO_CFLAGS) - -libjuicer_la_LDFLAGS += \ - $(CDIO_LIBS) + sj-metadata-musicbrainz3.h \ + sj-metadata-musicbrainz3.c endif # diff --git a/libjuicer/sj-metadata-cdtext.c b/libjuicer/sj-metadata-cdtext.c index dde7343..5796e69 100644 --- a/libjuicer/sj-metadata-cdtext.c +++ b/libjuicer/sj-metadata-cdtext.c @@ -40,7 +40,6 @@ struct SjMetadataCdtextPrivate { char *cdrom; GList *albums; - GError *error; }; #define GET_PRIVATE(o) \ @@ -64,35 +63,25 @@ G_DEFINE_TYPE_WITH_CODE (SjMetadataCdtext, sj_metadata_cdtext, * Private methods */ -static gboolean -fire_signal_idle (SjMetadataCdtext *m) +static GList * +cdtext_list_albums (SjMetadata *metadata, char **url, GError **error) { - g_return_val_if_fail (SJ_IS_METADATA_CDTEXT (m), FALSE); - g_signal_emit_by_name (G_OBJECT (m), "metadata", m->priv->albums, m->priv->error); - return FALSE; -} - -static void -cdtext_list_albums (SjMetadata *metadata, GError **error) -{ - /* TODO: put in a thread */ SjMetadataCdtextPrivate *priv; AlbumDetails *album; CdIo *cdio; track_t cdtrack, last_cdtrack; const cdtext_t *cdtext; - g_return_if_fail (SJ_IS_METADATA_CDTEXT (metadata)); + g_return_val_if_fail (SJ_IS_METADATA_CDTEXT (metadata), NULL); priv = SJ_METADATA_CDTEXT (metadata)->priv; cdio = cdio_open (priv->cdrom, DRIVER_UNKNOWN); if (!cdio) { g_warning ("Cannot open CD"); - priv->error = g_error_new (SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Cannot read CD")); + g_set_error (error, SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, _("Cannot read CD")); priv->albums = NULL; - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); - return; + return NULL; } #if 0 @@ -120,7 +109,8 @@ cdtext_list_albums (SjMetadata *metadata, GError **error) track->title = g_strdup (cdtext_get (CDTEXT_TITLE, cdtext)); track->artist = g_strdup (cdtext_get (CDTEXT_PERFORMER, cdtext)); } else { - g_print ("No CD-TEXT for track %u\n", cdtrack); + track->title = g_strdup_printf (_("Track %d"), cdtrack); + track->artist = g_strdup (_("Unknown Artist")); } track->duration = cdio_get_track_sec_count (cdio, cdtrack) / CDIO_CD_FRAMES_PER_SEC; @@ -130,15 +120,24 @@ cdtext_list_albums (SjMetadata *metadata, GError **error) /* TODO: why can't I do this first? */ cdtext = cdio_get_cdtext(cdio, 0); - album->title = g_strdup (cdtext_get (CDTEXT_TITLE, cdtext)); - album->artist = g_strdup (cdtext_get (CDTEXT_PERFORMER, cdtext)); - album->genre = g_strdup (cdtext_get (CDTEXT_GENRE, cdtext)); + if (cdtext) { + album->title = g_strdup (cdtext_get (CDTEXT_TITLE, cdtext)); + album->artist = g_strdup (cdtext_get (CDTEXT_PERFORMER, cdtext)); + album->genre = g_strdup (cdtext_get (CDTEXT_GENRE, cdtext)); + + album->metadata_source = SOURCE_CDTEXT; + } else { + album->artist = g_strdup (_("Unknown Artist")); + album->title = g_strdup (_("Unknown Title")); + album->genre = g_strdup (""); + + album->metadata_source = SOURCE_FALLBACK; + } - album->metadata_source = SOURCE_CDTEXT; - priv->error = NULL; priv->albums = g_list_append (NULL, album); - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); + + return priv->albums; } @@ -198,8 +197,6 @@ sj_metadata_cdtext_finalize (GObject *object) SjMetadataCdtextPrivate *priv = SJ_METADATA_CDTEXT (object)->priv; g_free (priv->cdrom); g_list_deep_free (priv->albums, (GFunc)album_details_free); - if (priv->error) - g_error_free (priv->error); } static void diff --git a/libjuicer/sj-metadata-getter.c b/libjuicer/sj-metadata-getter.c new file mode 100644 index 0000000..6c08f46 --- /dev/null +++ b/libjuicer/sj-metadata-getter.c @@ -0,0 +1,251 @@ +/* + * sj-metadata.c + * Copyright (C) 2003 Ross Burton <ross@burtonini.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include <glib-object.h> +#include <glib/gi18n.h> +#include "sj-metadata-getter.h" +#include "sj-metadata-marshal.h" +#include "sj-metadata.h" +#ifdef HAVE_MB3 +#include "sj-metadata-musicbrainz3.h" +#endif /* HAVE_MB3 */ +#include "sj-metadata-musicbrainz.h" +#include "sj-metadata-cdtext.h" +#include "sj-error.h" + +enum { + METADATA, + LAST_SIGNAL +}; + +struct SjMetadataGetterPrivate { + char *url; + char *cdrom; + char *proxy_host; + int proxy_port; +}; + +struct SjMetadataGetterSignal { + SjMetadataGetter *mdg; + SjMetadata *metadata; + GList *albums; + GError *error; +}; + +typedef struct SjMetadataGetterPrivate SjMetadataGetterPrivate; +typedef struct SjMetadataGetterSignal SjMetadataGetterSignal; + +static int signals[LAST_SIGNAL] = { 0 }; + +static void sj_metadata_getter_finalize (GObject *object); +static void sj_metadata_getter_init (SjMetadataGetter *mdg); + +G_DEFINE_TYPE(SjMetadataGetter, sj_metadata_getter, G_TYPE_OBJECT); + +#define GETTER_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), SJ_TYPE_METADATA_GETTER, SjMetadataGetterPrivate)) + +static void +sj_metadata_getter_class_init (SjMetadataGetterClass *klass) +{ + GObjectClass *object_class; + object_class = (GObjectClass *)klass; + + g_type_class_add_private (klass, sizeof (SjMetadataGetterPrivate)); + + object_class->finalize = sj_metadata_getter_finalize; + + /* Properties */ + signals[METADATA] = g_signal_new ("metadata", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SjMetadataGetterClass, metadata), + NULL, NULL, + metadata_marshal_VOID__POINTER_POINTER, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); +} + +static void +sj_metadata_getter_finalize (GObject *object) +{ + SjMetadataGetterPrivate *priv = GETTER_PRIVATE (object); + + g_free (priv->url); + g_free (priv->cdrom); + g_free (priv->proxy_host); + + G_OBJECT_CLASS (sj_metadata_getter_parent_class)->finalize (object); +} + +static void +sj_metadata_getter_init (SjMetadataGetter *mdg) +{ +} + +SjMetadataGetter * +sj_metadata_getter_new (void) +{ + return SJ_METADATA_GETTER (g_object_new (SJ_TYPE_METADATA_GETTER, NULL)); +} + +void +sj_metadata_getter_set_cdrom (SjMetadataGetter *mdg, const char* device) +{ + SjMetadataGetterPrivate *priv; + + priv = GETTER_PRIVATE (mdg); + + if (priv->cdrom) + g_free (priv->cdrom); + priv->cdrom = g_strdup (device); +} + +void +sj_metadata_getter_set_proxy (SjMetadataGetter *mdg, const char* proxy) +{ + SjMetadataGetterPrivate *priv; + + priv = GETTER_PRIVATE (mdg); + + if (priv->proxy_host) + g_free (priv->proxy_host); + priv->proxy_host = g_strdup (proxy); +} + +void +sj_metadata_getter_set_proxy_port (SjMetadataGetter *mdg, const int proxy_port) +{ + SjMetadataGetterPrivate *priv; + + priv = GETTER_PRIVATE (mdg); + + priv->proxy_port = proxy_port; +} + +static gboolean +fire_signal_idle (SjMetadataGetterSignal *signal) +{ + g_signal_emit_by_name (G_OBJECT (signal->mdg), "metadata", + signal->albums, signal->error); + + /* This will kill the albums, as + * those belong to the metadata backend */ + if (signal->metadata) + g_object_unref (signal->metadata); + if (signal->error != NULL) + g_error_free (signal->error); + g_free (signal); + + return FALSE; +} + +static gpointer +lookup_cd (SjMetadataGetter *mdg) +{ + SjMetadata *metadata; + guint i; + SjMetadataGetterPrivate *priv; + GError *error = NULL; + gboolean found = FALSE; + GType types[] = { +#ifdef HAVE_MB3 + SJ_TYPE_METADATA_MUSICBRAINZ3, +#endif /* HAVE_MB3 */ + SJ_TYPE_METADATA_MUSICBRAINZ, + SJ_TYPE_METADATA_CDTEXT, + }; + + priv = GETTER_PRIVATE (mdg); + + g_free (priv->url); + priv->url = NULL; + + for (i = 0; i < G_N_ELEMENTS (types); i++) { + GList *albums; + + metadata = g_object_new (types[i], + "device", priv->cdrom, + "proxy-host", priv->proxy_host, + "proxy-port", priv->proxy_port, + NULL); + if (priv->url == NULL) + albums = sj_metadata_list_albums (metadata, &priv->url, &error); + else + albums = sj_metadata_list_albums (metadata, NULL, &error); + + if (albums != NULL) { + SjMetadataGetterSignal *signal; + + signal = g_new0 (SjMetadataGetterSignal, 1); + signal->albums = albums; + signal->mdg = mdg; + signal->metadata = metadata; + g_idle_add ((GSourceFunc)fire_signal_idle, signal); + break; + } + + g_object_unref (metadata); + + if (error != NULL) { + SjMetadataGetterSignal *signal; + + g_assert (found == FALSE); + + signal = g_new0 (SjMetadataGetterSignal, 1); + signal->error = error; + signal->mdg = mdg; + g_idle_add ((GSourceFunc)fire_signal_idle, signal); + break; + } + } + + return NULL; +} + +gboolean +sj_metadata_getter_list_albums (SjMetadataGetter *mdg, GError **error) +{ + GThread *thread; + + thread = g_thread_create ((GThreadFunc)lookup_cd, mdg, TRUE, error); + if (thread == NULL) { + g_set_error (error, + SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, + _("Could not create CD lookup thread")); + return FALSE; + } + + return TRUE; +} + +char * +sj_metadata_getter_get_submit_url (SjMetadataGetter *mdg) +{ + SjMetadataGetterPrivate *priv; + + priv = GETTER_PRIVATE (mdg); + + if (priv->url) + return g_strdup (priv->url); + return NULL; +} + diff --git a/libjuicer/sj-metadata-getter.h b/libjuicer/sj-metadata-getter.h new file mode 100644 index 0000000..05b93a4 --- /dev/null +++ b/libjuicer/sj-metadata-getter.h @@ -0,0 +1,62 @@ +/* + * sj-metadata-getter.h + * Copyright (C) 2008 Bastien Nocera + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SJ_METADATA_GETTER_H +#define SJ_METADATA_GETTER_H + +#include <glib-object.h> +#include <glib/gerror.h> + +G_BEGIN_DECLS + +#define SJ_TYPE_METADATA_GETTER (sj_metadata_getter_get_type ()) +#define SJ_METADATA_GETTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SJ_TYPE_METADATA_GETTER, SjMetadataGetter)) +#define SJ_METADATA_GETTER_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), SJ_TYPE_METADATA_GETTER, SjMetadataGetterClass)) +#define SJ_IS_METADATA_GETTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SJ_TYPE_METADATA_GETTER)) +#define SJ_IS_METADATA_GETTER_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), SJ_TYPE_METADATA_GETTER)) +#define SJ_METADATA_GETTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SJ_TYPE_METADATA_GETTER, SjMetadataGetterClass)) + +struct _SjMetadataGetter +{ + GObject parent; +}; + +typedef struct _SjMetadataGetter SjMetadataGetter; +typedef struct _SjMetadataGetterClass SjMetadataGetterClass; + +struct _SjMetadataGetterClass +{ + GObjectClass parent; + + /* Signals */ + void (*metadata) (SjMetadataGetter *mdg, GList *albums, GError *error); +}; + +GType sj_metadata_getter_get_type (void); +SjMetadataGetter *sj_metadata_getter_new (void); +void sj_metadata_getter_set_cdrom (SjMetadataGetter *mdg, const char* device); +void sj_metadata_getter_set_proxy (SjMetadataGetter *mdg, const char* proxy); +void sj_metadata_getter_set_proxy_port (SjMetadataGetter *mdg, const int proxy_port); +gboolean sj_metadata_getter_list_albums (SjMetadataGetter *mdg, GError **error); +char *sj_metadata_getter_get_submit_url (SjMetadataGetter *mdg); + +G_END_DECLS + +#endif /* SJ_METADATA_GETTER_H */ diff --git a/libjuicer/sj-metadata-musicbrainz.c b/libjuicer/sj-metadata-musicbrainz.c index b78d8a5..c221ae4 100644 --- a/libjuicer/sj-metadata-musicbrainz.c +++ b/libjuicer/sj-metadata-musicbrainz.c @@ -55,9 +55,7 @@ struct SjMetadataMusicbrainzPrivate { char *http_proxy; int http_proxy_port; char *cdrom; - /* TODO: remove and use an async queue? */ GList *albums; - GError *error; GRegex *disc_regex; }; @@ -94,54 +92,6 @@ get_duration_from_sectors (int sectors) return (sectors * BYTES_PER_SECTOR / BYTES_PER_SECOND); } -static GList* -get_offline_track_listing(SjMetadata *metadata, GError **error) -{ - SjMetadataMusicbrainzPrivate *priv; - GList* list = NULL; - AlbumDetails *album; - TrackDetails *track; - int num_tracks, i; - - g_return_val_if_fail (metadata != NULL, NULL); - priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv; - - if (!mb_Query (priv->mb, MBQ_GetCDTOC)) { - char message[255]; - mb_GetQueryError (priv->mb, message, 255); - g_set_error (error, - SJ_ERROR, SJ_ERROR_CD_LOOKUP_ERROR, - _("Cannot read CD: %s"), message); - return NULL; - } - - num_tracks = mb_GetResultInt (priv->mb, MBE_TOCGetLastTrack); - - album = g_new0 (AlbumDetails, 1); - album->artist = g_strdup (_("Unknown Artist")); - album->title = g_strdup (_("Unknown Title")); - album->genre = NULL; - for (i = 1; i <= num_tracks; i++) { - track = g_new0 (TrackDetails, 1); - track->album = album; - track->number = i; - track->title = g_strdup_printf (_("Track %d"), i); - track->artist = g_strdup (album->artist); - track->duration = get_duration_from_sectors (mb_GetResultInt1 (priv->mb, MBE_TOCGetTrackNumSectors, i+1)); - album->tracks = g_list_append (album->tracks, track); - album->number++; - } - return g_list_append (list, album); -} - -static gboolean -fire_signal_idle (SjMetadataMusicbrainz *m) -{ - g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ (m), FALSE); - g_signal_emit_by_name (G_OBJECT (m), "metadata", m->priv->albums, m->priv->error); - return FALSE; -} - /** * Virtual methods */ @@ -324,8 +274,8 @@ convert_encoding(char **str) g_free (iso8859); } -static gpointer -lookup_cd (SjMetadata *metadata) +static GList * +mb_list_albums (SjMetadata *metadata, char **url, GError **error) { /** The size of the buffer used in MusicBrainz lookups */ SjMetadataMusicbrainzPrivate *priv; @@ -338,12 +288,10 @@ lookup_cd (SjMetadata *metadata) NautilusBurnDriveMonitor *monitor; NautilusBurnDrive *drive; - /* TODO: fire error signal */ g_return_val_if_fail (metadata != NULL, NULL); g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ (metadata), NULL); priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv; g_return_val_if_fail (priv->cdrom != NULL, NULL); - priv->error = NULL; /* TODO: hack */ if (! nautilus_burn_initialized ()) { nautilus_burn_init (); @@ -367,21 +315,24 @@ lookup_cd (SjMetadata *metadata) msg = g_strdup_printf (_("Device '%s' could not be opened. Check the access permissions on the device."), priv->cdrom); err = SJ_ERROR_CD_PERMISSION_ERROR; } - priv->error = g_error_new (SJ_ERROR, err, _("Cannot read CD: %s"), msg); + g_set_error (error, SJ_ERROR, err, _("Cannot read CD: %s"), msg); g_free (msg); priv->albums = NULL; - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); return NULL; } get_rdf (metadata); + if (url != NULL) { + mb_GetWebSubmitURL(priv->mb, data, sizeof(data)); + *url = g_strdup(data); + } + num_albums = mb_GetResultInt(priv->mb, MBE_GetNumAlbums); if (num_albums < 1) { - priv->albums = get_offline_track_listing (metadata, &(priv->error)); - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); - return priv->albums; + priv->albums = NULL; + return NULL; } for (i = 1; i <= num_albums; i++) { @@ -467,9 +418,8 @@ lookup_cd (SjMetadata *metadata) g_free (album->title); g_free (album); g_warning (_("Incomplete metadata for this CD")); - priv->albums = get_offline_track_listing (metadata, &(priv->error)); - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); - return priv->albums; + priv->albums = NULL; + return NULL; } for (j = 1; j <= num_tracks; j++) { @@ -561,45 +511,9 @@ lookup_cd (SjMetadata *metadata) } } - priv->albums = albums; - g_idle_add ((GSourceFunc)fire_signal_idle, metadata); return albums; } -static void -mb_list_albums (SjMetadata *metadata, GError **error) -{ - GThread *thread; - - g_return_if_fail (SJ_IS_METADATA_MUSICBRAINZ (metadata)); - - thread = g_thread_create ((GThreadFunc)lookup_cd, metadata, TRUE, error); - if (thread == NULL) { - g_set_error (error, - SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, - _("Could not create CD lookup thread")); - return; - } -} - -static char * -mb_get_submit_url (SjMetadata *metadata) -{ - SjMetadataMusicbrainzPrivate *priv; - char url[1025]; - - g_return_val_if_fail (metadata != NULL, NULL); - - priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv; - - if (mb_GetWebSubmitURL(priv->mb, url, 1024)) { - return g_strdup(url); - } else { - return NULL; - } -} - - /* * GObject methods */ @@ -609,7 +523,6 @@ metadata_interface_init (gpointer g_iface, gpointer iface_data) { SjMetadataClass *klass = (SjMetadataClass*)g_iface; klass->list_albums = mb_list_albums; - klass->get_submit_url = mb_get_submit_url; } static void diff --git a/libjuicer/sj-metadata-musicbrainz3.c b/libjuicer/sj-metadata-musicbrainz3.c new file mode 100644 index 0000000..f59dbb0 --- /dev/null +++ b/libjuicer/sj-metadata-musicbrainz3.c @@ -0,0 +1,451 @@ +/* + * sj-metadata-musicbrainz3.c + * Copyright (C) 2008 Ross Burton <ross@burtonini.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <glib.h> +#include <glib-object.h> +#include <glib/gi18n.h> +#include <gconf/gconf-client.h> +#include <nautilus-burn.h> +#include <musicbrainz3/mb_c.h> + +#include "sj-metadata-musicbrainz3.h" +#include "sj-metadata-cdtext.h" +#include "sj-structures.h" +#include "sj-error.h" + +#define GET(field, function, obj) function (obj, buffer, sizeof (buffer)); if (field) g_free (field); field = g_strdup (buffer); + +#define GCONF_PROXY_USE_PROXY "/system/http_proxy/use_http_proxy" +#define GCONF_PROXY_HOST "/system/http_proxy/host" +#define GCONF_PROXY_PORT "/system/http_proxy/port" +#define GCONF_PROXY_USE_AUTHENTICATION "/system/http_proxy/use_authentication" +#define GCONF_PROXY_USERNAME "/system/http_proxy/authentication_user" +#define GCONF_PROXY_PASSWORD "/system/http_proxy/authentication_password" + +typedef struct { + MbWebService mb; + MbDisc disc; + char *cdrom; + GList *albums; + /* Proxy */ + char *http_proxy; + int http_proxy_port; +} SjMetadataMusicbrainz3Private; + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), SJ_TYPE_METADATA_MUSICBRAINZ3, SjMetadataMusicbrainz3Private)) + +enum { + PROP_0, + PROP_DEVICE, + PROP_USE_PROXY, + PROP_PROXY_HOST, + PROP_PROXY_PORT, +}; + +static void metadata_interface_init (gpointer g_iface, gpointer iface_data); + +G_DEFINE_TYPE_WITH_CODE (SjMetadataMusicbrainz3, + sj_metadata_musicbrainz3, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (SJ_TYPE_METADATA, + metadata_interface_init)); + + +/* + * Private methods + */ + +static AlbumDetails * +make_album_from_release (MbRelease *release) +{ + AlbumDetails *album; + char buffer[512]; + MbArtist artist; + GRegex *disc_regex; + GMatchInfo *info; + int i; + + g_assert (release); + + album = g_new0 (AlbumDetails, 1); + + /* Some versions of libmusicbrainz3 seem to forget the trailing .html in the URL */ + GET (album->album_id, mb_release_get_id, release); + if (album->album_id && g_str_has_suffix (album->album_id, ".html") == FALSE) { + char *tmp; + tmp = g_strdup_printf ("%s.html", album->album_id); + g_free (album->album_id); + album->album_id = tmp; + } + + GET (album->title, mb_release_get_title, release); + disc_regex = g_regex_new (".+( \\(disc (\\d+).*)", 0, 0, NULL); + + if (g_regex_match (disc_regex, album->title, 0, &info)) { + int pos = 0; + char *s; + + g_match_info_fetch_pos (info, 1, &pos, NULL); + if (pos) { + s = g_strndup (album->title, pos); + g_free (album->title); + album->title = s; + } + + s = g_match_info_fetch (info, 2); + album->disc_number = atoi (s); + g_free (s); + } + + g_match_info_free (info); + g_regex_unref (disc_regex); + + artist = mb_release_get_artist (release); + GET (album->artist_id, mb_artist_get_id, artist); + GET (album->artist, mb_artist_get_name, artist); + GET (album->artist_sortname, mb_artist_get_sortname, artist); + + if (mb_release_get_num_release_events (release) >= 1) { + MbReleaseEvent event; + char *date = NULL; + int matched, year=1, month=1, day=1; + + event = mb_release_get_release_event (release, 1); + GET (date, mb_release_event_get_date, event); + matched = sscanf(date, "%u-%u-%u", &year, &month, &day); + if (matched >= 1) + album->release_date = g_date_new_dmy ((day == 0) ? 1 : day, (month == 0) ? 1 : month, year); + g_free (date); + } + + album->number = mb_release_get_num_tracks (release); + GET (album->asin, mb_release_get_asin, release); + + for (i = 0; i < mb_release_get_num_relations (release); i++) { + MbRelation relation; + char *type = NULL; + + relation = mb_release_get_relation (release, i); + GET(type, mb_relation_get_type, relation); + if (type && g_str_equal (type, "http://musicbrainz.org/ns/rel-1.0#Wikipedia")) { + GET (album->wikipedia, mb_relation_get_target_id, relation); + } else if (type && g_str_equal (type, "http://musicbrainz.org/ns/rel-1.0#Discogs")) { + GET (album->discogs, mb_relation_get_target_id, relation); + continue; + } + g_free (type); + } + + for (i = 0; i < album->number; i++) { + MbTrack mbt; + TrackDetails *track; + + mbt = mb_release_get_track (release, i); + track = g_new0 (TrackDetails, 1); + + track->album = album; + + track->number = i + 1; + GET (track->track_id, mb_track_get_id, mbt); + + GET (track->title, mb_track_get_title, mbt); + track->duration = mb_track_get_duration (mbt) / 1000; + + artist = mb_release_get_artist (release); + GET (track->artist_id, mb_artist_get_id, artist); + GET (track->artist, mb_artist_get_name, artist); + GET (track->artist_sortname, mb_artist_get_sortname, artist); + + album->tracks = g_list_append (album->tracks, track); + } + + return album; +} + +static void +fill_empty_durations (MbDisc *disc, AlbumDetails *album) +{ + if (disc == NULL) + return; +} + +static MbReleaseIncludes +get_release_includes (void) +{ + MbReleaseIncludes includes; + + includes = mb_release_includes_new (); + includes = mb_release_includes_artist (includes); + includes = mb_release_includes_tracks (includes); + includes = mb_artist_includes_release_events (includes); + includes = mb_track_includes_url_relations (includes); + + return includes; +} + +/** + * Virtual methods + */ + +static GList * +mb_list_albums (SjMetadata *metadata, char **url, GError **error) +{ + SjMetadataMusicbrainz3Private *priv; + MbQuery query; + MbReleaseFilter filter; + MbResultList results; + MbRelease release; + char *id = NULL; + char buffer[512]; + int i; + NautilusBurnMediaType type; + NautilusBurnDriveMonitor *monitor; + NautilusBurnDrive *drive; + + g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ3 (metadata), FALSE); + + priv = GET_PRIVATE (metadata); + + if (! nautilus_burn_initialized ()) { + nautilus_burn_init (); + } + monitor = nautilus_burn_get_drive_monitor (); + drive = nautilus_burn_drive_monitor_get_drive_for_device (monitor, priv->cdrom); + if (drive == NULL) { + return NULL; + } + type = nautilus_burn_drive_get_media_type (drive); + nautilus_burn_drive_unref (drive); + + if (type == NAUTILUS_BURN_MEDIA_TYPE_ERROR) { + char *msg; + SjError err; + + if (access (priv->cdrom, W_OK) == 0) { + msg = g_strdup_printf (_("Device '%s' does not contain any media"), priv->cdrom); + err = SJ_ERROR_CD_NO_MEDIA; + } else { + msg = g_strdup_printf (_("Device '%s' could not be opened. Check the access permissions on the device."), priv->cdrom); + err = SJ_ERROR_CD_PERMISSION_ERROR; + } + g_set_error (error, SJ_ERROR, err, _("Cannot read CD: %s"), msg); + g_free (msg); + + priv->albums = NULL; + return NULL; + } + + priv->disc = mb_read_disc (priv->cdrom); + if (url != NULL) { + mb_get_submission_url (priv->disc, NULL, 0, buffer, sizeof (buffer)); + *url = g_strdup (buffer); + } + + GET(id, mb_disc_get_id, priv->disc); + + query = mb_query_new (priv->mb, "sound-juicer"); + filter = mb_release_filter_new (); + filter = mb_release_filter_disc_id (filter, id); + results = mb_query_get_releases (query, filter); + mb_release_filter_free (filter); + + if (mb_result_list_get_size (results) == 0) { + mb_result_list_free (results); + mb_query_free (query); + return NULL; + } + + for (i = 0; i < mb_result_list_get_size (results); i++) { + AlbumDetails *album; + MbReleaseIncludes includes; + char buffer[512]; + + release = mb_result_list_get_release (results, i); + mb_release_get_id (release, buffer, sizeof (buffer)); + includes = get_release_includes (); + release = mb_query_get_release_by_id (query, buffer, includes); + mb_release_includes_free (includes); + + album = make_album_from_release (release); + album->metadata_source = SOURCE_MUSICBRAINZ; + fill_empty_durations (priv->disc, album); + priv->albums = g_list_append (priv->albums, album); + mb_release_free (release); + } + mb_result_list_free (results); + mb_query_free (query); + + return priv->albums; +} + +/* + * GObject methods + */ + +static void +metadata_interface_init (gpointer g_iface, gpointer iface_data) +{ + SjMetadataClass *klass = (SjMetadataClass*)g_iface; + + klass->list_albums = mb_list_albums; +} + +static void +sj_metadata_musicbrainz3_init (SjMetadataMusicbrainz3 *self) +{ + GConfClient *gconf_client; + SjMetadataMusicbrainz3Private *priv; + + priv = GET_PRIVATE (self); + + priv->mb = mb_webservice_new(); + + gconf_client = gconf_client_get_default (); + + /* Set the HTTP proxy */ + if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_PROXY, NULL)) { + char *proxy_host; + int port; + + proxy_host = gconf_client_get_string (gconf_client, GCONF_PROXY_HOST, NULL); + mb_webservice_set_proxy_host (priv->mb, proxy_host); + g_free (proxy_host); + + port = gconf_client_get_int (gconf_client, GCONF_PROXY_PORT, NULL); + mb_webservice_set_proxy_port (priv->mb, port); + + if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_AUTHENTICATION, NULL)) { + char *username, *password; + + username = gconf_client_get_string (gconf_client, GCONF_PROXY_USERNAME, NULL); + mb_webservice_set_proxy_username (priv->mb, username); + g_free (username); + + password = gconf_client_get_string (gconf_client, GCONF_PROXY_PASSWORD, NULL); + mb_webservice_set_proxy_password (priv->mb, password); + g_free (password); + } + } + + g_object_unref (gconf_client); +} + +static void +sj_metadata_musicbrainz3_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + SjMetadataMusicbrainz3Private *priv = GET_PRIVATE (object); + g_assert (priv); + + switch (property_id) { + case PROP_DEVICE: + g_value_set_string (value, priv->cdrom); + break; + case PROP_PROXY_HOST: + g_value_set_string (value, priv->http_proxy); + break; + case PROP_PROXY_PORT: + g_value_set_int (value, priv->http_proxy_port); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sj_metadata_musicbrainz3_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + SjMetadataMusicbrainz3Private *priv = GET_PRIVATE (object); + g_assert (priv); + + switch (property_id) { + case PROP_DEVICE: + if (priv->cdrom) + g_free (priv->cdrom); + priv->cdrom = g_value_dup_string (value); + break; + case PROP_PROXY_HOST: + if (priv->http_proxy) { + g_free (priv->http_proxy); + } + priv->http_proxy = g_value_dup_string (value); + /* TODO: check this unsets the proxy if NULL, or should we pass "" ? */ + mb_webservice_set_proxy_host (priv->mb, priv->http_proxy); + break; + case PROP_PROXY_PORT: + priv->http_proxy_port = g_value_get_int (value); + mb_webservice_set_proxy_port (priv->mb, priv->http_proxy_port); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +sj_metadata_musicbrainz3_finalize (GObject *object) +{ + SjMetadataMusicbrainz3Private *priv; + + priv = GET_PRIVATE (object); + + if (priv->mb != NULL) { + mb_webservice_free (priv->mb); + priv->mb = NULL; + } + g_free (priv->cdrom); + + G_OBJECT_CLASS (sj_metadata_musicbrainz3_parent_class)->finalize (object); +} + +static void +sj_metadata_musicbrainz3_class_init (SjMetadataMusicbrainz3Class *class) +{ + GObjectClass *object_class = (GObjectClass*)class; + + g_type_class_add_private (class, sizeof (SjMetadataMusicbrainz3Private)); + + object_class->get_property = sj_metadata_musicbrainz3_get_property; + object_class->set_property = sj_metadata_musicbrainz3_set_property; + object_class->finalize = sj_metadata_musicbrainz3_finalize; + + g_object_class_override_property (object_class, PROP_DEVICE, "device"); + g_object_class_override_property (object_class, PROP_PROXY_HOST, "proxy-host"); + g_object_class_override_property (object_class, PROP_PROXY_PORT, "proxy-port"); +} + + +/* + * Public methods. + */ + +GObject * +sj_metadata_musicbrainz3_new (void) +{ + return g_object_new (SJ_TYPE_METADATA_MUSICBRAINZ3, NULL); +} diff --git a/libjuicer/sj-metadata-musicbrainz3.h b/libjuicer/sj-metadata-musicbrainz3.h new file mode 100644 index 0000000..1d4684b --- /dev/null +++ b/libjuicer/sj-metadata-musicbrainz3.h @@ -0,0 +1,55 @@ +/* + * sj-metadata-musicbrainz3.h + * Copyright (C) 2008 Ross Burton <ross@burtonini.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SJ_METADATA_MUSICBRAINZ3_H +#define SJ_METADATA_MUSICBRAINZ3_H + +#include <glib-object.h> +#include "sj-metadata.h" + +G_BEGIN_DECLS + +#define SJ_TYPE_METADATA_MUSICBRAINZ3 (sj_metadata_musicbrainz3_get_type ()) +#define SJ_METADATA_MUSICBRAINZ3(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SJ_TYPE_METADATA_MUSICBRAINZ3, SjMetadataMusicbrainz3)) +#define SJ_METADATA_MUSICBRAINZ3_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), SJ_TYPE_METADATA_MUSICBRAINZ3, SjMetadataMusicbrainz3Class)) +#define SJ_IS_METADATA_MUSICBRAINZ3(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SJ_TYPE_METADATA_MUSICBRAINZ3)) +#define SJ_IS_METADATA_MUSICBRAINZ3_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), SJ_TYPE_METADATA_MUSICBRAINZ3)) +#define SJ_METADATA_MUSICBRAINZ3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SJ_TYPE_METADATA_MUSICBRAINZ3, SjMetadataMusicbrainz3Class)) + +typedef struct _SjMetadataMusicbrainz3 SjMetadataMusicbrainz3; +typedef struct _SjMetadataMusicbrainz3Class SjMetadataMusicbrainz3Class; + +struct _SjMetadataMusicbrainz3 +{ + GObject parent; +}; + +struct _SjMetadataMusicbrainz3Class +{ + GObjectClass parent; +}; + +GType sj_metadata_musicbrainz3_get_type (void); + +GObject *sj_metadata_musicbrainz3_new (void); + +G_END_DECLS + +#endif /* SJ_METADATA_MUSICBRAINZ3_H */ diff --git a/libjuicer/sj-metadata.c b/libjuicer/sj-metadata.c index 4772e7d..6e96223 100644 --- a/libjuicer/sj-metadata.c +++ b/libjuicer/sj-metadata.c @@ -27,21 +27,11 @@ enum { LAST_SIGNAL }; -static int signals[LAST_SIGNAL] = { 0 }; - static void sj_metadata_base_init (gpointer g_iface) { static gboolean initialized = FALSE; if (!initialized) { - signals[METADATA] = g_signal_new ("metadata", - G_TYPE_FROM_CLASS (g_iface), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (SjMetadataClass, metadata), - NULL, NULL, - metadata_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - /* TODO: make these constructors */ /* TODO: add nice nick and blurb strings */ g_object_interface_install_property (g_iface, @@ -106,17 +96,9 @@ sj_metadata_set_proxy_port (SjMetadata *metadata, const int proxy_port) g_object_set (metadata, "proxy-port", proxy_port, NULL); } -void -sj_metadata_list_albums (SjMetadata *metadata, GError **error) +GList * +sj_metadata_list_albums (SjMetadata *metadata, char **url, GError **error) { - SJ_METADATA_GET_CLASS (metadata)->list_albums (metadata, error); + return SJ_METADATA_GET_CLASS (metadata)->list_albums (metadata, url, error); } -char * -sj_metadata_get_submit_url (SjMetadata *metadata) -{ - if (SJ_METADATA_GET_CLASS (metadata)->get_submit_url) - return SJ_METADATA_GET_CLASS (metadata)->get_submit_url (metadata); - else - return NULL; -} diff --git a/libjuicer/sj-metadata.h b/libjuicer/sj-metadata.h index 1e153bb..acb4330 100644 --- a/libjuicer/sj-metadata.h +++ b/libjuicer/sj-metadata.h @@ -40,20 +40,15 @@ struct _SjMetadataClass { GTypeInterface g_iface; - /* Signals */ - void (*metadata) (SjMetadata *md, GList *albums, GError *error); - /* Virtual Table */ - void (*list_albums) (SjMetadata *metadata, GError **error); - char *(*get_submit_url) (SjMetadata *metadata); + GList * (*list_albums) (SjMetadata *metadata, char **url, GError **error); }; GType sj_metadata_get_type (void); void sj_metadata_set_cdrom (SjMetadata *metadata, const char* device); void sj_metadata_set_proxy (SjMetadata *metadata, const char* proxy); void sj_metadata_set_proxy_port (SjMetadata *metadata, const int proxy_port); -void sj_metadata_list_albums (SjMetadata *metadata, GError **error); -char *sj_metadata_get_submit_url (SjMetadata *metadata); +GList * sj_metadata_list_albums (SjMetadata *metadata, char **url, GError **error); G_END_DECLS diff --git a/libjuicer/sj-structures.h b/libjuicer/sj-structures.h index 840aa92..284d524 100644 --- a/libjuicer/sj-structures.h +++ b/libjuicer/sj-structures.h @@ -35,7 +35,8 @@ enum _MetadataSource { SOURCE_UNKNOWN = 0, SOURCE_CDTEXT, SOURCE_FREEDB, - SOURCE_MUSICBRAINZ + SOURCE_MUSICBRAINZ, + SOURCE_FALLBACK }; struct _TrackDetails { diff --git a/po/ChangeLog b/po/ChangeLog index cd558c1..76a3ec6 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,3 +1,7 @@ +2008-09-03 Bastien Nocera <hadess@hadess.net> + + * POTFILES.in: upd + 2008-08-30 Claude Paroz <claude@2xlibre.net> * fr.po: Updated French translation. diff --git a/po/POTFILES.in b/po/POTFILES.in index af71800..beba2f4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -8,7 +8,9 @@ libjuicer/sj-error.c libjuicer/sj-extractor.c libjuicer/sj-metadata.c libjuicer/sj-metadata-cdtext.c +libjuicer/sj-metadata-getter.c libjuicer/sj-metadata-musicbrainz.c +libjuicer/sj-metadata-musicbrainz3.c libjuicer/sj-structures.c libjuicer/sj-util.c src/egg-play-preview.c diff --git a/src/sj-main.c b/src/sj-main.c index 898d6e7..d233358 100644 --- a/src/sj-main.c +++ b/src/sj-main.c @@ -43,8 +43,7 @@ #include "bacon-message-connection.h" #include "gconf-bridge.h" #include "sj-about.h" -#include "sj-metadata.h" -#include "sj-metadata-musicbrainz.h" +#include "sj-metadata-getter.h" #include "sj-extractor.h" #include "sj-structures.h" #include "sj-error.h" @@ -69,7 +68,7 @@ void on_disc_number_edit_changed(GtkEditable *widget, gpointer user_data); GladeXML *glade; -SjMetadata *metadata; +SjMetadataGetter *metadata; SjExtractor *extractor; GConfClient *gconf_client; @@ -797,7 +796,7 @@ static void audio_volume_changed_cb (GConfClient *client, guint cnxn_id, GConfEn } static void -metadata_cb (SjMetadata *m, GList *albums, GError *error) +metadata_cb (SjMetadataGetter *m, GList *albums, GError *error) { gboolean realized = GTK_WIDGET_REALIZED (main_window); @@ -825,6 +824,11 @@ metadata_cb (SjMetadata *m, GList *albums, GError *error) return; } + current_submit_url = sj_metadata_getter_get_submit_url (metadata); + if (current_submit_url) { + gtk_widget_set_sensitive (submit_menuitem, TRUE); + } + /* Free old album details */ if (current_album != NULL) { album_details_free (current_album); @@ -914,12 +918,7 @@ static void reread_cd (gboolean ignore_no_media) return; } - current_submit_url = sj_metadata_get_submit_url (metadata); - if (current_submit_url) { - gtk_widget_set_sensitive (submit_menuitem, TRUE); - } - - sj_metadata_list_albums (metadata, &error); + sj_metadata_getter_list_albums (metadata, &error); if (error && !(error->code == SJ_ERROR_CD_NO_MEDIA && ignore_no_media)) { GtkWidget *dialog; @@ -1046,7 +1045,7 @@ set_device (const char* device, gboolean ignore_no_media) set_drive_from_device (device); } - sj_metadata_set_cdrom (metadata, device); + sj_metadata_getter_set_cdrom (metadata, device); sj_extractor_set_device (extractor, device); if (drive != NULL) { @@ -1174,16 +1173,16 @@ static void http_proxy_setup (GConfClient *client) { if (!gconf_client_get_bool (client, GCONF_HTTP_PROXY_ENABLE, NULL)) { - sj_metadata_set_proxy (metadata, NULL); + sj_metadata_getter_set_proxy (metadata, NULL); } else { char *host; int port; host = gconf_client_get_string (client, GCONF_HTTP_PROXY, NULL); - sj_metadata_set_proxy (metadata, host); + sj_metadata_getter_set_proxy (metadata, host); g_free (host); port = gconf_client_get_int (client, GCONF_HTTP_PROXY_PORT, NULL); - sj_metadata_set_proxy_port (metadata, port); + sj_metadata_getter_set_proxy_port (metadata, port); } } @@ -1632,7 +1631,7 @@ int main (int argc, char **argv) bacon_message_connection_set_callback (connection, on_message_received, NULL); } - metadata = SJ_METADATA (sj_metadata_musicbrainz_new ()); + metadata = sj_metadata_getter_new (); g_signal_connect (metadata, "metadata", G_CALLBACK (metadata_cb), NULL); gconf_client = gconf_client_get_default (); diff --git a/tests/mb-test.c b/tests/mb-test.c index 0148b3d..f6bd2af 100644 --- a/tests/mb-test.c +++ b/tests/mb-test.c @@ -2,7 +2,7 @@ #include <stdlib.h> #include "sj-structures.h" #include "sj-metadata.h" -#include "sj-metadata-musicbrainz.h" +#include "sj-metadata-getter.h" static const char * source_to_str (MetadataSource source) @@ -11,24 +11,31 @@ source_to_str (MetadataSource source) "Unknown", "CD-Text", "FreeDB", - "MusicBrainz" + "MusicBrainz", + "Fallback" }; return strs[source]; } static void -metadata_cb (SjMetadata *metadata, GList *albums, GError *error) +metadata_cb (SjMetadataGetter *metadata, GList *albums, GError *error) { + char *url; + if (error != NULL) { g_print ("Error: %s\n", error->message); - g_error_free (error); g_object_unref (metadata); exit (1); } + url = sj_metadata_getter_get_submit_url (metadata); + g_print ("Submit URL: %s\n", url); + g_free (url); + while (albums) { AlbumDetails *album; album = (AlbumDetails*)albums->data; + char *disc_number; g_print ("Source: %s\n", source_to_str(album->metadata_source)); if (album->metadata_source == SOURCE_MUSICBRAINZ) g_print ("Album ID: %s\n", album->album_id); @@ -38,7 +45,9 @@ metadata_cb (SjMetadata *metadata, GList *albums, GError *error) g_print ("Discogs: %s\n", album->discogs); if (album->wikipedia != NULL) g_print ("Wikipedia: %s\n", album->wikipedia); - g_print ("'%s', by %s\n", album->title, album->artist); + disc_number = g_strdup_printf (" (Disc %d)", album->disc_number); + g_print ("'%s', by %s%s\n", album->title, album->artist, album->disc_number ? disc_number : ""); + g_free (disc_number); while (album->tracks) { TrackDetails *track = (TrackDetails*)album->tracks->data; g_print (" Track %d; Title: %s; Artist: %s Duration: %d sec\n", track->number, track->title, track->artist, track->duration); @@ -53,16 +62,17 @@ metadata_cb (SjMetadata *metadata, GList *albums, GError *error) int main (int argc, char** argv) { - SjMetadata *metadata; + SjMetadataGetter *metadata; GMainLoop *loop; + GError *error = NULL; g_type_init (); g_thread_init (NULL); - metadata = (SjMetadata*)sj_metadata_musicbrainz_new (); + metadata = sj_metadata_getter_new (); if (argc == 2) { - sj_metadata_set_cdrom (metadata, argv[1]); + sj_metadata_getter_set_cdrom (metadata, argv[1]); } else { g_print ("Usage: %s [CD device]\n", argv[0]); exit (1); @@ -70,7 +80,11 @@ int main (int argc, char** argv) g_signal_connect (G_OBJECT (metadata), "metadata", G_CALLBACK (metadata_cb), NULL); - sj_metadata_list_albums (metadata, NULL); + if (sj_metadata_getter_list_albums (metadata, &error) == FALSE) { + g_warning ("Couldn't list tracks on album: %s", error->message); + g_error_free (error); + return 1; + } loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); |