[rhythmbox] audioscrobbler: add tool button to download free tracks
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] audioscrobbler: add tool button to download free tracks
- Date: Tue, 21 Sep 2010 10:54:17 +0000 (UTC)
commit ab15a8b098384ed6b4b0aa8b2e1eae29243a3817
Author: Jamie Nicol <jamie thenicols net>
Date: Wed Aug 4 17:17:45 2010 +0100
audioscrobbler: add tool button to download free tracks
Appears in toolbar next to love and ban actions. When a song is being
played from a radio source which has a download link the user will
be able to download the track into their library.
.../rb-audioscrobbler-profile-source.c | 188 +++++++++++++++++---
1 files changed, 161 insertions(+), 27 deletions(-)
---
diff --git a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
index 57a46d3..8ea863f 100644
--- a/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
+++ b/plugins/audioscrobbler/rb-audioscrobbler-profile-source.c
@@ -38,6 +38,7 @@
#include "rb-audioscrobbler-account.h"
#include "rb-audioscrobbler-user.h"
#include "rb-audioscrobbler-radio-source.h"
+#include "rb-audioscrobbler-radio-track-entry-type.h"
#include "rb-debug.h"
#include "rb-builder-helpers.h"
#include "rb-file-helpers.h"
@@ -109,6 +110,7 @@ struct _RBAudioscrobblerProfileSourcePrivate {
GtkActionGroup *service_action_group;
char *love_action_name;
char *ban_action_name;
+ char *download_action_name;
};
#define RB_AUDIOSCROBBLER_PROFILE_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_AUDIOSCROBBLER_PROFILE_SOURCE, RBAudioscrobblerProfileSourcePrivate))
@@ -162,10 +164,13 @@ static void scrobbler_statistics_changed_cb (RBAudioscrobbler *audioscrobbler,
static void playing_song_changed_cb (RBShellPlayer *player,
RhythmDBEntry *entry,
RBAudioscrobblerProfileSource *source);
+static void update_service_actions_sensitivity (RBAudioscrobblerProfileSource *source);
/* GtkAction callbacks */
static void love_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source);
static void ban_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source);
+static void download_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source);
+static void download_track_batch_complete_cb (RBTrackTransferBatch *batch, RBAudioscrobblerProfileSource *source);
static void refresh_profile_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source);
/* radio station creation/deletion */
@@ -450,6 +455,7 @@ rb_audioscrobbler_profile_source_finalize (GObject *object)
g_free (source->priv->love_action_name);
g_free (source->priv->ban_action_name);
+ g_free (source->priv->download_action_name);
G_OBJECT_CLASS (rb_audioscrobbler_profile_source_parent_class)->finalize (object);
}
@@ -579,7 +585,6 @@ init_actions (RBAudioscrobblerProfileSource *source)
RBPlugin *plugin;
GtkUIManager *ui_manager;
char *group_name;
- RhythmDBEntry *playing;
g_object_get (source, "shell", &shell, "plugin", &plugin, "ui-manager", &ui_manager, NULL);
ui_file = rb_plugin_find_file (plugin, "audioscrobbler-profile-ui.xml");
@@ -602,6 +607,7 @@ init_actions (RBAudioscrobblerProfileSource *source)
group_name = g_strdup_printf ("%sActions", rb_audioscrobbler_service_get_name (source->priv->service));
source->priv->love_action_name = g_strdup_printf ("%sLoveTrack", rb_audioscrobbler_service_get_name (source->priv->service));
source->priv->ban_action_name = g_strdup_printf ("%sBanTrack", rb_audioscrobbler_service_get_name (source->priv->service));
+ source->priv->download_action_name = g_strdup_printf ("%sDownloadTrack", rb_audioscrobbler_service_get_name (source->priv->service));
GtkActionEntry service_actions [] =
{
@@ -610,7 +616,10 @@ init_actions (RBAudioscrobblerProfileSource *source)
G_CALLBACK (love_track_action_cb) },
{ source->priv->ban_action_name, GTK_STOCK_CANCEL, N_("Ban"), NULL,
N_("Ban the current track from being played again"),
- G_CALLBACK (ban_track_action_cb) }
+ G_CALLBACK (ban_track_action_cb) },
+ { source->priv->download_action_name, GTK_STOCK_SAVE, N_("Download"), NULL,
+ N_("Download the currently playing track"),
+ G_CALLBACK (download_track_action_cb) }
};
source->priv->service_action_group = _rb_source_register_action_group (RB_SOURCE (source),
@@ -618,15 +627,7 @@ init_actions (RBAudioscrobblerProfileSource *source)
service_actions,
G_N_ELEMENTS (service_actions),
source);
- /* disable the love and ban actions if there is no playing entry */
- playing = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
- if (playing == NULL) {
- GtkAction *love = gtk_action_group_get_action (source->priv->service_action_group, source->priv->love_action_name);
- GtkAction *ban = gtk_action_group_get_action (source->priv->service_action_group, source->priv->ban_action_name);
- gtk_action_set_sensitive (love, FALSE);
- gtk_action_set_sensitive (ban, FALSE);
- rhythmdb_entry_unref (playing);
- }
+ update_service_actions_sensitivity (source);
g_free (ui_file);
g_object_unref (shell);
@@ -860,37 +861,69 @@ playing_song_changed_cb (RBShellPlayer *player,
RhythmDBEntry *entry,
RBAudioscrobblerProfileSource *source)
{
+ update_service_actions_sensitivity (source);
+}
+
+static void
+update_service_actions_sensitivity (RBAudioscrobblerProfileSource *source)
+{
+ RBShell *shell;
+ RhythmDBEntry *playing;
GtkAction *love;
GtkAction *ban;
+ GtkAction *download;
- /* enable or disable love/ban */
+ g_object_get (source, "shell", &shell, NULL);
+ playing = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
+
+ /* enable love/ban if an entry is playing */
love = gtk_action_group_get_action (source->priv->service_action_group, source->priv->love_action_name);
ban = gtk_action_group_get_action (source->priv->service_action_group, source->priv->ban_action_name);
- if (entry == NULL) {
+ if (playing == NULL) {
gtk_action_set_sensitive (love, FALSE);
gtk_action_set_sensitive (ban, FALSE);
} else {
gtk_action_set_sensitive (love, TRUE);
gtk_action_set_sensitive (ban, TRUE);
}
+
+ /* enable download if the playing entry is a radio track from this service which provides a download url */
+ download = gtk_action_group_get_action (source->priv->service_action_group, source->priv->download_action_name);
+ if (playing != NULL &&
+ rhythmdb_entry_get_entry_type (playing) == RHYTHMDB_ENTRY_TYPE_AUDIOSCROBBLER_RADIO_TRACK) {
+ RBAudioscrobblerRadioTrackData *data;
+ data = RHYTHMDB_ENTRY_GET_TYPE_DATA (playing, RBAudioscrobblerRadioTrackData);
+
+ if (data->service == source->priv->service && data->download_url != NULL) {
+ gtk_action_set_sensitive (download, TRUE);
+ } else {
+ gtk_action_set_sensitive (download, FALSE);
+ }
+ } else {
+ gtk_action_set_sensitive (download, FALSE);
+ }
+
+ g_object_unref (shell);
+ if (playing != NULL) {
+ rhythmdb_entry_unref (playing);
+ }
}
static void
love_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source)
{
RBShell *shell;
- RhythmDBEntry *entry;
+ RhythmDBEntry *playing;
GtkAction *ban_action;
g_object_get (source, "shell", &shell, NULL);
+ playing = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
- entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
-
- if (entry != NULL) {
+ if (playing != 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);
+ rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_TITLE),
+ rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_ARTIST));
+ rhythmdb_entry_unref (playing);
}
/* disable love/ban */
@@ -905,17 +938,16 @@ static void
ban_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source)
{
RBShell *shell;
- RhythmDBEntry *entry;
+ RhythmDBEntry *playing;
g_object_get (source, "shell", &shell, NULL);
+ playing = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
- entry = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
-
- if (entry != NULL) {
+ if (playing != 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);
+ rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_TITLE),
+ rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_ARTIST));
+ rhythmdb_entry_unref (playing);
}
/* skip to next track */
@@ -925,6 +957,107 @@ ban_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source)
}
static void
+download_track_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source)
+{
+ RBShell *shell;
+ RhythmDBEntry *playing;
+
+ /* disable the action */
+ gtk_action_set_sensitive (action, FALSE);
+
+ g_object_get (source, "shell", &shell, NULL);
+ playing = rb_shell_player_get_playing_entry (RB_SHELL_PLAYER (rb_shell_get_player (shell)));
+
+ if (playing != NULL &&
+ rhythmdb_entry_get_entry_type (playing) == RHYTHMDB_ENTRY_TYPE_AUDIOSCROBBLER_RADIO_TRACK) {
+ RBAudioscrobblerRadioTrackData *data;
+ data = RHYTHMDB_ENTRY_GET_TYPE_DATA (playing, RBAudioscrobblerRadioTrackData);
+
+ if (data->download_url != NULL) {
+ RhythmDB *db;
+ RBSource *library;
+ RhythmDBEntry *download;
+ GValue val = { 0, };
+ RBTrackTransferBatch *batch;
+
+ /* we need the library source to paste into */
+ g_object_get (shell, "db", &db, "library-source", &library, NULL);
+
+ /* create a new entry to paste */
+ download = rhythmdb_entry_new (db,
+ RHYTHMDB_ENTRY_TYPE_AUDIOSCROBBLER_RADIO_TRACK, /* not really, but it needs a type */
+ data->download_url);
+
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_string (&val, rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_TITLE));
+ rhythmdb_entry_set (db, download, RHYTHMDB_PROP_TITLE, &val);
+ g_value_unset (&val);
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_string (&val, rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_ARTIST));
+ rhythmdb_entry_set (db, download, RHYTHMDB_PROP_ARTIST, &val);
+ g_value_unset (&val);
+ g_value_init (&val, G_TYPE_STRING);
+ g_value_set_string (&val, rhythmdb_entry_get_string (playing, RHYTHMDB_PROP_ALBUM));
+ rhythmdb_entry_set (db, download, RHYTHMDB_PROP_ALBUM, &val);
+ g_value_unset (&val);
+
+ rb_debug ("downloading track from %s", data->download_url);
+ batch = rb_source_paste (library, g_list_append (NULL, download));
+
+ if (batch == NULL) {
+ /* delete the entry we just created */
+ rhythmdb_entry_delete (db, download);
+ rhythmdb_entry_unref (download);
+ } else {
+ /* connect a callback to delete the entry when transfer is done */
+ g_signal_connect_object (batch,
+ "complete",
+ G_CALLBACK (download_track_batch_complete_cb),
+ source,
+ 0);
+ }
+
+ g_object_unref (db);
+ g_object_unref (library);
+ } else {
+ rb_debug ("cannot download: no download url");
+ }
+ rhythmdb_entry_unref (playing);
+ } else {
+ rb_debug ("cannot download: playing entry is not an audioscrobbler radio track");
+ }
+
+ g_object_unref (shell);
+}
+
+static void
+download_track_batch_complete_cb (RBTrackTransferBatch *batch,
+ RBAudioscrobblerProfileSource *source)
+{
+ GList *entries;
+ RBShell *shell;
+ RhythmDB *db;
+ GList *i;
+
+ g_object_get (batch, "entry-list", &entries, NULL);
+ g_object_get (source, "shell", &shell, NULL);
+ g_object_get (shell, "db", &db, NULL);
+
+ /* delete the entries which were transfered.
+ * need to call unref twice as g_object_get will have reffed them
+ */
+ for (i = entries; i != NULL; i = i->next) {
+ rhythmdb_entry_delete (db, i->data);
+ rhythmdb_entry_unref (i->data);
+ rhythmdb_entry_unref (i->data);
+ }
+
+ g_list_free (entries);
+ g_object_unref (shell);
+ g_object_unref (db);
+}
+
+static void
refresh_profile_action_cb (GtkAction *action, RBAudioscrobblerProfileSource *source)
{
rb_audioscrobbler_user_update (source->priv->user);
@@ -1672,6 +1805,7 @@ impl_get_ui_actions (RBSource *asource)
actions = g_list_append (actions, g_strdup (source->priv->love_action_name));
actions = g_list_append (actions, g_strdup (source->priv->ban_action_name));
+ actions = g_list_append (actions, g_strdup (source->priv->download_action_name));
return actions;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]