rhythmbox r5879 - in trunk: . plugins/audiocd
- From: hadess svn gnome org
- To: svn-commits-list gnome org
- Subject: rhythmbox r5879 - in trunk: . plugins/audiocd
- Date: Fri, 5 Sep 2008 00:38:27 +0000 (UTC)
Author: hadess
Date: Fri Sep 5 00:38:27 2008
New Revision: 5879
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=5879&view=rev
Log:
2008-09-05 Bastien Nocera <hadess hadess net>
* configure.ac:
* plugins/audiocd/Makefile.am:
* plugins/audiocd/rb-audiocd-source.c (metadata_cb),
(metadata_cancelled_cb), (rb_audiocd_load_metadata),
(rb_audiocd_is_volume_audiocd):
* plugins/audiocd/sj-*.[ch]:
* plugins/audiocd/update-from-egg.sh: Update from sound-juicer
trunk, adds CD-Text support via gvfs trunk, and Musicbrainz3
(Closes: #550481)
Added:
trunk/plugins/audiocd/sj-metadata-getter.c
trunk/plugins/audiocd/sj-metadata-getter.h
trunk/plugins/audiocd/sj-metadata-musicbrainz3.c
trunk/plugins/audiocd/sj-metadata-musicbrainz3.h
trunk/plugins/audiocd/update-from-egg.sh (contents, props changed)
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/plugins/audiocd/Makefile.am
trunk/plugins/audiocd/rb-audiocd-source.c
trunk/plugins/audiocd/sj-error.c
trunk/plugins/audiocd/sj-error.h
trunk/plugins/audiocd/sj-metadata-musicbrainz.c
trunk/plugins/audiocd/sj-metadata-musicbrainz.h
trunk/plugins/audiocd/sj-metadata.c
trunk/plugins/audiocd/sj-metadata.h
trunk/plugins/audiocd/sj-structures.c
trunk/plugins/audiocd/sj-structures.h
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Fri Sep 5 00:38:27 2008
@@ -438,10 +438,16 @@
RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $MUSICBRAINZ_CFLAGS"
RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $MUSICBRAINZ_LIBS"
AC_DEFINE(HAVE_MUSICBRAINZ, 1, [define if you have Musicbrainz])
+
+ PKG_CHECK_MODULES(MUSICBRAINZ3, libmusicbrainz3, [have_mb3=yes], [have_mb3=no])
+ AC_SUBST(MUSICBRAINZ3_CFLAGS)
+ AC_SUBST(MUSICBRAINZ3_LIBS)
+ if test "$have_mb3" = "yes" ; then
+ AC_DEFINE([HAVE_MUSICBRAINZ3], 1, [Whether libmusicbrainz3 is available])
+ fi
fi
AM_CONDITIONAL(HAVE_MUSICBRAINZ, test "x$enable_musicbrainz" = "xyes")
-
-
+AM_CONDITIONAL([HAVE_MUSICBRAINZ3], [test "x$have_mb3" = "xyes"])
AC_PATH_XTRA
CFLAGS="$CFLAGS $X_CFLAGS"
Modified: trunk/plugins/audiocd/Makefile.am
==============================================================================
--- trunk/plugins/audiocd/Makefile.am (original)
+++ trunk/plugins/audiocd/Makefile.am Fri Sep 5 00:38:27 2008
@@ -6,17 +6,19 @@
rb-audiocd-source.c \
rb-audiocd-source.h
-libaudiocd_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS) $(LIBNAUTILUS_BURN_LIBS) $(MUSICBRAINZ_LIBS)
+libaudiocd_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
libaudiocd_la_LIBADD = \
$(top_builddir)/corelib/librhythmbox-core.la \
- $(HAL_LIBS) \
$(TOTEM_PLPARSER_LIBS) \
$(LIBNAUTILUS_BURN_LIBS)
if HAVE_MUSICBRAINZ
libaudiocd_la_LIBADD += $(MUSICBRAINZ_LIBS)
endif
+if HAVE_MUSICBRAINZ3
+libaudiocd_la_LIBADD +=$(MUSICBRAINZ3_LIBS)
+endif
libaudiocd_la_LIBADD += $(NULL)
@@ -41,9 +43,10 @@
-DSHARE_DIR=\"$(pkgdatadir)\" \
-DDATADIR=\""$(datadir)"\" \
$(TOTEM_PLPARSER_CFLAGS) \
- $(HAL_CFLAGS) \
$(RHYTHMBOX_CFLAGS) \
+ $(MUSICBRAINZ_CFLAGS) $(MUSICBRAINZ3_CFLAGS) \
$(LIBNAUTILUS_BURN_CFLAGS) \
+ -DUSE_TOTEM_PL_PARSER \
-D_XOPEN_SOURCE -D_BSD_SOURCE
gladedir = $(plugindir)
@@ -60,16 +63,36 @@
EXTRA_DIST = $(glade_DATA) $(uixml_DATA) $(plugin_in_files) sj-metadata-marshal.list
+SJ_FILES = \
+ sj-error.c sj-error.h \
+ sj-metadata.c sj-metadata.h \
+ sj-metadata-gvfs.c sj-metadata-gvfs.h \
+ sj-metadata-getter.c sj-metadata-getter.h \
+ sj-metadata-musicbrainz3.c sj-metadata-musicbrainz3.h \
+ sj-metadata-musicbrainz.c sj-metadata-musicbrainz.h \
+ sj-structures.c sj-structures.h \
+ sj-metadata-marshal.list
+
+EGGDIR=$(srcdir)/../../../sound-juicer/libjuicer
+regenerate-built-sources:
+ EGGFILES="$(SJ_FILES)" EGGDIR="$(EGGDIR)" $(srcdir)/update-from-egg.sh || true
+
MARSHALFILES =
if HAVE_MUSICBRAINZ
-libaudiocd_la_SOURCES += \
- sj-metadata.h sj-metadata.c \
- sj-metadata-musicbrainz.h sj-metadata-musicbrainz.c \
- sj-structures.h sj-structures.c \
- sj-error.h sj-error.c \
+libaudiocd_la_SOURCES += \
+ sj-metadata.h sj-metadata.c \
+ sj-metadata-getter.c sj-metadata-getter.h \
+ sj-metadata-musicbrainz.h sj-metadata-musicbrainz.c \
+ sj-metadata-gvfs.c sj-metadata-gvfs.h \
+ sj-structures.h sj-structures.c \
+ sj-error.h sj-error.c \
$(MARSHALFILES)
+if HAVE_MUSICBRAINZ3
+libaudiocd_la_SOURCES += sj-metadata-musicbrainz3.c sj-metadata-musicbrainz3.h
+endif
+
MARSHALFILES += sj-metadata-marshal.h sj-metadata-marshal.c
sj-metadata-marshal.h: sj-metadata-marshal.list
Modified: trunk/plugins/audiocd/rb-audiocd-source.c
==============================================================================
--- trunk/plugins/audiocd/rb-audiocd-source.c (original)
+++ trunk/plugins/audiocd/rb-audiocd-source.c Fri Sep 5 00:38:27 2008
@@ -39,24 +39,19 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gst/gst.h>
-/*#include <totem-disc.h>*/
#include "rb-plugin.h"
#include "rhythmdb.h"
#include "eel-gconf-extensions.h"
+#include "rb-shell.h"
#include "rb-audiocd-source.h"
#include "rb-util.h"
#include "rb-debug.h"
#include "rb-dialog.h"
#include "rb-glade-helpers.h"
-#ifdef HAVE_HAL
-#include <libhal.h>
-#include <dbus/dbus.h>
-#endif
-
#ifdef HAVE_MUSICBRAINZ
-#include "sj-metadata-musicbrainz.h"
+#include "sj-metadata-getter.h"
#include "sj-structures.h"
#endif
@@ -86,7 +81,7 @@
GstElement *fakesink;
#ifdef HAVE_MUSICBRAINZ
- SjMetadata *metadata;
+ SjMetadataGetter *metadata;
#endif
} RBAudioCdSourcePrivate;
@@ -506,7 +501,7 @@
static void
-metadata_cb (SjMetadata *metadata,
+metadata_cb (SjMetadataGetter *metadata,
GList *albums,
GError *error,
RBAudioCdSource *source)
@@ -549,6 +544,13 @@
} else
album = (AlbumDetails *)albums->data;
+ if (album->metadata_source == SOURCE_FALLBACK) {
+ g_object_unref (metadata);
+ priv->metadata = NULL;
+ g_object_unref (db);
+ return;
+ }
+
g_object_set (G_OBJECT (source), "name", album->title, NULL);
while (album->tracks && cd_track) {
@@ -616,7 +618,7 @@
}
static void
-metadata_cancelled_cb (SjMetadata *metadata,
+metadata_cancelled_cb (SjMetadataGetter *metadata,
GList *albums,
GError *error,
gpointer old_source)
@@ -633,12 +635,12 @@
#ifdef HAVE_MUSICBRAINZ
RBAudioCdSourcePrivate *priv = AUDIOCD_SOURCE_GET_PRIVATE (source);
- priv->metadata = (SjMetadata*)sj_metadata_musicbrainz_new ();
- sj_metadata_set_cdrom (priv->metadata, priv->device_path);
+ priv->metadata = sj_metadata_getter_new ();
+ sj_metadata_getter_set_cdrom (priv->metadata, priv->device_path);
g_signal_connect (G_OBJECT (priv->metadata), "metadata",
G_CALLBACK (metadata_cb), source);
- sj_metadata_list_albums (priv->metadata, NULL);
+ sj_metadata_getter_list_albums (priv->metadata, NULL);
#endif
}
@@ -720,178 +722,27 @@
g_object_unref (db);
}
-#if 0
-gboolean
-rb_audiocd_is_volume_audiocd (GVolume *volume)
-{
- char *device_path;
-
- device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
- if (device_path != NULL) {
- gboolean result;
- TotemDiscMediaType media_type;
- GError *error = NULL;
-
- /* should we do any kind of checking before we make this call? */
- media_type = totem_cd_detect_type (device_path, &error);
- if (error != NULL) {
- rb_debug ("error detecting if volume is an audio CD: %s", error->message);
- g_error_free (error);
- result = FALSE;
- } else if (media_type == MEDIA_TYPE_CDDA) {
- rb_debug ("totem-disc says this is an audio CD");
- result = TRUE;
- } else {
- rb_debug ("totem-disc says this is not an audio CD");
- result = FALSE;
- }
-
- g_free (device_path);
- return result;
- } else {
- rb_debug ("couldn't get device path");
- return FALSE;
- }
-}
-#endif
-
-
-#ifdef HAVE_HAL
-
-/* copied this stuff from the generic player plugin,
- * so it should probably go somewhere common.
- */
-
-static void
-free_dbus_error (const char *what, DBusError *error)
-{
- if (dbus_error_is_set (error)) {
- rb_debug ("%s: dbus error: %s", what, error->message);
- dbus_error_free (error);
- }
-}
-
-static LibHalContext *
-get_hal_context (void)
-{
- LibHalContext *ctx = NULL;
- DBusConnection *conn = NULL;
- DBusError error;
- gboolean result = FALSE;
-
- dbus_error_init (&error);
- ctx = libhal_ctx_new ();
- if (ctx == NULL)
- return NULL;
-
- conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
- if (conn != NULL && !dbus_error_is_set (&error)) {
- libhal_ctx_set_dbus_connection (ctx, conn);
- if (libhal_ctx_init (ctx, &error))
- result = TRUE;
- }
-
- if (dbus_error_is_set (&error)) {
- free_dbus_error ("setting up hal context", &error);
- result = FALSE;
- }
-
- if (!result) {
- libhal_ctx_free (ctx);
- ctx = NULL;
- }
- return ctx;
-}
-
-static void
-cleanup_hal_context (LibHalContext *ctx)
-{
- DBusError error;
- if (ctx == NULL)
- return;
-
- dbus_error_init (&error);
- libhal_ctx_shutdown (ctx, &error);
- libhal_ctx_free (ctx);
- free_dbus_error ("cleaning up hal context", &error);
-}
-
-#endif
-
gboolean
rb_audiocd_is_volume_audiocd (GVolume *volume)
{
GMount *mount;
-#ifdef HAVE_HAL
- LibHalContext *ctx;
- char *udi;
- char *device_path;
-
- /* get device path for debug purposes */
- device_path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
- if (device_path == NULL) {
- device_path = g_strdup ("unknown device");
- }
-
- /* look at HAL properties to see if it's an audio CD */
- udi = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_HAL_UDI);
- if (udi != NULL) {
- ctx = get_hal_context ();
- if (ctx != NULL) {
- gboolean result = FALSE;
- DBusError error;
- dbus_error_init (&error);
-
- /* check if it's a disc at all */
- if (libhal_device_query_capability (ctx, udi, "volume.disc", &error) &&
- !dbus_error_is_set (&error)) {
- /* check it's a CD with audio; maybe check it's not blank? */
- dbus_bool_t is_audio;
-
- is_audio = libhal_device_get_property_bool (ctx, udi, "volume.disc.has_audio", &error);
- if (dbus_error_is_set (&error)) {
- free_dbus_error ("checking if disc has audio", &error);
- is_audio = FALSE;
- }
-
- if (is_audio) {
- rb_debug ("disc in %s is an audio CD", device_path);
- result = TRUE;
- } else {
- rb_debug ("disc %s is not an audio CD", device_path);
- }
-
- } else if (dbus_error_is_set (&error)) {
- free_dbus_error ("checking volume type", &error);
- } else {
- rb_debug ("volume in %s is not a disc", device_path);
- }
-
- cleanup_hal_context (ctx);
- return result;
- }
- }
- g_free (device_path);
- rb_debug ("HAL couldn't tell us if this is an audio CD or not");
-#endif
/* if it's mounted, we can check the mount root URI scheme */
mount = g_volume_get_mount (volume);
if (mount != NULL) {
- GFile *mount_root;
- char *uri_scheme;
gboolean result = FALSE;
+ char **types;
+ guint i;
- mount_root = g_mount_get_root (mount);
- if (mount_root != NULL) {
- uri_scheme = g_file_get_uri_scheme (mount_root);
- rb_debug ("URI scheme of mounted volume is %s", uri_scheme);
- result = (strcmp (uri_scheme, "cdda") == 0);
-
- g_free (uri_scheme);
- g_object_unref (mount_root);
+ types = g_mount_guess_content_type_sync (mount, FALSE, NULL, NULL);
+ for (i = 0; types[i] != NULL; i++) {
+ if (g_str_equal (types[i], "x-content/audio-cdda") != FALSE) {
+ result = TRUE;
+ break;
+ }
}
+ g_strfreev (types);
g_object_unref (mount);
return result;
}
Modified: trunk/plugins/audiocd/sj-error.c
==============================================================================
--- trunk/plugins/audiocd/sj-error.c (original)
+++ trunk/plugins/audiocd/sj-error.c Fri Sep 5 00:38:27 2008
@@ -3,28 +3,21 @@
*
* Sound Juicer - sj-error.c
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 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.
+
* Authors: Ross Burton <ross burtonini com>
*/
Modified: trunk/plugins/audiocd/sj-error.h
==============================================================================
--- trunk/plugins/audiocd/sj-error.h (original)
+++ trunk/plugins/audiocd/sj-error.h Fri Sep 5 00:38:27 2008
@@ -3,27 +3,20 @@
*
* Sound Juicer - sj-error.h
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 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.
*
* Authors: Ross Burton <ross burtonini com>
*/
Added: trunk/plugins/audiocd/sj-metadata-getter.c
==============================================================================
--- (empty file)
+++ trunk/plugins/audiocd/sj-metadata-getter.c Fri Sep 5 00:38:27 2008
@@ -0,0 +1,263 @@
+/*
+ * 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_MUSICBRAINZ3
+#include "sj-metadata-musicbrainz3.h"
+#endif /* HAVE_MUSICBRAINZ3 */
+#include "sj-metadata-musicbrainz.h"
+#ifdef HAVE_LIBCDIO
+#include "sj-metadata-cdtext.h"
+#endif /* HAVE_LIBCDIO */
+#include "sj-metadata-gvfs.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);
+
+ g_free (priv->cdrom);
+
+#if defined (sun) && defined (__SVR4)
+ if (g_str_has_prefix (device, "/dev/dsk/")) {
+ priv->cdrom = g_strdup_printf ("/dev/rdsk/%s", device + strlen ("/dev/dsk/"));
+ return;
+ }
+#endif
+ 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_MUSICBRAINZ3
+ SJ_TYPE_METADATA_MUSICBRAINZ3,
+#endif /* HAVE_MUSICBRAINZ3 */
+ SJ_TYPE_METADATA_MUSICBRAINZ,
+#ifdef HAVE_LIBCDIO
+ SJ_TYPE_METADATA_CDTEXT,
+#endif /* HAVE_LIBCDIO */
+ SJ_TYPE_METADATA_GVFS
+ };
+
+ 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;
+}
+
Added: trunk/plugins/audiocd/sj-metadata-getter.h
==============================================================================
--- (empty file)
+++ trunk/plugins/audiocd/sj-metadata-getter.h Fri Sep 5 00:38:27 2008
@@ -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 */
Modified: trunk/plugins/audiocd/sj-metadata-musicbrainz.c
==============================================================================
--- trunk/plugins/audiocd/sj-metadata-musicbrainz.c (original)
+++ trunk/plugins/audiocd/sj-metadata-musicbrainz.c Fri Sep 5 00:38:27 2008
@@ -7,14 +7,6 @@
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your 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
@@ -31,7 +23,6 @@
#endif /* HAVE_CONFIG_H */
#include <string.h>
-#include <stdio.h>
#include <glib-object.h>
#include <glib/gi18n.h>
#include <glib/gerror.h>
@@ -42,32 +33,11 @@
#include <musicbrainz/queries.h>
#include <musicbrainz/mb_c.h>
#include <stdlib.h>
-#include <unistd.h>
-
-#include <totem-disc.h>
#include "sj-metadata-musicbrainz.h"
#include "sj-structures.h"
#include "sj-error.h"
-struct SjMetadataMusicbrainzPrivate {
- GError *construct_error;
- musicbrainz_t mb;
- char *http_proxy;
- int http_proxy_port;
- char *cdrom;
- /* TODO: remove and use an async queue or something l33t */
- GList *albums;
- GError *error;
-};
-
-static GError* mb_get_new_error (SjMetadata *metadata);
-static void mb_set_cdrom (SjMetadata *metadata, const char* device);
-static void mb_set_proxy (SjMetadata *metadata, const char* proxy);
-static void mb_set_proxy_port (SjMetadata *metadata, const int port);
-static void mb_list_albums (SjMetadata *metadata, GError **error);
-static char *mb_get_submit_url (SjMetadata *metadata);
-
#define GCONF_MUSICBRAINZ_SERVER "/apps/sound-juicer/musicbrainz_server"
#define GCONF_PROXY_USE_PROXY "/system/http_proxy/use_http_proxy"
#define GCONF_PROXY_HOST "/system/http_proxy/host"
@@ -76,256 +46,52 @@
#define GCONF_PROXY_USERNAME "/system/http_proxy/authentication_user"
#define GCONF_PROXY_PASSWORD "/system/http_proxy/authentication_password"
-/**
- * GObject methods
- */
-
-static GObjectClass *parent_class = NULL;
-
-static void
-sj_metadata_musicbrainz_finalize (GObject *object)
-{
- SjMetadataMusicbrainzPrivate *priv;
- g_return_if_fail (object != NULL);
- priv = SJ_METADATA_MUSICBRAINZ (object)->priv;
-
- g_free (priv->http_proxy);
- g_free (priv->cdrom);
- mb_Delete (priv->mb);
- g_free (priv);
-
- parent_class->finalize (object);
-}
-
-static void
-sj_metadata_musicbrainz_instance_init (GTypeInstance *instance, gpointer g_class)
-{
- GConfClient *gconf_client;
- char *server_name = NULL;
- SjMetadataMusicbrainz *self = (SjMetadataMusicbrainz*)instance;
- self->priv = g_new0 (SjMetadataMusicbrainzPrivate, 1);
- self->priv->construct_error = NULL;
- self->priv->mb = mb_New ();
- /* TODO: something. :/ */
- if (!self->priv->mb) {
- g_set_error (&self->priv->construct_error,
- SJ_ERROR, SJ_ERROR_CD_LOOKUP_ERROR,
- _("Cannot create MusicBrainz client"));
- return;
- }
- mb_UseUTF8 (self->priv->mb, TRUE);
-
- gconf_client = gconf_client_get_default ();
- server_name = gconf_client_get_string (gconf_client, GCONF_MUSICBRAINZ_SERVER, NULL);
- if (server_name) {
- g_strstrip (server_name);
- }
- if (server_name && strcmp (server_name, "") != 0) {
- mb_SetServer (self->priv->mb, server_name, 80);
- g_free (server_name);
- }
-
- /* Set the HTTP proxy */
- if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_PROXY, NULL)) {
- char *proxy_host = gconf_client_get_string (gconf_client, GCONF_PROXY_HOST, NULL);
- mb_SetProxy (self->priv->mb, proxy_host,
- gconf_client_get_int (gconf_client, GCONF_PROXY_PORT, NULL));
- g_free (proxy_host);
- if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_AUTHENTICATION, NULL)) {
-#if HAVE_MB_SETPROXYCREDS
- char *username = gconf_client_get_string (gconf_client, GCONF_PROXY_USERNAME, NULL);
- char *password = gconf_client_get_string (gconf_client, GCONF_PROXY_PASSWORD, NULL);
- mb_SetProxyCreds (self->priv->mb, username, password);
- g_free (username);
- g_free (password);
-#else
- g_warning ("mb_SetProxyCreds() not found, no proxy authorisation possible.");
-#endif
- }
- }
- g_object_unref (gconf_client);
+struct SjMetadataMusicbrainzPrivate {
+ musicbrainz_t mb;
+ char *http_proxy;
+ int http_proxy_port;
+ char *cdrom;
+ GList *albums;
+};
- if (g_getenv("MUSICBRAINZ_DEBUG")) {
- mb_SetDebug (self->priv->mb, TRUE);
- }
-}
+#define GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SJ_TYPE_METADATA_MUSICBRAINZ, SjMetadataMusicbrainzPrivate))
-static void
-metadata_interface_init (gpointer g_iface, gpointer iface_data)
-{
- SjMetadataClass *klass = (SjMetadataClass*)g_iface;
- klass->get_new_error = mb_get_new_error;
- klass->set_cdrom = mb_set_cdrom;
- klass->set_proxy = mb_set_proxy;
- klass->set_proxy_port = mb_set_proxy_port;
- klass->list_albums = mb_list_albums;
- klass->get_submit_url = mb_get_submit_url;
-}
+enum {
+ PROP_0,
+ PROP_DEVICE,
+ PROP_USE_PROXY,
+ PROP_PROXY_HOST,
+ PROP_PROXY_PORT,
+};
-static void
-sj_metadata_musicbrainz_class_init (SjMetadataMusicbrainzClass *class)
-{
- GObjectClass *object_class;
- parent_class = g_type_class_peek_parent (class);
- object_class = (GObjectClass*) class;
- object_class->finalize = sj_metadata_musicbrainz_finalize;
-}
+static void metadata_interface_init (gpointer g_iface, gpointer iface_data);
-GType
-sj_metadata_musicbrainz_get_type (void)
-{
- static GType type = 0;
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof (SjMetadataMusicbrainzClass),
- NULL,
- NULL,
- (GClassInitFunc)sj_metadata_musicbrainz_class_init,
- NULL,
- NULL,
- sizeof (SjMetadataMusicbrainz),
- 0,
- sj_metadata_musicbrainz_instance_init,
- NULL
- };
- static const GInterfaceInfo metadata_i_info = {
- (GInterfaceInitFunc) metadata_interface_init,
- NULL, NULL
- };
- type = g_type_register_static (G_TYPE_OBJECT, "SjMetadataMusicBrainzClass", &info, 0);
- g_type_add_interface_static (type, SJ_TYPE_METADATA, &metadata_i_info);
- }
- return type;
-}
+G_DEFINE_TYPE_WITH_CODE (SjMetadataMusicbrainz,
+ sj_metadata_musicbrainz,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (SJ_TYPE_METADATA,
+ metadata_interface_init));
-GObject *
-sj_metadata_musicbrainz_new (void)
-{
- return g_object_new (sj_metadata_musicbrainz_get_type (), NULL);
-}
-/**
+/*
* Private methods
*/
-#define BYTES_PER_SECTOR 2352
-#define BYTES_PER_SECOND (44100 / 8) / 16 / 2
-
static int
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;
- }
+#define BYTES_PER_SECTOR 2352
+#define BYTES_PER_SECOND (44100 / 8) / 16 / 2
- 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;
+ return (sectors * BYTES_PER_SECTOR / BYTES_PER_SECOND);
}
/**
* Virtual methods
*/
-static GError*
-mb_get_new_error (SjMetadata *metadata)
-{
- GError *error = NULL;
- if (metadata == NULL || SJ_METADATA_MUSICBRAINZ (metadata)->priv == NULL) {
- g_set_error (&error,
- SJ_ERROR, SJ_ERROR_INTERNAL_ERROR,
- _("MusicBrainz metadata object is not valid. This is bad, check your console for errors."));
- return error;
- }
- return SJ_METADATA_MUSICBRAINZ (metadata)->priv->construct_error;
-}
-
-static void
-mb_set_cdrom (SjMetadata *metadata, const char* device)
-{
- SjMetadataMusicbrainzPrivate *priv;
- g_return_if_fail (metadata != NULL);
- g_return_if_fail (device != NULL);
- priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv;
-
- if (priv->cdrom) {
- g_free (priv->cdrom);
- }
- priv->cdrom = g_strdup (device);
- mb_SetDevice (priv->mb, priv->cdrom);
-}
-
-static void
-mb_set_proxy (SjMetadata *metadata, const char* proxy)
-{
- SjMetadataMusicbrainzPrivate *priv;
- g_return_if_fail (metadata != NULL);
- priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv;
-
- if (proxy == NULL) {
- proxy = "";
- }
- if (priv->http_proxy) {
- g_free (priv->http_proxy);
- }
- priv->http_proxy = g_strdup (proxy);
- mb_SetProxy (priv->mb, priv->http_proxy, priv->http_proxy_port);
-}
-
-static void
-mb_set_proxy_port (SjMetadata *metadata, const int port)
-{
- SjMetadataMusicbrainzPrivate *priv;
- g_return_if_fail (metadata != NULL);
- priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv;
-
- priv->http_proxy_port = port;
- mb_SetProxy (priv->mb, priv->http_proxy, priv->http_proxy_port);
-}
-
/* Data imported from FreeDB is horrendeous for compilations,
* Try to split the 'Various' artist */
static void
@@ -333,7 +99,7 @@
{
char *slash, **split;
- if (g_ascii_strncasecmp (MBI_VARIOUS_ARTIST_ID, track->album->artist_id, 64) != 0 && track->album->artist_id[0] != '\0' && track->artist_id[0] != '\0') {
+ if (g_ascii_strncasecmp (track->album->album_id, "freedb:", 7) != 0 && track->album->artist_id[0] != '\0' && track->artist_id[0] != '\0') {
track->title = g_strdup (data);
return;
}
@@ -382,7 +148,7 @@
g_free (rdf);
}
-/*
+/**
* Load into the MusicBrainz object the RDF from the specified cache file if it
* exists and is valid then return TRUE, otherwise return FALSE.
*/
@@ -425,7 +191,7 @@
}
#endif
-/*
+/**
* Fill the MusicBrainz object with RDF. Basically get the CD Index and check
* the local cache, if that fails then lookup the data online.
*/
@@ -476,8 +242,36 @@
g_free (cdindex);
}
-static gpointer
-lookup_cd (SjMetadata *metadata)
+/*
+ * Magic character set encoding to try and repair brain-dead FreeDB encoding,
+ * converting it to the current locale's encoding (which is likely to be the
+ * intended encoding).
+ */
+static void
+convert_encoding(char **str)
+{
+ char *iso8859;
+ char *converted;
+
+ if (str == NULL || *str == NULL)
+ return;
+
+ iso8859 = g_convert (*str, -1, "ISO-8859-1", "UTF-8", NULL, NULL, NULL);
+
+ if (iso8859) {
+ converted = g_locale_to_utf8 (iso8859, -1, NULL, NULL, NULL);
+
+ if (converted) {
+ g_free (*str);
+ *str = converted;
+ }
+ }
+
+ g_free (iso8859);
+}
+
+static GList *
+mb_list_albums (SjMetadata *metadata, char **url, GError **error)
{
/** The size of the buffer used in MusicBrainz lookups */
SjMetadataMusicbrainzPrivate *priv;
@@ -485,43 +279,41 @@
GList *al, *tl;
char data[256];
int num_albums, i, j;
- TotemDiscMediaType type;
- GError *totem_error = NULL;
- /* 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 */
- type = totem_cd_detect_type (priv->cdrom, &totem_error);
-
- if (totem_error != NULL) {
- priv->error = g_error_new (SJ_ERROR, SJ_ERROR_CD_NO_MEDIA, _("Cannot read CD: %s"), totem_error->message);
- g_error_free (totem_error);
+ if (sj_metadata_helper_check_media (priv->cdrom, error) == FALSE) {
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++) {
int num_tracks;
AlbumDetails *album;
+ gboolean from_freedb = FALSE;
mb_Select1(priv->mb, MBS_SelectAlbum, i);
album = g_new0 (AlbumDetails, 1);
if (mb_GetResultData(priv->mb, MBE_AlbumGetAlbumId, data, sizeof (data))) {
+ from_freedb = strstr(data, "freedb:") == data;
+
mb_GetIDFromURL (priv->mb, data, data, sizeof (data));
album->album_id = g_strdup (data);
}
@@ -529,37 +321,43 @@
if (mb_GetResultData (priv->mb, MBE_AlbumGetAlbumArtistId, data, sizeof (data))) {
mb_GetIDFromURL (priv->mb, data, data, sizeof (data));
album->artist_id = g_strdup (data);
- if (g_ascii_strncasecmp (MBI_VARIOUS_ARTIST_ID, data, 64) == 0) {
- album->artist = g_strdup (_("Various"));
+
+ if (mb_GetResultData (priv->mb, MBE_AlbumGetAlbumArtistName, data, sizeof (data))) {
+ album->artist = g_strdup (data);
} else {
- if (*data && mb_GetResultData1(priv->mb, MBE_AlbumGetArtistName, data, sizeof (data), 1)) {
- album->artist = g_strdup (data);
+ if (g_ascii_strcasecmp (MBI_VARIOUS_ARTIST_ID, album->artist_id) == 0) {
+ album->artist = g_strdup (_("Various"));
} else {
album->artist = g_strdup (_("Unknown Artist"));
}
- if (*data && mb_GetResultData1(priv->mb, MBE_AlbumGetArtistSortName, data, sizeof (data), 1)) {
- album->artist_sortname = g_strdup (data);
- }
+ }
+ if (mb_GetResultData(priv->mb, MBE_AlbumGetAlbumArtistSortName, data, sizeof (data))) {
+ album->artist_sortname = g_strdup (data);
}
}
if (mb_GetResultData(priv->mb, MBE_AlbumGetAlbumName, data, sizeof (data))) {
- album->title = g_strdup (data);
+ char *new_title;
+ new_title = sj_metadata_helper_scan_disc_number (data, &album->disc_number);
+ if (new_title)
+ album->title = new_title;
+ else
+ album->title = g_strdup (data);
} else {
album->title = g_strdup (_("Unknown Title"));
}
+ if (mb_GetResultData(priv->mb, MBE_AlbumGetAmazonAsin, data, sizeof (data))) {
+ album->asin = g_strdup (data);
+ }
+
{
int num_releases;
num_releases = mb_GetResultInt (priv->mb, MBE_AlbumGetNumReleaseDates);
if (num_releases > 0) {
mb_Select1(priv->mb, MBS_SelectReleaseDate, 1);
if (mb_GetResultData(priv->mb, MBE_ReleaseGetDate, data, sizeof (data))) {
- int matched, year=1, month=1, day=1;
- matched = sscanf(data, "%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);
- }
+ album->release_date = sj_metadata_helper_scan_date (data);
}
mb_Select(priv->mb, MBS_Back);
}
@@ -572,9 +370,8 @@
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++) {
@@ -601,6 +398,8 @@
} else {
track->title = g_strdup (data);
}
+ } else {
+ track->title = g_strdup (_("[Untitled]"));
}
if (track->artist == NULL && mb_GetResultData1(priv->mb, MBE_AlbumGetArtistName, data, sizeof (data), j)) {
@@ -614,11 +413,29 @@
if (mb_GetResultData1(priv->mb, MBE_AlbumGetTrackDuration, data, sizeof (data), j)) {
track->duration = atoi (data) / 1000;
}
+
+ if (from_freedb) {
+ convert_encoding(&track->title);
+ convert_encoding(&track->artist);
+ convert_encoding(&track->artist_sortname);
+ }
album->tracks = g_list_append (album->tracks, track);
album->number++;
}
+ if (from_freedb) {
+ convert_encoding(&album->title);
+ convert_encoding(&album->artist);
+ convert_encoding(&album->artist_sortname);
+ }
+
+ if (from_freedb) {
+ album->metadata_source = SOURCE_FREEDB;
+ } else {
+ album->metadata_source = SOURCE_MUSICBRAINZ;
+ }
+
albums = g_list_append (albums, album);
mb_Select (priv->mb, MBS_Rewind);
@@ -646,40 +463,157 @@
}
}
- priv->albums = albums;
- g_idle_add ((GSourceFunc)fire_signal_idle, metadata);
return 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
-mb_list_albums (SjMetadata *metadata, GError **error)
+sj_metadata_musicbrainz_init (SjMetadataMusicbrainz *self)
{
- GThread *thread;
+ GConfClient *gconf_client;
+ char *server_name = NULL;
- g_return_if_fail (SJ_IS_METADATA_MUSICBRAINZ (metadata));
+ self->priv = GET_PRIVATE (self);
+ self->priv->mb = mb_New ();
+ mb_UseUTF8 (self->priv->mb, TRUE);
- 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;
+ gconf_client = gconf_client_get_default ();
+ server_name = gconf_client_get_string (gconf_client, GCONF_MUSICBRAINZ_SERVER, NULL);
+ if (server_name) {
+ g_strstrip (server_name);
+ }
+ if (server_name && strcmp (server_name, "") != 0) {
+ mb_SetServer (self->priv->mb, server_name, 80);
+ g_free (server_name);
+ }
+
+ /* Set the HTTP proxy */
+ if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_PROXY, NULL)) {
+ char *proxy_host = gconf_client_get_string (gconf_client, GCONF_PROXY_HOST, NULL);
+ mb_SetProxy (self->priv->mb, proxy_host,
+ gconf_client_get_int (gconf_client, GCONF_PROXY_PORT, NULL));
+ g_free (proxy_host);
+ if (gconf_client_get_bool (gconf_client, GCONF_PROXY_USE_AUTHENTICATION, NULL)) {
+#if HAVE_MB_SETPROXYCREDS
+ char *username = gconf_client_get_string (gconf_client, GCONF_PROXY_USERNAME, NULL);
+ char *password = gconf_client_get_string (gconf_client, GCONF_PROXY_PASSWORD, NULL);
+ mb_SetProxyCreds (self->priv->mb, username, password);
+ g_free (username);
+ g_free (password);
+#else
+ g_warning ("mb_SetProxyCreds() not found, no proxy authorisation possible.");
+#endif
+ }
+ }
+
+ g_object_unref (gconf_client);
+
+ if (g_getenv("MUSICBRAINZ_DEBUG")) {
+ mb_SetDebug (self->priv->mb, TRUE);
}
}
-static char *
-mb_get_submit_url (SjMetadata *metadata)
+static void
+sj_metadata_musicbrainz_get_property (GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ SjMetadataMusicbrainzPrivate *priv = SJ_METADATA_MUSICBRAINZ (object)->priv;
+ 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_musicbrainz_set_property (GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ SjMetadataMusicbrainzPrivate *priv = SJ_METADATA_MUSICBRAINZ (object)->priv;
+ g_assert (priv);
+
+ switch (property_id) {
+ case PROP_DEVICE:
+ if (priv->cdrom)
+ g_free (priv->cdrom);
+ priv->cdrom = g_value_dup_string (value);
+ if (priv->cdrom)
+ mb_SetDevice (priv->mb, priv->cdrom);
+ 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_SetProxy (priv->mb, priv->http_proxy, priv->http_proxy_port);
+ break;
+ case PROP_PROXY_PORT:
+ priv->http_proxy_port = g_value_get_int (value);
+ mb_SetProxy (priv->mb, priv->http_proxy, priv->http_proxy_port);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+sj_metadata_musicbrainz_finalize (GObject *object)
{
SjMetadataMusicbrainzPrivate *priv;
- char url[1025];
+
+ priv = SJ_METADATA_MUSICBRAINZ (object)->priv;
- g_return_val_if_fail (metadata != NULL, NULL);
+ g_free (priv->http_proxy);
+ g_free (priv->cdrom);
+ mb_Delete (priv->mb);
- priv = SJ_METADATA_MUSICBRAINZ (metadata)->priv;
+ G_OBJECT_CLASS (sj_metadata_musicbrainz_parent_class)->finalize (object);
+}
- if (mb_GetWebSubmitURL(priv->mb, url, 1024)) {
- return g_strdup(url);
- } else {
- return NULL;
- }
+static void
+sj_metadata_musicbrainz_class_init (SjMetadataMusicbrainzClass *class)
+{
+ GObjectClass *object_class = (GObjectClass*)class;
+
+ g_type_class_add_private (class, sizeof (SjMetadataMusicbrainzPrivate));
+
+ object_class->get_property = sj_metadata_musicbrainz_get_property;
+ object_class->set_property = sj_metadata_musicbrainz_set_property;
+ object_class->finalize = sj_metadata_musicbrainz_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_musicbrainz_new (void)
+{
+ return g_object_new (SJ_TYPE_METADATA_MUSICBRAINZ, NULL);
}
Modified: trunk/plugins/audiocd/sj-metadata-musicbrainz.h
==============================================================================
--- trunk/plugins/audiocd/sj-metadata-musicbrainz.h (original)
+++ trunk/plugins/audiocd/sj-metadata-musicbrainz.h Fri Sep 5 00:38:27 2008
@@ -7,14 +7,6 @@
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your 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
@@ -34,7 +26,7 @@
G_BEGIN_DECLS
-#define SJ_TYPE_METADATA_MUSICBRAINZ (sj_metadata_get_type ())
+#define SJ_TYPE_METADATA_MUSICBRAINZ (sj_metadata_musicbrainz_get_type ())
#define SJ_METADATA_MUSICBRAINZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SJ_TYPE_METADATA_MUSICBRAINZ, SjMetadataMusicbrainz))
#define SJ_METADATA_MUSICBRAINZ_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), SJ_TYPE_METADATA_MUSICBRAINZ, SjMetadataMusicbrainzClass))
#define SJ_IS_METADATA_MUSICBRAINZ(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SJ_TYPE_METADATA_MUSICBRAINZ))
Added: trunk/plugins/audiocd/sj-metadata-musicbrainz3.c
==============================================================================
--- (empty file)
+++ trunk/plugins/audiocd/sj-metadata-musicbrainz3.c Fri Sep 5 00:38:27 2008
@@ -0,0 +1,425 @@
+/*
+ * sj-metadata-musicbrainz3.c
+ * Copyright (C) 2008 Ross Burton <ross burtonini com>
+ * Copyright (C) 2008 Bastien Nocera <hadess hadess net>
+ *
+ * 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 <glib.h>
+#include <glib-object.h>
+#include <gconf/gconf-client.h>
+#include <musicbrainz3/mb_c.h>
+
+#include "sj-metadata-musicbrainz3.h"
+#include "sj-structures.h"
+#include "sj-error.h"
+
+#define GET(field, function, obj) { \
+ function (obj, buffer, sizeof (buffer)); \
+ if (field) \
+ g_free (field); \
+ if (*buffer == '\0') \
+ field = NULL; \
+ else \
+ 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;
+ char *new_title;
+ 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);
+ new_title = sj_metadata_helper_scan_disc_number (album->title, &album->disc_number);
+ if (new_title) {
+ g_free (album->title);
+ album->title = new_title;
+ }
+
+ 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;
+
+ event = mb_release_get_release_event (release, 0);
+ GET (date, mb_release_event_get_date, event);
+ album->release_date = sj_metadata_helper_scan_date (date);
+ 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 < mb_release_get_num_types (release); i++) {
+ mb_release_get_type (release, i, buffer, sizeof(buffer));
+
+ if (g_str_has_suffix (buffer, "#Spokenword")
+ || g_str_has_suffix (buffer, "#Interview")
+ || g_str_has_suffix (buffer, "#Audiobook")) {
+ album->is_spoken_word = TRUE;
+ break;
+ }
+ }
+
+ 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;
+ g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ3 (metadata), FALSE);
+
+ priv = GET_PRIVATE (metadata);
+
+ if (sj_metadata_helper_check_media (priv->cdrom, error) == FALSE) {
+ 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);
+ }
+
+ if (g_getenv("MUSICBRAINZ_FORCE_DISC_ID")) {
+ id = g_strdup (g_getenv("MUSICBRAINZ_FORCE_DISC_ID"));
+ } else {
+ 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);
+ g_free (id);
+
+ 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);
+}
Added: trunk/plugins/audiocd/sj-metadata-musicbrainz3.h
==============================================================================
--- (empty file)
+++ trunk/plugins/audiocd/sj-metadata-musicbrainz3.h Fri Sep 5 00:38:27 2008
@@ -0,0 +1,56 @@
+/*
+ * sj-metadata-musicbrainz3.h
+ * Copyright (C) 2008 Ross Burton <ross burtonini com>
+ * Copyright (C) 2008 Bastien Nocera <hadess hadess net>
+ *
+ * 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 */
Modified: trunk/plugins/audiocd/sj-metadata.c
==============================================================================
--- trunk/plugins/audiocd/sj-metadata.c (original)
+++ trunk/plugins/audiocd/sj-metadata.c Fri Sep 5 00:38:27 2008
@@ -7,14 +7,6 @@
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your 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
@@ -26,31 +18,50 @@
* Boston, MA 02111-1307, USA.
*/
-#include "config.h"
-
#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef USE_TOTEM_PL_PARSER
+#include <unistd.h>
+#include <nautilus-burn.h>
+#else
+#include <totem-disc.h>
+#endif /* USE_TOTEM_PL_PARSER */
+
#include "sj-metadata.h"
#include "sj-metadata-marshal.h"
+#include "sj-error.h"
enum {
METADATA,
LAST_SIGNAL
};
-static int signals[LAST_SIGNAL] = { 0 };
-
static void
-sj_metadata_base_init (gpointer g_class)
+sj_metadata_base_init (gpointer g_iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
- signals[METADATA] = g_signal_new ("metadata",
- G_TYPE_FROM_CLASS (g_class),
- 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,
+ g_param_spec_string ("device", "device", NULL, NULL,
+ G_PARAM_READABLE|G_PARAM_WRITABLE|
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+ g_object_interface_install_property (g_iface,
+ g_param_spec_string ("proxy-host", "proxy-host", NULL, NULL,
+ G_PARAM_READABLE|G_PARAM_WRITABLE|
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+ g_object_interface_install_property (g_iface,
+ g_param_spec_int ("proxy-port", "proxy-port", NULL,
+ 0, G_MAXINT, 0,
+ G_PARAM_READABLE|G_PARAM_WRITABLE|
+ G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
initialized = TRUE;
}
}
@@ -79,49 +90,124 @@
return type;
}
-GError *
-sj_metadata_get_new_error (SjMetadata *metadata)
-{
- return SJ_METADATA_GET_CLASS (metadata)->get_new_error (metadata);
-}
-
void
sj_metadata_set_cdrom (SjMetadata *metadata, const char* device)
{
-#if defined (sun) && defined (__SVR4)
- if (g_str_has_prefix (device, "/dev/dsk/")) {
- char *raw_path = g_strdup_printf ("/dev/rdsk/%s", device + strlen ("/dev/dsk/"));
- SJ_METADATA_GET_CLASS (metadata)->set_cdrom (metadata, raw_path);
- g_free (raw_path);
- }
-#else
- SJ_METADATA_GET_CLASS (metadata)->set_cdrom (metadata, device);
-#endif
+ g_object_set (metadata, "device", device, NULL);
}
void
sj_metadata_set_proxy (SjMetadata *metadata, const char* proxy)
{
- SJ_METADATA_GET_CLASS (metadata)->set_proxy (metadata, proxy);
+ g_object_set (metadata, "proxy-host", proxy, NULL);
}
void
sj_metadata_set_proxy_port (SjMetadata *metadata, const int proxy_port)
{
- SJ_METADATA_GET_CLASS (metadata)->set_proxy_port (metadata, 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)
+sj_metadata_helper_scan_disc_number (const char *album_title, int *disc_number)
+{
+ GRegex *disc_regex;
+ GMatchInfo *info;
+ char *new_title;
+ int num;
+
+ disc_regex = g_regex_new (".+( \\(disc (\\d+).*)", 0, 0, NULL);
+ new_title = NULL;
+ *disc_number = 0;
+
+ 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) {
+ new_title = g_strndup (album_title, pos);
+ }
+
+ s = g_match_info_fetch (info, 2);
+ num = atoi (s);
+ *disc_number = num;
+ g_free (s);
+ }
+
+ g_match_info_free (info);
+ g_regex_unref (disc_regex);
+
+ return new_title;
+}
+
+GDate *
+sj_metadata_helper_scan_date (const char *date)
{
- if (SJ_METADATA_GET_CLASS (metadata)->get_submit_url)
- return SJ_METADATA_GET_CLASS (metadata)->get_submit_url (metadata);
- else
- return NULL;
+ int matched, year=1, month=1, day=1;
+ matched = sscanf(date, "%u-%u-%u", &year, &month, &day);
+ if (matched >= 1) {
+ return g_date_new_dmy ((day == 0) ? 1 : day, (month == 0) ? 1 : month, year);
+ }
+
+ return NULL;
+}
+
+gboolean
+sj_metadata_helper_check_media (const char *cdrom, GError **error)
+{
+#ifndef USE_TOTEM_PL_PARSER
+ NautilusBurnMediaType type;
+ NautilusBurnDriveMonitor *monitor;
+ NautilusBurnDrive *drive;
+
+ if (! nautilus_burn_initialized ()) {
+ nautilus_burn_init ();
+ }
+ monitor = nautilus_burn_get_drive_monitor ();
+ drive = nautilus_burn_drive_monitor_get_drive_for_device (monitor, cdrom);
+ if (drive == NULL) {
+ return FALSE;
+ }
+ 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 (cdrom, W_OK) == 0) {
+ msg = g_strdup_printf (_("Device '%s' does not contain any media"), 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."), cdrom);
+ err = SJ_ERROR_CD_PERMISSION_ERROR;
+ }
+ g_set_error (error, SJ_ERROR, err, _("Cannot read CD: %s"), msg);
+ g_free (msg);
+
+ return FALSE;
+ }
+#else
+ TotemDiscMediaType type;
+ GError *totem_error = NULL;
+
+ type = totem_cd_detect_type (cdrom, &totem_error);
+
+ if (totem_error != NULL) {
+ g_set_error (error, SJ_ERROR, SJ_ERROR_CD_NO_MEDIA, _("Cannot read CD: %s"), totem_error->message);
+ g_error_free (totem_error);
+
+ return FALSE;
+ }
+#endif /* !USE_TOTEM_PL_PARSER */
+
+ return TRUE;
}
+
Modified: trunk/plugins/audiocd/sj-metadata.h
==============================================================================
--- trunk/plugins/audiocd/sj-metadata.h (original)
+++ trunk/plugins/audiocd/sj-metadata.h Fri Sep 5 00:38:27 2008
@@ -7,14 +7,6 @@
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your 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
@@ -48,25 +40,19 @@
{
GTypeInterface g_iface;
- /* Signals */
- void (*metadata) (SjMetadata *md, GList *albums, GError *error);
-
/* Virtual Table */
- GError* (*get_new_error) (SjMetadata *metadata);
- void (*set_cdrom) (SjMetadata *metadata, const char* device);
- void (*set_proxy) (SjMetadata *metadata, const char* proxy);
- void (*set_proxy_port) (SjMetadata *metadata, int proxy_port);
- 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);
-GError *sj_metadata_get_new_error (SjMetadata *metadata);
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);
+
+char * sj_metadata_helper_scan_disc_number (const char *album_title, int *disc_number);
+GDate * sj_metadata_helper_scan_date (const char *date);
+gboolean sj_metadata_helper_check_media (const char *cdrom, GError **error);
G_END_DECLS
Modified: trunk/plugins/audiocd/sj-structures.c
==============================================================================
--- trunk/plugins/audiocd/sj-structures.c (original)
+++ trunk/plugins/audiocd/sj-structures.c Fri Sep 5 00:38:27 2008
@@ -3,33 +3,24 @@
*
* Sound Juicer - sj-structures.c
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 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.*
*
* Authors: Ross Burton <ross burtonini com>
*/
-#include "config.h"
-
#include "sj-structures.h"
#include <glib/gmessages.h>
#include <glib/glist.h>
@@ -62,5 +53,8 @@
g_list_foreach (album->tracks, (GFunc)track_details_free, NULL);
g_list_free (album->tracks);
g_free (album->artist_sortname);
+ g_free (album->asin);
+ g_free (album->discogs);
+ g_free (album->wikipedia);
g_free (album);
}
Modified: trunk/plugins/audiocd/sj-structures.h
==============================================================================
--- trunk/plugins/audiocd/sj-structures.h (original)
+++ trunk/plugins/audiocd/sj-structures.h Fri Sep 5 00:38:27 2008
@@ -3,27 +3,20 @@
*
* Sound Juicer - sj-structures.h
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * 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.
*
- * The Rhythmbox authors hereby grants permission for non-GPL compatible
- * GStreamer plugins to be used and distributed together with GStreamer
- * and Rhythmbox. This permission is above and beyond the permissions granted
- * by the GPL license by which Rhythmbox is covered. If you modify this code
- * you may extend this exception to your version of the code, but you are not
- * obligated to do so. If you do not wish to do so, delete this exception
- * statement from your version.
- *
- * This program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 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.
*
* Authors: Ross Burton <ross burtonini com>
*/
@@ -32,11 +25,20 @@
#define SJ_STRUCTURES_H
#include <glib/glist.h>
-#include <gtk/gtktreemodel.h>
+#include <glib/gdate.h>
+
+typedef enum _MetadataSource MetadataSource;
typedef struct _AlbumDetails AlbumDetails;
typedef struct _TrackDetails TrackDetails;
+enum _MetadataSource {
+ SOURCE_UNKNOWN = 0,
+ SOURCE_CDTEXT,
+ SOURCE_FREEDB,
+ SOURCE_MUSICBRAINZ,
+ SOURCE_FALLBACK
+};
struct _TrackDetails {
AlbumDetails *album;
@@ -47,7 +49,6 @@
int duration; /* seconds */
char* track_id;
char* artist_id;
- GtkTreeIter iter; /* Temporary iterator for internal use */
};
struct _AlbumDetails {
@@ -56,10 +57,16 @@
char* artist_sortname;
char *genre;
int number; /* number of tracks in the album */
+ int disc_number;
GList* tracks;
GDate *release_date; /* MusicBrainz support multiple releases per album */
char* album_id;
char* artist_id;
+ char* asin;
+ char* discogs;
+ char* wikipedia;
+ MetadataSource metadata_source;
+ gboolean is_spoken_word;
};
void album_details_free(AlbumDetails *album);
Added: trunk/plugins/audiocd/update-from-egg.sh
==============================================================================
--- (empty file)
+++ trunk/plugins/audiocd/update-from-egg.sh Fri Sep 5 00:38:27 2008
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+function die() {
+ echo $*
+ exit 1
+}
+
+if test -z "$EGGDIR"; then
+ echo "Must set EGGDIR"
+ exit 1
+fi
+
+if test -z "$EGGFILES"; then
+ echo "Must set EGGFILES"
+ exit 1
+fi
+
+for FILE in $EGGFILES; do
+ if cmp -s $EGGDIR/$FILE $FILE; then
+ echo "File $FILE is unchanged"
+ else
+ cp $EGGDIR/$FILE $FILE || die "Could not move $EGGDIR/$FILE to $FILE"
+ echo "Updated $FILE"
+ fi
+done
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]