[rhythmbox] Patch to replace DAAP-related code with libdmapsharing
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] Patch to replace DAAP-related code with libdmapsharing
- Date: Sun, 30 May 2010 09:45:20 +0000 (UTC)
commit ef580491b70233cbcb17416b8fadcdda3ac89829
Author: W. Michael Petullo <mike flyn org>
Date: Sat May 29 13:04:18 2010 -0500
Patch to replace DAAP-related code with libdmapsharing
This patch requires libdmapsharing 1.9.0.20. Receiving playlists as a
client, receiving songs as a client, serving songs, serving playlists
and password-protected shares have survived basic testing. This
patch integrates with the new artist and album sort order code in
libdmapsharing.
Signed-off-by: W. Michael Petullo <mike flyn org>
configure.ac | 48 +-
plugins/Makefile.am | 2 +-
plugins/daap/Makefile.am | 54 +-
plugins/daap/rb-daap-connection.c | 1894 --------------------
plugins/daap/rb-daap-connection.h | 120 --
plugins/daap/rb-daap-container-record.c | 183 ++
plugins/daap/rb-daap-container-record.h | 75 +
plugins/daap/rb-daap-hash.c | 518 ------
plugins/daap/rb-daap-mdns-avahi.c | 122 --
plugins/daap/rb-daap-mdns-avahi.h | 40 -
plugins/daap/rb-daap-mdns-browser-avahi.c | 405 -----
plugins/daap/rb-daap-mdns-browser.h | 91 -
plugins/daap/rb-daap-mdns-publisher-avahi.c | 423 -----
plugins/daap/rb-daap-mdns-publisher.h | 98 -
plugins/daap/rb-daap-plugin.c | 86 +-
.../{rb-daap-hash.h => rb-daap-record-factory.c} | 61 +-
plugins/daap/rb-daap-record-factory.h | 67 +
plugins/daap/rb-daap-record.c | 412 +++++
plugins/daap/rb-daap-record.h | 72 +
plugins/daap/rb-daap-share.c | 1785 ------------------
plugins/daap/rb-daap-share.h | 68 -
plugins/daap/rb-daap-sharing.c | 19 +-
plugins/daap/rb-daap-source.c | 80 +-
plugins/daap/rb-daap-source.h | 23 +-
plugins/daap/rb-daap-src.c | 35 +-
plugins/daap/rb-daap-structure.c | 751 --------
plugins/daap/rb-daap-structure.h | 204 ---
plugins/daap/rb-dmap-container-db-adapter.c | 193 ++
plugins/daap/rb-dmap-container-db-adapter.h | 64 +
plugins/daap/rb-rhythmdb-dmap-db-adapter.c | 275 +++
plugins/daap/rb-rhythmdb-dmap-db-adapter.h | 61 +
.../daap/rb-rhythmdb-query-model-dmap-db-adapter.c | 156 ++
.../daap/rb-rhythmdb-query-model-dmap-db-adapter.h | 61 +
33 files changed, 1874 insertions(+), 6672 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 37a6c25..f807236 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,11 +250,6 @@ PKG_CHECK_MODULES(GSTREAMER_0_10, \
RHYTHMBOX_CFLAGS="$RHYTHMBOX_CFLAGS $GSTREAMER_0_10_CFLAGS"
RHYTHMBOX_LIBS="$RHYTHMBOX_LIBS $GSTREAMER_0_10_LIBS -lgstinterfaces-0.10"
-dnl DAAP (iTunes Music Shares)
-AC_ARG_ENABLE(daap,
- AC_HELP_STRING([--disable-daap],
- [Disable Digital Audio Access Protocol (music sharing) in rhythmbox]))
-
AC_ARG_WITH(mdns,
AC_HELP_STRING([--with-mdns=auto|avahi],
[Select the mDNS/DNS-SD implementation to use (default auto)]),,
@@ -327,22 +322,6 @@ if test x$enable_libnotify = xyes ; then
AC_SUBST(NOTIFY_LIBS)
fi
-dnl daap support
-if test "x$enable_daap" != "xno"; then
- if test x"$have_mdns" = xno; then
- if test "x$enable_daap" = "xyes"; then
- AC_MSG_ERROR([DAAP support explicitly requested, but no mDNS implementation found. Install Avahi])
- fi
- enable_daap=no
- else
- AC_DEFINE(WITH_DAAP_SUPPORT, 1, [Define if DAAP should be enabled])
- enable_daap="yes"
- AC_SUBST(MDNS_CFLAGS)
- AC_SUBST(MDNS_LIBS)
- fi
-fi
-AM_CONDITIONAL(USE_DAAP, test "x$enable_daap" != "xno")
-
AC_CHECK_LIB(z, uncompress)
dnl check for libgstcdda, needed to list the audio tracks
@@ -797,6 +776,31 @@ AC_ARG_VAR([MOZILLA_PLUGINDIR],[Where to install the browser plugin to])
AM_CONDITIONAL([ENABLE_BROWSER_PLUGIN], test x$enable_browser_plugin = xyes)
+
+dnl ================================================================
+dnl Use libdmapsharing for DAAP?
+dnl ================================================================
+AC_ARG_ENABLE(daap,
+ AC_HELP_STRING([--disable-daap],
+ [Disable DAAP support]),,
+ enable_daap=auto)
+if test "x$enable_daap" != "xno"; then
+ PKG_CHECK_MODULES(DMAPSHARING, libdmapsharing-1.9 >= 1.9.0.20,
+ have_libdmapsharing=yes,
+ have_libdmapsharing=no)
+ if test "x$have_libdmapsharing" = "xno" -a "x$enable_daap" = "xyes"; then
+ AC_MSG_ERROR([DAAP support explicitly requested, but libdmapsharing couldn't be found])
+ fi
+ if test x"$have_libdmapsharing" = "xyes"; then
+ AC_DEFINE(HAVE_LIBDMAPSHARING, 1, [Define if libdmapsharing support is enabled])
+ fi
+fi
+
+AM_CONDITIONAL(USE_LIBDMAPSHARING, test x"$have_libdmapsharing" = "xyes")
+
+AC_SUBST(DMAPSHARING_CFLAGS)
+AC_SUBST(DMAPSHARING_LIBS)
+
dnl ================================================================
dnl end-game
dnl ================================================================
@@ -941,7 +945,7 @@ elif test x"$have_libnautilus_burn" != xno; then
else
AC_MSG_NOTICE([ CD burning support disabled])
fi
-if test x"$enable_daap" = xyes; then
+if test x"$have_libdmapsharing" = xyes; then
AC_MSG_NOTICE([** DAAP (music sharing) support is enabled])
else
AC_MSG_NOTICE([ DAAP (music sharing) support is disabled])
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index dd7732e..55755f5 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -46,7 +46,7 @@ SUBDIRS += cd-recorder
endif # HAVE_NAUTILUS_BURN
endif # HAVE_LIBBRASERO_MEDIA
-if USE_DAAP
+if USE_LIBDMAPSHARING
SUBDIRS += daap
endif
diff --git a/plugins/daap/Makefile.am b/plugins/daap/Makefile.am
index dfc1058..a22f866 100644
--- a/plugins/daap/Makefile.am
+++ b/plugins/daap/Makefile.am
@@ -4,39 +4,37 @@ plugindir = $(PLUGINDIR)/daap
plugin_LTLIBRARIES = libdaap.la
libdaap_la_SOURCES = \
- rb-daap-plugin.c \
- rb-daap-plugin.h \
- rb-daap-source.c \
- rb-daap-source.h \
- rb-daap-sharing.c \
- rb-daap-sharing.h \
- rb-daap-share.c \
- rb-daap-share.h \
- rb-daap-structure.c \
- rb-daap-structure.h \
- rb-daap-mdns-publisher.h \
- rb-daap-mdns-browser.h \
- rb-daap-connection.c \
- rb-daap-connection.h \
- rb-daap-hash.c \
- rb-daap-hash.h \
- rb-daap-src.c \
- rb-daap-src.h \
- rb-daap-dialog.c \
- rb-daap-dialog.h \
- rb-daap-mdns-avahi.c \
- rb-daap-mdns-avahi.h \
- rb-daap-mdns-publisher-avahi.c \
- rb-daap-mdns-browser-avahi.c \
+ rb-daap-container-record.c \
+ rb-daap-container-record.h \
+ rb-daap-plugin.c \
+ rb-daap-plugin.h \
+ rb-daap-record.c \
+ rb-daap-record.h \
+ rb-daap-record-factory.c \
+ rb-daap-record-factory.h \
+ rb-daap-sharing.c \
+ rb-daap-sharing.h \
+ rb-daap-source.c \
+ rb-daap-source.h \
+ rb-daap-src.c \
+ rb-daap-src.h \
+ rb-dmap-container-db-adapter.c \
+ rb-dmap-container-db-adapter.h \
+ rb-daap-dialog.c \
+ rb-daap-dialog.h \
+ rb-rhythmdb-dmap-db-adapter.c \
+ rb-rhythmdb-dmap-db-adapter.h \
+ rb-rhythmdb-query-model-dmap-db-adapter.c \
+ rb-rhythmdb-query-model-dmap-db-adapter.h \
$(NULL)
libdaap_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
libdaap_la_LIBTOOLFLAGS = --tag=disable-static
libdaap_la_LIBADD = \
$(top_builddir)/shell/librhythmbox-core.la \
+ $(DMAPSHARING_LIBS) \
$(DBUS_LIBS) \
- $(RHYTHMBOX_LIBS) \
- $(MDNS_LIBS)
+ $(RHYTHMBOX_LIBS)
INCLUDES = \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
@@ -59,7 +57,7 @@ INCLUDES = \
-DPIXMAP_DIR=\""$(datadir)/pixmaps"\" \
-DSHARE_DIR=\"$(pkgdatadir)\" \
-DDATADIR=\""$(datadir)"\" \
- $(MDNS_CFLAGS) \
+ $(DMAPSHARING_CFLAGS) \
$(RHYTHMBOX_CFLAGS) \
$(DBUS_CFLAGS) \
-D_XOPEN_SOURCE -D_BSD_SOURCE
@@ -88,7 +86,7 @@ plugin_DATA = \
$(NULL)
EXTRA_DIST = \
- $(gtkbuilder_DATA) \
+ $(gtkbuilder_DATA) \
$(uixml_DATA) \
$(plugin_in_files) \
$(NULL)
diff --git a/plugins/daap/rb-daap-container-record.c b/plugins/daap/rb-daap-container-record.c
new file mode 100644
index 0000000..843f915
--- /dev/null
+++ b/plugins/daap/rb-daap-container-record.c
@@ -0,0 +1,183 @@
+/*
+ * Container / playlist database record class for DAAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "rhythmdb-query-model.h"
+#include "rb-daap-container-record.h"
+#include "rb-rhythmdb-query-model-dmap-db-adapter.h"
+
+enum {
+ PROP_0,
+ PROP_NAME
+};
+
+struct RBDAAPContainerRecordPrivate {
+ char *name;
+ RBPlaylistSource *source;
+};
+
+static void rb_daap_container_record_finalize (GObject *object);
+
+static void
+rb_daap_container_record_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ RBDAAPContainerRecord *record = RB_DAAP_CONTAINER_RECORD (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_free (record->priv->name);
+ record->priv->name = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+rb_daap_container_record_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ RBDAAPContainerRecord *record = RB_DAAP_CONTAINER_RECORD (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, record->priv->name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+guint
+rb_daap_container_record_get_id (DMAPContainerRecord *record)
+{
+ return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (RB_DAAP_CONTAINER_RECORD (record)->priv->source), "daap_id"));
+}
+
+void
+rb_daap_container_record_add_entry (DMAPContainerRecord *container_record,
+ DMAPRecord *record, gint id)
+{
+ g_error ("Unimplemented");
+}
+
+guint64
+rb_daap_container_record_get_entry_count (DMAPContainerRecord *record)
+{
+ RhythmDBQueryModel *model;
+ guint64 count;
+ g_object_get (RB_DAAP_CONTAINER_RECORD (record)->priv->source,
+ "base-query-model",
+ &model,
+ NULL);
+ count = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
+ g_object_unref (model);
+ return count;
+}
+
+const DMAPDb *
+rb_daap_container_record_get_entries (DMAPContainerRecord *record)
+{
+ RhythmDBQueryModel *model;
+ g_object_get (RB_DAAP_CONTAINER_RECORD (record)->priv->source,
+ "base-query-model",
+ &model,
+ NULL);
+ return DMAP_DB (rb_rhythmdb_query_model_dmap_db_adapter_new (model));
+}
+
+static void
+rb_daap_container_record_init (RBDAAPContainerRecord *record)
+{
+ record->priv = RB_DAAP_CONTAINER_RECORD_GET_PRIVATE (record);
+}
+
+static void
+rb_daap_container_record_class_init (RBDAAPContainerRecordClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (RBDAAPContainerRecordPrivate));
+
+ gobject_class->set_property = rb_daap_container_record_set_property;
+ gobject_class->get_property = rb_daap_container_record_get_property;
+ gobject_class->finalize = rb_daap_container_record_finalize;
+
+ g_object_class_override_property (gobject_class, PROP_NAME, "name");
+}
+
+static void
+rb_daap_container_record_daap_iface_init (gpointer iface, gpointer data)
+{
+ DMAPContainerRecordInterface *dmap_container_record = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (dmap_container_record) == TYPE_DMAP_CONTAINER_RECORD);
+
+ dmap_container_record->get_id = rb_daap_container_record_get_id;
+ dmap_container_record->add_entry = rb_daap_container_record_add_entry;
+ dmap_container_record->get_entry_count = rb_daap_container_record_get_entry_count;
+ dmap_container_record->get_entries = rb_daap_container_record_get_entries;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDAAPContainerRecord, rb_daap_container_record, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_CONTAINER_RECORD, rb_daap_container_record_daap_iface_init))
+
+static void rb_daap_container_record_finalize (GObject *object)
+{
+ RBDAAPContainerRecord *record = RB_DAAP_CONTAINER_RECORD (object);
+
+ g_free (record->priv->name);
+
+ G_OBJECT_CLASS (rb_daap_container_record_parent_class)->finalize (object);
+}
+
+RBDAAPContainerRecord *
+rb_daap_container_record_new (char *name, RBPlaylistSource *source)
+{
+ RBDAAPContainerRecord *record;
+
+ record = g_object_new (RB_TYPE_DAAP_CONTAINER_RECORD, NULL);
+
+ record->priv->source = source;
+ record->priv->name = name;
+
+ return record;
+}
diff --git a/plugins/daap/rb-daap-container-record.h b/plugins/daap/rb-daap-container-record.h
new file mode 100644
index 0000000..b52d9b7
--- /dev/null
+++ b/plugins/daap/rb-daap-container-record.h
@@ -0,0 +1,75 @@
+/*
+ * Container / playlist database record class for DAAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_DAAP_CONTAINER_RECORD
+#define __RB_DAAP_CONTAINER_RECORD
+
+#include <libdmapsharing/dmap.h>
+
+#include "rb-playlist-source.h"
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DAAP_CONTAINER_RECORD (rb_daap_container_record_get_type ())
+#define RB_DAAP_CONTAINER_RECORD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_CONTAINER_RECORD, RBDAAPContainerRecord))
+#define RB_DAAP_CONTAINER_RECORD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_CONTAINER_RECORD, RBDAAPContainerRecordClass))
+#define RB_IS_DAAP_CONTAINER_RECORD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_CONTAINER_RECORD))
+#define RB_IS_DAAP_CONTAINER_RECORD_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_CONTAINER_RECORD_CLASS))
+#define RB_DAAP_CONTAINER_RECORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_CONTAINER_RECORD, RBDAAPContainerRecordClass))
+#define RB_DAAP_CONTAINER_RECORD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_CONTAINER_RECORD, RBDAAPContainerRecordPrivate))
+
+typedef struct RBDAAPContainerRecordPrivate RBDAAPContainerRecordPrivate;
+
+typedef struct {
+ GObject parent;
+ RBDAAPContainerRecordPrivate *priv;
+} RBDAAPContainerRecord;
+
+typedef struct {
+ GObjectClass parent;
+} RBDAAPContainerRecordClass;
+
+GType rb_daap_container_record_get_type (void);
+
+guint rb_daap_container_record_get_id (DMAPContainerRecord *record);
+
+void rb_daap_container_record_add_entry (DMAPContainerRecord *container_record,
+ DMAPRecord *record,
+ gint id);
+
+guint64 rb_daap_container_record_get_entry_count (DMAPContainerRecord *record);
+
+const DMAPDb *rb_daap_container_record_get_entries (DMAPContainerRecord *record);
+
+RBDAAPContainerRecord *rb_daap_container_record_new (char *name,
+ RBPlaylistSource *model);
+
+#endif /* __RB_DAAP_CONTAINER_RECORD */
+
+G_END_DECLS
diff --git a/plugins/daap/rb-daap-plugin.c b/plugins/daap/rb-daap-plugin.c
index f14f809..c03afe0 100644
--- a/plugins/daap/rb-daap-plugin.c
+++ b/plugins/daap/rb-daap-plugin.c
@@ -53,7 +53,7 @@
#include "rb-daap-src.h"
#include "rb-uri-dialog.h"
-#include "rb-daap-mdns-browser.h"
+#include <libdmapsharing/dmap.h>
/* preferences */
#define CONF_DAAP_PREFIX CONF_PREFIX "/plugins/daap"
@@ -74,7 +74,7 @@ struct RBDaapPluginPrivate
GtkActionGroup *daap_action_group;
guint daap_ui_merge_id;
- RBDaapMdnsBrowser *mdns_browser;
+ DMAPMdnsBrowser *mdns_browser;
GHashTable *source_lookup;
@@ -113,6 +113,10 @@ static void enable_browsing_changed_cb (GConfClient *client,
guint cnxn_id,
GConfEntry *entry,
RBDaapPlugin *plugin);
+static void libdmapsharing_debug (const char *domain,
+ GLogLevelFlags level,
+ const char *message,
+ gpointer data);
gboolean rb_daap_add_source (RBDaapPlugin *plugin, gchar *service_name, gchar *host, unsigned int port, GError **error);
gboolean rb_daap_remove_source (RBDaapPlugin *plugin, gchar *service_name, GError **error);
@@ -223,6 +227,11 @@ impl_activate (RBPlugin *bplugin,
plugin->priv->shutdown = FALSE;
plugin->priv->shell = g_object_ref (shell);
+ g_log_set_handler ("libdmapsharing",
+ G_LOG_LEVEL_MASK,
+ libdmapsharing_debug,
+ NULL);
+
value = gconf_client_get_without_default (client,
CONF_ENABLE_BROWSING, NULL);
if (value != NULL) {
@@ -458,33 +467,33 @@ find_source_by_service_name (RBDaapPlugin *plugin,
}
static void
-mdns_service_added (RBDaapMdnsBrowser *browser,
- const char *service_name,
- const char *name,
- const char *host,
- guint port,
- gboolean password_protected,
- RBDaapPlugin *plugin)
+mdns_service_added (DMAPMdnsBrowser *browser,
+ DMAPMdnsBrowserService *service,
+ RBDaapPlugin *plugin)
{
RBSource *source;
rb_debug ("New service: %s name=%s host=%s port=%u password=%d",
- service_name, name, host, port, password_protected);
+ service->service_name,
+ service->name,
+ service->host,
+ service->port,
+ service->password_protected);
GDK_THREADS_ENTER ();
- source = find_source_by_service_name (plugin, service_name);
+ source = find_source_by_service_name (plugin, service->service_name);
if (source == NULL) {
- source = rb_daap_source_new (plugin->priv->shell, RB_PLUGIN (plugin), service_name, name, host, port, password_protected);
- g_hash_table_insert (plugin->priv->source_lookup, g_strdup (service_name), source);
+ source = rb_daap_source_new (plugin->priv->shell, RB_PLUGIN (plugin), service->service_name, service->name, service->host, service->port, service->password_protected);
+ g_hash_table_insert (plugin->priv->source_lookup, g_strdup (service->service_name), source);
rb_shell_append_source (plugin->priv->shell, source, NULL);
} else {
g_object_set (G_OBJECT (source),
- "name", name,
- "host", host,
- "port", port,
- "password-protected", password_protected,
+ "name", service->name,
+ "host", service->host,
+ "port", service->port,
+ "password-protected", service->password_protected,
NULL);
}
@@ -492,7 +501,7 @@ mdns_service_added (RBDaapMdnsBrowser *browser,
}
static void
-mdns_service_removed (RBDaapMdnsBrowser *browser,
+mdns_service_removed (DMAPMdnsBrowser *browser,
const char *service_name,
RBDaapPlugin *plugin)
{
@@ -533,7 +542,7 @@ start_browsing (RBDaapPlugin *plugin)
return;
}
- plugin->priv->mdns_browser = rb_daap_mdns_browser_new ();
+ plugin->priv->mdns_browser = dmap_mdns_browser_new (DMAP_MDNS_BROWSER_SERVICE_TYPE_DAAP);
if (plugin->priv->mdns_browser == NULL) {
g_warning ("Unable to start mDNS browsing");
return;
@@ -551,7 +560,7 @@ start_browsing (RBDaapPlugin *plugin)
0);
error = NULL;
- rb_daap_mdns_browser_start (plugin->priv->mdns_browser, &error);
+ dmap_mdns_browser_start (plugin->priv->mdns_browser, &error);
if (error != NULL) {
g_warning ("Unable to start mDNS browsing: %s", error->message);
g_error_free (error);
@@ -581,7 +590,7 @@ stop_browsing (RBDaapPlugin *plugin)
g_signal_handlers_disconnect_by_func (plugin->priv->mdns_browser, mdns_service_removed, plugin);
error = NULL;
- rb_daap_mdns_browser_stop (plugin->priv->mdns_browser, &error);
+ dmap_mdns_browser_stop (plugin->priv->mdns_browser, &error);
if (error != NULL) {
g_warning ("Unable to stop mDNS browsing: %s", error->message);
g_error_free (error);
@@ -606,6 +615,19 @@ enable_browsing_changed_cb (GConfClient *client,
}
}
+static void
+libdmapsharing_debug (const char *domain,
+ GLogLevelFlags level,
+ const char *message,
+ gpointer data)
+{
+ if ((level & G_LOG_LEVEL_DEBUG) != 0) {
+ rb_debug ("%s", message);
+ } else {
+ g_log_default_handler (domain, level, message, data);
+ }
+}
+
/* daap share connect/disconnect commands */
static void
@@ -627,6 +649,7 @@ new_daap_share_location_added_cb (RBURIDialog *dialog,
char *host;
char *p;
int port = 3689;
+ DMAPMdnsBrowserService service;
host = g_strdup (location);
p = strrchr (host, ':');
@@ -636,12 +659,12 @@ new_daap_share_location_added_cb (RBURIDialog *dialog,
}
rb_debug ("adding manually specified DAAP share at %s", location);
+ service.name = (char *) location;
+ service.host = (char *) location;
+ service.port = port;
+ service.password_protected = FALSE;
mdns_service_added (NULL,
- g_strdup (location),
- g_strdup (location),
- g_strdup (host),
- port,
- FALSE,
+ &service,
plugin);
g_free (host);
@@ -900,6 +923,7 @@ impl_create_configure_dialog (RBPlugin *bplugin)
gboolean
rb_daap_add_source (RBDaapPlugin *plugin, gchar *service_name, gchar *host, unsigned int port, GError **error)
{
+ DMAPMdnsBrowserService service;
if (plugin->priv->shutdown)
return FALSE;
@@ -907,12 +931,12 @@ rb_daap_add_source (RBDaapPlugin *plugin, gchar *service_name, gchar *host, unsi
rb_debug ("Add DAAP source %s (%s:%d)", service_name, host, port);
rb_debug ("adding manually specified DAAP share at %s", service_name);
+ service.name = service_name;
+ service.host = host;
+ service.port = port;
+ service.password_protected = FALSE;
mdns_service_added (NULL,
- g_strdup (service_name),
- g_strdup (service_name),
- g_strdup (host),
- port,
- FALSE,
+ &service,
plugin);
return TRUE;
diff --git a/plugins/daap/rb-daap-hash.h b/plugins/daap/rb-daap-record-factory.c
similarity index 50%
rename from plugins/daap/rb-daap-hash.h
rename to plugins/daap/rb-daap-record-factory.c
index e6c25ad..be750e4 100644
--- a/plugins/daap/rb-daap-hash.h
+++ b/plugins/daap/rb-daap-record-factory.c
@@ -1,8 +1,7 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+/*
+ * RBDAAPRecord factory class
*
- * Header for DAAP (iTunes Music Sharing) hashing, connection
- *
- * Copyright (C) 2004-2005 Charles Schmidt <cschmidt2 emich edu>
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
*
* 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
@@ -28,19 +27,51 @@
*
*/
-#ifndef __RB_DAAP_HASH_H
-#define __RB_DAAP_HASH_H
+#include "rhythmdb.h"
+#include "rb-daap-record-factory.h"
+#include "rb-daap-record.h"
+
+DMAPRecord *
+rb_daap_record_factory_create (DMAPRecordFactory *factory,
+ gpointer user_data)
+{
+ DAAPRecord *record;
+
+ record = DAAP_RECORD (rb_daap_record_new ((RhythmDBEntry *) user_data));
+
+ return (DMAP_RECORD (record));
+}
+
+static void
+rb_daap_record_factory_init (RBDAAPRecordFactory *factory)
+{
+}
+
+static void
+rb_daap_record_factory_class_init (RBDAAPRecordFactoryClass *klass)
+{
+}
+
+static void
+rb_daap_record_factory_interface_init (gpointer iface, gpointer data)
+{
+ DMAPRecordFactoryInterface *factory = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (factory) == TYPE_DMAP_RECORD_FACTORY);
-#include <glib.h>
+ factory->create = rb_daap_record_factory_create;
+}
-G_BEGIN_DECLS
+G_DEFINE_TYPE_WITH_CODE (RBDAAPRecordFactory, rb_daap_record_factory, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_RECORD_FACTORY,
+ rb_daap_record_factory_interface_init))
-void rb_daap_hash_generate (short version_major,
- const guchar *url,
- guchar hash_select,
- guchar *out,
- gint request_id);
+RBDAAPRecordFactory *
+rb_daap_record_factory_new (void)
+{
+ RBDAAPRecordFactory *factory;
-G_END_DECLS
+ factory = RB_DAAP_RECORD_FACTORY (g_object_new (RB_TYPE_DAAP_RECORD_FACTORY, NULL));
-#endif /* __RB_DAAP_HASH_H */
+ return factory;
+}
diff --git a/plugins/daap/rb-daap-record-factory.h b/plugins/daap/rb-daap-record-factory.h
new file mode 100644
index 0000000..3bb9961
--- /dev/null
+++ b/plugins/daap/rb-daap-record-factory.h
@@ -0,0 +1,67 @@
+/*
+ * RBDAAPRecord factory class
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_DAAP_RECORD_FACTORY
+#define __RB_DAAP_RECORD_FACTORY
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DAAP_RECORD_FACTORY (rb_daap_record_factory_get_type ())
+#define RB_DAAP_RECORD_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
+ RB_TYPE_DAAP_RECORD_FACTORY, RBDAAPRecordFactory))
+#define RB_DAAP_RECORD_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), \
+ RB_TYPE_DAAP_RECORD_FACTORY, RBDAAPRecordFactoryClass))
+#define RB_IS_DAAP_RECORD_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), \
+ RB_TYPE_DAAP_RECORD_FACTORY))
+#define RB_IS_DAAP_RECORD_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), \
+ RB_TYPE_DAAP_RECORD_FACTORY_CLASS))
+#define RB_DAAP_RECORD_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), \
+ RB_TYPE_DAAP_RECORD_FACTORY, RBDAAPRecordFactoryClass))
+
+typedef struct RBDAAPRecordFactoryPrivate RBDAAPRecordFactoryPrivate;
+
+typedef struct {
+ GObject parent;
+} RBDAAPRecordFactory;
+
+typedef struct {
+ GObjectClass parent;
+} RBDAAPRecordFactoryClass;
+
+GType rb_daap_record_factory_get_type (void);
+
+RBDAAPRecordFactory *rb_daap_record_factory_new (void);
+
+DMAPRecord *rb_daap_record_factory_create (DMAPRecordFactory *factory, gpointer user_data);
+
+#endif /* __RB_DAAP_RECORD_FACTORY */
+
+G_END_DECLS
diff --git a/plugins/daap/rb-daap-record.c b/plugins/daap/rb-daap-record.c
new file mode 100644
index 0000000..e995b90
--- /dev/null
+++ b/plugins/daap/rb-daap-record.c
@@ -0,0 +1,412 @@
+/*
+ * Database record class for DAAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "rhythmdb.h"
+#include "rb-daap-record.h"
+
+struct RBDAAPRecordPrivate {
+ guint64 filesize;
+ char *location;
+ char *format; /* Format, possibly after transcoding. */
+ char *real_format;
+ char *title;
+ char *album;
+ char *artist;
+ char *genre;
+ gboolean has_video;
+ gint rating;
+ int duration;
+ int track;
+ int year;
+ int firstseen;
+ int mtime;
+ int disc;
+ int bitrate;
+ char *sort_artist;
+ char *sort_album;
+};
+
+enum {
+ PROP_0,
+ PROP_LOCATION,
+ PROP_TITLE,
+ PROP_RATING,
+ PROP_FILESIZE,
+ PROP_ALBUM,
+ PROP_ARTIST,
+ PROP_GENRE,
+ PROP_FORMAT,
+ PROP_DURATION,
+ PROP_TRACK,
+ PROP_YEAR,
+ PROP_FIRSTSEEN,
+ PROP_MTIME,
+ PROP_DISC,
+ PROP_BITRATE,
+ PROP_HAS_VIDEO,
+ PROP_REAL_FORMAT,
+ PROP_ARTIST_SORT_NAME,
+ PROP_ALBUM_SORT_NAME
+};
+
+static void rb_daap_record_finalize (GObject *object);
+
+static void
+rb_daap_record_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ RBDAAPRecord *record = RB_DAAP_RECORD (object);
+
+ switch (prop_id) {
+ case PROP_LOCATION:
+ g_free (record->priv->location);
+ record->priv->location = g_value_dup_string (value);
+ break;
+ case PROP_TITLE:
+ g_free (record->priv->title);
+ record->priv->title = g_value_dup_string (value);
+ break;
+ case PROP_ALBUM:
+ g_free (record->priv->album);
+ record->priv->album = g_value_dup_string (value);
+ break;
+ case PROP_ARTIST:
+ g_free (record->priv->artist);
+ record->priv->artist = g_value_dup_string (value);
+ break;
+ case PROP_GENRE:
+ g_free (record->priv->genre);
+ record->priv->genre = g_value_dup_string (value);
+ break;
+ case PROP_FORMAT:
+ g_free (record->priv->format);
+ record->priv->format = g_value_dup_string (value);
+ break;
+ case PROP_RATING:
+ record->priv->rating = g_value_get_int (value);
+ break;
+ case PROP_FILESIZE:
+ record->priv->filesize = g_value_get_uint64 (value);
+ break;
+ case PROP_DURATION:
+ record->priv->duration = g_value_get_int (value);
+ break;
+ case PROP_TRACK:
+ record->priv->track = g_value_get_int (value);
+ break;
+ case PROP_YEAR:
+ record->priv->year = g_value_get_int (value);
+ break;
+ case PROP_FIRSTSEEN:
+ record->priv->firstseen = g_value_get_int (value);
+ break;
+ case PROP_MTIME:
+ record->priv->mtime = g_value_get_int (value);
+ break;
+ case PROP_DISC:
+ record->priv->disc = g_value_get_int (value);
+ break;
+ case PROP_BITRATE:
+ record->priv->bitrate = g_value_get_int (value);
+ break;
+ case PROP_HAS_VIDEO:
+ record->priv->has_video = g_value_get_boolean (value);
+ break;
+ case PROP_REAL_FORMAT:
+ g_free (record->priv->real_format);
+ record->priv->real_format = g_value_dup_string (value);
+ break;
+ case PROP_ARTIST_SORT_NAME:
+ g_free (record->priv->sort_artist);
+ record->priv->sort_artist = g_value_dup_string (value);
+ break;
+ case PROP_ALBUM_SORT_NAME:
+ g_free (record->priv->sort_album);
+ record->priv->sort_album = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+rb_daap_record_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ RBDAAPRecord *record = RB_DAAP_RECORD (object);
+
+ switch (prop_id) {
+ case PROP_LOCATION:
+ g_value_set_string (value, record->priv->location);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, record->priv->title);
+ break;
+ case PROP_ALBUM:
+ g_value_set_string (value, record->priv->album);
+ break;
+ case PROP_ARTIST:
+ g_value_set_string (value, record->priv->artist);
+ break;
+ case PROP_GENRE:
+ g_value_set_string (value, record->priv->genre);
+ break;
+ case PROP_FORMAT:
+ g_value_set_string (value, record->priv->format);
+ break;
+ case PROP_RATING:
+ g_value_set_int (value, record->priv->rating);
+ break;
+ case PROP_FILESIZE:
+ g_value_set_uint64 (value, record->priv->filesize);
+ break;
+ case PROP_DURATION:
+ g_value_set_int (value, record->priv->duration);
+ break;
+ case PROP_TRACK:
+ g_value_set_int (value, record->priv->track);
+ break;
+ case PROP_YEAR:
+ g_value_set_int (value, record->priv->year);
+ break;
+ case PROP_FIRSTSEEN:
+ g_value_set_int (value, record->priv->firstseen);
+ break;
+ case PROP_MTIME:
+ g_value_set_int (value, record->priv->mtime);
+ break;
+ case PROP_DISC:
+ g_value_set_int (value, record->priv->disc);
+ break;
+ case PROP_BITRATE:
+ g_value_set_int (value, record->priv->bitrate);
+ break;
+ case PROP_HAS_VIDEO:
+ g_value_set_boolean (value, record->priv->has_video);
+ break;
+ case PROP_REAL_FORMAT:
+ g_value_set_string (value, record->priv->real_format);
+ break;
+ case PROP_ARTIST_SORT_NAME:
+ g_value_set_string (value, record->priv->sort_artist);
+ break;
+ case PROP_ALBUM_SORT_NAME:
+ g_value_set_string (value, record->priv->sort_album);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+gboolean
+rb_daap_record_itunes_compat (DAAPRecord *record)
+{
+ const gchar *format = RB_DAAP_RECORD (record)->priv->real_format;
+
+ if (! strcmp (format, "mp3"))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+GInputStream *
+rb_daap_record_read (DAAPRecord *record, GError **error)
+{
+ GFile *file;
+ GInputStream *fnval = NULL;
+
+ file = g_file_new_for_uri (RB_DAAP_RECORD (record)->priv->location);
+ fnval = G_INPUT_STREAM (g_file_read (file, NULL, error));
+
+ g_object_unref (file);
+
+ return fnval;
+}
+
+static void
+rb_daap_record_init (RBDAAPRecord *record)
+{
+ record->priv = RB_DAAP_RECORD_GET_PRIVATE (record);
+}
+
+static void
+rb_daap_record_class_init (RBDAAPRecordClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (RBDAAPRecordPrivate));
+
+ gobject_class->set_property = rb_daap_record_set_property;
+ gobject_class->get_property = rb_daap_record_get_property;
+ gobject_class->finalize = rb_daap_record_finalize;
+
+ g_object_class_override_property (gobject_class, PROP_LOCATION, "location");
+ g_object_class_override_property (gobject_class, PROP_TITLE, "title");
+ g_object_class_override_property (gobject_class, PROP_ALBUM, "daap.songalbum");
+ g_object_class_override_property (gobject_class, PROP_ARTIST, "daap.songartist");
+ g_object_class_override_property (gobject_class, PROP_GENRE, "daap.songgenre");
+ g_object_class_override_property (gobject_class, PROP_FORMAT, "format");
+ g_object_class_override_property (gobject_class, PROP_RATING, "rating");
+ g_object_class_override_property (gobject_class, PROP_FILESIZE, "filesize");
+ g_object_class_override_property (gobject_class, PROP_DURATION, "duration");
+ g_object_class_override_property (gobject_class, PROP_TRACK, "track");
+ g_object_class_override_property (gobject_class, PROP_YEAR, "year");
+ g_object_class_override_property (gobject_class, PROP_FIRSTSEEN, "firstseen");
+ g_object_class_override_property (gobject_class, PROP_MTIME, "mtime");
+ g_object_class_override_property (gobject_class, PROP_DISC, "disc");
+ g_object_class_override_property (gobject_class, PROP_BITRATE, "bitrate");
+ g_object_class_override_property (gobject_class, PROP_HAS_VIDEO, "has-video");
+ g_object_class_override_property (gobject_class, PROP_ARTIST_SORT_NAME, "sort_artist");
+ g_object_class_override_property (gobject_class, PROP_ALBUM_SORT_NAME, "sort_album");
+
+ g_object_class_install_property (gobject_class, PROP_REAL_FORMAT,
+ g_param_spec_string ("real-format",
+ "Real format of song data",
+ "Real format of song data",
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+rb_daap_record_daap_iface_init (gpointer iface, gpointer data)
+{
+ DAAPRecordInterface *daap_record = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (daap_record) == TYPE_DAAP_RECORD);
+
+ daap_record->itunes_compat = rb_daap_record_itunes_compat;
+ daap_record->read = rb_daap_record_read;
+}
+
+static void
+rb_daap_record_dmap_iface_init (gpointer iface, gpointer data)
+{
+ DMAPRecordInterface *dmap_record = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (dmap_record) == TYPE_DMAP_RECORD);
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDAAPRecord, rb_daap_record, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DAAP_RECORD, rb_daap_record_daap_iface_init)
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_RECORD, rb_daap_record_dmap_iface_init))
+
+static void rb_daap_record_finalize (GObject *object)
+{
+ RBDAAPRecord *record = RB_DAAP_RECORD (object);
+
+ g_free (record->priv->location);
+ g_free (record->priv->title);
+ g_free (record->priv->format);
+ g_free (record->priv->album);
+ g_free (record->priv->artist);
+ g_free (record->priv->genre);
+ g_free (record->priv->real_format);
+
+ G_OBJECT_CLASS (rb_daap_record_parent_class)->finalize (object);
+}
+
+RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry)
+{
+ RBDAAPRecord *record = NULL;
+ record = RB_DAAP_RECORD (g_object_new (RB_TYPE_DAAP_RECORD, NULL));
+
+ /* When browsing, entry will be NULL because we will pull
+ * the metadata from the DAAP query. When sharing, entry will
+ * point to an existing entry from the Rhythmbox DB.
+ */
+ if (entry) {
+ gchar *ext;
+
+ record->priv->filesize = rhythmdb_entry_get_uint64
+ (entry, RHYTHMDB_PROP_FILE_SIZE);
+
+ record->priv->location = rhythmdb_entry_dup_string
+ (entry, RHYTHMDB_PROP_LOCATION);
+
+ record->priv->title = rhythmdb_entry_dup_string
+ (entry, RHYTHMDB_PROP_TITLE);
+
+ record->priv->artist = rhythmdb_entry_dup_string
+ (entry, RHYTHMDB_PROP_ARTIST);
+
+ record->priv->album = rhythmdb_entry_dup_string
+ (entry, RHYTHMDB_PROP_ALBUM);
+
+ record->priv->genre = rhythmdb_entry_dup_string
+ (entry, RHYTHMDB_PROP_GENRE);
+
+ /* FIXME: Support transcoding: */
+ /* FIXME: we should use RHYTHMDB_PROP_MIMETYPE instead */
+ ext = strrchr (record->priv->location, '.');
+ if (ext == NULL) {
+ ext = "mp3";
+ } else {
+ ext++;
+ }
+ record->priv->real_format = g_strdup (ext);
+ record->priv->format = g_strdup (record->priv->real_format);
+
+ record->priv->track = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_TRACK_NUMBER);
+
+ record->priv->duration = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_DURATION);
+
+ record->priv->rating = (gint) rhythmdb_entry_get_double
+ (entry, RHYTHMDB_PROP_RATING);
+
+ record->priv->year = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_YEAR);
+
+ record->priv->firstseen = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_FIRST_SEEN);
+
+ record->priv->mtime = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_MTIME);
+
+ record->priv->disc = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_DISC_NUMBER);
+
+ record->priv->bitrate = rhythmdb_entry_get_ulong
+ (entry, RHYTHMDB_PROP_BITRATE);
+ }
+
+ return record;
+}
diff --git a/plugins/daap/rb-daap-record.h b/plugins/daap/rb-daap-record.h
new file mode 100644
index 0000000..0a1edd0
--- /dev/null
+++ b/plugins/daap/rb-daap-record.h
@@ -0,0 +1,72 @@
+/*
+ * Database record class for DAAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_DAAP_RECORD
+#define __RB_DAAP_RECORD
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DAAP_RECORD (rb_daap_record_get_type ())
+#define RB_DAAP_RECORD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DAAP_RECORD, RBDAAPRecord))
+#define RB_DAAP_RECORD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DAAP_RECORD, RBDAAPRecordClass))
+#define RB_IS_DAAP_RECORD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DAAP_RECORD))
+#define RB_IS_DAAP_RECORD_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DAAP_RECORD_CLASS))
+#define RB_DAAP_RECORD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DAAP_RECORD, RBDAAPRecordClass))
+#define RB_DAAP_RECORD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DAAP_RECORD, RBDAAPRecordPrivate))
+
+typedef struct RBDAAPRecordPrivate RBDAAPRecordPrivate;
+
+typedef struct {
+ GObject parent;
+ RBDAAPRecordPrivate *priv;
+} RBDAAPRecord;
+
+typedef struct {
+ GObjectClass parent;
+} RBDAAPRecordClass;
+
+GType rb_daap_record_get_type (void);
+
+RBDAAPRecord *rb_daap_record_new (RhythmDBEntry *entry);
+
+gint rb_daap_record_get_id (DAAPRecord *record);
+
+gboolean rb_daap_record_itunes_compat (DAAPRecord *record);
+
+void rb_daap_record_set_transcode_format (DAAPRecord *record,
+ const gint format);
+
+GInputStream *rb_daap_record_read (DAAPRecord *record,
+ GError **err);
+
+#endif /* __RB_DAAP_RECORD */
+
+G_END_DECLS
diff --git a/plugins/daap/rb-daap-sharing.c b/plugins/daap/rb-daap-sharing.c
index a5f43bb..4b446fa 100644
--- a/plugins/daap/rb-daap-sharing.c
+++ b/plugins/daap/rb-daap-sharing.c
@@ -36,14 +36,17 @@
#include <glib/gprintf.h>
#include "rb-daap-sharing.h"
-#include "rb-daap-share.h"
+#include "rb-rhythmdb-dmap-db-adapter.h"
+#include "rb-dmap-container-db-adapter.h"
#include "rb-debug.h"
#include "rb-dialog.h"
#include "rb-playlist-manager.h"
#include "eel-gconf-extensions.h"
#include "rb-preferences.h"
-static RBDAAPShare *share = NULL;
+#include <libdmapsharing/dmap.h>
+
+static DAAPShare *share = NULL;
static guint enable_sharing_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
static guint require_password_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
static guint share_name_notify_id = EEL_GCONF_UNDEFINED_CONNECTION;
@@ -65,7 +68,9 @@ rb_daap_sharing_default_share_name ()
static void
create_share (RBShell *shell)
{
- RhythmDB *db;
+ RhythmDB *rdb;
+ DMAPDb *db;
+ DMAPContainerDb *container_db;
RBPlaylistManager *playlist_manager;
char *name;
char *password;
@@ -81,8 +86,10 @@ create_share (RBShell *shell)
}
g_object_get (shell,
- "db", &db,
+ "db", &rdb,
"playlist-manager", &playlist_manager, NULL);
+ db = DMAP_DB (rb_rhythmdb_dmap_db_adapter_new (rdb, RHYTHMDB_ENTRY_TYPE_SONG));
+ container_db = DMAP_CONTAINER_DB (rb_dmap_container_db_adapter_new (playlist_manager));
require_password = eel_gconf_get_boolean (CONF_DAAP_REQUIRE_PASSWORD);
if (require_password) {
@@ -91,9 +98,11 @@ create_share (RBShell *shell)
password = NULL;
}
- share = rb_daap_share_new (name, password, db, RHYTHMDB_ENTRY_TYPE_SONG, playlist_manager);
+ share = daap_share_new (name, password, db, container_db, NULL);
g_object_unref (db);
+ g_object_unref (container_db);
+ g_object_unref (rdb);
g_object_unref (playlist_manager);
g_free (name);
diff --git a/plugins/daap/rb-daap-source.c b/plugins/daap/rb-daap-source.c
index 5e59e0a..9ec42af 100644
--- a/plugins/daap/rb-daap-source.c
+++ b/plugins/daap/rb-daap-source.c
@@ -50,14 +50,16 @@
#include "rb-dialog.h"
#include "rb-preferences.h"
#include "rb-daap-src.h"
+#include "rb-daap-record-factory.h"
+#include "rb-rhythmdb-dmap-db-adapter.h"
-#include "rb-daap-connection.h"
-#include "rb-daap-mdns-browser.h"
#include "rb-daap-dialog.h"
#include "rb-daap-plugin.h"
#include "rb-static-playlist-source.h"
+#include <libdmapsharing/dmap.h>
+
static void rb_daap_source_dispose (GObject *object);
static void rb_daap_source_set_property (GObject *object,
guint prop_id,
@@ -392,7 +394,7 @@ ask_password (RBDAAPSource *source, const char *name, const char *keyring)
}
static char *
-connection_auth_cb (RBDAAPConnection *connection,
+connection_auth_cb (DMAPConnection *connection,
const char *name,
RBDAAPSource *source)
{
@@ -440,8 +442,8 @@ connection_auth_cb (RBDAAPConnection *connection,
}
static void
-connection_connecting_cb (RBDAAPConnection *connection,
- RBDAAPConnectionState state,
+connection_connecting_cb (DMAPConnection *connection,
+ DMAPConnectionState state,
float progress,
RBDAAPSource *source)
{
@@ -452,20 +454,20 @@ connection_connecting_cb (RBDAAPConnection *connection,
rb_debug ("DAAP connection status: %d/%f", state, progress);
switch (state) {
- case DAAP_GET_INFO:
- case DAAP_GET_PASSWORD:
- case DAAP_LOGIN:
+ case DMAP_GET_INFO:
+ case DMAP_GET_PASSWORD:
+ case DMAP_LOGIN:
source->priv->connection_status = _("Connecting to music share");
break;
- case DAAP_GET_REVISION_NUMBER:
- case DAAP_GET_DB_INFO:
- case DAAP_GET_SONGS:
- case DAAP_GET_PLAYLISTS:
- case DAAP_GET_PLAYLIST_ENTRIES:
+ case DMAP_GET_REVISION_NUMBER:
+ case DMAP_GET_DB_INFO:
+ case DMAP_GET_SONGS:
+ case DMAP_GET_PLAYLISTS:
+ case DMAP_GET_PLAYLIST_ENTRIES:
source->priv->connection_status = _("Retrieving songs from music share");
break;
- case DAAP_LOGOUT:
- case DAAP_DONE:
+ case DMAP_LOGOUT:
+ case DMAP_DONE:
source->priv->connection_status = NULL;
break;
}
@@ -474,7 +476,7 @@ connection_connecting_cb (RBDAAPConnection *connection,
rb_source_notify_status_changed (RB_SOURCE (source));
- is_connected = rb_daap_connection_is_connected (connection);
+ is_connected = dmap_connection_is_connected (DMAP_CONNECTION (connection));
g_object_get (source, "plugin", &plugin, NULL);
g_assert (plugin != NULL);
@@ -491,7 +493,7 @@ connection_connecting_cb (RBDAAPConnection *connection,
}
static void
-connection_disconnected_cb (RBDAAPConnection *connection,
+connection_disconnected_cb (DMAPConnection *connection,
RBDAAPSource *source)
{
GdkPixbuf *icon;
@@ -527,13 +529,13 @@ release_connection (RBDAAPSource *daap_source)
}
static void
-_add_location_to_playlist (RBRefString *uri, RBStaticPlaylistSource *source)
+_add_location_to_playlist (const char *uri, RBStaticPlaylistSource *source)
{
- rb_static_playlist_source_add_location (source, rb_refstring_get (uri), -1);
+ rb_static_playlist_source_add_location (source, uri, -1);
}
static void
-rb_daap_source_connection_cb (RBDAAPConnection *connection,
+rb_daap_source_connection_cb (DMAPConnection *connection,
gboolean result,
const char *reason,
RBSource *source)
@@ -564,9 +566,9 @@ rb_daap_source_connection_cb (RBDAAPConnection *connection,
"shell", &shell,
"entry-type", &entry_type,
NULL);
- playlists = rb_daap_connection_get_playlists (RB_DAAP_CONNECTION (daap_source->priv->connection));
+ playlists = dmap_connection_get_playlists (DMAP_CONNECTION (daap_source->priv->connection));
for (l = playlists; l != NULL; l = g_slist_next (l)) {
- RBDAAPPlaylist *playlist = l->data;
+ DMAPPlaylist *playlist = l->data;
RBSource *playlist_source;
char *sorting_name;
@@ -591,7 +593,9 @@ rb_daap_source_activate (RBSource *source)
{
RBDAAPSource *daap_source = RB_DAAP_SOURCE (source);
RBShell *shell = NULL;
- RhythmDB *db = NULL;
+ DMAPRecordFactory *factory;
+ RhythmDB *rdb = NULL;
+ DMAPDb *db = NULL;
char *name = NULL;
RhythmDBEntryType type;
@@ -601,17 +605,20 @@ rb_daap_source_activate (RBSource *source)
g_object_get (daap_source,
"shell", &shell,
- "entry-type", &type,
"name", &name,
+ "entry-type", &type,
NULL);
- g_object_get (shell, "db", &db, NULL);
+ g_object_get (shell, "db", &rdb, NULL);
+ db = DMAP_DB (rb_rhythmdb_dmap_db_adapter_new (rdb, type));
+
+ factory = DMAP_RECORD_FACTORY (rb_daap_record_factory_new ());
- daap_source->priv->connection = rb_daap_connection_new (name,
+ daap_source->priv->connection = dmap_connection_new (name,
daap_source->priv->host,
daap_source->priv->port,
daap_source->priv->password_protected,
db,
- type);
+ factory);
g_boxed_free (RHYTHMDB_TYPE_ENTRY_TYPE, type);
g_object_add_weak_pointer (G_OBJECT (daap_source->priv->connection), (gpointer *)&daap_source->priv->connection);
@@ -630,16 +637,16 @@ rb_daap_source_activate (RBSource *source)
G_CALLBACK (connection_disconnected_cb),
source);
- rb_daap_connection_connect (RB_DAAP_CONNECTION (daap_source->priv->connection),
- (RBDAAPConnectionCallback) rb_daap_source_connection_cb,
+ dmap_connection_connect (DMAP_CONNECTION (daap_source->priv->connection),
+ (DMAPConnectionCallback) rb_daap_source_connection_cb,
source);
- g_object_unref (G_OBJECT (db));
+ g_object_unref (G_OBJECT (rdb));
g_object_unref (G_OBJECT (shell));
}
static void
-rb_daap_source_disconnect_cb (RBDAAPConnection *connection,
+rb_daap_source_disconnect_cb (DMAPConnection *connection,
gboolean result,
const char *reason,
RBSource *source)
@@ -704,8 +711,8 @@ rb_daap_source_disconnect (RBDAAPSource *daap_source)
/* keep the source alive until the disconnect completes */
g_object_ref (daap_source);
- rb_daap_connection_disconnect (daap_source->priv->connection,
- (RBDAAPConnectionCallback) rb_daap_source_disconnect_cb,
+ dmap_connection_disconnect (daap_source->priv->connection,
+ (DMAPConnectionCallback) rb_daap_source_disconnect_cb,
daap_source);
/* wait until disconnected */
@@ -726,7 +733,7 @@ rb_daap_source_show_popup (RBSource *source)
return TRUE;
}
-GstStructure *
+SoupMessageHeaders *
rb_daap_source_get_headers (RBDAAPSource *source,
const char *uri)
{
@@ -735,7 +742,7 @@ rb_daap_source_get_headers (RBDAAPSource *source,
return NULL;
}
- return rb_daap_connection_get_headers (source->priv->connection, uri);
+ return dmap_connection_get_headers (source->priv->connection, uri);
}
static char *
@@ -765,7 +772,7 @@ rb_daap_source_get_status (RBSource *source,
*progress_text = NULL;
}
if (progress != NULL) {
- *progress = 0.0;
+ *progress = 1.0;
}
if (daap_source->priv->connection_status != NULL) {
@@ -795,4 +802,3 @@ rb_daap_source_get_playback_uri (RhythmDBEntry *entry, gpointer data)
return g_strdup (location);
}
-
diff --git a/plugins/daap/rb-daap-source.h b/plugins/daap/rb-daap-source.h
index 3e92ab1..667d984 100644
--- a/plugins/daap/rb-daap-source.h
+++ b/plugins/daap/rb-daap-source.h
@@ -35,6 +35,7 @@
#include "rb-plugin.h"
#include <gst/gst.h>
+#include <libsoup/soup.h>
G_BEGIN_DECLS
@@ -57,20 +58,20 @@ typedef struct {
RBBrowserSourceClass parent;
} RBDAAPSourceClass;
-GType rb_daap_source_get_type (void);
+GType rb_daap_source_get_type (void);
-RBSource * rb_daap_source_new (RBShell *shell,
- RBPlugin *plugin,
- const char *service_name,
- const char *name,
- const char *host,
- guint port,
- gboolean password_protected);
+RBSource * rb_daap_source_new (RBShell *shell,
+ RBPlugin *plugin,
+ const char *service_name,
+ const char *name,
+ const char *host,
+ guint port,
+ gboolean password_protected);
-void rb_daap_source_disconnect (RBDAAPSource *daap_source);
+void rb_daap_source_disconnect (RBDAAPSource *daap_source);
-GstStructure * rb_daap_source_get_headers (RBDAAPSource *source,
- const gchar *uri);
+SoupMessageHeaders * rb_daap_source_get_headers (RBDAAPSource *source,
+ const gchar *uri);
G_END_DECLS
diff --git a/plugins/daap/rb-daap-src.c b/plugins/daap/rb-daap-src.c
index 60f66af..a23d634 100644
--- a/plugins/daap/rb-daap-src.c
+++ b/plugins/daap/rb-daap-src.c
@@ -241,6 +241,27 @@ rb_daap_src_get_property (GObject *object,
}
}
+static void
+rb_daap_src_set_header (const char *name, const char *value, gpointer headers)
+{
+ gst_structure_set (headers, name, G_TYPE_STRING, value, NULL);
+}
+
+static GstStructure *
+rb_daap_src_soup_message_headers_to_gst_structure (SoupMessageHeaders *headers)
+{
+ GstStructure *gst_headers = gst_structure_new ("extra-headers", NULL);
+
+ if (gst_headers == NULL)
+ return gst_headers;
+
+ soup_message_headers_foreach (headers,
+ rb_daap_src_set_header,
+ gst_headers);
+
+ return gst_headers;
+}
+
GstStateChangeReturn
rb_daap_src_change_state (GstElement *element, GstStateChange transition)
{
@@ -251,7 +272,8 @@ rb_daap_src_change_state (GstElement *element, GstStateChange transition)
{
const char *http = "http";
char *httpuri;
- GstStructure *headers;
+ SoupMessageHeaders *headers;
+ GstStructure *gst_headers;
RBDAAPSource *source;
/* Retrieve extra headers for the HTTP connection. */
@@ -267,8 +289,15 @@ rb_daap_src_change_state (GstElement *element, GstStateChange transition)
return GST_STATE_CHANGE_FAILURE;
}
- g_object_set (src->souphttpsrc, "extra-headers", headers, NULL);
- gst_structure_free (headers);
+ gst_headers = rb_daap_src_soup_message_headers_to_gst_structure
+ (headers);
+ if (gst_headers == NULL) {
+ return GST_STATE_CHANGE_FAILURE;
+ }
+ soup_message_headers_free (headers);
+
+ g_object_set (src->souphttpsrc, "extra-headers", gst_headers, NULL);
+ gst_structure_free (gst_headers);
/* Set daap://... URI as http:// on souphttpsrc to ready connection. */
httpuri = g_strdup (src->daap_uri);
diff --git a/plugins/daap/rb-dmap-container-db-adapter.c b/plugins/daap/rb-dmap-container-db-adapter.c
new file mode 100644
index 0000000..0f3e640
--- /dev/null
+++ b/plugins/daap/rb-dmap-container-db-adapter.c
@@ -0,0 +1,193 @@
+/*
+ * Container / Playlist database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "rb-playlist-manager.h"
+#include "rb-playlist-source.h"
+#include "rb-dmap-container-db-adapter.h"
+#include "rb-daap-container-record.h"
+
+#include <libdmapsharing/dmap.h>
+
+static guint next_playlist_id = 2;
+
+struct RBDMAPContainerDbAdapterPrivate {
+ RBPlaylistManager *playlist_manager;
+};
+
+typedef struct ForeachAdapterData {
+ gpointer data;
+ GHFunc func;
+} ForeachAdapterData;
+
+static guint find_by_id (gconstpointer a, gconstpointer b)
+{
+ return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "daap_id")) != GPOINTER_TO_UINT (b);
+
+}
+
+static DMAPContainerRecord *
+rb_dmap_container_db_adapter_lookup_by_id (DMAPContainerDb *db, guint id)
+{
+ gchar *name;
+ GList *playlists;
+ DMAPContainerRecord *fnval = NULL;
+
+ playlists = rb_playlist_manager_get_playlists (RB_DMAP_CONTAINER_DB_ADAPTER (db)->priv->playlist_manager);
+
+ if (playlists != NULL && playlists->data != NULL) {
+ GList *result;
+ result = g_list_find_custom (playlists, GINT_TO_POINTER (id), (GCompareFunc) find_by_id);
+ if (result != NULL && result->data != NULL) {
+ RBPlaylistSource *source;
+ source = RB_PLAYLIST_SOURCE (result->data);
+ g_object_get (source, "name", &name, NULL);
+ fnval = DMAP_CONTAINER_RECORD (rb_daap_container_record_new (name, source));
+ }
+ }
+
+ g_list_free (playlists);
+
+ return fnval;
+}
+
+static void
+foreach_adapter (RBPlaylistSource *entry, gpointer data)
+{
+ gchar *name;
+ DMAPContainerRecord *record;
+ ForeachAdapterData *foreach_adapter_data;
+
+ foreach_adapter_data = data;
+ g_object_get (entry, "name", &name, NULL);
+ record = DMAP_CONTAINER_RECORD (rb_daap_container_record_new (name, entry));
+
+ foreach_adapter_data->func (GINT_TO_POINTER (rb_daap_container_record_get_id (record)),
+ record,
+ foreach_adapter_data->data);
+
+ g_object_unref (record);
+}
+
+static void
+rb_dmap_container_db_adapter_foreach (DMAPContainerDb *db,
+ GHFunc func,
+ gpointer data)
+{
+ ForeachAdapterData *foreach_adapter_data;
+ GList *playlists;
+
+ playlists = rb_playlist_manager_get_playlists (RB_DMAP_CONTAINER_DB_ADAPTER (db)->priv->playlist_manager);
+
+ foreach_adapter_data = g_new (ForeachAdapterData, 1);
+ foreach_adapter_data->data = data;
+ foreach_adapter_data->func = func;
+ g_list_foreach (playlists, (GFunc) foreach_adapter, foreach_adapter_data);
+
+ g_list_free (playlists);
+ g_free (foreach_adapter_data);
+}
+
+static gint64
+rb_dmap_container_db_adapter_count (DMAPContainerDb *db)
+{
+ gint64 count = 0;
+ GList *playlists = rb_playlist_manager_get_playlists (
+ RB_DMAP_CONTAINER_DB_ADAPTER (db)->priv->playlist_manager);
+ count = g_list_length (playlists);
+ g_list_free (playlists);
+ return count;
+}
+
+static void
+rb_dmap_container_db_adapter_init (RBDMAPContainerDbAdapter *db)
+{
+ db->priv = RB_DMAP_CONTAINER_DB_ADAPTER_GET_PRIVATE (db);
+}
+
+static void
+rb_dmap_container_db_adapter_class_init (RBDMAPContainerDbAdapterClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (RBDMAPContainerDbAdapterPrivate));
+}
+
+static void
+rb_dmap_container_db_adapter_interface_init (gpointer iface, gpointer data)
+{
+ DMAPContainerDbInterface *dmap_db = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (dmap_db) == TYPE_DMAP_CONTAINER_DB);
+
+ dmap_db->lookup_by_id = rb_dmap_container_db_adapter_lookup_by_id;
+ dmap_db->foreach = rb_dmap_container_db_adapter_foreach;
+ dmap_db->count = rb_dmap_container_db_adapter_count;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBDMAPContainerDbAdapter, rb_dmap_container_db_adapter, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_CONTAINER_DB, rb_dmap_container_db_adapter_interface_init))
+
+static void
+assign_id (RBPlaylistManager *mgr,
+ RBSource *source)
+{
+ if (g_object_get_data (G_OBJECT (source), "daap_id") == NULL)
+ g_object_set_data (G_OBJECT (source), "daap_id", GUINT_TO_POINTER (next_playlist_id++));
+}
+
+RBDMAPContainerDbAdapter *
+rb_dmap_container_db_adapter_new (RBPlaylistManager *playlist_manager)
+{
+ RBDMAPContainerDbAdapter *db;
+ GList *playlists;
+
+ playlists = rb_playlist_manager_get_playlists (playlist_manager);
+
+ /* These IDs are DAAP-specific, so they are not a part of the
+ * general-purpose RBPlaylistSource class:
+ */
+ if (playlists != NULL && playlists->data != NULL) {
+ g_list_foreach (playlists, (GFunc) assign_id, NULL);
+ }
+
+ g_signal_connect (G_OBJECT (playlist_manager),
+ "playlist_created",
+ G_CALLBACK (assign_id),
+ NULL);
+
+ g_signal_connect (G_OBJECT (playlist_manager),
+ "playlist_added",
+ G_CALLBACK (assign_id),
+ NULL);
+
+ db = RB_DMAP_CONTAINER_DB_ADAPTER (g_object_new (RB_TYPE_DMAP_CONTAINER_DB_ADAPTER,
+ NULL));
+
+ db->priv->playlist_manager = playlist_manager;
+
+ return db;
+}
diff --git a/plugins/daap/rb-dmap-container-db-adapter.h b/plugins/daap/rb-dmap-container-db-adapter.h
new file mode 100644
index 0000000..160c80c
--- /dev/null
+++ b/plugins/daap/rb-dmap-container-db-adapter.h
@@ -0,0 +1,64 @@
+/*
+ * Container / playlist database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_DMAP_CONTAINER_DB_ADAPTER
+#define __RB_DMAP_CONTAINER_DB_ADAPTER
+
+#include <libdmapsharing/dmap.h>
+
+#include "rb-playlist-manager.h"
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DMAP_CONTAINER_DB_ADAPTER (rb_dmap_container_db_adapter_get_type ())
+#define RB_DMAP_CONTAINER_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER, RBDMAPContainerDbAdapter))
+#define RB_DMAP_CONTAINER_DB_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER, RBDMAPContainerDbAdapterClass))
+#define RB_IS_DMAP_CONTAINER_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER))
+#define RB_IS_DMAP_CONTAINER_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER_CLASS))
+#define RB_DMAP_CONTAINER_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER, RBDMAPContainerDbAdapterClass))
+#define RB_DMAP_CONTAINER_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DMAP_CONTAINER_DB_ADAPTER, RBDMAPContainerDbAdapterPrivate))
+
+typedef struct RBDMAPContainerDbAdapterPrivate RBDMAPContainerDbAdapterPrivate;
+
+typedef struct {
+ GObject parent;
+ RBDMAPContainerDbAdapterPrivate *priv;
+} RBDMAPContainerDbAdapter;
+
+typedef struct {
+ GObjectClass parent;
+} RBDMAPContainerDbAdapterClass;
+
+RBDMAPContainerDbAdapter *rb_dmap_container_db_adapter_new (
+ RBPlaylistManager *playlist_manager);
+GType rb_dmap_container_db_adapter_get_type (void);
+
+#endif /* _RB_DMAP_CONTAINER_DB_ADAPTER */
+
+G_END_DECLS
diff --git a/plugins/daap/rb-rhythmdb-dmap-db-adapter.c b/plugins/daap/rb-rhythmdb-dmap-db-adapter.c
new file mode 100644
index 0000000..b4370ce
--- /dev/null
+++ b/plugins/daap/rb-rhythmdb-dmap-db-adapter.c
@@ -0,0 +1,275 @@
+/*
+ * Database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "rhythmdb.h"
+#include "rb-rhythmdb-dmap-db-adapter.h"
+#include "rb-daap-record.h"
+
+#include <glib/gi18n.h>
+#include <libdmapsharing/dmap.h>
+
+struct RBRhythmDBDMAPDbAdapterPrivate {
+ RhythmDB *db;
+ RhythmDBEntryType type;
+};
+
+typedef struct ForeachAdapterData {
+ gpointer data;
+ GHFunc func;
+} ForeachAdapterData;
+
+static DMAPRecord *
+rb_rhythmdb_dmap_db_adapter_lookup_by_id (const DMAPDb *db, guint id)
+{
+ RhythmDBEntry *entry;
+
+ g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
+
+ entry = rhythmdb_entry_lookup_by_id (
+ RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
+ id);
+
+ return DMAP_RECORD (rb_daap_record_new (entry));
+}
+
+static void
+foreach_adapter (RhythmDBEntry *entry, gpointer data)
+{
+ ulong id;
+ DMAPRecord *record;
+ ForeachAdapterData *foreach_adapter_data;
+
+ id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
+ foreach_adapter_data = data;
+ record = DMAP_RECORD (rb_daap_record_new (entry));
+
+ foreach_adapter_data->func (GUINT_TO_POINTER (id),
+ record,
+ foreach_adapter_data->data);
+
+ g_object_unref (record);
+}
+
+static void
+rb_rhythmdb_dmap_db_adapter_foreach (const DMAPDb *db,
+ GHFunc func,
+ gpointer data)
+{
+ ForeachAdapterData *foreach_adapter_data;
+
+ g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
+
+ foreach_adapter_data = g_new (ForeachAdapterData, 1);
+ foreach_adapter_data->data = data;
+ foreach_adapter_data->func = func;
+
+ rhythmdb_entry_foreach_by_type (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
+ RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->type,
+ (GFunc) foreach_adapter,
+ foreach_adapter_data);
+
+ g_free (foreach_adapter_data);
+}
+
+static gint64
+rb_rhythmdb_dmap_db_adapter_count (const DMAPDb *db)
+{
+ g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
+ return rhythmdb_entry_count_by_type (
+ RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
+ RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->type);
+}
+
+static void
+entry_set_string_prop (RhythmDB *db,
+ RhythmDBEntry *entry,
+ RhythmDBPropType propid,
+ const char *str)
+{
+ GValue value = {0,};
+ const gchar *tmp;
+
+ if (str == NULL || *str == '\0' || !g_utf8_validate (str, -1, NULL)) {
+ tmp = _("Unknown");
+ } else {
+ tmp = str;
+ }
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, tmp);
+ rhythmdb_entry_set (RHYTHMDB (db), entry, propid, &value);
+ g_value_unset (&value);
+}
+
+static guint
+rb_rhythmdb_dmap_db_adapter_add (DMAPDb *db, DMAPRecord *record)
+{
+ gchar *uri = NULL;
+ const gchar *title = NULL;
+ const gchar *album = NULL;
+ const gchar *artist = NULL;
+ const gchar *format = NULL;
+ const gchar *genre = NULL;
+ gint length = 0;
+ gint track = 0;
+ gint disc = 0;
+ gint year = 0;
+ gint filesize = 0;
+ gint bitrate = 0;
+ GValue value = { 0, };
+ RhythmDBEntry *entry = NULL;
+ RBRhythmDBDMAPDbAdapterPrivate *priv = RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv;
+
+ g_assert (priv->db != NULL);
+
+ g_object_get (record,
+ "location", &uri,
+ "year", &year,
+ "track", &track,
+ "disc", &disc,
+ "bitrate", &bitrate,
+ "duration", &length,
+ "filesize", &filesize,
+ "format", &format,
+ "title", &title,
+ "daap.songalbum", &album,
+ "daap.songartist", &artist,
+ "daap.songgenre", &genre,
+ NULL);
+
+ entry = rhythmdb_entry_new (priv->db, priv->type, uri);
+
+ if (entry == NULL) {
+ g_warning ("cannot create entry for daap track %s", uri);
+ return FALSE;
+ }
+
+ /* year */
+ if (year != 0) {
+ GDate date;
+ gulong julian;
+
+ /* create dummy date with given year */
+ g_date_set_dmy (&date, 1, G_DATE_JANUARY, year);
+ julian = g_date_get_julian (&date);
+
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value,julian);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DATE, &value);
+ g_value_unset (&value);
+ }
+
+ /* track number */
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value,(gulong)track);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &value);
+ g_value_unset (&value);
+
+ /* disc number */
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value,(gulong)disc);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
+ g_value_unset (&value);
+
+ /* bitrate */
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value,(gulong)bitrate);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_BITRATE, &value);
+ g_value_unset (&value);
+
+ /* length */
+ g_value_init (&value, G_TYPE_ULONG);
+ g_value_set_ulong (&value,(gulong)length);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DURATION, &value);
+ g_value_unset (&value);
+
+ /* file size */
+ g_value_init (&value, G_TYPE_UINT64);
+ g_value_set_uint64(&value,(gint64)filesize);
+ rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_FILE_SIZE, &value);
+ g_value_unset (&value);
+
+ /* title */
+ entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_TITLE, title);
+
+ /* album */
+ entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ALBUM, album);
+
+ /* artist */
+ entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ARTIST, artist);
+
+ /* genre */
+ entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_GENRE, genre);
+
+ rhythmdb_commit (priv->db);
+
+ return rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
+}
+
+static void
+rb_rhythmdb_dmap_db_adapter_init (RBRhythmDBDMAPDbAdapter *db)
+{
+ db->priv = RB_RHYTHMDB_DMAP_DB_ADAPTER_GET_PRIVATE (db);
+}
+
+static void
+rb_rhythmdb_dmap_db_adapter_class_init (RBRhythmDBDMAPDbAdapterClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (RBRhythmDBDMAPDbAdapterPrivate));
+}
+
+static void
+rb_rhythmdb_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
+{
+ DMAPDbInterface *dmap_db = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (dmap_db) == TYPE_DMAP_DB);
+
+ dmap_db->add = rb_rhythmdb_dmap_db_adapter_add;
+ dmap_db->lookup_by_id = rb_rhythmdb_dmap_db_adapter_lookup_by_id;
+ dmap_db->foreach = rb_rhythmdb_dmap_db_adapter_foreach;
+ dmap_db->count = rb_rhythmdb_dmap_db_adapter_count;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBRhythmDBDMAPDbAdapter, rb_rhythmdb_dmap_db_adapter, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_DB, rb_rhythmdb_dmap_db_adapter_interface_init))
+
+RBRhythmDBDMAPDbAdapter *
+rb_rhythmdb_dmap_db_adapter_new (RhythmDB *rdb, RhythmDBEntryType type)
+{
+ RBRhythmDBDMAPDbAdapter *db;
+
+ db = RB_RHYTHMDB_DMAP_DB_ADAPTER (g_object_new (RB_TYPE_DMAP_DB_ADAPTER,
+ NULL));
+
+ db->priv->db = rdb;
+ db->priv->type = type;
+
+ return db;
+}
diff --git a/plugins/daap/rb-rhythmdb-dmap-db-adapter.h b/plugins/daap/rb-rhythmdb-dmap-db-adapter.h
new file mode 100644
index 0000000..536718d
--- /dev/null
+++ b/plugins/daap/rb-rhythmdb-dmap-db-adapter.h
@@ -0,0 +1,61 @@
+/*
+ * Database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_RHYTHMDB_DMAP_DB_ADAPTER
+#define __RB_RHYTHMDB_DMAP_DB_ADAPTER
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DMAP_DB_ADAPTER (rb_rhythmdb_dmap_db_adapter_get_type ())
+#define RB_RHYTHMDB_DMAP_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBDMAPDbAdapter))
+#define RB_RHYTHMDB_DMAP_DB_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBDMAPDbAdapterClass))
+#define RB_IS_DMAP_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DMAP_DB_ADAPTER))
+#define RB_IS_DMAP_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DMAP_DB_ADAPTER_CLASS))
+#define RB_RHYTHMDB_DMAP_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBDMAPDbAdapterClass))
+#define RB_RHYTHMDB_DMAP_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBDMAPDbAdapterPrivate))
+
+typedef struct RBRhythmDBDMAPDbAdapterPrivate RBRhythmDBDMAPDbAdapterPrivate;
+
+typedef struct {
+ GObject parent;
+ RBRhythmDBDMAPDbAdapterPrivate *priv;
+} RBRhythmDBDMAPDbAdapter;
+
+typedef struct {
+ GObjectClass parent;
+} RBRhythmDBDMAPDbAdapterClass;
+
+RBRhythmDBDMAPDbAdapter *rb_rhythmdb_dmap_db_adapter_new (RhythmDB *db, RhythmDBEntryType type);
+GType rb_rhythmdb_dmap_db_adapter_get_type (void);
+
+#endif /* _RB_RHYTHMDB_DMAP_DB_ADAPTER */
+
+G_END_DECLS
diff --git a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c
new file mode 100644
index 0000000..9607a39
--- /dev/null
+++ b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.c
@@ -0,0 +1,156 @@
+/*
+ * Database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "rhythmdb-query-model.h"
+#include "rb-rhythmdb-query-model-dmap-db-adapter.h"
+#include "rb-daap-record.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <libdmapsharing/dmap.h>
+
+struct RBRhythmDBQueryModelDMAPDbAdapterPrivate {
+ RhythmDBQueryModel *model;
+};
+
+typedef struct ForeachAdapterData {
+ gpointer data;
+ GHFunc func;
+} ForeachAdapterData;
+
+static DMAPRecord *
+rb_rhythmdb_query_model_dmap_db_adapter_lookup_by_id (const DMAPDb *db,
+ guint id)
+{
+ g_error ("Not implemented");
+ return NULL;
+}
+
+static gboolean
+foreach_adapter (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ ulong id;
+ DMAPRecord *record;
+ RhythmDBEntry *entry;
+ ForeachAdapterData *foreach_adapter_data;
+
+ gtk_tree_model_get (model, iter, 0, &entry, -1);
+
+ id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
+ foreach_adapter_data = data;
+ record = DMAP_RECORD (rb_daap_record_new (entry));
+
+ foreach_adapter_data->func (GUINT_TO_POINTER (id),
+ record,
+ foreach_adapter_data->data);
+
+ g_object_unref (record);
+ rhythmdb_entry_unref (entry);
+
+ return FALSE;
+}
+
+static void
+rb_rhythmdb_query_model_dmap_db_adapter_foreach (const DMAPDb *db,
+ GHFunc func,
+ gpointer data)
+{
+ ForeachAdapterData *foreach_adapter_data;
+
+ g_assert (RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (db)->priv->model != NULL);
+
+ foreach_adapter_data = g_new (ForeachAdapterData, 1);
+ foreach_adapter_data->data = data;
+ foreach_adapter_data->func = func;
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (db)->priv->model),
+ (GtkTreeModelForeachFunc) foreach_adapter,
+ foreach_adapter_data);
+
+ g_free (foreach_adapter_data);
+}
+
+static gint64
+rb_rhythmdb_query_model_dmap_db_adapter_count (const DMAPDb *db)
+{
+ g_assert (RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (db)->priv->model != NULL);
+ return gtk_tree_model_iter_n_children (
+ GTK_TREE_MODEL (RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (db)->priv->model), NULL);
+}
+
+static guint
+rb_rhythmdb_query_model_dmap_db_adapter_add (DMAPDb *db, DMAPRecord *record)
+{
+ g_error ("Not implemented");
+ return 0;
+}
+
+static void
+rb_rhythmdb_query_model_dmap_db_adapter_init (RBRhythmDBQueryModelDMAPDbAdapter *db)
+{
+ db->priv = RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_PRIVATE (db);
+}
+
+static void
+rb_rhythmdb_query_model_dmap_db_adapter_class_init (RBRhythmDBQueryModelDMAPDbAdapterClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (RBRhythmDBQueryModelDMAPDbAdapterPrivate));
+}
+
+static void
+rb_rhythmdb_query_model_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
+{
+ DMAPDbInterface *dmap_db = iface;
+
+ g_assert (G_TYPE_FROM_INTERFACE (dmap_db) == TYPE_DMAP_DB);
+
+ dmap_db->add = rb_rhythmdb_query_model_dmap_db_adapter_add;
+ dmap_db->lookup_by_id = rb_rhythmdb_query_model_dmap_db_adapter_lookup_by_id;
+ dmap_db->foreach = rb_rhythmdb_query_model_dmap_db_adapter_foreach;
+ dmap_db->count = rb_rhythmdb_query_model_dmap_db_adapter_count;
+}
+
+G_DEFINE_TYPE_WITH_CODE (RBRhythmDBQueryModelDMAPDbAdapter, rb_rhythmdb_query_model_dmap_db_adapter, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TYPE_DMAP_DB, rb_rhythmdb_query_model_dmap_db_adapter_interface_init))
+
+RBRhythmDBQueryModelDMAPDbAdapter *
+rb_rhythmdb_query_model_dmap_db_adapter_new (RhythmDBQueryModel *model)
+{
+ RBRhythmDBQueryModelDMAPDbAdapter *db;
+
+ db = RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER (g_object_new (RB_TYPE_DMAP_DB_ADAPTER,
+ NULL));
+
+ db->priv->model = model;
+
+ return db;
+}
diff --git a/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h
new file mode 100644
index 0000000..d35147a
--- /dev/null
+++ b/plugins/daap/rb-rhythmdb-query-model-dmap-db-adapter.h
@@ -0,0 +1,61 @@
+/*
+ * Database adapter class for DMAP sharing
+ *
+ * Copyright (C) 2008 W. Michael Petullo <mike flyn org>
+ *
+ * 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.
+ *
+ * The Rhythmbox authors hereby grant 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,
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER
+#define __RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER
+
+#include <libdmapsharing/dmap.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_DMAP_DB_ADAPTER (rb_rhythmdb_query_model_dmap_db_adapter_get_type ())
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapter))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
+#define RB_IS_DMAP_DB_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DMAP_DB_ADAPTER))
+#define RB_IS_DMAP_DB_ADAPTER_CLASS (k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DMAP_DB_ADAPTER_CLASS))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterClass))
+#define RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_DMAP_DB_ADAPTER, RBRhythmDBQueryModelDMAPDbAdapterPrivate))
+
+typedef struct RBRhythmDBQueryModelDMAPDbAdapterPrivate RBRhythmDBQueryModelDMAPDbAdapterPrivate;
+
+typedef struct {
+ GObject parent;
+ RBRhythmDBQueryModelDMAPDbAdapterPrivate *priv;
+} RBRhythmDBQueryModelDMAPDbAdapter;
+
+typedef struct {
+ GObjectClass parent;
+} RBRhythmDBQueryModelDMAPDbAdapterClass;
+
+RBRhythmDBQueryModelDMAPDbAdapter *rb_rhythmdb_query_model_dmap_db_adapter_new (RhythmDBQueryModel *db);
+GType rb_rhythmdb_query_model_dmap_db_adapter_get_type (void);
+
+#endif /* _RB_RHYTHMDB_QUERY_MODEL_DMAP_DB_ADAPTER */
+
+G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]