summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--configure.in24
-rw-r--r--libjuicer/Makefile.am22
-rw-r--r--libjuicer/sj-metadata-cdtext.c47
-rw-r--r--libjuicer/sj-metadata-getter.c251
-rw-r--r--libjuicer/sj-metadata-getter.h62
-rw-r--r--libjuicer/sj-metadata-musicbrainz.c111
-rw-r--r--libjuicer/sj-metadata-musicbrainz3.c451
-rw-r--r--libjuicer/sj-metadata-musicbrainz3.h55
-rw-r--r--libjuicer/sj-metadata.c24
-rw-r--r--libjuicer/sj-metadata.h9
-rw-r--r--libjuicer/sj-structures.h3
-rw-r--r--po/ChangeLog4
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/sj-main.c29
-rw-r--r--tests/mb-test.c32
16 files changed, 958 insertions, 198 deletions
diff --git a/ChangeLog b/ChangeLog
index 6027ebe..f9f6cb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);