mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 19:45:31 +01:00
Add GS 'My Music' support.
Fixes issue 2609 Retrieving and removing songs works well :) Adding songs doesn't work :(
This commit is contained in:
parent
0a4b6aec5c
commit
77c6199dd9
@ -92,6 +92,7 @@ GroovesharkService::GroovesharkService(Application* app, InternetModel *parent)
|
||||
stations_(NULL),
|
||||
grooveshark_radio_(NULL),
|
||||
favorites_(NULL),
|
||||
library_(NULL),
|
||||
playlists_parent_(NULL),
|
||||
subscribed_playlists_parent_(NULL),
|
||||
network_(new NetworkAccessManager(this)),
|
||||
@ -101,6 +102,7 @@ GroovesharkService::GroovesharkService(Application* app, InternetModel *parent)
|
||||
rename_playlist_(NULL),
|
||||
remove_from_playlist_(NULL),
|
||||
remove_from_favorites_(NULL),
|
||||
remove_from_library_(NULL),
|
||||
get_url_to_share_song_(NULL),
|
||||
get_url_to_share_playlist_(NULL),
|
||||
search_box_(new SearchBoxWidget(this)),
|
||||
@ -438,6 +440,7 @@ void GroovesharkService::RemoveItems() {
|
||||
search_ = NULL;
|
||||
popular_month_ = NULL;
|
||||
popular_today_ = NULL;
|
||||
library_ = NULL;
|
||||
favorites_ = NULL;
|
||||
subscribed_playlists_parent_ = NULL;
|
||||
stations_ = NULL;
|
||||
@ -463,6 +466,7 @@ void GroovesharkService::ShowContextMenu(const QPoint& global_pos) {
|
||||
bool display_delete_playlist_action = false,
|
||||
display_remove_from_playlist_action = false,
|
||||
display_remove_from_favorites_action = false,
|
||||
display_remove_from_library_action = false,
|
||||
display_share_song_url = false,
|
||||
display_share_playlist_url = false;
|
||||
|
||||
@ -479,6 +483,8 @@ void GroovesharkService::ShowContextMenu(const QPoint& global_pos) {
|
||||
int parent_playlist_type = index.parent().data(Role_PlaylistType).toInt();
|
||||
if (parent_playlist_type == UserFavorites)
|
||||
display_remove_from_favorites_action = true;
|
||||
else if (parent_playlist_type == UserLibrary)
|
||||
display_remove_from_library_action = true;
|
||||
else if (parent_playlist_type == UserPlaylist)
|
||||
display_remove_from_playlist_action = true;
|
||||
}
|
||||
@ -487,6 +493,7 @@ void GroovesharkService::ShowContextMenu(const QPoint& global_pos) {
|
||||
rename_playlist_->setVisible(display_delete_playlist_action);
|
||||
remove_from_playlist_->setVisible(display_remove_from_playlist_action);
|
||||
remove_from_favorites_->setVisible(display_remove_from_favorites_action);
|
||||
remove_from_library_->setVisible(display_remove_from_library_action);
|
||||
|
||||
// Check if we can display actions to get URL for sharing songs/playlists:
|
||||
// - share song
|
||||
@ -534,6 +541,9 @@ void GroovesharkService::EnsureMenuCreated() {
|
||||
remove_from_favorites_ = context_menu_->addAction(
|
||||
IconLoader::Load("list-remove"), tr("Remove from favorites"),
|
||||
this, SLOT(RemoveCurrentFromFavorites()));
|
||||
remove_from_library_ = context_menu_->addAction(
|
||||
IconLoader::Load("list-remove"), tr("Remove from My Music"),
|
||||
this, SLOT(RemoveCurrentFromLibrary()));
|
||||
get_url_to_share_song_ = context_menu_->addAction(
|
||||
tr("Get a URL to share this Grooveshark song"),
|
||||
this, SLOT(GetCurrentSongUrlToShare()));
|
||||
@ -604,6 +614,15 @@ void GroovesharkService::EnsureItemsCreated() {
|
||||
grooveshark_radio_->setData(InternetModel::Type_SmartPlaylist, InternetModel::Role_Type);
|
||||
radios_divider->appendRow(grooveshark_radio_);
|
||||
|
||||
library_ = new QStandardItem(IconLoader::Load("folder-sound"), tr("My Music"));
|
||||
library_->setData(InternetModel::Type_UserPlaylist, InternetModel::Role_Type);
|
||||
library_->setData(UserLibrary, Role_PlaylistType);
|
||||
library_->setData(true, InternetModel::Role_CanLazyLoad);
|
||||
library_->setData(true, InternetModel::Role_CanBeModified);
|
||||
library_->setData(InternetModel::PlayBehaviour_SingleItem,
|
||||
InternetModel::Role_PlayBehaviour);
|
||||
root_->appendRow(library_);
|
||||
|
||||
favorites_ = new QStandardItem(QIcon(":/last.fm/love.png"), tr("Favorites"));
|
||||
favorites_->setData(InternetModel::Type_UserPlaylist, InternetModel::Role_Type);
|
||||
favorites_->setData(UserFavorites, Role_PlaylistType);
|
||||
@ -620,6 +639,7 @@ void GroovesharkService::EnsureItemsCreated() {
|
||||
root_->appendRow(subscribed_playlists_parent_);
|
||||
|
||||
RetrieveUserFavorites();
|
||||
RetrieveUserLibrarySongs();
|
||||
RetrieveUserPlaylists();
|
||||
RetrieveSubscribedPlaylists();
|
||||
RetrieveAutoplayTags();
|
||||
@ -750,6 +770,40 @@ void GroovesharkService::UserFavoritesRetrieved(QNetworkReply* reply, int task_i
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::RetrieveUserLibrarySongs() {
|
||||
int task_id =
|
||||
app_->task_manager()->StartTask(tr("Retrieving Grooveshark My Music songs"));
|
||||
QNetworkReply* reply = CreateRequest("getUserLibrarySongs", QList<Param>());
|
||||
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
this, SLOT(UserLibrarySongsRetrieved(QNetworkReply*, int)), reply, task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::UserLibrarySongsRetrieved(QNetworkReply* reply, int task_id) {
|
||||
reply->deleteLater();
|
||||
|
||||
if (!library_) {
|
||||
// The use probably logged out before the response arrived.
|
||||
return;
|
||||
}
|
||||
|
||||
library_->removeRows(0, library_->rowCount());
|
||||
|
||||
QVariantMap result = ExtractResult(reply);
|
||||
SongList songs = ExtractSongs(result);
|
||||
foreach (const Song& song, songs) {
|
||||
QStandardItem* child = new QStandardItem(song.PrettyTitleWithArtist());
|
||||
child->setData(InternetModel::Type_Track, InternetModel::Role_Type);
|
||||
child->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
||||
child->setData(InternetModel::PlayBehaviour_SingleItem, InternetModel::Role_PlayBehaviour);
|
||||
child->setData(song.url(), InternetModel::Role_Url);
|
||||
child->setData(true, InternetModel::Role_CanBeModified);
|
||||
|
||||
library_->appendRow(child);
|
||||
}
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::RetrievePopularSongs() {
|
||||
task_popular_id_ =
|
||||
app_->task_manager()->StartTask(tr("Getting Grooveshark popular songs"));
|
||||
@ -1021,6 +1075,12 @@ void GroovesharkService::DropMimeData(const QMimeData* data, const QModelIndex&
|
||||
foreach (int song_id, data_songs_ids) {
|
||||
AddUserFavoriteSong(song_id);
|
||||
}
|
||||
} else if (playlist_type == UserLibrary || parent_playlist_type == UserLibrary) {
|
||||
// FIXME: Adding songs to user libray doesn't work atm, but the problem
|
||||
// seems to be on Grooveshark server side, as it returns success=true
|
||||
// when calling addUserLibrarySongs with a valid song id.
|
||||
// So this code is deactivated for now to not mislead user
|
||||
//AddUserLibrarySongs(data_songs_ids);
|
||||
} else { // Dropped on a normal playlist
|
||||
// Get the playlist
|
||||
int playlist_id = index.data(Role_UserPlaylistId).toInt();
|
||||
@ -1053,6 +1113,12 @@ QList<QAction*> GroovesharkService::playlistitem_actions(const Song& song) {
|
||||
connect(add_to_favorites, SIGNAL(triggered()), SLOT(AddCurrentSongToUserFavorites()));
|
||||
playlistitem_actions_.append(add_to_favorites);
|
||||
|
||||
// FIXME: as explained above, adding songs to library doesn't work currently
|
||||
//QAction* add_to_library = new QAction(IconLoader::Load("folder-sound"),
|
||||
// tr("Add to Grooveshark My Music"), this);
|
||||
//connect(add_to_library, SIGNAL(triggered()), SLOT(AddCurrentSongToUserLibrary()));
|
||||
//playlistitem_actions_.append(add_to_library);
|
||||
|
||||
// Create a menu with 'add to playlist' actions for each Grooveshark playlist
|
||||
QAction* add_to_playlists = new QAction(IconLoader::Load("list-add"),
|
||||
tr("Add to Grooveshark playlists"), this);
|
||||
@ -1350,6 +1416,42 @@ void GroovesharkService::UserFavoriteSongAdded(QNetworkReply* reply, int task_id
|
||||
RetrieveUserFavorites();
|
||||
}
|
||||
|
||||
void GroovesharkService::AddUserLibrarySongs(QList<int>& songs_ids) {
|
||||
int task_id = app_->task_manager()->StartTask(tr("Adding song to My Music"));
|
||||
QList<Param> parameters;
|
||||
|
||||
// Convert songs ids to QVariant
|
||||
QVariantList songs_ids_qvariant;
|
||||
foreach (int song_id, songs_ids) {
|
||||
songs_ids_qvariant << QVariant(song_id);
|
||||
}
|
||||
QVariantList albums_ids_qvariant;
|
||||
QVariantList artists_ids_qvariant;
|
||||
|
||||
parameters << Param("songIDs", songs_ids_qvariant);
|
||||
// We do not support albums and artist parameters for now, but they are
|
||||
// required
|
||||
parameters << Param("albumIDs", albums_ids_qvariant);
|
||||
parameters << Param("artistIDs", artists_ids_qvariant);
|
||||
QNetworkReply* reply = CreateRequest("addUserLibrarySongs", parameters);
|
||||
NewClosure(reply, SIGNAL(finished()),
|
||||
this, SLOT(UserLibrarySongAdded(QNetworkReply*, int)),
|
||||
reply, task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::UserLibrarySongAdded(QNetworkReply* reply, int task_id) {
|
||||
reply->deleteLater();
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
|
||||
QVariantMap result = ExtractResult(reply);
|
||||
if (!result["success"].toBool()) {
|
||||
qLog(Warning) << "Grooveshark addUserLibrarySongs failed";
|
||||
return;
|
||||
}
|
||||
// Refresh user's library list
|
||||
RetrieveUserLibrarySongs();
|
||||
}
|
||||
|
||||
void GroovesharkService::RemoveCurrentFromPlaylist() {
|
||||
const QModelIndexList& indexes(model()->selected_indexes());
|
||||
QMap<int, QList<int> > playlists_songs_ids;
|
||||
@ -1410,7 +1512,7 @@ void GroovesharkService::RemoveFromFavorites(const QList<int>& songs_ids_to_remo
|
||||
if (songs_ids_to_remove.isEmpty())
|
||||
return;
|
||||
|
||||
int task_id = app_->task_manager()->StartTask(tr("Removing song from favorites"));
|
||||
int task_id = app_->task_manager()->StartTask(tr("Removing songs from favorites"));
|
||||
QList<Param> parameters;
|
||||
|
||||
// Convert song ids to QVariant
|
||||
@ -1422,10 +1524,10 @@ void GroovesharkService::RemoveFromFavorites(const QList<int>& songs_ids_to_remo
|
||||
parameters << Param("songIDs", songs_ids_qvariant);
|
||||
QNetworkReply* reply = CreateRequest("removeUserFavoriteSongs", parameters);
|
||||
NewClosure(reply, SIGNAL(finished()), this,
|
||||
SLOT(SongRemovedFromFavorites(QNetworkReply*, int)), reply, task_id);
|
||||
SLOT(SongsRemovedFromFavorites(QNetworkReply*, int)), reply, task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::SongRemovedFromFavorites(QNetworkReply* reply, int task_id) {
|
||||
void GroovesharkService::SongsRemovedFromFavorites(QNetworkReply* reply, int task_id) {
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
reply->deleteLater();
|
||||
|
||||
@ -1437,8 +1539,68 @@ void GroovesharkService::SongRemovedFromFavorites(QNetworkReply* reply, int task
|
||||
RetrieveUserFavorites();
|
||||
}
|
||||
|
||||
QNetworkReply* GroovesharkService::CreateRequest(const QString& method_name, QList<Param> params,
|
||||
void GroovesharkService::RemoveCurrentFromLibrary() {
|
||||
const QModelIndexList& indexes(model()->selected_indexes());
|
||||
QList<int> songs_ids;
|
||||
|
||||
foreach (const QModelIndex& index, indexes) {
|
||||
|
||||
if (index.parent().data(Role_PlaylistType).toInt() != UserLibrary) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int song_id = ExtractSongId(index.data(InternetModel::Role_Url).toUrl());
|
||||
if (song_id) {
|
||||
songs_ids << song_id;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveFromLibrary(songs_ids);
|
||||
}
|
||||
|
||||
void GroovesharkService::RemoveFromLibrary(const QList<int>& songs_ids_to_remove) {
|
||||
if (songs_ids_to_remove.isEmpty())
|
||||
return;
|
||||
|
||||
int task_id = app_->task_manager()->StartTask(tr("Removing songs from My Music"));
|
||||
QList<Param> parameters;
|
||||
|
||||
// Convert song ids to QVariant
|
||||
QVariantList songs_ids_qvariant;
|
||||
foreach (const int song_id, songs_ids_to_remove) {
|
||||
songs_ids_qvariant << QVariant(song_id);
|
||||
}
|
||||
QVariantList albums_ids_qvariant;
|
||||
QVariantList artists_ids_qvariant;
|
||||
|
||||
parameters << Param("songIDs", songs_ids_qvariant);
|
||||
// We do not support albums and artist parameters for now, but they are
|
||||
// required
|
||||
parameters << Param("albumIDs", albums_ids_qvariant);
|
||||
parameters << Param("artistIDs", artists_ids_qvariant);
|
||||
|
||||
QNetworkReply* reply = CreateRequest("removeUserLibrarySongs", parameters);
|
||||
NewClosure(reply, SIGNAL(finished()), this,
|
||||
SLOT(SongsRemovedFromLibrary(QNetworkReply*, int)), reply, task_id);
|
||||
}
|
||||
|
||||
void GroovesharkService::SongsRemovedFromLibrary(QNetworkReply* reply, int task_id) {
|
||||
app_->task_manager()->SetTaskFinished(task_id);
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap result = ExtractResult(reply);
|
||||
if (!result["success"].toBool()) {
|
||||
qLog(Warning) << "Grooveshark removeUserLibrarySongs failed";
|
||||
return;
|
||||
}
|
||||
RetrieveUserLibrarySongs();
|
||||
}
|
||||
|
||||
QNetworkReply* GroovesharkService::CreateRequest(
|
||||
const QString& method_name,
|
||||
const QList<Param>& params,
|
||||
bool use_https) {
|
||||
|
||||
QVariantMap request_params;
|
||||
request_params.insert("method", method_name);
|
||||
|
||||
|
@ -46,9 +46,10 @@ class GroovesharkService : public InternetService {
|
||||
|
||||
enum PlaylistType {
|
||||
UserPlaylist = Qt::UserRole,
|
||||
// Favorites list is like a playlist, but we want to do special treatments
|
||||
// in some cases
|
||||
// Favorites and Library list are like playlists, but we want to do special
|
||||
// treatments in some cases
|
||||
UserFavorites,
|
||||
UserLibrary,
|
||||
SubscribedPlaylist
|
||||
};
|
||||
|
||||
@ -80,6 +81,7 @@ class GroovesharkService : public InternetService {
|
||||
bool IsLoggedIn() const { return !session_id_.isEmpty(); }
|
||||
void RetrieveUserPlaylists();
|
||||
void RetrieveUserFavorites();
|
||||
void RetrieveUserLibrarySongs();
|
||||
void RetrievePopularSongs();
|
||||
void RetrievePopularSongsMonth();
|
||||
void RetrievePopularSongsToday();
|
||||
@ -93,6 +95,8 @@ class GroovesharkService : public InternetService {
|
||||
void RenamePlaylist(int playlist_id);
|
||||
void AddUserFavoriteSong(int song_id);
|
||||
void RemoveFromFavorites(const QList<int>& songs_ids_to_remove);
|
||||
void AddUserLibrarySongs(QList<int>& songs_ids);
|
||||
void RemoveFromLibrary(const QList<int>& songs_ids_to_remove);
|
||||
void GetSongUrlToShare(int song_id);
|
||||
void GetPlaylistUrlToShare(int playlist_id);
|
||||
// Start autoplay for the given tag_id, fill the autoplay_state, returns a
|
||||
@ -156,6 +160,7 @@ class GroovesharkService : public InternetService {
|
||||
void Authenticated();
|
||||
void UserPlaylistsRetrieved();
|
||||
void UserFavoritesRetrieved(QNetworkReply* reply, int task_id);
|
||||
void UserLibrarySongsRetrieved(QNetworkReply* reply, int task_id);
|
||||
void PopularSongsMonthRetrieved(QNetworkReply* reply);
|
||||
void PopularSongsTodayRetrieved(QNetworkReply* reply);
|
||||
void SubscribedPlaylistsRetrieved(QNetworkReply* reply);
|
||||
@ -169,15 +174,19 @@ class GroovesharkService : public InternetService {
|
||||
void PlaylistDeleted(QNetworkReply* reply, int playlist_id);
|
||||
void PlaylistRenamed(QNetworkReply* reply, int playlist_id, const QString& new_name);
|
||||
void AddCurrentSongToUserFavorites() { AddUserFavoriteSong(current_song_id_); }
|
||||
void AddCurrentSongToUserLibrary() { AddUserLibrarySongs(QList<int>() << current_song_id_); }
|
||||
void AddCurrentSongToPlaylist(QAction* action);
|
||||
void UserFavoriteSongAdded(QNetworkReply* reply, int task_id);
|
||||
void UserLibrarySongAdded(QNetworkReply* reply, int task_id);
|
||||
void GetCurrentSongUrlToShare();
|
||||
void SongUrlToShareReceived(QNetworkReply* reply);
|
||||
void GetCurrentPlaylistUrlToShare();
|
||||
void PlaylistUrlToShareReceived(QNetworkReply* reply);
|
||||
void RemoveCurrentFromPlaylist();
|
||||
void RemoveCurrentFromFavorites();
|
||||
void SongRemovedFromFavorites(QNetworkReply* reply, int task_id);
|
||||
void RemoveCurrentFromLibrary();
|
||||
void SongsRemovedFromFavorites(QNetworkReply* reply, int task_id);
|
||||
void SongsRemovedFromLibrary(QNetworkReply* reply, int task_id);
|
||||
void StreamMarked();
|
||||
void SongMarkedAsComplete();
|
||||
|
||||
@ -204,7 +213,9 @@ class GroovesharkService : public InternetService {
|
||||
// Create a request for the given method, with the given params.
|
||||
// If need_authentication is true, add session_id to params.
|
||||
// Returns the reply object created
|
||||
QNetworkReply* CreateRequest(const QString& method_name, const QList<QPair<QString, QVariant> > params,
|
||||
QNetworkReply* CreateRequest(
|
||||
const QString& method_name,
|
||||
const QList<QPair<QString, QVariant> >& params,
|
||||
bool use_https = false);
|
||||
// Convenient function which block until 'reply' replies, or timeout after 10
|
||||
// seconds. Returns false if reply has timeouted
|
||||
@ -249,6 +260,10 @@ class GroovesharkService : public InternetService {
|
||||
QStandardItem* stations_;
|
||||
QStandardItem* grooveshark_radio_;
|
||||
QStandardItem* favorites_;
|
||||
// Grooveshark Library (corresponds to Grooveshark 'MyMusic' actually, but
|
||||
// called 'Library' in the API).
|
||||
// Nothing to do with Clementine's local library
|
||||
QStandardItem* library_;
|
||||
QStandardItem* playlists_parent_;
|
||||
QStandardItem* subscribed_playlists_parent_;
|
||||
|
||||
@ -265,6 +280,7 @@ class GroovesharkService : public InternetService {
|
||||
QAction* rename_playlist_;
|
||||
QAction* remove_from_playlist_;
|
||||
QAction* remove_from_favorites_;
|
||||
QAction* remove_from_library_;
|
||||
QAction* get_url_to_share_song_;
|
||||
QAction* get_url_to_share_playlist_;
|
||||
QList<QAction*> playlistitem_actions_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user