From a0314d34fb4de7f896f7682dde758a4a72f5481a Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 5 Oct 2011 14:08:33 +0200 Subject: [PATCH] Support albums from GrooveShark in global search. Quality is pretty bad though. --- .../groovesharksearchprovider.cpp | 50 ++++++++++++++++--- src/globalsearch/groovesharksearchprovider.h | 4 ++ src/internet/groovesharkservice.cpp | 47 +++++++++++++++-- src/internet/groovesharkservice.h | 5 ++ 4 files changed, 97 insertions(+), 9 deletions(-) diff --git a/src/globalsearch/groovesharksearchprovider.cpp b/src/globalsearch/groovesharksearchprovider.cpp index 3c40d6ca8..0b79f0935 100644 --- a/src/globalsearch/groovesharksearchprovider.cpp +++ b/src/globalsearch/groovesharksearchprovider.cpp @@ -34,6 +34,10 @@ void GrooveSharkSearchProvider::Init(GrooveSharkService* service) { QIcon(":providers/grooveshark.png"), true, false); connect(service_, SIGNAL(SimpleSearchResults(int, SongList)), SLOT(SearchDone(int, SongList))); + connect(service_, SIGNAL(AlbumSearchResult(int, SongList)), + SLOT(AlbumSearchResult(int, SongList))); + connect(service_, SIGNAL(AlbumSongsLoaded(int, SongList)), + SLOT(AlbumSongsLoaded(int, SongList))); cover_loader_ = new BackgroundThreadImplementation(this); cover_loader_->Start(true); @@ -50,7 +54,8 @@ void GrooveSharkSearchProvider::SearchAsync(int id, const QString& query) { const int service_id = service_->SimpleSearch(query); pending_searches_[service_id] = id; - service_->SearchAlbums(query); + const int album_id = service_->SearchAlbums(query); + pending_searches_[album_id] = id; } void GrooveSharkSearchProvider::SearchDone(int id, const SongList& songs) { @@ -68,9 +73,26 @@ void GrooveSharkSearchProvider::SearchDone(int id, const SongList& songs) { } emit ResultsAvailable(global_search_id, ret); - emit SearchFinished(global_search_id); + // TODO: emit SearchFinished() when the album search is complete too. } +void GrooveSharkSearchProvider::AlbumSearchResult(int id, const SongList& songs) { + const int global_search_id = pending_searches_.take(id); + + ResultList ret; + foreach (const Song& s, songs) { + Result result(this); + result.type_ = Result::Type_Album; + result.match_quality_ = Result::Quality_AtStart; + result.metadata_ = s; + + ret << result; + } + + emit ResultsAvailable(global_search_id, ret); +} + + void GrooveSharkSearchProvider::LoadArtAsync(int id, const Result& result) { quint64 loader_id = cover_loader_->Worker()->LoadImageAsync(result.metadata_); cover_loader_tasks_[loader_id] = id; @@ -88,19 +110,35 @@ void GrooveSharkSearchProvider::LoadTracksAsync(int id, const Result& result) { SongList ret; switch (result.type_) { - case Result::Type_Track: + case Result::Type_Track: { ret << result.metadata_; + SortSongs(&ret); + + SongMimeData* mime_data = new SongMimeData; + mime_data->songs = ret; + + emit TracksLoaded(id, mime_data); + break; + } + + case Result::Type_Album: + FetchAlbum(id, result); break; default: - // TODO: Implement albums in GrooveShark global search. Q_ASSERT(0); } - SortSongs(&ret); +} +void GrooveSharkSearchProvider::FetchAlbum(int id, const Result& result) { + service_->FetchSongsForAlbum(id, result.metadata_.url()); +} + +void GrooveSharkSearchProvider::AlbumSongsLoaded(int id, const SongList& songs) { SongMimeData* mime_data = new SongMimeData; - mime_data->songs = ret; + mime_data->songs = songs; + SortSongs(&mime_data->songs); emit TracksLoaded(id, mime_data); } diff --git a/src/globalsearch/groovesharksearchprovider.h b/src/globalsearch/groovesharksearchprovider.h index 02a02271d..faabad1ea 100644 --- a/src/globalsearch/groovesharksearchprovider.h +++ b/src/globalsearch/groovesharksearchprovider.h @@ -38,9 +38,13 @@ class GrooveSharkSearchProvider : public SearchProvider { private slots: void SearchDone(int id, const SongList& songs); + void AlbumSearchResult(int id, const SongList& songs); void AlbumArtLoaded(quint64 id, const QImage& image); + void AlbumSongsLoaded(int id, const SongList& songs); private: + void FetchAlbum(int id, const Result& result); + GrooveSharkService* service_; QMap pending_searches_; diff --git a/src/internet/groovesharkservice.cpp b/src/internet/groovesharkservice.cpp index 64858c8cd..337b542bf 100644 --- a/src/internet/groovesharkservice.cpp +++ b/src/internet/groovesharkservice.cpp @@ -167,7 +167,7 @@ int GrooveSharkService::SearchAlbums(const QString& query) { QList parameters; parameters << Param("query", query) << Param("country", "") - << Param("limit", QString::number(kSongSearchLimit)); + << Param("limit", QString::number(5)); QNetworkReply* reply = CreateRequest("getAlbumSearchResults", parameters, false); @@ -186,15 +186,56 @@ void GrooveSharkService::SearchAlbumsFinished(QNetworkReply* reply, int id) { QVariantMap result = ExtractResult(reply); QVariantList albums = result["albums"].toList(); + + SongList ret; foreach (const QVariant& v, albums) { QVariantMap album = v.toMap(); - //quint64 album_id = album["AlbumID"].toULongLong(); + quint64 album_id = album["AlbumID"].toULongLong(); QString album_name = album["AlbumName"].toString(); QString artist_name = album["ArtistName"].toString(); - //QString cover_art = album["CoverArtFilename"].toString(); + QString cover_art = album["CoverArtFilename"].toString(); qLog(Debug) << "Found:" << album_name << artist_name; + Song song; + song.Init(QString::null, album_name, artist_name, 0); + song.set_art_automatic(QString(kUrlCover) + cover_art); + QUrl url; + url.setScheme("grooveshark"); + url.setPath(QString("album/%1").arg(album_id)); + song.set_url(url); + + ret << song; } + + emit AlbumSearchResult(id, ret); +} + +void GrooveSharkService::FetchSongsForAlbum(int id, const QUrl& url) { + QStringList split = url.path().split('/'); + Q_ASSERT(split.length() == 2); + FetchSongsForAlbum(id, split[1].toULongLong()); +} + +void GrooveSharkService::FetchSongsForAlbum(int id, quint64 album_id) { + QList parameters; + parameters << Param("albumID", album_id) + << Param("country", ""); + + QNetworkReply* reply = CreateRequest("getAlbumSongs", parameters, false); + new Closure(reply, SIGNAL(finished()), + this, SLOT(GetAlbumSongsFinished(QNetworkReply*,int)), + C_ARG(QNetworkReply*, reply), + C_ARG(int, id)); +} + +void GrooveSharkService::GetAlbumSongsFinished( + QNetworkReply* reply, int id) { + reply->deleteLater(); + + QVariantMap result = ExtractResult(reply); + SongList songs = ExtractSongs(result); + + emit AlbumSongsLoaded(id, songs); } void GrooveSharkService::DoSearch() { diff --git a/src/internet/groovesharkservice.h b/src/internet/groovesharkservice.h index 5717690d2..b18846622 100644 --- a/src/internet/groovesharkservice.h +++ b/src/internet/groovesharkservice.h @@ -73,6 +73,8 @@ class GrooveSharkService : public InternetService { int SimpleSearch(const QString& query); int SearchAlbums(const QString& query); + void FetchSongsForAlbum(int id, const QUrl& url); + void FetchSongsForAlbum(int id, quint64 album_id); static const char* kServiceName; static const char* kSettingsGroup; @@ -88,6 +90,8 @@ class GrooveSharkService : public InternetService { signals: void LoginFinished(bool success); void SimpleSearchResults(int id, SongList songs); + void AlbumSearchResult(int id, SongList songs); + void AlbumSongsLoaded(int id, SongList songs); protected: QModelIndex GetCurrentIndex(); @@ -111,6 +115,7 @@ class GrooveSharkService : public InternetService { void SearchSongsFinished(); void SimpleSearchFinished(); void SearchAlbumsFinished(QNetworkReply* reply, int id); + void GetAlbumSongsFinished(QNetworkReply* reply, int id); void Authenticated(); void UserPlaylistsRetrieved(); void PlaylistSongsRetrieved();