[rhythmbox] audioscrobbler: reorganise, comment and tidy various pieces of code



commit 35f8788da351bcf0d85873b7a9d46e4950f4ade8
Author: Jamie Nicol <jamie thenicols net>
Date:   Sat Jul 17 15:37:24 2010 +0100

    audioscrobbler: reorganise, comment and tidy various pieces of code

 plugins/audioscrobbler/rb-audioscrobbler-account.c |   53 +-
 .../rb-audioscrobbler-profile-source.c             |  520 ++++++++++----------
 .../rb-audioscrobbler-radio-source.c               |  312 ++++++------
 3 files changed, 442 insertions(+), 443 deletions(-)
---
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index 91f2825..9c26e6d 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -66,6 +66,11 @@ struct _RBAudioscrobblerAccountPrivate
 
 #define RB_AUDIOSCROBBLER_ACCOUNT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_ACCOUNT, RBAudioscrobblerAccountPrivate))
 
+static void          rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass);
+static void          rb_audioscrobbler_account_init (RBAudioscrobblerAccount *account);
+static void          rb_audioscrobbler_account_constructed (GObject *object);
+static void          rb_audioscrobbler_account_dispose (GObject *object);
+static void          rb_audioscrobbler_account_finalize (GObject *object);
 static void	     rb_audioscrobbler_account_get_property (GObject *object,
                                                              guint prop_id,
                                                              GValue *value,
@@ -74,12 +79,12 @@ static void	     rb_audioscrobbler_account_set_property (GObject *object,
                                                              guint prop_id,
                                                              const GValue *value,
                                                              GParamSpec *pspec);
-static void          rb_audioscrobbler_account_dispose (GObject *object);
-static void          rb_audioscrobbler_account_finalize (GObject *object);
 
+/* load/save session to file to avoid having to reauthenticate */
 static void          rb_audioscrobbler_account_load_session_settings (RBAudioscrobblerAccount *account);
 static void          rb_audioscrobbler_account_save_session_settings (RBAudioscrobblerAccount *account);
 
+/* private functions used in authentication process */
 static void          rb_audioscrobbler_account_cancel_session (RBAudioscrobblerAccount *account);
 static void          rb_audioscrobbler_account_request_token (RBAudioscrobblerAccount *account);
 static void          rb_audioscrobbler_account_got_token_cb (SoupSession *session,
@@ -108,15 +113,12 @@ static guint rb_audioscrobbler_account_signals[LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (RBAudioscrobblerAccount, rb_audioscrobbler_account, G_TYPE_OBJECT)
 
-static void
-rb_audioscrobbler_account_constructed (GObject *object)
+RBAudioscrobblerAccount *
+rb_audioscrobbler_account_new (RBAudioscrobblerService *service)
 {
-	RBAudioscrobblerAccount *account;
-
-	RB_CHAIN_GOBJECT_METHOD (rb_audioscrobbler_account_parent_class, constructed, object);
-	account = RB_AUDIOSCROBBLER_ACCOUNT (object);
-
-	rb_audioscrobbler_account_load_session_settings (account);
+	return g_object_new (RB_TYPE_AUDIOSCROBBLER_ACCOUNT,
+                             "service", service,
+	                     NULL);
 }
 
 static void
@@ -158,11 +160,11 @@ rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass)
 	g_object_class_install_property (object_class,
 	                                 PROP_LOGIN_STATUS,
 	                                 g_param_spec_enum ("login-status",
-	                                                     "Login Status",
-	                                                     "Login status",
-	                                                     RB_TYPE_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS,
-	                                                     RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT,
-                                                             G_PARAM_READABLE));
+	                                                    "Login Status",
+	                                                    "Login status",
+	                                                    RB_TYPE_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS,
+	                                                    RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT,
+                                                            G_PARAM_READABLE));
 
 	/**
 	 * RBAudioscrobblerAccount::login-status-changed:
@@ -199,6 +201,17 @@ rb_audioscrobbler_account_init (RBAudioscrobblerAccount *account)
 }
 
 static void
+rb_audioscrobbler_account_constructed (GObject *object)
+{
+	RBAudioscrobblerAccount *account;
+
+	RB_CHAIN_GOBJECT_METHOD (rb_audioscrobbler_account_parent_class, constructed, object);
+	account = RB_AUDIOSCROBBLER_ACCOUNT (object);
+
+	rb_audioscrobbler_account_load_session_settings (account);
+}
+
+static void
 rb_audioscrobbler_account_dispose (GObject *object)
 {
 	RBAudioscrobblerAccount *account = RB_AUDIOSCROBBLER_ACCOUNT (object);
@@ -234,14 +247,6 @@ rb_audioscrobbler_account_finalize (GObject *object)
 	G_OBJECT_CLASS (rb_audioscrobbler_account_parent_class)->finalize (object);
 }
 
-RBAudioscrobblerAccount *
-rb_audioscrobbler_account_new (RBAudioscrobblerService *service)
-{
-	return g_object_new (RB_TYPE_AUDIOSCROBBLER_ACCOUNT,
-                             "service", service,
-	                     NULL);
-}
-
 static void
 rb_audioscrobbler_account_get_property (GObject *object,
                                         guint prop_id,
@@ -425,7 +430,6 @@ rb_audioscrobbler_account_save_session_settings (RBAudioscrobblerAccount *accoun
 	g_object_unref (out_file);
 }
 
-/* public authentication functions */
 void
 rb_audioscrobbler_account_authenticate (RBAudioscrobblerAccount *account)
 {
@@ -466,7 +470,6 @@ rb_audioscrobbler_account_notify_of_auth_error (RBAudioscrobblerAccount *account
 	               0, account->priv->login_status);
 }
 
-/* private authentication functions */
 static void
 rb_audioscrobbler_account_cancel_session (RBAudioscrobblerAccount *account)
 {
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index 7e71652..a471c63 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -53,18 +53,22 @@ struct _RBAudioscrobblerProfileSourcePrivate {
 	RBAudioscrobblerAccount *account;
 	RBAudioscrobbler *audioscrobbler;
 
+	/* Used to request the user's profile data */
 	RBAudioscrobblerUser *user;
 
+	/* List of radio stations owned by this source */
 	GList *radio_sources;
 
 	guint scrobbling_enabled_notification_id;
 
 	GtkWidget *main_vbox;
 
+	/* Login related UI */
 	GtkWidget *login_bar;
 	GtkWidget *login_status_label;
 	GtkWidget *login_response_button;
 
+	/* Profile UI */
 	GtkWidget *profile_vbox;
 
 	GtkWidget *user_info_area;
@@ -74,15 +78,18 @@ struct _RBAudioscrobblerProfileSourcePrivate {
 	GtkWidget *scrobbling_enabled_check;
 	GtkWidget *view_profile_link;
 
+	/* Scrobbler statistics */
 	GtkWidget *scrobbler_status_msg_label;
 	GtkWidget *scrobbler_queue_count_label;
 	GtkWidget *scrobbler_submit_count_label;
 	GtkWidget *scrobbler_submit_time_label;
 
+	/* Station creation UI */
 	GtkWidget *station_creator_type_combo;
 	GtkWidget *station_creator_arg_label;
 	GtkWidget *station_creator_arg_entry;
 
+	/* Profile data lists */
 	GtkWidget *recent_tracks_area;
 	GtkWidget *recent_tracks_table;
 	GtkWidget *top_tracks_area;
@@ -116,42 +123,56 @@ static void rb_audioscrobbler_profile_source_set_property (GObject *object,
                                                            const GValue *value,
                                                            GParamSpec *pspec);
 
+/* UI initialisation functions */
 static void rb_audioscrobbler_profile_source_init_login_ui (RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_init_profile_ui (RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_init_actions (RBAudioscrobblerProfileSource *source);
 
+/* login related callbacks */
 static void rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
                                                                  gint response_id,
-                                                                 gpointer user_data);
+                                                                 RBAudioscrobblerProfileSource *source);
 void rb_audioscrobbler_profile_source_logout_button_clicked_cb (GtkButton *button,
-                                                                gpointer user_data);
+                                                                RBAudioscrobblerProfileSource *source);
+static void rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount *account,
+                                                                     RBAudioscrobblerAccountLoginStatus status,
+                                                                     RBAudioscrobblerProfileSource *source);
+
+/* scrobbling enabled preference */
 void rb_audioscrobbler_profile_source_scrobbling_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                                                           gpointer user_data);
+                                                                           RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_scrobbling_enabled_changed_cb (GConfClient *client,
                                                                             guint cnxn_id,
                                                                             GConfEntry *entry,
                                                                             RBAudioscrobblerProfileSource *source);
 
-static void rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount *account,
-                                                                     RBAudioscrobblerAccountLoginStatus status,
-                                                                     gpointer user_data);
-
+/* callbacks from scrobbler object */
 static void rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
-                                                                                gpointer user_data);
+                                                                                RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb (RBAudioscrobbler *audioscrobbler,
                                                                               const char *status_msg,
                                                                               guint queue_count,
                                                                               guint submit_count,
                                                                               const char *submit_time,
-                                                                              gpointer user_data);
+                                                                              RBAudioscrobblerProfileSource *source);
+
 static void rb_audioscrobbler_profile_source_playing_song_changed_cb (RBShellPlayer *player,
-                                                                     RhythmDBEntry *entry,
-                                                                     RBAudioscrobblerProfileSource *source);
+                                                                      RhythmDBEntry *entry,
+                                                                      RBAudioscrobblerProfileSource *source);
+
+/* GtkAction callbacks */
+static void rb_audioscrobbler_profile_source_love_track_action_cb (GtkAction *action,
+                                                                   RBAudioscrobblerProfileSource *source);
+static void rb_audioscrobbler_profile_source_ban_track_action_cb (GtkAction *action,
+                                                                  RBAudioscrobblerProfileSource *source);
 
+/* Radio station creation UI callbacks */
 static void rb_audioscrobbler_profile_source_station_creator_type_combo_changed_cb (GtkComboBox *combo_box,
                                                                                     RBAudioscrobblerProfileSource *source);
 void rb_audioscrobbler_profile_source_station_creator_button_clicked_cb (GtkButton *button,
                                                                          RBAudioscrobblerProfileSource *source);
+
+/* radio station creation/deletion */
 static void rb_audioscrobbler_profile_source_load_radio_stations (RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_save_radio_stations (RBAudioscrobblerProfileSource *source);
 static RBSource *rb_audioscrobbler_profile_source_add_radio_station (RBAudioscrobblerProfileSource *source,
@@ -161,25 +182,27 @@ static void rb_audioscrobbler_profile_source_radio_station_name_changed_cb (RBAu
                                                                             GParamSpec *spec,
                                                                             RBAudioscrobblerProfileSource *source);
 
+/* callbacks from user profile data requests */
 static void rb_audioscrobbler_profile_source_user_info_updated_cb (RBAudioscrobblerUser *user,
                                                                    RBAudioscrobblerUserData *info,
-                                                                   gpointer user_data);
+                                                                   RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_recent_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                                        GPtrArray *recent_tracks,
-                                                                       gpointer user_data);
+                                                                       RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_top_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                                     GPtrArray *top_tracks,
-                                                                    gpointer user_data);
+                                                                    RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_loved_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                                       GPtrArray *loved_tracks,
-                                                                      gpointer user_data);
+                                                                      RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_top_artists_updated_cb (RBAudioscrobblerUser *user,
                                                                      GPtrArray *top_artists,
-                                                                     gpointer user_data);
+                                                                     RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_recommended_artists_updated_cb (RBAudioscrobblerUser *user,
                                                                              GPtrArray *recommended_artists,
-                                                                             gpointer user_data);
+                                                                             RBAudioscrobblerProfileSource *source);
 
+/* UI creation for profile data lists, eg top artists, loved tracks */
 static void rb_audioscrobbler_profile_source_set_user_list (RBAudioscrobblerProfileSource *source,
                                                             GtkWidget *list_table,
                                                             GPtrArray *list_data);
@@ -187,29 +210,24 @@ static GtkWidget *rb_audioscrobbler_profile_source_create_list_button (RBAudiosc
                                                                        RBAudioscrobblerUserData *data);
 static GtkWidget *rb_audioscrobbler_profile_source_create_popup_menu (RBAudioscrobblerProfileSource *source,
                                                                       RBAudioscrobblerUserData *data);
-static void rb_audioscrobbler_profile_source_list_item_clicked_cb (GtkButton *button, gpointer user_data);
-static void rb_audioscrobbler_profile_source_list_item_view_url_activated_cb (GtkMenuItem *menuitem,
-                                                                              gpointer user_data);
-static void rb_audioscrobbler_profile_source_list_item_listen_similar_artists_activated_cb (GtkMenuItem *menuitem,
-                                                                                            gpointer user_data);
-static void rb_audioscrobbler_profile_source_list_item_listen_top_fans_activated_cb (GtkMenuItem *menuitem,
-                                                                                     gpointer user_data);
-
 static void rb_audioscrobbler_profile_source_list_table_pack_start (GtkTable *list_table, GtkWidget *item);
 void rb_audioscrobbler_profile_source_list_layout_size_allocate_cb (GtkWidget *layout,
                                                                     GtkAllocation *allocation,
                                                                     gpointer user_data);
 
-static void rb_audioscrobbler_profile_source_love_track_action_cb (GtkAction *action,
-                                                                   RBAudioscrobblerProfileSource *source);
-static void rb_audioscrobbler_profile_source_ban_track_action_cb (GtkAction *action,
-                                                                  RBAudioscrobblerProfileSource *source);
+/* callbacks from data list buttons and related popup menus */
+static void rb_audioscrobbler_profile_source_list_item_clicked_cb (GtkButton *button, RBAudioscrobblerProfileSource *source);
+static void rb_audioscrobbler_profile_source_list_item_view_url_activated_cb (GtkMenuItem *menuitem,
+                                                                              RBAudioscrobblerProfileSource *source);
+static void rb_audioscrobbler_profile_source_list_item_listen_similar_artists_activated_cb (GtkMenuItem *menuitem,
+                                                                                            RBAudioscrobblerProfileSource *source);
+static void rb_audioscrobbler_profile_source_list_item_listen_top_fans_activated_cb (GtkMenuItem *menuitem,
+                                                                                     RBAudioscrobblerProfileSource *source);
 
+/* RBSource implementations */
 static GList *impl_get_ui_actions (RBSource *asource);
 static void impl_delete_thyself (RBSource *asource);
 
-
-
 enum {
 	PROP_0,
 	PROP_SERVICE
@@ -598,10 +616,8 @@ rb_audioscrobbler_profile_source_init_actions (RBAudioscrobblerProfileSource *so
 static void
 rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
                                                      gint response_id,
-                                                     gpointer user_data)
+                                                     RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	switch (rb_audioscrobbler_account_get_login_status (source->priv->account)) {
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT:
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR:
@@ -620,70 +636,16 @@ rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
 
 void
 rb_audioscrobbler_profile_source_logout_button_clicked_cb (GtkButton *button,
-                                                           gpointer user_data)
+                                                           RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	rb_audioscrobbler_account_logout (source->priv->account);
 }
 
-void
-rb_audioscrobbler_profile_source_scrobbling_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
-                                                                      gpointer user_data)
-{
-	RBAudioscrobblerProfileSource *source;
-	char *conf_key;
-
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-	conf_key = g_strdup_printf (CONF_AUDIOSCROBBLER_ENABLE_SCROBBLING,
-	                            rb_audioscrobbler_service_get_name (source->priv->service));
-	eel_gconf_set_boolean (conf_key,
-			       gtk_toggle_button_get_active (togglebutton));
-	g_free (conf_key);
-}
-
-static void
-rb_audioscrobbler_profile_source_scrobbling_enabled_changed_cb (GConfClient *client,
-                                                                guint cnxn_id,
-                                                                GConfEntry *entry,
-                                                                RBAudioscrobblerProfileSource *source)
-{
-	gboolean enabled = gconf_value_get_bool (entry->value);
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (source->priv->scrobbling_enabled_check),
-	                              enabled);
-
-	if (source->priv->audioscrobbler != NULL && enabled == FALSE) {
-		g_object_unref (source->priv->audioscrobbler);
-		source->priv->audioscrobbler = NULL;
-		gtk_label_set_label (GTK_LABEL (source->priv->scrobbler_status_msg_label),
-		                     _("Disabled"));
-	} else if (source->priv->audioscrobbler == NULL && enabled == TRUE) {
-		RBShell *shell;
-		g_object_get (source, "shell", &shell, NULL);
-		source->priv->audioscrobbler =
-			rb_audioscrobbler_new (source->priv->service,
-				               RB_SHELL_PLAYER (rb_shell_get_player (shell)),
-                                               rb_audioscrobbler_account_get_username (source->priv->account),
-			                       rb_audioscrobbler_account_get_session_key (source->priv->account));
-		g_signal_connect (source->priv->audioscrobbler,
-			          "authentication-error",
-			          (GCallback)rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb,
-			          source);
-		g_signal_connect (source->priv->audioscrobbler,
-			          "statistics-changed",
-			          (GCallback)rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb,
-			          source);
-		rb_audioscrobbler_statistics_changed (source->priv->audioscrobbler);
-		g_object_unref (shell);
-	}
-}
-
 static void
 rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount *account,
                                                          RBAudioscrobblerAccountLoginStatus status,
-                                                         gpointer user_data)
+                                                         RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	const char *username;
 	const char *session_key;
 	char *scrobbling_enabled_conf_key;
@@ -692,8 +654,6 @@ rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount
 	gboolean show_login_bar;
 	gboolean show_profile;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	username = rb_audioscrobbler_account_get_username (source->priv->account);
 	session_key = rb_audioscrobbler_account_get_session_key (source->priv->account);
 
@@ -792,12 +752,59 @@ rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount
 	g_free (button_text);
 }
 
+void
+rb_audioscrobbler_profile_source_scrobbling_enabled_check_toggled_cb (GtkToggleButton *togglebutton,
+                                                                      RBAudioscrobblerProfileSource *source)
+{
+	char *conf_key;
+
+	conf_key = g_strdup_printf (CONF_AUDIOSCROBBLER_ENABLE_SCROBBLING,
+	                            rb_audioscrobbler_service_get_name (source->priv->service));
+	eel_gconf_set_boolean (conf_key,
+			       gtk_toggle_button_get_active (togglebutton));
+	g_free (conf_key);
+}
+
 static void
-rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
-                                                                    gpointer user_data)
+rb_audioscrobbler_profile_source_scrobbling_enabled_changed_cb (GConfClient *client,
+                                                                guint cnxn_id,
+                                                                GConfEntry *entry,
+                                                                RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
+	gboolean enabled = gconf_value_get_bool (entry->value);
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (source->priv->scrobbling_enabled_check),
+	                              enabled);
+
+	if (source->priv->audioscrobbler != NULL && enabled == FALSE) {
+		g_object_unref (source->priv->audioscrobbler);
+		source->priv->audioscrobbler = NULL;
+		gtk_label_set_label (GTK_LABEL (source->priv->scrobbler_status_msg_label),
+		                     _("Disabled"));
+	} else if (source->priv->audioscrobbler == NULL && enabled == TRUE) {
+		RBShell *shell;
+		g_object_get (source, "shell", &shell, NULL);
+		source->priv->audioscrobbler =
+			rb_audioscrobbler_new (source->priv->service,
+				               RB_SHELL_PLAYER (rb_shell_get_player (shell)),
+                                               rb_audioscrobbler_account_get_username (source->priv->account),
+			                       rb_audioscrobbler_account_get_session_key (source->priv->account));
+		g_signal_connect (source->priv->audioscrobbler,
+			          "authentication-error",
+			          (GCallback)rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb,
+			          source);
+		g_signal_connect (source->priv->audioscrobbler,
+			          "statistics-changed",
+			          (GCallback)rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb,
+			          source);
+		rb_audioscrobbler_statistics_changed (source->priv->audioscrobbler);
+		g_object_unref (shell);
+	}
+}
 
+static void
+rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
+                                                                    RBAudioscrobblerProfileSource *source)
+{
 	rb_audioscrobbler_account_notify_of_auth_error (source->priv->account);
 }
 
@@ -807,14 +814,11 @@ rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb (RBAudioscrobbl
                                                                   guint queue_count,
                                                                   guint submit_count,
                                                                   const char *submit_time,
-                                                                  gpointer user_data)
+                                                                  RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	char *queue_count_text;
 	char *submit_count_text;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	gtk_label_set_text (GTK_LABEL (source->priv->scrobbler_status_msg_label), status_msg);
 
 	queue_count_text = g_strdup_printf ("%u", queue_count);
@@ -829,10 +833,11 @@ rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb (RBAudioscrobbl
 	g_free (submit_count_text);
 }
 
+/* re-enabled the love and ban GtkActions when a new song is played */
 static void
 rb_audioscrobbler_profile_source_playing_song_changed_cb (RBShellPlayer *player,
-                                                         RhythmDBEntry *entry,
-                                                         RBAudioscrobblerProfileSource *source)
+                                                          RhythmDBEntry *entry,
+                                                          RBAudioscrobblerProfileSource *source)
 {
 	char *action_name;
 	GtkAction *action;
@@ -850,6 +855,60 @@ rb_audioscrobbler_profile_source_playing_song_changed_cb (RBShellPlayer *player,
 }
 
 static void
+rb_audioscrobbler_profile_source_love_track_action_cb (GtkAction *action,
+                                                       RBAudioscrobblerProfileSource *source)
+{
+	RBShell *shell;
+	RhythmDBEntry *entry;
+	char *ban_action_name;
+	GtkAction *ban_action;
+
+	g_object_get (source, "shell", &shell, NULL);
+
+	entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
+
+	if (entry != NULL) {
+		rb_audioscrobbler_user_love_track (source->priv->user,
+			                           rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
+			                           rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
+		rhythmdb_entry_unref (entry);
+	}
+
+	/* disable love/ban */
+	gtk_action_set_sensitive (action, FALSE);
+	ban_action_name = g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+	ban_action = gtk_action_group_get_action (source->priv->action_group, ban_action_name);
+	gtk_action_set_sensitive (ban_action, FALSE);
+
+	g_free (ban_action_name);
+	g_object_unref (shell);
+}
+
+static void
+rb_audioscrobbler_profile_source_ban_track_action_cb (GtkAction *action,
+                                                      RBAudioscrobblerProfileSource *source)
+{
+	RBShell *shell;
+	RhythmDBEntry *entry;
+
+	g_object_get (source, "shell", &shell, NULL);
+
+	entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
+
+	if (entry != NULL) {
+		rb_audioscrobbler_user_ban_track (source->priv->user,
+			                          rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
+			                          rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
+		rhythmdb_entry_unref (entry);
+	}
+
+	/* skip to next track */
+	rb_shell_player_do_next (RB_SHELL_PLAYER (rb_shell_get_player (shell)), NULL);
+
+	g_object_unref (shell);
+}
+
+static void
 rb_audioscrobbler_profile_source_station_creator_type_combo_changed_cb (GtkComboBox *combo_box,
                                                                         RBAudioscrobblerProfileSource *source)
 {
@@ -1074,7 +1133,7 @@ rb_audioscrobbler_profile_source_add_radio_station (RBAudioscrobblerProfileSourc
 	return radio;
 }
 
-/* callback from notify::name for each radio station owned by this profile source */
+/* called when a radio station's name changes */
 static void
 rb_audioscrobbler_profile_source_radio_station_name_changed_cb (RBAudioscrobblerRadioSource *radio,
                                                                 GParamSpec *spec,
@@ -1103,9 +1162,8 @@ rb_audioscrobbler_profile_source_remove_radio_station (RBAudioscrobblerProfileSo
 static void
 rb_audioscrobbler_profile_source_user_info_updated_cb (RBAudioscrobblerUser *user,
                                                        RBAudioscrobblerUserData *data,
-                                                       gpointer user_data)
+                                                       RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
 	if (data != NULL) {
 		char *playcount_text;
 
@@ -1132,10 +1190,8 @@ rb_audioscrobbler_profile_source_user_info_updated_cb (RBAudioscrobblerUser *use
 static void
 rb_audioscrobbler_profile_source_recent_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                            GPtrArray *recent_tracks,
-                                                           gpointer user_data)
+                                                           RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	if (recent_tracks != NULL) {
 		rb_audioscrobbler_profile_source_set_user_list (source, source->priv->recent_tracks_table, recent_tracks);
 		gtk_widget_show_all (source->priv->recent_tracks_area);
@@ -1147,10 +1203,8 @@ rb_audioscrobbler_profile_source_recent_tracks_updated_cb (RBAudioscrobblerUser
 static void
 rb_audioscrobbler_profile_source_top_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                         GPtrArray *top_tracks,
-                                                        gpointer user_data)
+                                                        RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	if (top_tracks != NULL) {
 		rb_audioscrobbler_profile_source_set_user_list (source, source->priv->top_tracks_table, top_tracks);
 		gtk_widget_show_all (source->priv->top_tracks_area);
@@ -1162,10 +1216,8 @@ rb_audioscrobbler_profile_source_top_tracks_updated_cb (RBAudioscrobblerUser *us
 static void
 rb_audioscrobbler_profile_source_loved_tracks_updated_cb (RBAudioscrobblerUser *user,
                                                           GPtrArray *loved_tracks,
-                                                          gpointer user_data)
+                                                          RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	if (loved_tracks != NULL) {
 		rb_audioscrobbler_profile_source_set_user_list (source, source->priv->loved_tracks_table, loved_tracks);
 		gtk_widget_show_all (source->priv->loved_tracks_area);
@@ -1177,10 +1229,8 @@ rb_audioscrobbler_profile_source_loved_tracks_updated_cb (RBAudioscrobblerUser *
 static void
 rb_audioscrobbler_profile_source_top_artists_updated_cb (RBAudioscrobblerUser *user,
                                                          GPtrArray *top_artists,
-                                                         gpointer user_data)
+                                                         RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	if (top_artists != NULL) {
 		rb_audioscrobbler_profile_source_set_user_list (source, source->priv->top_artists_table, top_artists);
 		gtk_widget_show_all (source->priv->top_artists_area);
@@ -1192,10 +1242,8 @@ rb_audioscrobbler_profile_source_top_artists_updated_cb (RBAudioscrobblerUser *u
 static void
 rb_audioscrobbler_profile_source_recommended_artists_updated_cb (RBAudioscrobblerUser *user,
                                                                  GPtrArray *recommended_artists,
-                                                                 gpointer user_data)
+                                                                 RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
-
 	if (recommended_artists != NULL) {
 		rb_audioscrobbler_profile_source_set_user_list (source, source->priv->recommended_artists_table, recommended_artists);
 		gtk_widget_show_all (source->priv->recommended_artists_area);
@@ -1204,6 +1252,9 @@ rb_audioscrobbler_profile_source_recommended_artists_updated_cb (RBAudioscrobble
 	}
 }
 
+/* Creates a list of buttons packed in a table for a list of data
+ * eg user's top tracks or recommended artists
+ */
 static void
 rb_audioscrobbler_profile_source_set_user_list (RBAudioscrobblerProfileSource *source,
                                                 GtkWidget *list_table,
@@ -1240,6 +1291,7 @@ rb_audioscrobbler_profile_source_set_user_list (RBAudioscrobblerProfileSource *s
 	}
 }
 
+/* creates a button for use in a list */
 static GtkWidget *
 rb_audioscrobbler_profile_source_create_list_button (RBAudioscrobblerProfileSource *source,
                                                      RBAudioscrobblerUserData *data)
@@ -1322,6 +1374,7 @@ rb_audioscrobbler_profile_source_create_list_button (RBAudioscrobblerProfileSour
 	return button;
 }
 
+/* creates a menu to be popped up when a button is clicked */
 static GtkWidget *
 rb_audioscrobbler_profile_source_create_popup_menu (RBAudioscrobblerProfileSource *source,
                                                     RBAudioscrobblerUserData *data)
@@ -1380,13 +1433,91 @@ rb_audioscrobbler_profile_source_create_popup_menu (RBAudioscrobblerProfileSourc
 	return menu;
 }
 
+/* packs a button into a GtkTable, from right to left then top to bottom */
 static void
-rb_audioscrobbler_profile_source_list_item_clicked_cb (GtkButton *button, gpointer user_data)
+rb_audioscrobbler_profile_source_list_table_pack_start (GtkTable *list_table, GtkWidget *item)
+{
+	int num_columns;
+	int num_rows;
+	int i;
+
+	g_object_get (list_table, "n-columns", &num_columns, "n-rows", &num_rows, NULL);
+	i = g_list_length (gtk_container_get_children (GTK_CONTAINER (list_table)));
+
+	gtk_table_attach_defaults (list_table,
+	                           item,
+	                           i % num_columns, i % num_columns + 1,
+	                           i / num_columns, i / num_columns + 1);
+}
+
+/* allocates the correct amount of size for a table containing a list of buttons */
+void
+rb_audioscrobbler_profile_source_list_layout_size_allocate_cb (GtkWidget *layout,
+                                                               GtkAllocation *allocation,
+                                                               gpointer user_data)
+{
+	GtkWidget *table = gtk_container_get_children (GTK_CONTAINER (layout))->data;
+	GList *buttons = gtk_container_get_children (GTK_CONTAINER (table));
+	int num_buttons;
+	GtkAllocation button_allocation;
+	int current_num_columns;
+	int new_num_columns;
+	int spacing;
+	GtkRequisition table_requisition;
+
+	num_buttons = g_list_length (buttons);
+	if (num_buttons == 0)
+		return;
+
+	gtk_widget_get_allocation (buttons->data, &button_allocation);
+
+	g_object_get (table, "n-columns", &current_num_columns, NULL);
+	spacing = gtk_table_get_default_col_spacing (GTK_TABLE (table));
+
+	new_num_columns = allocation->width / (button_allocation.width + spacing);
+	if (new_num_columns == 0) {
+		new_num_columns = 1;
+	}
+
+	if (new_num_columns != current_num_columns) {
+		int new_num_rows;
+		GList *button;
+
+		new_num_rows = (double)ceil ((double)num_buttons / (double)new_num_columns);
+
+		/* remove each button from the table, reffing it first so that it is not destroyed */
+		for (button = g_list_first (buttons); button != NULL; button = g_list_next (button)) {
+			g_object_ref (button->data);
+			gtk_container_remove (GTK_CONTAINER (table), button->data);
+		}
+
+		/* resize the table */
+		rb_debug ("resizing table from %i to %ix%i", current_num_columns, new_num_columns, new_num_rows);
+		gtk_table_resize (GTK_TABLE (table), new_num_columns, new_num_rows);
+
+		/* don't know why, but g_table_resize doesn't always update these properties properly */
+		g_object_set (table, "n-columns", new_num_columns, "n-rows", new_num_rows, NULL);
+
+		/* re-attach each button to the table */
+		for (button = g_list_last (buttons); button != NULL; button = g_list_previous (button)) {
+
+			rb_audioscrobbler_profile_source_list_table_pack_start (GTK_TABLE (table),
+			                                                        button->data);
+			g_object_unref (button->data);
+		}
+	}
+
+	gtk_widget_get_requisition (table, &table_requisition);
+	gtk_widget_set_size_request (layout, 0, table_requisition.height);
+	gtk_layout_set_size (GTK_LAYOUT (layout), table_requisition.width, table_requisition.height);
+}
+
+/* popup the appropriate menu */
+static void
+rb_audioscrobbler_profile_source_list_item_clicked_cb (GtkButton *button, RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	GtkWidget *menu;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
 	menu = g_hash_table_lookup (source->priv->button_to_popup_menu_map, button);
 
 	/* show menu if it has any items in it */
@@ -1397,13 +1528,11 @@ rb_audioscrobbler_profile_source_list_item_clicked_cb (GtkButton *button, gpoint
 
 static void
 rb_audioscrobbler_profile_source_list_item_view_url_activated_cb (GtkMenuItem *menuitem,
-                                                                  gpointer user_data)
+                                                                  RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	GtkWidget *menu;
 	RBAudioscrobblerUserData *data;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
 	menu = gtk_widget_get_parent (GTK_WIDGET (menuitem));
 	data = g_hash_table_lookup (source->priv->popup_menu_to_data_map, menu);
 
@@ -1420,9 +1549,8 @@ rb_audioscrobbler_profile_source_list_item_view_url_activated_cb (GtkMenuItem *m
 
 static void
 rb_audioscrobbler_profile_source_list_item_listen_similar_artists_activated_cb (GtkMenuItem *menuitem,
-                                                                                gpointer user_data)
+                                                                                RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	GtkWidget *menu;
 	RBAudioscrobblerUserData *data;
 	const char *artist = NULL;
@@ -1432,7 +1560,6 @@ rb_audioscrobbler_profile_source_list_item_listen_similar_artists_activated_cb (
 	RBShell *shell;
 	RBSourceList *sourcelist;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
 	menu = gtk_widget_get_parent (GTK_WIDGET (menuitem));
 	data = g_hash_table_lookup (source->priv->popup_menu_to_data_map, menu);
 	if (data->type == RB_AUDIOSCROBBLER_USER_DATA_TYPE_ARTIST) {
@@ -1459,9 +1586,8 @@ rb_audioscrobbler_profile_source_list_item_listen_similar_artists_activated_cb (
 
 static void
 rb_audioscrobbler_profile_source_list_item_listen_top_fans_activated_cb (GtkMenuItem *menuitem,
-                                                                         gpointer user_data)
+                                                                         RBAudioscrobblerProfileSource *source)
 {
-	RBAudioscrobblerProfileSource *source;
 	GtkWidget *menu;
 	RBAudioscrobblerUserData *data;
 	const char *artist = NULL;
@@ -1471,7 +1597,6 @@ rb_audioscrobbler_profile_source_list_item_listen_top_fans_activated_cb (GtkMenu
 	RBShell *shell;
 	RBSourceList *sourcelist;
 
-	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
 	menu = gtk_widget_get_parent (GTK_WIDGET (menuitem));
 	data = g_hash_table_lookup (source->priv->popup_menu_to_data_map, menu);
 	if (data->type == RB_AUDIOSCROBBLER_USER_DATA_TYPE_ARTIST) {
@@ -1496,139 +1621,6 @@ rb_audioscrobbler_profile_source_list_item_listen_top_fans_activated_cb (GtkMenu
 	g_object_unref (sourcelist);
 }
 
-static void
-rb_audioscrobbler_profile_source_list_table_pack_start (GtkTable *list_table, GtkWidget *item)
-{
-	int num_columns;
-	int num_rows;
-	int i;
-
-	g_object_get (list_table, "n-columns", &num_columns, "n-rows", &num_rows, NULL);
-	i = g_list_length (gtk_container_get_children (GTK_CONTAINER (list_table)));
-
-	gtk_table_attach_defaults (list_table,
-	                           item,
-	                           i % num_columns, i % num_columns + 1,
-	                           i / num_columns, i / num_columns + 1);
-}
-
-void
-rb_audioscrobbler_profile_source_list_layout_size_allocate_cb (GtkWidget *layout,
-                                                               GtkAllocation *allocation,
-                                                               gpointer user_data)
-{
-	GtkWidget *table = gtk_container_get_children (GTK_CONTAINER (layout))->data;
-	GList *buttons = gtk_container_get_children (GTK_CONTAINER (table));
-	int num_buttons;
-	GtkAllocation button_allocation;
-	int current_num_columns;
-	int new_num_columns;
-	int spacing;
-	GtkRequisition table_requisition;
-
-	num_buttons = g_list_length (buttons);
-	if (num_buttons == 0)
-		return;
-
-	gtk_widget_get_allocation (buttons->data, &button_allocation);
-
-	g_object_get (table, "n-columns", &current_num_columns, NULL);
-	spacing = gtk_table_get_default_col_spacing (GTK_TABLE (table));
-
-	new_num_columns = allocation->width / (button_allocation.width + spacing);
-	if (new_num_columns == 0) {
-		new_num_columns = 1;
-	}
-
-	if (new_num_columns != current_num_columns) {
-		int new_num_rows;
-		GList *button;
-
-		new_num_rows = (double)ceil ((double)num_buttons / (double)new_num_columns);
-
-		/* remove each button from the table, reffing it first so that it is not destroyed */
-		for (button = g_list_first (buttons); button != NULL; button = g_list_next (button)) {
-			g_object_ref (button->data);
-			gtk_container_remove (GTK_CONTAINER (table), button->data);
-		}
-
-		/* resize the table */
-		rb_debug ("resizing table from %i to %ix%i", current_num_columns, new_num_columns, new_num_rows);
-		gtk_table_resize (GTK_TABLE (table), new_num_columns, new_num_rows);
-
-		/* don't know why, but g_table_resize doesn't always update these properties properly */
-		g_object_set (table, "n-columns", new_num_columns, "n-rows", new_num_rows, NULL);
-
-		/* re-attach each button to the table */
-		for (button = g_list_last (buttons); button != NULL; button = g_list_previous (button)) {
-
-			rb_audioscrobbler_profile_source_list_table_pack_start (GTK_TABLE (table),
-			                                                        button->data);
-			g_object_unref (button->data);
-		}
-	}
-
-	gtk_widget_get_requisition (table, &table_requisition);
-	gtk_widget_set_size_request (layout, 0, table_requisition.height);
-	gtk_layout_set_size (GTK_LAYOUT (layout), table_requisition.width, table_requisition.height);
-}
-
-/* GtkAction callbacks */
-static void
-rb_audioscrobbler_profile_source_love_track_action_cb (GtkAction *action,
-                                                       RBAudioscrobblerProfileSource *source)
-{
-	RBShell *shell;
-	RhythmDBEntry *entry;
-	char *ban_action_name;
-	GtkAction *ban_action;
-
-	g_object_get (source, "shell", &shell, NULL);
-
-	entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
-
-	if (entry != NULL) {
-		rb_audioscrobbler_user_love_track (source->priv->user,
-			                           rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
-			                           rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
-		rhythmdb_entry_unref (entry);
-	}
-
-	/* disable love/ban */
-	gtk_action_set_sensitive (action, FALSE);
-	ban_action_name = g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service));
-	ban_action = gtk_action_group_get_action (source->priv->action_group, ban_action_name);
-	gtk_action_set_sensitive (ban_action, FALSE);
-
-	g_free (ban_action_name);
-	g_object_unref (shell);
-}
-
-static void
-rb_audioscrobbler_profile_source_ban_track_action_cb (GtkAction *action,
-                                                      RBAudioscrobblerProfileSource *source)
-{
-	RBShell *shell;
-	RhythmDBEntry *entry;
-
-	g_object_get (source, "shell", &shell, NULL);
-
-	entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
-
-	if (entry != NULL) {
-		rb_audioscrobbler_user_ban_track (source->priv->user,
-			                          rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
-			                          rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST));
-		rhythmdb_entry_unref (entry);
-	}
-
-	/* skip to next track */
-	rb_shell_player_do_next (RB_SHELL_PLAYER (rb_shell_get_player (shell)), NULL);
-
-	g_object_unref (shell);
-}
-
-/* RBSource implementations */
 static GList *
 impl_get_ui_actions (RBSource *asource)
 {
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
index bc86cdd..636a7e4 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
@@ -96,7 +96,6 @@ rb_audioscrobbler_radio_type_get_default_name (RBAudioscrobblerRadioType type)
 }
 
 /* entry data stuff */
-
 typedef struct
 {
 	char *image_url;
@@ -115,8 +114,7 @@ destroy_track_data (RhythmDBEntry *entry, gpointer meh)
 	g_free (data->download_url);
 }
 
-/* source declerations */
-
+/* source declarations */
 struct _RBAudioscrobblerRadioSourcePrivate
 {
 	RBAudioscrobblerProfileSource *parent;
@@ -140,7 +138,7 @@ struct _RBAudioscrobblerRadioSourcePrivate
 
 	RBPlayOrder *play_order;
 
-	/* the currently playing entry of this source, if there is one */
+	/* the currently playing entry from this source, if there is one */
 	RhythmDBEntry *playing_entry;
 
 	guint emit_coverart_id;
@@ -164,20 +162,25 @@ static void rb_audioscrobbler_radio_source_set_property (GObject *object,
                                                          const GValue *value,
                                                          GParamSpec *pspec);
 
+static void rb_audioscrobbler_radio_source_playing_song_changed_cb (RBShellPlayer *player,
+                                                                    RhythmDBEntry *entry,
+                                                                    RBAudioscrobblerRadioSource *source);
+
+/* last.fm api requests */
 static void rb_audioscrobbler_radio_source_tune (RBAudioscrobblerRadioSource *source);
 static void rb_audioscrobbler_radio_source_tune_response_cb (SoupSession *session,
                                                              SoupMessage *msg,
                                                              gpointer user_data);
-
 static void rb_audioscrobbler_radio_source_fetch_playlist (RBAudioscrobblerRadioSource *source);
 static void rb_audioscrobbler_radio_source_fetch_playlist_response_cb (SoupSession *session,
                                                                        SoupMessage *msg,
                                                                        gpointer user_data);
+static void rb_audioscrobbler_radio_source_xspf_entry_parsed (TotemPlParser *parser,
+                                                              const char *uri,
+                                                              GHashTable *metadata,
+                                                              RBAudioscrobblerRadioSource *source);
 
-static void rb_audioscrobbler_radio_source_playing_song_changed_cb (RBShellPlayer *player,
-                                                                    RhythmDBEntry *entry,
-                                                                    RBAudioscrobblerRadioSource *source);
-
+/* action callbacks */
 static void rb_audioscrobbler_radio_source_rename_station_action_cb (GtkAction *action,
                                                                      RBAudioscrobblerRadioSource *source);
 static void rb_audioscrobbler_radio_source_delete_station_action_cb (GtkAction *action,
@@ -540,6 +543,80 @@ mkmd5 (char *string)
 }
 
 static void
+rb_audioscrobbler_radio_source_playing_song_changed_cb (RBShellPlayer *player,
+                                                        RhythmDBEntry *entry,
+                                                        RBAudioscrobblerRadioSource *source)
+{
+	RhythmDB *db;
+	GtkTreeIter playing_iter;
+
+	g_object_get (player, "db", &db, NULL);
+
+	/* delete old entry */
+	if (source->priv->playing_entry != NULL) {
+		rhythmdb_query_model_remove_entry (source->priv->track_model, source->priv->playing_entry);
+		rhythmdb_entry_delete (db, source->priv->playing_entry);
+		source->priv->playing_entry = NULL;
+	}
+
+	/* stop requesting cover art for old entry */
+	if (source->priv->emit_coverart_id != 0) {
+		g_source_remove (source->priv->emit_coverart_id);
+		source->priv->emit_coverart_id = 0;
+	}
+
+	/* check if the new playing entry is from this source */
+	if (rhythmdb_query_model_entry_to_iter (source->priv->track_model, entry, &playing_iter) == TRUE) {
+		GtkTreeIter iter;
+		gboolean reached_playing = FALSE;
+		int entries_after_playing = 0;
+		GList *remove = NULL;
+		GList *i;
+
+		/* update our playing entry */
+		source->priv->playing_entry = entry;
+
+		/* mark invalidated entries for removal and count remaining */
+		gtk_tree_model_get_iter_first (GTK_TREE_MODEL (source->priv->track_model), &iter);
+		do {
+			RhythmDBEntry *iter_entry;
+			iter_entry = rhythmdb_query_model_iter_to_entry (source->priv->track_model, &iter);
+
+			if (reached_playing == TRUE) {
+				entries_after_playing++;
+			} else if (iter_entry == entry) {
+				reached_playing = TRUE;
+			} else {
+				/* add to list of entries marked for removal */
+				remove = g_list_append (remove, iter_entry);
+			}
+
+			rhythmdb_entry_unref (iter_entry);
+
+		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (source->priv->track_model), &iter));
+
+		/* remove invalidated entries */
+		for (i = remove; i != NULL; i = i->next) {
+			rhythmdb_query_model_remove_entry (source->priv->track_model, i->data);
+			rhythmdb_entry_delete (db, i->data);
+		}
+
+		/* request more if needed */
+		if (entries_after_playing <= 2) {
+			rb_audioscrobbler_radio_source_tune (source);
+			rb_audioscrobbler_radio_source_fetch_playlist (source);
+		}
+
+		/* emit cover art notification */
+		source->priv->emit_coverart_id = g_idle_add ((GSourceFunc) emit_coverart_uri_cb, source);
+	}
+
+	rhythmdb_commit (db);
+
+	g_object_unref (db);
+}
+
+static void
 rb_audioscrobbler_radio_source_tune (RBAudioscrobblerRadioSource *source)
 {
 	char *sig_arg;
@@ -698,88 +775,6 @@ rb_audioscrobbler_radio_source_fetch_playlist (RBAudioscrobblerRadioSource *sour
 }
 
 static void
-xspf_entry_parsed (TotemPlParser *parser, const char *uri, GHashTable *metadata, RBAudioscrobblerRadioSource *source)
-{
-	RBShell *shell;
-	RhythmDBEntryType entry_type;
-	RhythmDB *db;
-
-	RhythmDBEntry *entry;
-	RBAudioscrobblerRadioTrackEntryData *track_data;
-	const char *value;
-	GValue v = {0,};
-	int i;
-	struct {
-		const char *field;
-		RhythmDBPropType prop;
-	} field_mapping[] = {
-		{ TOTEM_PL_PARSER_FIELD_TITLE, RHYTHMDB_PROP_TITLE },
-		{ TOTEM_PL_PARSER_FIELD_AUTHOR, RHYTHMDB_PROP_ARTIST },
-		{ TOTEM_PL_PARSER_FIELD_ALBUM, RHYTHMDB_PROP_ALBUM },
-	};
-
-	g_object_get (source, "shell", &shell, "entry-type", &entry_type, NULL);
-	g_object_get (shell, "db", &db, NULL);
-
-	/* create db entry if it doesn't already exist */
-	entry = rhythmdb_entry_lookup_by_location (db, uri);
-	if (entry == NULL) {
-		rb_debug ("creating new track entry for %s", uri);
-		entry = rhythmdb_entry_new (db, entry_type, uri);
-	} else {
-		rb_debug ("track entry %s already exists", uri);
-	}
-	track_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioscrobblerRadioTrackEntryData);
-
-	/* straightforward string copying */
-	for (i = 0; i < G_N_ELEMENTS (field_mapping); i++) {
-		value = g_hash_table_lookup (metadata, field_mapping[i].field);
-		if (value != NULL) {
-			g_value_init (&v, G_TYPE_STRING);
-			g_value_set_string (&v, value);
-			rhythmdb_entry_set (db, entry, field_mapping[i].prop, &v);
-			g_value_unset (&v);
-		}
-	}
-
-	/* duration needs some conversion */
-	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DURATION_MS);
-	if (value != NULL) {
-		gint64 duration;
-
-		duration = totem_pl_parser_parse_duration (value, FALSE);
-		if (duration > 0) {
-			g_value_init (&v, G_TYPE_ULONG);
-			g_value_set_ulong (&v, (gulong) duration / 1000);		/* ms -> s */
-			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &v);
-			g_value_unset (&v);
-		}
-	}
-
-	/* image URL and track auth ID are stored in entry type specific data */
-	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_IMAGE_URI);
-	if (value != NULL) {
-		track_data->image_url = g_strdup (value);
-	}
-
-	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_ID);
-	if (value != NULL) {
-		track_data->track_auth = g_strdup (value);
-	}
-
-	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DOWNLOAD_URI);
-	if (value != NULL) {
-		track_data->download_url = g_strdup (value);
-		rb_debug ("track %s has a download url: %s", uri, track_data->download_url);
-	}
-
-	rhythmdb_query_model_add_entry (source->priv->track_model, entry, -1);
-
-	g_object_unref (shell);
-	g_object_unref (db);
-}
-
-static void
 rb_audioscrobbler_radio_source_fetch_playlist_response_cb (SoupSession *session,
                                                            SoupMessage *msg,
                                                            gpointer user_data)
@@ -831,7 +826,9 @@ rb_audioscrobbler_radio_source_fetch_playlist_response_cb (SoupSession *session,
 	rb_debug ("parsing playlist %s", tmp_uri);
 
 	parser = totem_pl_parser_new ();
-	g_signal_connect_data (parser, "entry-parsed", G_CALLBACK (xspf_entry_parsed), source, NULL, 0);
+	g_signal_connect_data (parser, "entry-parsed",
+	                       G_CALLBACK (rb_audioscrobbler_radio_source_xspf_entry_parsed),
+	                       source, NULL, 0);
 	result = totem_pl_parser_parse (parser, tmp_uri, FALSE);
 
 	switch (result) {
@@ -864,76 +861,87 @@ rb_audioscrobbler_radio_source_fetch_playlist_response_cb (SoupSession *session,
 }
 
 static void
-rb_audioscrobbler_radio_source_playing_song_changed_cb (RBShellPlayer *player,
-                                                        RhythmDBEntry *entry,
-                                                        RBAudioscrobblerRadioSource *source)
+rb_audioscrobbler_radio_source_xspf_entry_parsed (TotemPlParser *parser,
+                                                  const char *uri,
+                                                  GHashTable *metadata,
+                                                  RBAudioscrobblerRadioSource *source)
 {
+	RBShell *shell;
+	RhythmDBEntryType entry_type;
 	RhythmDB *db;
-	GtkTreeIter playing_iter;
 
-	g_object_get (player, "db", &db, NULL);
+	RhythmDBEntry *entry;
+	RBAudioscrobblerRadioTrackEntryData *track_data;
+	const char *value;
+	GValue v = {0,};
+	int i;
+	struct {
+		const char *field;
+		RhythmDBPropType prop;
+	} field_mapping[] = {
+		{ TOTEM_PL_PARSER_FIELD_TITLE, RHYTHMDB_PROP_TITLE },
+		{ TOTEM_PL_PARSER_FIELD_AUTHOR, RHYTHMDB_PROP_ARTIST },
+		{ TOTEM_PL_PARSER_FIELD_ALBUM, RHYTHMDB_PROP_ALBUM },
+	};
 
-	/* delete old entry */
-	if (source->priv->playing_entry != NULL) {
-		rhythmdb_query_model_remove_entry (source->priv->track_model, source->priv->playing_entry);
-		rhythmdb_entry_delete (db, source->priv->playing_entry);
-		source->priv->playing_entry = NULL;
-	}
+	g_object_get (source, "shell", &shell, "entry-type", &entry_type, NULL);
+	g_object_get (shell, "db", &db, NULL);
 
-	/* stop requesting cover art for old entry */
-	if (source->priv->emit_coverart_id != 0) {
-		g_source_remove (source->priv->emit_coverart_id);
-		source->priv->emit_coverart_id = 0;
+	/* create db entry if it doesn't already exist */
+	entry = rhythmdb_entry_lookup_by_location (db, uri);
+	if (entry == NULL) {
+		rb_debug ("creating new track entry for %s", uri);
+		entry = rhythmdb_entry_new (db, entry_type, uri);
+	} else {
+		rb_debug ("track entry %s already exists", uri);
 	}
+	track_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (entry, RBAudioscrobblerRadioTrackEntryData);
 
-	/* check if the new playing entry is from this source */
-	if (rhythmdb_query_model_entry_to_iter (source->priv->track_model, entry, &playing_iter) == TRUE) {
-		GtkTreeIter iter;
-		gboolean reached_playing = FALSE;
-		int entries_after_playing = 0;
-		GList *remove = NULL;
-		GList *i;
-
-		/* update our playing entry */
-		source->priv->playing_entry = entry;
-
-		/* mark invalidated entries for removal and count remaining */
-		gtk_tree_model_get_iter_first (GTK_TREE_MODEL (source->priv->track_model), &iter);
-		do {
-			RhythmDBEntry *iter_entry;
-			iter_entry = rhythmdb_query_model_iter_to_entry (source->priv->track_model, &iter);
-
-			if (reached_playing == TRUE) {
-				entries_after_playing++;
-			} else if (iter_entry == entry) {
-				reached_playing = TRUE;
-			} else {
-				/* add to list of entries marked for removal */
-				remove = g_list_append (remove, iter_entry);
-			}
-
-			rhythmdb_entry_unref (iter_entry);
+	/* straightforward string copying */
+	for (i = 0; i < G_N_ELEMENTS (field_mapping); i++) {
+		value = g_hash_table_lookup (metadata, field_mapping[i].field);
+		if (value != NULL) {
+			g_value_init (&v, G_TYPE_STRING);
+			g_value_set_string (&v, value);
+			rhythmdb_entry_set (db, entry, field_mapping[i].prop, &v);
+			g_value_unset (&v);
+		}
+	}
 
-		} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (source->priv->track_model), &iter));
+	/* duration needs some conversion */
+	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DURATION_MS);
+	if (value != NULL) {
+		gint64 duration;
 
-		/* remove invalidated entries */
-		for (i = remove; i != NULL; i = i->next) {
-			rhythmdb_query_model_remove_entry (source->priv->track_model, i->data);
-			rhythmdb_entry_delete (db, i->data);
+		duration = totem_pl_parser_parse_duration (value, FALSE);
+		if (duration > 0) {
+			g_value_init (&v, G_TYPE_ULONG);
+			g_value_set_ulong (&v, (gulong) duration / 1000);		/* ms -> s */
+			rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DURATION, &v);
+			g_value_unset (&v);
 		}
+	}
 
-		/* request more if needed */
-		if (entries_after_playing <= 2) {
-			rb_audioscrobbler_radio_source_tune (source);
-			rb_audioscrobbler_radio_source_fetch_playlist (source);
-		}
+	/* image URL and track auth ID are stored in entry type specific data */
+	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_IMAGE_URI);
+	if (value != NULL) {
+		track_data->image_url = g_strdup (value);
+	}
 
-		/* emit cover art notification */
-		source->priv->emit_coverart_id = g_idle_add ((GSourceFunc) emit_coverart_uri_cb, source);
+	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_ID);
+	if (value != NULL) {
+		track_data->track_auth = g_strdup (value);
 	}
 
-	rhythmdb_commit (db);
+	value = g_hash_table_lookup (metadata, TOTEM_PL_PARSER_FIELD_DOWNLOAD_URI);
+	if (value != NULL) {
+		track_data->download_url = g_strdup (value);
+		rb_debug ("track %s has a download url: %s", uri, track_data->download_url);
+	}
+
+	rhythmdb_query_model_add_entry (source->priv->track_model, entry, -1);
 
+	g_object_unref (shell);
 	g_object_unref (db);
 }
 
@@ -957,7 +965,6 @@ static void
 rb_audioscrobbler_radio_source_delete_station_action_cb (GtkAction *action,
                                                          RBAudioscrobblerRadioSource *source)
 {
-	rb_debug ("deleting station %s", source->priv->station_url);
 	rb_audioscrobbler_profile_source_remove_radio_station (source->priv->parent, RB_SOURCE (source));
 }
 
@@ -1049,7 +1056,6 @@ emit_coverart_uri_cb (RBAudioscrobblerRadioSource *source)
 	return FALSE;
 }
 
-/* RBSource implementations */
 static void
 impl_activate (RBSource *asource)
 {
@@ -1077,8 +1083,8 @@ impl_get_status (RBSource *asource, char **text, char **progress_text, float *pr
 
 	/* pulse progressbar if we're busy, otherwise see what the streaming source part of us has to say */
 	if (source->priv->is_fetching_playlist) {
-		/* Actually, we could be calling either radio.tune or radio.getPlaylist methods,
-		 * but "Tuning station" seems like a user friendly message to display.
+		/* We could be calling either radio.tune or radio.getPlaylist methods.
+		 * "Tuning station" seems like a user friendly message to display for both cases.
 		 */
 		*progress_text = g_strdup (_("Tuning station"));
 		*progress = -1.0f;
@@ -1124,9 +1130,7 @@ impl_delete_thyself (RBSource *asource)
 	g_object_get (source, "shell", &shell, NULL);
 	g_object_get (shell, "db", &db, NULL);
 
-	/* Ensure playing entry is only deleted here, and not also when the playing entry changes
-	 * because it is deleted here.
-	 */
+	/* Ensure playing entry isn't deleted twice */
 	source->priv->playing_entry = NULL;
 
 	/* delete all entries */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]