[rhythmbox] audioscrobbler: allow scrobbler to report authentication errors



commit b98b5cec3e6bc0d2299a31070b9ea71b623d31cf
Author: Jamie Nicol <jamie thenicols net>
Date:   Thu Jun 3 17:29:58 2010 +0100

    audioscrobbler: allow scrobbler to report authentication errors
    
    RBAudioscrobbler will emit a signal on an authentication error. The
    RBAudioscrobblerAccount will be notified and will delete the existing
    session, then report an authentication error as its login status. This
    will then be displayed to the user and they will be told to try logging
    in again.

 plugins/audioscrobbler/rb-audioscrobbler-account.c |   22 +++++++++++++++
 plugins/audioscrobbler/rb-audioscrobbler-account.h |    4 ++-
 .../rb-audioscrobbler-profile-source.c             |   23 ++++++++++++++++
 plugins/audioscrobbler/rb-audioscrobbler.c         |   28 ++++++++++++++++++++
 plugins/audioscrobbler/rb-audioscrobbler.h         |    3 ++
 5 files changed, 79 insertions(+), 1 deletions(-)
---
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index 1d97b8f..98fc046 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -426,6 +426,27 @@ rb_audioscrobbler_account_logout (RBAudioscrobblerAccount *account)
 	               0, account->priv->login_status);
 }
 
+void
+rb_audioscrobbler_account_notify_of_auth_error (RBAudioscrobblerAccount *account)
+{
+	/* After a session has been granted, no authentication methods will be called
+	 * therefore we must rely on other classes which call other methods (submissions,
+	 * radio, etc) to notify us when there is an authentication error
+	 */
+
+	g_free (account->priv->username);
+	account->priv->username = NULL;
+
+	g_free (account->priv->session_key);
+	account->priv->session_key = NULL;
+
+	rb_audioscrobbler_account_save_session_settings (account);
+
+	account->priv->login_status = RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR;
+	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
+	               0, account->priv->login_status);
+}
+
 /* private authentication functions */
 static void
 rb_audioscrobbler_account_request_token (RBAudioscrobblerAccount *account)
@@ -653,6 +674,7 @@ rb_audioscrobbler_account_login_status_get_type (void)
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT, "Logged out"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN, "Logging in"),
 			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN, "Logged in"),
+			ENUM_ENTRY (RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR, "Authentication Error"),
 			{ 0, 0, 0 }
 		};
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.h b/plugins/audioscrobbler/rb-audioscrobbler-account.h
index b5738a1..fc56b3d 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.h
@@ -38,7 +38,8 @@ typedef enum
 {
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT,
 	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN,
-	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN
+	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_IN,
+	RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR
 } RBAudioscrobblerAccountLoginStatus;
 
 GType rb_audioscrobbler_account_login_status_get_type (void);
@@ -74,6 +75,7 @@ RBAudioscrobblerAccount *       rb_audioscrobbler_account_new (void);
 
 void                            rb_audioscrobbler_account_authenticate (RBAudioscrobblerAccount *account);
 void                            rb_audioscrobbler_account_logout (RBAudioscrobblerAccount *account);
+void                            rb_audioscrobbler_account_notify_of_auth_error (RBAudioscrobblerAccount *account);
 
 G_END_DECLS
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index 06f4a16..7070631 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -70,6 +70,9 @@ static void rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscro
                                                                      RBAudioscrobblerAccountLoginStatus status,
                                                                      gpointer user_data);
 
+static void rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
+                                                                                gpointer user_data);
+
 G_DEFINE_TYPE (RBAudioscrobblerProfileSource, rb_audioscrobbler_profile_source, RB_TYPE_SOURCE)
 
 RBSource *
@@ -163,6 +166,10 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
 		                       LASTFM_SCROBBLER_URL,
 		                       LASTFM_API_KEY,
 		                       LASTFM_API_SECRET);
+	g_signal_connect (source->priv->audioscrobbler,
+	                  "authentication-error",
+	                  (GCallback)rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb,
+	                  source);
 
 	/* sync account settings to UI and scrobbler settings */
 	g_object_get (source->priv->account, "login-status", &login_status, NULL);
@@ -237,6 +244,7 @@ rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
 
 	switch (status) {
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGED_OUT:
+	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR:
 		rb_audioscrobbler_account_authenticate (source->priv->account);
 		break;
 	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_LOGGING_IN:	
@@ -289,6 +297,12 @@ rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount
 		button_text = g_strdup (_("Logout"));
 		gtk_info_bar_set_message_type (GTK_INFO_BAR (source->priv->login_bar), GTK_MESSAGE_INFO);
 		break;
+	case RB_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS_AUTH_ERROR:
+		gtk_widget_show_all (source->priv->login_bar);
+		label_text = g_strdup (_("Authentication error. Please try logging in again."));
+		button_text = g_strdup (_("Login"));
+		gtk_info_bar_set_message_type (GTK_INFO_BAR (source->priv->login_bar), GTK_MESSAGE_WARNING);
+		break;
 	default:
 		g_assert_not_reached ();
 		break;
@@ -302,3 +316,12 @@ rb_audioscrobbler_profile_source_login_status_change_cb (RBAudioscrobblerAccount
 	g_free (label_text);
 	g_free (button_text);
 }
+
+static void
+rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb (RBAudioscrobbler *audioscrobbler,
+                                                                    gpointer user_data)
+{
+	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (user_data);
+
+	rb_audioscrobbler_account_notify_of_auth_error (source->priv->account);
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.c b/plugins/audioscrobbler/rb-audioscrobbler.c
index 30d0120..f2bce2a 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler.c
@@ -197,6 +197,14 @@ enum
 	PROP_API_SECRET
 };
 
+enum
+{
+	AUTHENTICATION_ERROR,
+	LAST_SIGNAL
+};
+
+static guint rb_audioscrobbler_signals[LAST_SIGNAL] = { 0 };
+
 G_DEFINE_TYPE (RBAudioscrobbler, rb_audioscrobbler, G_TYPE_OBJECT)
 
 
@@ -263,6 +271,23 @@ rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass)
 							      NULL,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
+	/**
+	 * RBAudioscrobbler::authentication-error:
+	 * @account: the #RBAudioscrobblerAccount
+	 * @status: new status
+	 *
+	 * Emitted when an authentication error occurs.
+	 */
+	rb_audioscrobbler_signals[AUTHENTICATION_ERROR] =
+		g_signal_new ("authentication-error",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBAudioscrobblerClass, authentication_error),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+
 	g_type_class_add_private (klass, sizeof (RBAudioscrobblerPrivate));
 }
 
@@ -685,6 +710,9 @@ rb_audioscrobbler_parse_response (RBAudioscrobbler *audioscrobbler, SoupMessage
 		} else if (g_str_has_prefix (breaks[0], "BADAUTH")) {
 			rb_debug ("Bad authorization");
 			audioscrobbler->priv->status = BADAUTH;
+			/* emit an authentication error signal.
+			 * this is the only error which needs to be addressed from outside this class */
+			g_signal_emit (audioscrobbler, rb_audioscrobbler_signals[AUTHENTICATION_ERROR], 0);
 		} else if (g_str_has_prefix (breaks[0], "BADTIME")) {
 			rb_debug ("Bad timestamp");
 			audioscrobbler->priv->status = BAD_TIMESTAMP;
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.h b/plugins/audioscrobbler/rb-audioscrobbler.h
index d82721b..e554993 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler.h
@@ -56,6 +56,9 @@ typedef struct
 typedef struct
 {
 	GObjectClass parent_class;
+
+	/* signals */
+	void (*authentication_error) (RBAudioscrobbler *audioscrobbler);
 } RBAudioscrobblerClass;
 
 



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