[rhythmbox] audioscrobbler: abstract service specific details into class



commit 795bde28622bb747edca9245d6280fa54904b5e5
Author: Jamie Nicol <jamie thenicols net>
Date:   Tue Jun 8 23:42:03 2010 +0100

    audioscrobbler: abstract service specific details into class
    
    RBAudioscrobblerService contains properties such as the api url and
    the service's name, which will vary between different services such
    as Last.fm and Libre.fm. The scrobbler, account, and profile source
    classes now own a Service instance which will determine which service
    they are talking to.

 plugins/audioscrobbler/Makefile.am                 |    2 +
 plugins/audioscrobbler/rb-audioscrobbler-account.c |  127 +++++++---
 plugins/audioscrobbler/rb-audioscrobbler-account.h |    7 +-
 plugins/audioscrobbler/rb-audioscrobbler-plugin.c  |   11 +-
 .../rb-audioscrobbler-profile-source.c             |   83 ++++++--
 .../rb-audioscrobbler-profile-source.h             |    5 +-
 plugins/audioscrobbler/rb-audioscrobbler-service.c |  242 ++++++++++++++++++++
 plugins/audioscrobbler/rb-audioscrobbler-service.h |   61 +++++
 plugins/audioscrobbler/rb-audioscrobbler.c         |  110 +++------
 plugins/audioscrobbler/rb-audioscrobbler.h         |    7 +-
 10 files changed, 521 insertions(+), 134 deletions(-)
---
diff --git a/plugins/audioscrobbler/Makefile.am b/plugins/audioscrobbler/Makefile.am
index 0013552..bd1b757 100644
--- a/plugins/audioscrobbler/Makefile.am
+++ b/plugins/audioscrobbler/Makefile.am
@@ -11,6 +11,8 @@ libaudioscrobbler_la_SOURCES = \
 	rb-audioscrobbler-profile-source.c		\
 	rb-audioscrobbler-account.h			\
 	rb-audioscrobbler-account.c			\
+	rb-audioscrobbler-service.h			\
+	rb-audioscrobbler-service.c			\
 	rb-audioscrobbler.c				\
 	rb-audioscrobbler.h				\
 	rb-lastfm-source.c				\
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.c b/plugins/audioscrobbler/rb-audioscrobbler-account.c
index cdb6e9b..fd5b130 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.c
@@ -39,19 +39,13 @@
 #include "rb-file-helpers.h"
 #include "rb-util.h"
 
-/* this API key belongs to Jamie Nicol <jamie thenicols net>
-   generated May 2010 for use in the audioscrobbler plugin */
-#define LASTFM_API_KEY "0337ff3c59299b6a31d75164041860b6"
-#define LASTFM_API_SECRET "776c85a04a445efa8f9ed7705473c606"
-#define LASTFM_API_URL "http://ws.audioscrobbler.com/2.0/";
-#define LASTFM_AUTH_URL "http://www.last.fm/api/auth/";
-#define LASTFM_SCROBBLER_URL "http://post.audioscrobbler.com/";
-
-#define LASTFM_SESSION_SETTINGS_FILE "lastfm_session"
+#define SESSION_SETTINGS_FILE "audioscrobbler_sessions"
 #define SESSION_KEY_REQUEST_TIMEOUT 5
 
 struct _RBAudioscrobblerAccountPrivate
 {
+	RBAudioscrobblerService *service;
+
 	/* Authentication info */
 	gchar *username;
 	gchar *auth_token;
@@ -98,6 +92,7 @@ static void          rb_audioscrobbler_account_got_session_key_cb (SoupSession *
 enum
 {
 	PROP_0,
+	PROP_SERVICE,
 	PROP_USERNAME,
 	PROP_SESSION_KEY,
 	PROP_LOGIN_STATUS
@@ -137,6 +132,14 @@ rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass)
 	object_class->set_property = rb_audioscrobbler_account_set_property;
 
 	g_object_class_install_property (object_class,
+	                                 PROP_SERVICE,
+	                                 g_param_spec_object ("service",
+	                                                      "Service",
+	                                                      "Audioscrobbler service the account is with",
+	                                                      RB_TYPE_AUDIOSCROBBLER_SERVICE,
+                                                              G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
 	                                 PROP_USERNAME,
 	                                 g_param_spec_string ("username",
 	                                                      "Username",
@@ -179,8 +182,6 @@ rb_audioscrobbler_account_class_init (RBAudioscrobblerAccountClass *klass)
 			      1,
 			      RB_TYPE_AUDIOSCROBBLER_ACCOUNT_LOGIN_STATUS);
 
-	g_assert (rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED] != 0);
-
 	g_type_class_add_private (klass, sizeof (RBAudioscrobblerAccountPrivate));
 }
 
@@ -200,9 +201,12 @@ rb_audioscrobbler_account_init (RBAudioscrobblerAccount *account)
 static void
 rb_audioscrobbler_account_dispose (GObject *object)
 {
-	RBAudioscrobblerAccount *account;
+	RBAudioscrobblerAccount *account = RB_AUDIOSCROBBLER_ACCOUNT (object);
 
-	account = RB_AUDIOSCROBBLER_ACCOUNT (object);
+	if (account->priv->service != NULL) {
+		g_object_unref (account->priv->service);
+		account->priv->service = NULL;
+	}
 
 	if (account->priv->session_key_timeout_id != 0) {
 		g_source_remove (account->priv->session_key_timeout_id);
@@ -221,9 +225,7 @@ rb_audioscrobbler_account_dispose (GObject *object)
 static void
 rb_audioscrobbler_account_finalize (GObject *object)
 {
-	RBAudioscrobblerAccount *account;
-
-	account = RB_AUDIOSCROBBLER_ACCOUNT (object);
+	RBAudioscrobblerAccount *account = RB_AUDIOSCROBBLER_ACCOUNT (object);
 
 	g_free (account->priv->username);
 	g_free (account->priv->auth_token);
@@ -233,10 +235,11 @@ rb_audioscrobbler_account_finalize (GObject *object)
 }
 
 RBAudioscrobblerAccount *
-rb_audioscrobbler_account_new (void)
+rb_audioscrobbler_account_new (RBAudioscrobblerService *service)
 {
 	return g_object_new (RB_TYPE_AUDIOSCROBBLER_ACCOUNT,
-                             NULL);
+                             "service", service,
+	                     NULL);
 }
 
 static void
@@ -269,7 +272,11 @@ rb_audioscrobbler_account_set_property (GObject *object,
                                         const GValue *value,
                                         GParamSpec *pspec)
 {
+	RBAudioscrobblerAccount *account = RB_AUDIOSCROBBLER_ACCOUNT (object);
 	switch (prop_id) {
+	case PROP_SERVICE:
+		account->priv->service = g_value_dup_object (value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -298,6 +305,7 @@ rb_audioscrobbler_account_load_session_settings (RBAudioscrobblerAccount *accoun
 	const char *rb_data_dir;
 	char *file_path;
 	GKeyFile *key_file;
+	char *service_name;
 
 	rb_data_dir = rb_user_data_dir ();
 	if (rb_data_dir == NULL) {
@@ -305,15 +313,19 @@ rb_audioscrobbler_account_load_session_settings (RBAudioscrobblerAccount *accoun
 		return;
 	}
 
-	file_path = g_build_filename (rb_data_dir, LASTFM_SESSION_SETTINGS_FILE, NULL);
+	file_path = g_build_filename (rb_data_dir, SESSION_SETTINGS_FILE, NULL);
 	key_file = g_key_file_new ();
 	g_key_file_load_from_file (key_file, file_path, G_KEY_FILE_NONE, NULL);
 
-	account->priv->username = g_key_file_get_string (key_file, "last.fm", "username", NULL);
-	account->priv->session_key = g_key_file_get_string (key_file, "last.fm", "session_key", NULL);
+	/* get the service name */
+	g_object_get (account->priv->service, "name", &service_name, NULL);
+
+	account->priv->username = g_key_file_get_string (key_file, service_name, "username", NULL);
+	account->priv->session_key = g_key_file_get_string (key_file, service_name, "session_key", NULL);
 
 	g_free (file_path);
 	g_key_file_free (key_file);
+	g_free (service_name);
 
 	if (account->priv->username != NULL && account->priv->session_key != NULL) {
 		rb_debug ("loaded session: username=\"%s\", session key=\"%s\"",
@@ -345,6 +357,7 @@ rb_audioscrobbler_account_save_session_settings (RBAudioscrobblerAccount *accoun
 	const char *rb_data_dir;
 	char *file_path;
 	GKeyFile *key_file;
+	char *service_name;
 	char *data;
 	gsize data_length;
 	GFile *out_file;
@@ -356,19 +369,24 @@ rb_audioscrobbler_account_save_session_settings (RBAudioscrobblerAccount *accoun
 		return;
 	}
 
-	file_path = g_build_filename (rb_data_dir, LASTFM_SESSION_SETTINGS_FILE, NULL);
+	file_path = g_build_filename (rb_data_dir, SESSION_SETTINGS_FILE, NULL);
 	key_file = g_key_file_new ();
 	/* load existing file contents. errors wont matter, just means file doesn't exist yet */
 	g_key_file_load_from_file (key_file, file_path, G_KEY_FILE_KEEP_COMMENTS, NULL);
 
+	/* get the service name */
+	g_object_get (account->priv->service, "name", &service_name, NULL);
+
 	/* set the new data */
 	if (account->priv->username != NULL && account->priv->session_key != NULL) {
-		g_key_file_set_string (key_file, "last.fm", "username", account->priv->username);
-		g_key_file_set_string (key_file, "last.fm", "session_key", account->priv->session_key);
+		g_key_file_set_string (key_file, service_name, "username", account->priv->username);
+		g_key_file_set_string (key_file, service_name, "session_key", account->priv->session_key);
 	} else {
-		g_key_file_remove_group (key_file, "last.fm", NULL);
+		g_key_file_remove_group (key_file, service_name, NULL);
 	}
 
+	g_free (service_name);
+
 	data = g_key_file_to_data (key_file, &data_length, NULL);
 	g_key_file_free (key_file);
 
@@ -460,6 +478,9 @@ rb_audioscrobbler_account_request_token (RBAudioscrobblerAccount *account)
 	/* requests an authentication token
 	 * first stage of the authentication process
 	 */
+	char *api_url;
+	char *api_key;
+	char *api_secret;
 	char *sig_arg;
 	char *sig;
 	char *url;
@@ -473,13 +494,20 @@ rb_audioscrobbler_account_request_token (RBAudioscrobblerAccount *account)
 		                                             NULL);
 	}
 
+	/* get the service details */
+	g_object_get (account->priv->service,
+	              "api-url", &api_url,
+	              "api-key", &api_key,
+	              "api-secret", &api_secret,
+	              NULL);
+
 	/* create the request */
 	sig_arg = g_strdup_printf ("api_key%smethodauth.getToken%s",
-	                           LASTFM_API_KEY,
-	                           LASTFM_API_SECRET);
+	                           api_key,
+	                           api_secret);
 	sig = mkmd5 (sig_arg);
 	url = g_strdup_printf ("%s?method=auth.getToken&api_key=%s&api_sig=%s",
-			       LASTFM_API_URL, LASTFM_API_KEY, sig);
+			       api_url, api_key, sig);
 
 	msg = soup_message_new ("GET", url);
 
@@ -495,6 +523,9 @@ rb_audioscrobbler_account_request_token (RBAudioscrobblerAccount *account)
 	g_signal_emit (account, rb_audioscrobbler_account_signals[LOGIN_STATUS_CHANGED],
 	               0, account->priv->login_status);
 
+	g_free (api_url);
+	g_free (api_key);
+	g_free (api_secret);
 	g_free (sig_arg);
 	g_free (sig);
 	g_free (url);
@@ -507,14 +538,13 @@ rb_audioscrobbler_account_got_token_cb (SoupSession *session,
 {
 	/* parses the authentication token from the response
 	 */
-	RBAudioscrobblerAccount *account;
-
-	g_assert (RB_IS_AUDIOSCROBBLER_ACCOUNT (user_data));
-	account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
+	RBAudioscrobblerAccount *account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
 
 	if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) && msg->response_body->length != 0) {
 		char **pre_split;
 		char **post_split;
+		char *auth_url;
+		char *api_key;
 		char *url;
 
 		/* parse the response */
@@ -524,10 +554,16 @@ rb_audioscrobbler_account_got_token_cb (SoupSession *session,
 
 		rb_debug ("granted auth token \"%s\"", account->priv->auth_token);
 
+		/* get the service details */
+		g_object_get (account->priv->service,
+			      "auth-url", &auth_url,
+			      "api-key", &api_key,
+			      NULL);
+
 		/* send the user to the web page using the token */
 		url = g_strdup_printf ("%s?api_key=%s&token=%s",
-		                       LASTFM_AUTH_URL,
-		                       LASTFM_API_KEY,
+		                       auth_url,
+		                       api_key,
 		                       account->priv->auth_token);
 		rb_debug ("sending user to %s", url);
 		gtk_show_uri (NULL, url, GDK_CURRENT_TIME, NULL);
@@ -540,6 +576,8 @@ rb_audioscrobbler_account_got_token_cb (SoupSession *session,
 
 		g_strfreev (pre_split);
 		g_strfreev (post_split);
+		g_free (auth_url);
+		g_free (api_key);
 		g_free (url);
 	} else {
 		/* failed. report connection error */
@@ -558,6 +596,9 @@ rb_audioscrobbler_account_request_session_key_timeout_cb (gpointer user_data)
 {
 	/* Periodically sends a request for the session key */
 	RBAudioscrobblerAccount *account;
+	char *api_url;
+	char *api_key;
+	char *api_secret;
 	char *sig_arg;
 	char *sig;
 	char *url;
@@ -566,15 +607,22 @@ rb_audioscrobbler_account_request_session_key_timeout_cb (gpointer user_data)
 	g_assert (RB_IS_AUDIOSCROBBLER_ACCOUNT (user_data));
 	account = RB_AUDIOSCROBBLER_ACCOUNT (user_data);
 
+	/* get the service details */
+	g_object_get (account->priv->service,
+	              "api-url", &api_url,
+	              "api-key", &api_key,
+	              "api-secret", &api_secret,
+	              NULL);
+
 	/* create the request */
 	sig_arg = g_strdup_printf ("api_key%smethodauth.getSessiontoken%s%s",
-	                           LASTFM_API_KEY,
+	                           api_key,
 	                           account->priv->auth_token,
-	                           LASTFM_API_SECRET);
+	                           api_secret);
 	sig = mkmd5 (sig_arg);
 	url = g_strdup_printf ("%s?method=auth.getSession&api_key=%s&token=%s&api_sig=%s",
-	                       LASTFM_API_URL,
-	                       LASTFM_API_KEY,
+	                       api_url,
+	                       api_key,
 	                       account->priv->auth_token,
 	                       sig);
 
@@ -587,6 +635,9 @@ rb_audioscrobbler_account_request_session_key_timeout_cb (gpointer user_data)
 	                            rb_audioscrobbler_account_got_session_key_cb,
 	                            account);
 
+	g_free (api_url);
+	g_free (api_key);
+	g_free (api_secret);
 	g_free (sig_arg);
 	g_free (sig);
 	g_free (url);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-account.h b/plugins/audioscrobbler/rb-audioscrobbler-account.h
index 37b6561..64cab79 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-account.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-account.h
@@ -29,8 +29,9 @@
 #ifndef __RB_AUDIOSCROBBLER_ACCOUNT_H
 #define __RB_AUDIOSCROBBLER_ACCOUNT_H
 
-#include <gtk/gtk.h>
-#include <glib.h>
+#include <glib-object.h>
+
+#include "rb-audioscrobbler-service.h"
 
 G_BEGIN_DECLS
 
@@ -72,7 +73,7 @@ typedef struct
 
 GType                           rb_audioscrobbler_account_get_type (void);
 
-RBAudioscrobblerAccount *       rb_audioscrobbler_account_new (void);
+RBAudioscrobblerAccount *       rb_audioscrobbler_account_new (RBAudioscrobblerService *service);
 
 void                            rb_audioscrobbler_account_authenticate (RBAudioscrobblerAccount *account);
 void                            rb_audioscrobbler_account_logout (RBAudioscrobblerAccount *account);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-plugin.c b/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
index cba893f..9054252 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-plugin.c
@@ -37,6 +37,7 @@
 #include <glib.h>
 #include <glib-object.h>
 
+#include "rb-audioscrobbler-service.h"
 #include "rb-audioscrobbler-profile-source.h"
 #include "rb-plugin.h"
 #include "rb-debug.h"
@@ -107,11 +108,17 @@ static void
 impl_activate (RBPlugin *bplugin,
 	       RBShell *shell)
 {
-	RBAudioscrobblerPlugin *plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
+	RBAudioscrobblerPlugin *plugin;
+	RBAudioscrobblerService *service;
+
+	plugin = RB_AUDIOSCROBBLER_PLUGIN (bplugin);
 
-	plugin->source = rb_audioscrobbler_profile_source_new (shell, bplugin);
+	service = rb_audioscrobbler_service_new ();
+	plugin->source = rb_audioscrobbler_profile_source_new (shell, bplugin, service);
 
 	rb_shell_append_source (shell, plugin->source, NULL);
+
+	g_object_unref (service);
 }
 
 static void
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index 3542988..4ff0d91 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -34,15 +34,8 @@
 #include "rb-debug.h"
 #include "rb-util.h"
 
-/* this API key belongs to Jamie Nicol <jamie thenicols net>
-   generated May 2010 for use in the audioscrobbler plugin */
-#define LASTFM_API_KEY "0337ff3c59299b6a31d75164041860b6"
-#define LASTFM_API_SECRET "776c85a04a445efa8f9ed7705473c606"
-#define LASTFM_API_URL "http://ws.audioscrobbler.com/2.0/";
-#define LASTFM_AUTH_URL "http://www.last.fm/api/auth/";
-#define LASTFM_SCROBBLER_URL "http://post.audioscrobbler.com/";
-
 struct _RBAudioscrobblerProfileSourcePrivate {
+	RBAudioscrobblerService *service;
 	RBAudioscrobblerAccount *account;
 	RBAudioscrobbler *audioscrobbler;
 
@@ -60,6 +53,14 @@ static void rb_audioscrobbler_profile_source_init (RBAudioscrobblerProfileSource
 static void rb_audioscrobbler_profile_source_constructed (GObject *object);
 static void rb_audioscrobbler_profile_source_dispose (GObject* object);
 static void rb_audioscrobbler_profile_source_finalize (GObject *object);
+static void rb_audioscrobbler_profile_source_get_property (GObject *object,
+                                                           guint prop_id,
+                                                           GValue *value,
+                                                           GParamSpec *pspec);
+static void rb_audioscrobbler_profile_source_set_property (GObject *object,
+                                                           guint prop_id,
+                                                           const GValue *value,
+                                                           GParamSpec *pspec);
 
 static void rb_audioscrobbler_profile_source_init_login_ui (RBAudioscrobblerProfileSource *source);
 static void rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
@@ -73,19 +74,26 @@ 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);
 
+enum {
+	PROP_0,
+	PROP_SERVICE
+};
+
 G_DEFINE_TYPE (RBAudioscrobblerProfileSource, rb_audioscrobbler_profile_source, RB_TYPE_SOURCE)
 
 RBSource *
-rb_audioscrobbler_profile_source_new (RBShell *shell, RBPlugin *plugin)
+rb_audioscrobbler_profile_source_new (RBShell *shell, RBPlugin *plugin, RBAudioscrobblerService *service)
 {
 	RBSource *source;
 	RhythmDB *db;
+	char *name;
 	RhythmDBEntryType entry_type;
 	gchar *icon_filename;
 	gint icon_size;
 	GdkPixbuf *icon_pixbuf;
 
 	g_object_get (shell, "db", &db, NULL);
+	g_object_get (service, "name", &name, NULL);
 
 	entry_type = rhythmdb_entry_type_get_by_name (db, "audioscrobbler-radio-track");
 	if (entry_type == RHYTHMDB_ENTRY_TYPE_INVALID) {
@@ -101,15 +109,17 @@ rb_audioscrobbler_profile_source_new (RBShell *shell, RBPlugin *plugin)
 	source = RB_SOURCE (g_object_new (RB_TYPE_AUDIOSCROBBLER_PROFILE_SOURCE,
 	                                  "shell", shell,
 	                                  "plugin", plugin,
-	                                  "name", _("Last.fm"),
+	                                  "name", name,
 	                                  "source-group", RB_SOURCE_GROUP_LIBRARY,
 	                                  "entry-type", entry_type,
 	                                  "icon", icon_pixbuf,
+	                                  "service", service,
 	                                  NULL));
 
 	rb_shell_register_entry_type_for_source (shell, source, entry_type);
 
 	g_object_unref (db);
+	g_free (name);
 	g_free (icon_filename);
 	g_object_unref (icon_pixbuf);
 
@@ -124,6 +134,16 @@ rb_audioscrobbler_profile_source_class_init (RBAudioscrobblerProfileSourceClass
 	object_class->constructed = rb_audioscrobbler_profile_source_constructed;
 	object_class->dispose = rb_audioscrobbler_profile_source_dispose;
 	object_class->finalize = rb_audioscrobbler_profile_source_finalize;
+	object_class->get_property = rb_audioscrobbler_profile_source_get_property;
+	object_class->set_property = rb_audioscrobbler_profile_source_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_SERVICE,
+	                                 g_param_spec_object ("service",
+	                                                      "Service",
+	                                                      "Audioscrobbler service that this is a source for",
+	                                                      RB_TYPE_AUDIOSCROBBLER_SERVICE,
+                                                              G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
 	g_type_class_add_private (klass, sizeof (RBAudioscrobblerProfileSourcePrivate));
 }
@@ -154,7 +174,7 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
 	g_object_get (source, "shell", &shell, NULL);
 
 	/* create the account */
-	source->priv->account = rb_audioscrobbler_account_new ();
+	source->priv->account = rb_audioscrobbler_account_new (source->priv->service);
 	g_signal_connect (source->priv->account,
 	                  "login-status-changed",
 	                  (GCallback)rb_audioscrobbler_profile_source_login_status_change_cb,
@@ -162,10 +182,8 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
 
 	/* create the scrobbler */
 	source->priv->audioscrobbler =
-		rb_audioscrobbler_new (RB_SHELL_PLAYER (rb_shell_get_player (shell)),
-		                       LASTFM_SCROBBLER_URL,
-		                       LASTFM_API_KEY,
-		                       LASTFM_API_SECRET);
+		rb_audioscrobbler_new (source->priv->service,
+		                       RB_SHELL_PLAYER (rb_shell_get_player (shell)));
 	g_signal_connect (source->priv->audioscrobbler,
 	                  "authentication-error",
 	                  (GCallback)rb_audioscrobbler_profile_source_scrobbler_authentication_error_cb,
@@ -187,6 +205,11 @@ rb_audioscrobbler_profile_source_dispose (GObject* object)
 
 	source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (object);
 
+	if (source->priv->service != NULL) {
+		g_object_unref (source->priv->service);
+		source->priv->service = NULL;
+	}
+
 	if (source->priv->audioscrobbler != NULL) {
 		g_object_unref (source->priv->audioscrobbler);
 		source->priv->audioscrobbler = NULL;
@@ -211,6 +234,36 @@ rb_audioscrobbler_profile_source_finalize (GObject *object)
 }
 
 static void
+rb_audioscrobbler_profile_source_get_property (GObject *object,
+                                               guint prop_id,
+                                               GValue *value,
+                                               GParamSpec *pspec)
+{
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+rb_audioscrobbler_profile_source_set_property (GObject *object,
+                                               guint prop_id,
+                                               const GValue *value,
+                                               GParamSpec *pspec)
+{
+	RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (object);
+	switch (prop_id) {
+	case PROP_SERVICE:
+		source->priv->service = g_value_dup_object (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
 rb_audioscrobbler_profile_source_init_login_ui (RBAudioscrobblerProfileSource *source)
 {
 	GtkWidget *content_area;
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.h b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.h
index 7acf09a..a54c921 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.h
@@ -32,6 +32,7 @@
 #include "rb-source.h"
 #include "rb-shell.h"
 #include "rb-plugin.h"
+#include "rb-audioscrobbler-service.h"
 
 G_BEGIN_DECLS
 
@@ -57,7 +58,9 @@ typedef struct
 } RBAudioscrobblerProfileSourceClass;
 
 GType rb_audioscrobbler_profile_source_get_type (void);
-RBSource *rb_audioscrobbler_profile_source_new (RBShell *shell, RBPlugin *plugin);
+RBSource *rb_audioscrobbler_profile_source_new (RBShell *shell,
+                                                RBPlugin *plugin,
+                                                RBAudioscrobblerService *service);
 
 G_END_DECLS
 
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.c b/plugins/audioscrobbler/rb-audioscrobbler-service.c
new file mode 100644
index 0000000..9e2c1a7
--- /dev/null
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.c
@@ -0,0 +1,242 @@
+/*
+ * rb-audioscrobbler-service.c
+ *
+ * Copyright (C) 2010 Jamie Nicol <jamie thenicols net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The Rhythmbox authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Rhythmbox. This permission is above and beyond the permissions granted
+ * by the GPL license by which Rhythmbox is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ */
+
+#include "rb-audioscrobbler-service.h"
+
+/* Last.fm details */
+#define LASTFM_NAME "Last.fm"
+#define LASTFM_AUTH_URL "http://www.last.fm/api/auth/";
+#define LASTFM_SCROBBLER_URL "http://post.audioscrobbler.com/";
+#define LASTFM_API_URL "http://ws.audioscrobbler.com/2.0/";
+/* this API key belongs to Jamie Nicol <jamie thenicols net>
+   generated May 2010 for use in the audioscrobbler plugin */
+#define LASTFM_API_KEY "0337ff3c59299b6a31d75164041860b6"
+#define LASTFM_API_SECRET "776c85a04a445efa8f9ed7705473c606"
+
+struct _RBAudioscrobblerServicePrivate {
+	char *name;
+	char *auth_url;
+	char *scrobbler_url;
+	char *api_url;
+	char *api_key;
+	char *api_secret;
+};
+
+#define RB_AUDIOSCROBBLER_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_SERVICE, RBAudioscrobblerServicePrivate))
+
+static void rb_audioscrobbler_service_class_init (RBAudioscrobblerServiceClass *klass);
+static void rb_audioscrobbler_service_init (RBAudioscrobblerService *service);
+static void rb_audioscrobbler_service_finalize (GObject *object);
+static void rb_audioscrobbler_service_get_property (GObject *object,
+                                                    guint prop_id,
+                                                    GValue *value,
+                                                    GParamSpec *pspec);
+static void rb_audioscrobbler_service_set_property (GObject *object,
+                                                    guint prop_id,
+                                                    const GValue *value,
+                                                    GParamSpec *pspec);
+
+enum
+{
+	PROP_0,
+	PROP_NAME,
+	PROP_AUTH_URL,
+	PROP_SCROBBLER_URL,
+	PROP_API_URL,
+	PROP_API_KEY,
+	PROP_API_SECRET,
+};
+
+G_DEFINE_TYPE (RBAudioscrobblerService, rb_audioscrobbler_service, G_TYPE_OBJECT)
+
+RBAudioscrobblerService *
+rb_audioscrobbler_service_new (void)
+{
+	/* create a Last.fm service */
+	return g_object_new (RB_TYPE_AUDIOSCROBBLER_SERVICE,
+	                     "name", LASTFM_NAME,
+	                     "auth-url", LASTFM_AUTH_URL,
+	                     "scrobbler-url", LASTFM_SCROBBLER_URL,
+	                     "api-url", LASTFM_API_URL,
+	                     "api-key", LASTFM_API_KEY,
+	                     "api-secret", LASTFM_API_SECRET,
+	                     NULL);
+}
+
+static void
+rb_audioscrobbler_service_class_init (RBAudioscrobblerServiceClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = rb_audioscrobbler_service_finalize;
+	object_class->get_property = rb_audioscrobbler_service_get_property;
+	object_class->set_property = rb_audioscrobbler_service_set_property;
+
+	g_object_class_install_property (object_class,
+	                                 PROP_NAME,
+	                                 g_param_spec_string ("name",
+	                                                      "Name",
+	                                                      "Name of the service",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_AUTH_URL,
+	                                 g_param_spec_string ("auth-url",
+	                                                      "Authentication URL",
+	                                                      "URL user should be taken to for authentication",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_SCROBBLER_URL,
+	                                 g_param_spec_string ("scrobbler-url",
+	                                                      "Scrobbler URL",
+	                                                      "URL scrobbler sessions should be made with",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_API_URL,
+	                                 g_param_spec_string ("api-url",
+	                                                      "API URL",
+	                                                      "URL API requests should be sent to",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_API_KEY,
+	                                 g_param_spec_string ("api-key",
+	                                                      "API Key",
+	                                                      "API key",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
+	                                 PROP_API_SECRET,
+	                                 g_param_spec_string ("api-secret",
+	                                                      "API Secret",
+	                                                      "API secret",
+	                                                      NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_type_class_add_private (klass, sizeof (RBAudioscrobblerServicePrivate));
+}
+
+static void
+rb_audioscrobbler_service_init (RBAudioscrobblerService *service)
+{
+	service->priv = RB_AUDIOSCROBBLER_SERVICE_GET_PRIVATE (service);
+}
+
+static void
+rb_audioscrobbler_service_finalize (GObject *object)
+{
+	RBAudioscrobblerService *service = RB_AUDIOSCROBBLER_SERVICE (object);
+
+	g_free (service->priv->name);
+	g_free (service->priv->auth_url);
+	g_free (service->priv->scrobbler_url);
+	g_free (service->priv->api_url);
+	g_free (service->priv->api_key);
+	g_free (service->priv->api_secret);
+
+	G_OBJECT_CLASS (rb_audioscrobbler_service_parent_class)->finalize (object);
+}
+
+static void
+rb_audioscrobbler_service_get_property (GObject *object,
+                                        guint prop_id,
+                                        GValue *value,
+                                        GParamSpec *pspec)
+{
+	RBAudioscrobblerService *service = RB_AUDIOSCROBBLER_SERVICE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_value_set_string (value, service->priv->name);
+		break;
+	case PROP_AUTH_URL:
+		g_value_set_string (value, service->priv->auth_url);
+		break;
+	case PROP_SCROBBLER_URL:
+		g_value_set_string (value, service->priv->scrobbler_url);
+		break;
+	case PROP_API_URL:
+		g_value_set_string (value, service->priv->api_url);
+		break;
+	case PROP_API_KEY:
+		g_value_set_string (value, service->priv->api_key);
+		break;
+	case PROP_API_SECRET:
+		g_value_set_string (value, service->priv->api_secret);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+rb_audioscrobbler_service_set_property (GObject *object,
+                                        guint prop_id,
+                                        const GValue *value,
+                                        GParamSpec *pspec)
+{
+	RBAudioscrobblerService *service = RB_AUDIOSCROBBLER_SERVICE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		g_free (service->priv->name);
+		service->priv->name = g_value_dup_string (value);
+		break;
+	case PROP_AUTH_URL:
+		g_free (service->priv->auth_url);
+		service->priv->auth_url = g_value_dup_string (value);
+		break;
+	case PROP_SCROBBLER_URL:
+		g_free (service->priv->scrobbler_url);
+		service->priv->scrobbler_url = g_value_dup_string (value);
+		break;
+	case PROP_API_URL:
+		g_free (service->priv->api_url);
+		service->priv->api_url = g_value_dup_string (value);
+		break;
+	case PROP_API_KEY:
+		g_free (service->priv->api_key);
+		service->priv->api_key = g_value_dup_string (value);
+		break;
+	case PROP_API_SECRET:
+		g_free (service->priv->api_secret);
+		service->priv->api_secret = g_value_dup_string (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-service.h b/plugins/audioscrobbler/rb-audioscrobbler-service.h
new file mode 100644
index 0000000..257d9de
--- /dev/null
+++ b/plugins/audioscrobbler/rb-audioscrobbler-service.h
@@ -0,0 +1,61 @@
+/*
+ * rb-audioscrobbler-service.h
+ *
+ * Copyright (C) 2010 Jamie Nicol <jamie thenicols net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The Rhythmbox authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Rhythmbox. This permission is above and beyond the permissions granted
+ * by the GPL license by which Rhythmbox is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ */
+
+#ifndef __RB_AUDIOSCROBBLER_SERVICE_H
+#define __RB_AUDIOSCROBBLER_SERVICE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define RB_TYPE_AUDIOSCROBBLER_SERVICE         (rb_audioscrobbler_service_get_type ())
+#define RB_AUDIOSCROBBLER_SERVICE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_AUDIOSCROBBLER_SERVICE, RBAudioscrobblerService))
+#define RB_AUDIOSCROBBLER_SERVICE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_AUDIOSCROBBLER_SERVICE, RBAudioscrobblerServiceClass))
+#define RB_IS_AUDIOSCROBBLER_SERVICE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_AUDIOSCROBBLER_SERVICE))
+#define RB_IS_AUDIOSCROBBLER_SERVICE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_AUDIOSCROBBLER_SERVICE))
+#define RB_AUDIOSCROBBLER_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_AUDIOSCROBBLER_SERVICE, RBAudioscrobblerServiceClass))
+
+typedef struct _RBAudioscrobblerServicePrivate RBAudioscrobblerServicePrivate;
+
+typedef struct {
+	GObject parent;
+
+	RBAudioscrobblerServicePrivate *priv;
+} RBAudioscrobblerService;
+
+typedef struct {
+	GObjectClass parent_class;
+} RBAudioscrobblerServiceClass;
+
+GType rb_audioscrobbler_service_get_type (void);
+
+RBAudioscrobblerService *rb_audioscrobbler_service_new (void);
+
+G_END_DECLS
+
+#endif /* __RB_AUDIOSCROBBLER_SERVICE_H */
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.c b/plugins/audioscrobbler/rb-audioscrobbler.c
index f2bce2a..20848e1 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler.c
@@ -76,6 +76,8 @@
 
 struct _RBAudioscrobblerPrivate
 {
+	RBAudioscrobblerService *service;
+
 	RBShellPlayer *shell_player;
 
 	/* Data for the prefs pane */
@@ -107,13 +109,6 @@ struct _RBAudioscrobblerPrivate
 	/* Only write the queue to a file if it has been changed */
 	gboolean queue_changed;
 
-	/* API settings - These will differ depending on which scrobbler
-	 * service is being used. eg Last.fm or Libre.fm
-	 */
-	gchar *scrobbler_url;
-	gchar *api_key;
-	gchar *api_secret;
-
 	/* Authentication cookie + authentication info */
 	gchar *sessionid;
 	gchar *username;
@@ -191,10 +186,8 @@ static void          rb_audioscrobbler_nowplaying (RBAudioscrobbler *audioscrobb
 enum
 {
 	PROP_0,
-	PROP_SHELL_PLAYER,
-	PROP_SCROBBLER_URL,
-	PROP_API_KEY,
-	PROP_API_SECRET
+	PROP_SERVICE,
+	PROP_SHELL_PLAYER
 };
 
 enum
@@ -240,6 +233,14 @@ rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass)
 	object_class->get_property = rb_audioscrobbler_get_property;
 
 	g_object_class_install_property (object_class,
+	                                 PROP_SERVICE,
+	                                 g_param_spec_object ("service",
+	                                                      "Service",
+	                                                      "Audioscrobbler service to scrobble to",
+	                                                      RB_TYPE_AUDIOSCROBBLER_SERVICE,
+                                                              G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+	g_object_class_install_property (object_class,
 					 PROP_SHELL_PLAYER,
 					 g_param_spec_object ("shell-player",
 							      "RBShellPlayer",
@@ -247,30 +248,6 @@ rb_audioscrobbler_class_init (RBAudioscrobblerClass *klass)
 							      RB_TYPE_SHELL_PLAYER,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-	g_object_class_install_property (object_class,
-					 PROP_SCROBBLER_URL,
-					 g_param_spec_string ("scrobbler-url",
-							      "Scrobbler URL",
-							      "URL that the scrobbling session should be created with",
-							      NULL,
-							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class,
-					 PROP_API_KEY,
-					 g_param_spec_string ("api-key",
-							      "API Key",
-							      "API key used to authenticate the application with the scrobbler service",
-							      NULL,
-							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
-	g_object_class_install_property (object_class,
-					 PROP_API_SECRET,
-					 g_param_spec_string ("api-secret",
-							      "API Secret",
-							      "API secret used to authenticate the application with the scrobbler service",
-							      NULL,
-							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
 	/**
 	 * RBAudioscrobbler::authentication-error:
 	 * @account: the #RBAudioscrobblerAccount
@@ -347,6 +324,11 @@ rb_audioscrobbler_dispose (GObject *object)
 		audioscrobbler->priv->soup_session = NULL;
 	}
 
+	if (audioscrobbler->priv->service != NULL) {
+		g_object_unref (audioscrobbler->priv->service);
+		audioscrobbler->priv->service = NULL;
+	}
+
 	if (audioscrobbler->priv->shell_player != NULL) {
 		g_object_unref (audioscrobbler->priv->shell_player);
 		audioscrobbler->priv->shell_player = NULL;
@@ -370,10 +352,6 @@ rb_audioscrobbler_finalize (GObject *object)
 	/* Save any remaining entries */
 	rb_audioscrobbler_save_queue (audioscrobbler);
 
-	g_free (audioscrobbler->priv->scrobbler_url);
-	g_free (audioscrobbler->priv->api_key);
-	g_free (audioscrobbler->priv->api_secret);
-
 	g_free (audioscrobbler->priv->sessionid);
 	g_free (audioscrobbler->priv->username);
 	g_free (audioscrobbler->priv->session_key);
@@ -392,16 +370,12 @@ rb_audioscrobbler_finalize (GObject *object)
 }
 
 RBAudioscrobbler*
-rb_audioscrobbler_new (RBShellPlayer *shell_player,
-                       const char *scrobbler_url,
-                       const char *api_key,
-                       const char *api_secret)
+rb_audioscrobbler_new (RBAudioscrobblerService *service,
+                       RBShellPlayer *shell_player)
 {
 	return g_object_new (RB_TYPE_AUDIOSCROBBLER,
+	                     "service", service,
 			     "shell-player", shell_player,
-	                     "scrobbler-url", scrobbler_url,
-	                     "api-key", api_key,
-	                     "api-secret", api_secret,
 			     NULL);
 }
 
@@ -414,6 +388,9 @@ rb_audioscrobbler_set_property (GObject *object,
 	RBAudioscrobbler *audioscrobbler = RB_AUDIOSCROBBLER (object);
 
 	switch (prop_id) {
+	case PROP_SERVICE:
+		audioscrobbler->priv->service = g_value_dup_object (value);
+		break;
 	case PROP_SHELL_PLAYER:
 		audioscrobbler->priv->shell_player = g_value_get_object (value);
 		g_object_ref (G_OBJECT (audioscrobbler->priv->shell_player));
@@ -422,18 +399,6 @@ rb_audioscrobbler_set_property (GObject *object,
 					 G_CALLBACK (rb_audioscrobbler_song_changed_cb),
 					 audioscrobbler, 0);
 		break;
-	case PROP_SCROBBLER_URL:
-		g_free (audioscrobbler->priv->scrobbler_url);
-		audioscrobbler->priv->scrobbler_url = g_value_dup_string (value);
-		break;
-	case PROP_API_KEY:
-		g_free (audioscrobbler->priv->api_key);
-		audioscrobbler->priv->api_key = g_value_dup_string (value);
-		break;
-	case PROP_API_SECRET:
-		g_free (audioscrobbler->priv->api_secret);
-		audioscrobbler->priv->api_secret = g_value_dup_string (value);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -452,15 +417,6 @@ rb_audioscrobbler_get_property (GObject *object,
 	case PROP_SHELL_PLAYER:
 		g_value_set_object (value, audioscrobbler->priv->shell_player);
 		break;
-	case PROP_SCROBBLER_URL:
-		g_value_set_string (value, audioscrobbler->priv->scrobbler_url);
-		break;
-	case PROP_API_KEY:
-		g_value_set_string (value, audioscrobbler->priv->api_key);
-		break;
-	case PROP_API_SECRET:
-		g_value_set_string (value, audioscrobbler->priv->api_secret);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -826,6 +782,9 @@ rb_audioscrobbler_should_handshake (RBAudioscrobbler *audioscrobbler)
 static void
 rb_audioscrobbler_do_handshake (RBAudioscrobbler *audioscrobbler)
 {
+	gchar *api_key;
+	gchar *api_secret;
+	gchar *scrobbler_url;
 	gchar *username;
 	gchar *url;
 	gchar *auth;
@@ -836,23 +795,32 @@ rb_audioscrobbler_do_handshake (RBAudioscrobbler *audioscrobbler)
 		return;
 	}
 
+	/* get the service details */
+	g_object_get (audioscrobbler->priv->service,
+	              "api-key", &api_key,
+	              "api-secret", &api_secret,
+	              "scrobbler-url", &scrobbler_url,
+	              NULL);
+
 	username = soup_uri_encode (audioscrobbler->priv->username, EXTRA_URI_ENCODE_CHARS);
 	timestamp = time (NULL);
 
-	autharg = g_strdup_printf ("%s%d", audioscrobbler->priv->api_secret, timestamp);
+	autharg = g_strdup_printf ("%s%d", api_secret, timestamp);
 	auth = mkmd5 (autharg);
 
 	url = g_strdup_printf ("%s?hs=true&p=%s&c=%s&v=%s&u=%s&t=%d&a=%s&api_key=%s&sk=%s",
-			       audioscrobbler->priv->scrobbler_url,
+			       scrobbler_url,
 			       SCROBBLER_VERSION,
 			       CLIENT_ID,
 			       CLIENT_VERSION,
 			       username,
 			       timestamp,
 			       auth,
-	                       audioscrobbler->priv->api_key,
+	                       api_key,
 	                       audioscrobbler->priv->session_key);
-
+	g_free (api_key);
+	g_free (api_secret);
+	g_free (scrobbler_url);
 	g_free (auth);
 	g_free (autharg);
 	g_free (username);
diff --git a/plugins/audioscrobbler/rb-audioscrobbler.h b/plugins/audioscrobbler/rb-audioscrobbler.h
index e554993..5083617 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
 
 #include "rb-shell-player.h"
 #include "rb-plugin.h"
+#include "rb-audioscrobbler-service.h"
 
 #define RB_TYPE_AUDIOSCROBBLER			(rb_audioscrobbler_get_type ())
 #define RB_AUDIOSCROBBLER(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_AUDIOSCROBBLER, RBAudioscrobbler))
@@ -64,10 +65,8 @@ typedef struct
 
 GType			rb_audioscrobbler_get_type (void);
 
-RBAudioscrobbler *	rb_audioscrobbler_new (RBShellPlayer *shell_player,
-                                               const char *scrobbler_url,
-                                               const char *api_key,
-                                               const char *api_secret);
+RBAudioscrobbler *	rb_audioscrobbler_new (RBAudioscrobblerService *service,
+                                               RBShellPlayer *shell_player);
 
 void                    rb_audioscrobbler_set_authentication_details (RBAudioscrobbler *audioscrobbler,
                                                                       const char *username,



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