[rhythmbox] audioscrobbler: report scrobbler statistics in profile source



commit 91ff4db3426b9f0b17d11700bfb8a859dec33b77
Author: Jamie Nicol <jamie thenicols net>
Date:   Sun Jun 27 14:30:34 2010 +0100

    audioscrobbler: report scrobbler statistics in profile source
    
    Scrobbler status, queue size, number of submitted songs and the time
    of last submission are reported to the user in an expander in the profile
    source. These used to be located in the preferences dialog.

 lib/rb-marshal.list                                |    1 +
 plugins/audioscrobbler/audioscrobbler-profile.ui   |  167 ++++++++++++++++++--
 .../rb-audioscrobbler-profile-source.c             |   58 +++++++
 plugins/audioscrobbler/rb-audioscrobbler.c         |   79 +++++++++-
 plugins/audioscrobbler/rb-audioscrobbler.h         |    8 +-
 5 files changed, 296 insertions(+), 17 deletions(-)
---
diff --git a/lib/rb-marshal.list b/lib/rb-marshal.list
index 73fa151..eb66d79 100644
--- a/lib/rb-marshal.list
+++ b/lib/rb-marshal.list
@@ -58,3 +58,4 @@ VOID:UINT64,STRING,POINTER
 VOID:ULONG,FLOAT
 VOID:OBJECT,BOOLEAN
 VOID:STRING,STRING,POINTER,POINTER
+VOID:STRING,UINT,UINT,STRING
diff --git a/plugins/audioscrobbler/audioscrobbler-profile.ui b/plugins/audioscrobbler/audioscrobbler-profile.ui
index ea582a9..1701b0d 100644
--- a/plugins/audioscrobbler/audioscrobbler-profile.ui
+++ b/plugins/audioscrobbler/audioscrobbler-profile.ui
@@ -10,12 +10,21 @@
       <object class="GtkHBox" id="user_info_area">
         <property name="visible">True</property>
         <child>
-          <object class="GtkViewport" id="viewport1">
+          <object class="GtkAlignment" id="alignment4">
             <property name="visible">True</property>
-            <property name="resize_mode">queue</property>
+            <property name="xalign">0</property>
+            <property name="yalign">0</property>
+            <property name="xscale">0</property>
+            <property name="yscale">0</property>
             <child>
-              <object class="GtkImage" id="profile_image">
+              <object class="GtkViewport" id="viewport1">
                 <property name="visible">True</property>
+                <property name="resize_mode">queue</property>
+                <child>
+                  <object class="GtkImage" id="profile_image">
+                    <property name="visible">True</property>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
@@ -94,15 +103,13 @@
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="xscale">0</property>
-                <property name="left_padding">4</property>
                 <child>
-                  <object class="GtkCheckButton" id="scrobbling_enabled_check">
-                    <property name="label" translatable="yes">Submit listening data</property>
+                  <object class="GtkLinkButton" id="view_profile_link">
+                    <property name="label" translatable="yes">View your profile</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                    <signal name="toggled" handler="rb_audioscrobbler_profile_source_scrobbling_enabled_check_toggled_cb"/>
+                    <property name="receives_default">True</property>
+                    <property name="relief">none</property>
                   </object>
                 </child>
               </object>
@@ -117,13 +124,15 @@
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
                 <property name="xscale">0</property>
+                <property name="left_padding">4</property>
                 <child>
-                  <object class="GtkLinkButton" id="view_profile_link">
-                    <property name="label" translatable="yes">View your profile</property>
+                  <object class="GtkCheckButton" id="scrobbling_enabled_check">
+                    <property name="label" translatable="yes">Submit listening data</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="relief">none</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <signal name="toggled" handler="rb_audioscrobbler_profile_source_scrobbling_enabled_check_toggled_cb"/>
                   </object>
                 </child>
               </object>
@@ -134,7 +143,137 @@
               </packing>
             </child>
             <child>
-              <placeholder/>
+              <object class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="spacing">5</property>
+                <child>
+                  <object class="GtkTable" id="table2">
+                    <property name="visible">True</property>
+                    <property name="n_rows">4</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">12</property>
+                    <property name="row_spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label41">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Status:</property>
+                      </object>
+                      <packing>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label42">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Queued tracks:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label43">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Tracks submitted:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label44">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Last submission time:</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="scrobbler_submit_time_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Never</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">3</property>
+                        <property name="bottom_attach">4</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="scrobbler_status_msg_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Disabled</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="scrobbler_queue_count_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="scrobbler_submit_count_label">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label">0</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">2</property>
+                        <property name="bottom_attach">3</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="statistics_label">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Submission statistics</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">4</property>
+              </packing>
             </child>
           </object>
           <packing>
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index fe1896f..aa2be7b 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -70,6 +70,11 @@ struct _RBAudioscrobblerProfileSourcePrivate {
 	GtkWidget *scrobbling_enabled_check;
 	GtkWidget *view_profile_link;
 
+	GtkWidget *scrobbler_status_msg_label;
+	GtkWidget *scrobbler_queue_count_label;
+	GtkWidget *scrobbler_submit_count_label;
+	GtkWidget *scrobbler_submit_time_label;
+
 	GtkWidget *recent_tracks_area;
 	GtkWidget *recent_tracks_table;
 	GtkWidget *top_tracks_area;
@@ -119,6 +124,12 @@ static void rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscro
 
 static void rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
                                                                                 gpointer user_data);
+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);
 
 static void rb_audioscrobbler_profile_source_user_info_updated_cb (RBAudioscrobblerUser *user,
                                                                    RBAudioscrobblerUserData *info,
@@ -302,6 +313,11 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
 			          "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);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (source->priv->scrobbling_enabled_check),
 		                              TRUE);
 	}
@@ -428,6 +444,13 @@ rb_audioscrobbler_profile_source_init_profile_ui (RBAudioscrobblerProfileSource
 	source->priv->scrobbling_enabled_check = GTK_WIDGET (gtk_builder_get_object (builder, "scrobbling_enabled_check"));
 	source->priv->view_profile_link = GTK_WIDGET (gtk_builder_get_object (builder, "view_profile_link"));
 
+	/* scrobbler statistics */
+	source->priv->scrobbler_status_msg_label = GTK_WIDGET (gtk_builder_get_object (builder, "scrobbler_status_msg_label"));
+	source->priv->scrobbler_queue_count_label = GTK_WIDGET (gtk_builder_get_object (builder, "scrobbler_queue_count_label"));
+	source->priv->scrobbler_submit_count_label = GTK_WIDGET (gtk_builder_get_object (builder, "scrobbler_submit_count_label"));
+	source->priv->scrobbler_submit_time_label = GTK_WIDGET (gtk_builder_get_object (builder, "scrobbler_submit_time_label"));
+
+	/* lists of data */
 	source->priv->recent_tracks_area = GTK_WIDGET (gtk_builder_get_object (builder, "recent_tracks_area"));
 	source->priv->recent_tracks_table = GTK_WIDGET (gtk_builder_get_object (builder, "recent_tracks_table"));
 
@@ -525,6 +548,8 @@ rb_audioscrobbler_profile_source_scrobbling_enabled_changed_cb (GConfClient *cli
 	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);
@@ -538,6 +563,11 @@ rb_audioscrobbler_profile_source_scrobbling_enabled_changed_cb (GConfClient *cli
 			          "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);
 	}
 }
@@ -639,6 +669,34 @@ rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrob
 }
 
 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;
+	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);
+	gtk_label_set_text (GTK_LABEL (source->priv->scrobbler_queue_count_label), queue_count_text);
+
+	submit_count_text = g_strdup_printf ("%u", submit_count);
+	gtk_label_set_text (GTK_LABEL (source->priv->scrobbler_submit_count_label), submit_count_text);
+
+	gtk_label_set_text (GTK_LABEL (source->priv->scrobbler_submit_time_label), submit_time);
+
+	g_free (queue_count_text);
+	g_free (submit_count_text);
+}
+
+static void
 rb_audioscrobbler_profile_source_set_user_list (RBAudioscrobblerProfileSource *source,
                                                 GtkWidget *list_table,
                                                 GPtrArray *list_data)
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.c b/plugins/audioscrobbler/rb-audioscrobbler.c
index 5760fbd..8b1209f 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler.c
@@ -59,7 +59,7 @@
 #include "rb-plugin.h"
 #include "rb-util.h"
 #include "rb-podcast-entry-types.h"
-
+#include "rb-marshal.h"
 #include "rb-audioscrobbler-entry.h"
 
 #define CLIENT_ID "rbx"
@@ -193,6 +193,7 @@ enum
 enum
 {
 	AUTHENTICATION_ERROR,
+	STATISTICS_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -276,6 +277,29 @@ rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass)
 			      G_TYPE_NONE,
 			      0);
 
+	/**
+	 * RBAudioscrobbler::statistics-changed:
+	 * @status_msg: description of the status
+	 * @queued_count: the number of tracks queued for submission
+	 * @submit_count: the number of tracks already submitted this session
+	 * @submit_time: the time at which the last submission was made
+	 *
+	 * Emitted when the scrobbling session's statistics change.
+	 */
+	rb_audioscrobbler_signals[STATISTICS_CHANGED] =
+		g_signal_new ("statistics-changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBAudioscrobblerClass, statistics_changed),
+			      NULL, NULL,
+			      rb_marshal_VOID__STRING_UINT_UINT_STRING,
+			      G_TYPE_NONE,
+		              4,
+			      G_TYPE_STRING,
+		              G_TYPE_UINT,
+		              G_TYPE_UINT,
+		              G_TYPE_STRING);
+
 	g_type_class_add_private (klass, sizeof (RBAudioscrobblerPrivate));
 }
 
@@ -299,6 +323,8 @@ rb_audioscrobbler_init (RBAudioscrobbler *audioscrobbler)
 	rb_audioscrobbler_load_queue (audioscrobbler);
 
 	rb_audioscrobbler_add_timeout (audioscrobbler);
+
+	rb_audioscrobbler_statistics_changed (audioscrobbler);
 }
 
 static void
@@ -450,6 +476,53 @@ rb_audioscrobbler_set_authentication_details (RBAudioscrobbler *audioscrobbler,
 	audioscrobbler->priv->handshake_next = 0;
 }
 
+/* emits the statistics-changed signal */
+void
+rb_audioscrobbler_statistics_changed (RBAudioscrobbler *audioscrobbler)
+{
+	const char *status;
+	char *status_msg;
+
+	switch (audioscrobbler->priv->status) {
+	case STATUS_OK:
+		status = _("OK");
+		break;
+	case HANDSHAKING:
+		status = _("Logging in");
+		break;
+	case REQUEST_FAILED:
+		status = _("Request failed");
+		break;
+	case BADAUTH:
+		status = _("Authentication error");
+		break;
+	case BAD_TIMESTAMP:
+		status = _("Clock is not set correctly");
+		break;
+	case CLIENT_BANNED:
+		status = _("This version of Rhythmbox has been banned.");
+		break;
+	case GIVEN_UP:
+		status = _("Track submission failed too many times");
+		break;
+	default:
+		g_assert_not_reached ();
+		break;
+	}
+
+	if (audioscrobbler->priv->status_msg && audioscrobbler->priv->status_msg[0] != '\0') {
+		status_msg = g_strdup_printf ("%s: %s", status, audioscrobbler->priv->status_msg);
+	} else {
+		status_msg = g_strdup (status);
+	}
+
+	g_signal_emit_by_name (audioscrobbler, "statistics-changed",
+	                       status_msg, audioscrobbler->priv->queue_count,
+	                       audioscrobbler->priv->submit_count, audioscrobbler->priv->submit_time);
+
+	g_free (status_msg);
+}
+
 /* Add the audioscrobbler thread timer */
 static void
 rb_audioscrobbler_add_timeout (RBAudioscrobbler *audioscrobbler)
@@ -559,6 +632,7 @@ maybe_add_current_song_to_queue (RBAudioscrobbler *audioscrobbler)
 			rb_audioscrobbler_add_to_queue (audioscrobbler, cur_entry);
 			audioscrobbler->priv->currently_playing = NULL;
 
+			rb_audioscrobbler_statistics_changed (audioscrobbler);
 		} else if (elapsed_delta > 20) {
 			rb_debug ("Skipping detected; not submitting current song");
 			/* not sure about this - what if I skip to somewhere towards
@@ -839,6 +913,7 @@ rb_audioscrobbler_do_handshake (RBAudioscrobbler *audioscrobbler)
 	rb_debug ("Performing handshake with Audioscrobbler server: %s", url);
 
 	audioscrobbler->priv->status = HANDSHAKING;
+	rb_audioscrobbler_statistics_changed (audioscrobbler);
 
 	rb_audioscrobbler_perform (audioscrobbler,
 				   url,
@@ -856,6 +931,7 @@ rb_audioscrobbler_do_handshake_cb (SoupSession *session, SoupMessage *msg, gpoin
 
 	rb_debug ("Handshake response");
 	rb_audioscrobbler_parse_response (audioscrobbler, msg, TRUE);
+	rb_audioscrobbler_statistics_changed (audioscrobbler);
 
 	switch (audioscrobbler->priv->status) {
 	case STATUS_OK:
@@ -994,6 +1070,7 @@ rb_audioscrobbler_submit_queue_cb (SoupSession *session, SoupMessage *msg, gpoin
 		}
 	}
 
+	rb_audioscrobbler_statistics_changed (audioscrobbler);
 	g_idle_add ((GSourceFunc) idle_unref_cb, audioscrobbler);
 }
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.h b/plugins/audioscrobbler/rb-audioscrobbler.h
index 5083617..62c3fb8 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler.h
@@ -60,6 +60,11 @@ typedef struct
 
 	/* signals */
 	void (*authentication_error) (RBAudioscrobbler *audioscrobbler);
+	void (*statistics_changed) (RBAudioscrobbler *audioscrobbler,
+	                            const char *status_msg,
+	                            guint queue_count,
+	                            guint submit_count,
+	                            const char *submit_time);
 } RBAudioscrobblerClass;
 
 
@@ -72,8 +77,7 @@ void                    rb_audioscrobbler_set_authentication_details (RBAudioscr
                                                                       const char *username,
                                                                       const char *session_key);
 
-void			rb_audioscrobbler_enabled_check_changed_cb (GtkCheckButton *button,
-								    RBAudioscrobbler *audioscrobbler);
+void                    rb_audioscrobbler_statistics_changed (RBAudioscrobbler *audioscrobbler);
 
 
 G_END_DECLS



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