Index: player/rb-player-gst.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/player/rb-player-gst.c,v
retrieving revision 1.38
diff -u -r1.38 rb-player-gst.c
--- player/rb-player-gst.c	29 Jul 2005 14:53:09 -0000	1.38
+++ player/rb-player-gst.c	31 Jul 2005 04:35:18 -0000
@@ -287,31 +287,52 @@
 }
 
 static void
-deep_notify_cb (GstElement *element, GstElement *orig,
-	        GParamSpec *pspec, RBPlayer *player)
+process_tag (const GstTagList *list, const gchar *tag, RBPlayer *player)
 {
-	if (!(pspec->flags & G_PARAM_READABLE)) return;
-
-	if (strcmp (pspec->name, "iradio-title") == 0) {
-		RBPlayerSignal *signal;
-
-		rb_debug ("caught deep notify for iradio-title");
+	int count;
+	RBMetaDataField field;
+	RBPlayerSignal *signal;
+	const GValue *val;
+	GValue *newval;
 
-		signal = g_new0 (RBPlayerSignal, 1);
+	count = gst_tag_list_get_tag_size (list, tag);
+	if (count < 1)
+		return;
+	
+	/* only handle the subset of fields we use for iradio */
+	if (!strcmp (tag, GST_TAG_TITLE))
+		field = RB_METADATA_FIELD_TITLE;
+	else if (!strcmp (tag, GST_TAG_GENRE))
+		field = RB_METADATA_FIELD_GENRE;
+	else if (!strcmp (tag, GST_TAG_COMMENT))
+		field = RB_METADATA_FIELD_COMMENT;
+	else
+		return;
 
-		signal->type = INFO;
-		signal->info_field = RB_METADATA_FIELD_TITLE;
-		signal->info = g_new0 (GValue, 1);
-		g_value_init (signal->info, G_TYPE_STRING); 
-		g_object_get_property (G_OBJECT (orig), pspec->name, signal->info);
+	/* of those, all are strings */
+	newval = g_new0 (GValue, 1);
+	g_value_init (newval, G_TYPE_STRING);
+	val = gst_tag_list_get_value_index (list, tag, 0);
+	if (!g_value_transform (val, newval)) {
+		rb_debug ("Could not transform tag value type %s into string",
+			  g_type_name (G_VALUE_TYPE (val)));
+		return;
+	}
 
-		signal->object = player;
+	signal = g_new0 (RBPlayerSignal, 1);
+	signal->object = player;
+	signal->info_field = field;
+	signal->info = newval;
+	signal->type = INFO;
 
-		g_object_ref (G_OBJECT (player));
+	g_object_ref (G_OBJECT (player));
+	g_idle_add ((GSourceFunc) emit_signal_idle, signal);
+}
 
-		g_idle_add ((GSourceFunc) emit_signal_idle, signal);
-		return;
-	}
+static void
+found_tag_cb (GObject *pipeline, GstElement *source, GstTagList *tags, RBPlayer *player)
+{
+	gst_tag_list_foreach (tags, (GstTagForeachFunc) process_tag, player);
 }
 
 static void
@@ -344,8 +365,8 @@
 		goto missing_element;
 	}
 	g_signal_connect_object (G_OBJECT (mp->priv->playbin),
-				 "deep_notify",
-				 G_CALLBACK (deep_notify_cb),
+				 "found_tag",
+				 G_CALLBACK (found_tag_cb),
 				 mp, 0);
 
 	mp->priv->buffering_signal_id =
Index: shell/rb-shell-player.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell-player.c,v
retrieving revision 1.158
diff -u -r1.158 rb-shell-player.c
--- shell/rb-shell-player.c	29 Jul 2005 14:53:10 -0000	1.158
+++ shell/rb-shell-player.c	31 Jul 2005 04:35:20 -0000
@@ -2129,7 +2129,9 @@
         RBShellPlayer *player = RB_SHELL_PLAYER (data);
         RBEntryView *songs;
         RhythmDBEntry *entry;
+        RhythmDBPropType entry_field = 0;
         gboolean changed = FALSE;
+        gboolean set_field = FALSE;
         rb_debug ("info: %d", field);
 
         /* Sanity check, this signal may come in after we stopped the
@@ -2150,26 +2152,80 @@
                 goto out_unlock;
         }
 
-        switch (field) {
-        case RB_METADATA_FIELD_TITLE:
-        {
-                char *song = g_value_dup_string (value);
-                if (!g_utf8_validate (song, -1, NULL)) {
-                        g_warning ("Invalid UTF-8 from internet radio: %s", song);
-                        goto out_unlock;
-                }
-
-                if ((!song && player->priv->song)
-                    || !player->priv->song
-                    || strcmp (song, player->priv->song)) {
-                        changed = TRUE;
-                        g_free (player->priv->song);
-                        player->priv->song = song;
-                } else {
-                        g_free (song);
+	if (entry->type != RHYTHMDB_ENTRY_TYPE_IRADIO_STATION) {
+		rb_debug ("Got info_available but entry isn't an iradio station");
+		goto out_unlock;
+	}
+
+	switch (field)	{
+	case RB_METADATA_FIELD_TITLE:
+	{
+		char *song = g_value_dup_string (value);
+		if (!g_utf8_validate (song, -1, NULL)) {
+			g_warning ("Invalid UTF-8 from internet radio: %s", song);
+			goto out_unlock;
 		}
-                break;
-        }
+
+		if ((!song && player->priv->song)
+		    || !player->priv->song
+		    || strcmp (song, player->priv->song)) {
+			changed = TRUE;
+			g_free (player->priv->song);
+			player->priv->song = song;
+		}
+		else
+			g_free (song);
+		break;
+	}
+	case RB_METADATA_FIELD_GENRE:
+	{
+		const char *genre = g_value_get_string (value);
+		const char *existing;
+		if (!g_utf8_validate (genre, -1, NULL)) {
+			g_warning ("Invalid UTF-8 from internet radio: %s", genre);
+			goto out_unlock;
+		}
+
+		/* check if the db entry already has a genre; if so, don't change it */
+		existing = rb_refstring_get (entry->genre);
+		if ((existing == NULL) || 
+		    (strcmp (existing, "") == 0) ||
+		    (strcmp (existing, _("Unknown")) == 0)) {
+			entry_field = RHYTHMDB_PROP_GENRE;
+			rb_debug ("setting genre of iradio station to %s", genre);
+			set_field = TRUE;
+		} else {
+			rb_debug ("iradio station already has genre: %s; ignoring %s", existing, genre);
+		}
+		break;
+	}
+	case RB_METADATA_FIELD_COMMENT:
+	{
+		const char *name = g_value_get_string (value);
+		const char *existing;
+		if (!g_utf8_validate (name, -1, NULL)) {
+			g_warning ("Invalid UTF-8 from internet radio: %s", name);
+			goto out_unlock;
+		}
+
+		/* check if the db entry already has a title; if so, don't change it.
+		 * consider title==URI to be the same as no title, since that's what
+		 * happens for stations imported by DnD or commandline args.
+		 * if the station title really is the same as the URI, then surely
+		 * the station title in the stream metadata will say that too..
+		 */
+		existing = rb_refstring_get (entry->title);
+		if ((existing == NULL) || 
+		    (strcmp(existing, "") == 0) || 
+		    (strcmp(existing, entry->location) == 0)) {
+			entry_field = RHYTHMDB_PROP_TITLE;
+			rb_debug ("setting title of iradio station to %s", name);
+			set_field = TRUE;
+		} else {
+			rb_debug ("iradio station already has title: %s; ignoring %s", existing, name);
+		}
+		break;
+	}
 	default:
 		break;
 	}
@@ -2177,6 +2233,11 @@
 	if (changed)
 		rb_shell_player_sync_with_source (player);
 
+	if (set_field && entry_field != 0) {
+		rhythmdb_entry_sync (player->priv->db, entry, entry_field, value);
+		rhythmdb_commit (player->priv->db);
+	}
+
  out_unlock:
 	GDK_THREADS_LEAVE ();
 }
