[rhythmbox] audioscrobbler: add love and ban actions
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] audioscrobbler: add love and ban actions
- Date: Tue, 21 Sep 2010 10:50:31 +0000 (UTC)
commit 28f0bc1af438070ef869051b838c2903a41e14f2
Author: Jamie Nicol <jamie thenicols net>
Date: Wed Jul 7 22:15:43 2010 +0100
audioscrobbler: add love and ban actions
.../rb-audioscrobbler-profile-source.c | 145 ++++++++++++++++++++
.../rb-audioscrobbler-radio-source.c | 10 ++
plugins/audioscrobbler/rb-audioscrobbler-user.c | 116 ++++++++++++++++
plugins/audioscrobbler/rb-audioscrobbler-user.h | 7 +
4 files changed, 278 insertions(+), 0 deletions(-)
---
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index af3eb67..ccd5110 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -91,6 +91,8 @@ struct _RBAudioscrobblerProfileSourcePrivate {
GHashTable *button_to_popup_menu_map;
GHashTable *popup_menu_to_data_map;
+
+ GtkActionGroup *action_group;
};
#define RB_AUDIOSCROBBLER_PROFILE_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_PROFILE_SOURCE, RBAudioscrobblerProfileSourcePrivate))
@@ -111,6 +113,7 @@ static void rb_audioscrobbler_profile_source_set_property (GObject *object,
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);
static void rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
gint response_id,
@@ -136,6 +139,9 @@ static void rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb (RB
guint submit_count,
const char *submit_time,
gpointer user_data);
+static void rb_audioscrobbler_profile_source_playing_song_changed_cb (RBShellPlayer *player,
+ RhythmDBEntry *entry,
+ RBAudioscrobblerProfileSource *source);
static void rb_audioscrobbler_profile_source_create_radio_sources (RBAudioscrobblerProfileSource *source);
@@ -173,6 +179,12 @@ void rb_audioscrobbler_profile_source_list_layout_size_allocate_cb (GtkWidget *l
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);
+
+static GList *impl_get_ui_actions (RBSource *asource);
static void impl_delete_thyself (RBSource *asource);
@@ -233,6 +245,7 @@ rb_audioscrobbler_profile_source_class_init (RBAudioscrobblerProfileSourceClass
object_class->set_property = rb_audioscrobbler_profile_source_set_property;
source_class = RB_SOURCE_CLASS (klass);
+ source_class->impl_get_ui_actions = impl_get_ui_actions;
source_class->impl_delete_thyself = impl_delete_thyself;
g_object_class_install_property (object_class,
@@ -269,6 +282,11 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
rb_shell_append_source (shell, RB_SOURCE (source), NULL);
+ g_signal_connect_object (rb_shell_get_player (shell),
+ "playing-song-changed",
+ G_CALLBACK (rb_audioscrobbler_profile_source_playing_song_changed_cb),
+ source, 0);
+
/* create the UI */
source->priv->main_vbox = gtk_vbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (source), source->priv->main_vbox, TRUE, TRUE, 0);
@@ -276,6 +294,7 @@ rb_audioscrobbler_profile_source_constructed (GObject *object)
rb_audioscrobbler_profile_source_init_login_ui (source);
rb_audioscrobbler_profile_source_init_profile_ui (source);
+ rb_audioscrobbler_profile_source_init_actions (source);
/* create the user */
source->priv->user = rb_audioscrobbler_user_new (source->priv->service);
@@ -518,6 +537,43 @@ rb_audioscrobbler_profile_source_init_profile_ui (RBAudioscrobblerProfileSource
}
static void
+rb_audioscrobbler_profile_source_init_actions (RBAudioscrobblerProfileSource *source)
+{
+ /* Unfortunately we can't use the usual trick of declaring a static array of GtkActionEntry,
+ * and simply using _rb_source_register_action_group with that array.
+ * This is because each instance of this source needs its own love and ban actions
+ * so tracks can be loved/banned differently for different audioscrobbler services.
+ */
+
+ char *group_name;
+ char *love_name;
+ char *ban_name;
+
+ group_name = g_strdup_printf ("%sActions", rb_audioscrobbler_service_get_name (source->priv->service));
+ love_name = g_strdup_printf ("%sLoveTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+ ban_name = g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+
+ GtkActionEntry actions [] =
+ {
+ { love_name, "emblem-favorite", N_("Love"), NULL,
+ N_("Mark this song as loved"),
+ G_CALLBACK (rb_audioscrobbler_profile_source_love_track_action_cb) },
+ { ban_name, GTK_STOCK_CANCEL, N_("Ban"), NULL,
+ N_("Ban the current track from being played again"),
+ G_CALLBACK (rb_audioscrobbler_profile_source_ban_track_action_cb) },
+ };
+
+ source->priv->action_group = _rb_source_register_action_group (RB_SOURCE (source),
+ group_name,
+ actions,
+ G_N_ELEMENTS (actions),
+ source);
+ g_free (group_name);
+ g_free (love_name);
+ g_free (ban_name);
+}
+
+static void
rb_audioscrobbler_profile_source_login_bar_response (GtkInfoBar *info_bar,
gint response_id,
gpointer user_data)
@@ -728,6 +784,26 @@ rb_audioscrobbler_profile_source_scrobbler_statistics_changed_cb (RBAudioscrobbl
}
static void
+rb_audioscrobbler_profile_source_playing_song_changed_cb (RBShellPlayer *player,
+ RhythmDBEntry *entry,
+ RBAudioscrobblerProfileSource *source)
+{
+ char *action_name;
+ GtkAction *action;
+
+ /* re-enable love/ban */
+ action_name = g_strdup_printf ("%sLoveTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+ action = gtk_action_group_get_action (source->priv->action_group, action_name);
+ gtk_action_set_sensitive (action, TRUE);
+ g_free (action_name);
+
+ action_name = g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+ action = gtk_action_group_get_action (source->priv->action_group, action_name);
+ gtk_action_set_sensitive (action, TRUE);
+ g_free (action_name);
+}
+
+static void
rb_audioscrobbler_profile_source_create_radio_sources (RBAudioscrobblerProfileSource *source)
{
const char *username;
@@ -1141,7 +1217,76 @@ rb_audioscrobbler_profile_source_list_layout_size_allocate_cb (GtkWidget *layout
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 ("%sBanSong", 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)
+{
+ RBAudioscrobblerProfileSource *source = RB_AUDIOSCROBBLER_PROFILE_SOURCE (asource);
+ GList *actions = NULL;
+
+ actions = g_list_append (actions,
+ g_strdup_printf ("%sLoveTrack", rb_audioscrobbler_service_get_name (source->priv->service)));
+ actions = g_list_append (actions,
+ g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service)));
+
+ return actions;
+}
+
static void
impl_delete_thyself (RBSource *asource)
{
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
index cd31243..4155e12 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-radio-source.c
@@ -131,6 +131,7 @@ static void impl_activate (RBSource *source);
static RBEntryView *impl_get_entry_view (RBSource *asource);
static void impl_get_status (RBSource *asource, char **text, char **progress_text, float *progress);
static RBSourceEOFType impl_handle_eos (RBSource *asource);
+static GList *impl_get_ui_actions (RBSource *asource);
static void impl_delete_thyself (RBSource *asource);
enum {
@@ -213,6 +214,7 @@ rb_audioscrobbler_radio_source_class_init (RBAudioscrobblerRadioSourceClass *kla
source_class->impl_get_entry_view = impl_get_entry_view;
source_class->impl_get_status = impl_get_status;
source_class->impl_handle_eos = impl_handle_eos;
+ source_class->impl_get_ui_actions = impl_get_ui_actions;
source_class->impl_delete_thyself = impl_delete_thyself;
g_object_class_install_property (object_class,
@@ -911,6 +913,14 @@ impl_handle_eos (RBSource *asource)
return RB_SOURCE_EOF_NEXT;
}
+static GList *
+impl_get_ui_actions (RBSource *asource)
+{
+ RBAudioscrobblerRadioSource *source = RB_AUDIOSCROBBLER_RADIO_SOURCE (asource);
+
+ return rb_source_get_ui_actions (RB_SOURCE (source->priv->parent));
+}
+
static void
impl_delete_thyself (RBSource *asource)
{
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-user.c b/plugins/audioscrobbler/rb-audioscrobbler-user.c
index fd8ffc8..4ac3d85 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-user.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-user.c
@@ -26,6 +26,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <string.h>
#include <libsoup/soup.h>
#include <libsoup/soup-gnome.h>
#include <json-glib/json-glib.h>
@@ -204,6 +205,13 @@ static void rb_audioscrobbler_user_download_image (RBAudioscrobblerUser *user,
static void rb_audioscrobbler_user_image_download_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data);
+
+static void rb_audioscrobbler_user_love_track_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data);
+static void rb_audioscrobbler_user_ban_track_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data);
enum {
PROP_0,
PROP_SERVICE
@@ -1587,3 +1595,111 @@ rb_audioscrobbler_user_image_download_cb (GObject *source_object, GAsyncResult *
rb_debug ("error downloading image. possibly due to cancellation");
}
}
+
+void
+rb_audioscrobbler_user_love_track (RBAudioscrobblerUser *user,
+ const char *title,
+ const char *artist)
+{
+ char *sig_arg;
+ char *sig;
+ char *request;
+ SoupMessage *msg;
+
+ rb_debug ("loving track %s - %s", artist, title);
+
+ sig_arg = g_strdup_printf ("api_key%sartist%smethodtrack.lovesk%strack%s%s",
+ rb_audioscrobbler_service_get_api_key (user->priv->service),
+ artist,
+ user->priv->session_key,
+ title,
+ rb_audioscrobbler_service_get_api_secret (user->priv->service));
+
+ sig = mkmd5 (sig_arg);
+
+ request = g_strdup_printf ("method=track.love&track=%s&artist=%s&api_key=%s&api_sig=%s&sk=%s",
+ title,
+ artist,
+ rb_audioscrobbler_service_get_api_key (user->priv->service),
+ sig,
+ user->priv->session_key);
+
+ msg = soup_message_new ("POST", rb_audioscrobbler_service_get_api_url (user->priv->service));
+ soup_message_set_request (msg,
+ "application/x-www-form-urlencoded",
+ SOUP_MEMORY_COPY,
+ request,
+ strlen (request));
+ soup_session_queue_message (user->priv->soup_session,
+ msg,
+ rb_audioscrobbler_user_love_track_response_cb,
+ user);
+
+ g_free (sig_arg);
+ g_free (sig);
+ g_free (request);
+}
+
+static void
+rb_audioscrobbler_user_love_track_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ /* Don't know if there's anything to do here,
+ * might want a debug message indicating success or failure?
+ */
+}
+
+void
+rb_audioscrobbler_user_ban_track (RBAudioscrobblerUser *user,
+ const char *title,
+ const char *artist)
+{
+ char *sig_arg;
+ char *sig;
+ char *request;
+ SoupMessage *msg;
+
+ rb_debug ("banning track %s - %s", artist, title);
+
+ sig_arg = g_strdup_printf ("api_key%sartist%smethodtrack.bansk%strack%s%s",
+ rb_audioscrobbler_service_get_api_key (user->priv->service),
+ artist,
+ user->priv->session_key,
+ title,
+ rb_audioscrobbler_service_get_api_secret (user->priv->service));
+
+ sig = mkmd5 (sig_arg);
+
+ request = g_strdup_printf ("method=track.ban&track=%s&artist=%s&api_key=%s&api_sig=%s&sk=%s",
+ title,
+ artist,
+ rb_audioscrobbler_service_get_api_key (user->priv->service),
+ sig,
+ user->priv->session_key);
+
+ msg = soup_message_new ("POST", rb_audioscrobbler_service_get_api_url (user->priv->service));
+ soup_message_set_request (msg,
+ "application/x-www-form-urlencoded",
+ SOUP_MEMORY_COPY,
+ request,
+ strlen (request));
+ soup_session_queue_message (user->priv->soup_session,
+ msg,
+ rb_audioscrobbler_user_ban_track_response_cb,
+ user);
+
+ g_free (sig_arg);
+ g_free (sig);
+ g_free (request);
+}
+
+static void
+rb_audioscrobbler_user_ban_track_response_cb (SoupSession *session,
+ SoupMessage *msg,
+ gpointer user_data)
+{
+ /* Don't know if there's anything to do here,
+ * might want a debug message indicating success or failure?
+ */
+}
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-user.h b/plugins/audioscrobbler/rb-audioscrobbler-user.h
index 8aaa591..fbd9120 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-user.h
+++ b/plugins/audioscrobbler/rb-audioscrobbler-user.h
@@ -96,6 +96,13 @@ void rb_audioscrobbler_user_set_authentication_details (RBAudioscrobblerUser *us
void rb_audioscrobbler_user_update (RBAudioscrobblerUser *user);
+void rb_audioscrobbler_user_love_track (RBAudioscrobblerUser *user,
+ const char *title,
+ const char *artist);
+void rb_audioscrobbler_user_ban_track (RBAudioscrobblerUser *user,
+ const char *title,
+ const char *artist);
+
G_END_DECLS
#endif /* __RB_AUDIOSCROBBLER_USER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]