When (global) searching GS albums, retrieve albums' songs at the same time (instead of album load time).

Albums search is slower, but we can display songs in search results, which is IMHO really nicer.
This commit is contained in:
Arnaud Bienner 2012-02-26 16:51:11 +01:00
parent 63f13b19f2
commit 747e0f510f
4 changed files with 30 additions and 48 deletions

View File

@ -39,8 +39,8 @@ void GroovesharkSearchProvider::Init(GroovesharkService* service) {
connect(service_, SIGNAL(SimpleSearchResults(int, SongList)),
SLOT(SearchDone(int, SongList)));
connect(service_, SIGNAL(AlbumSearchResult(int, SongList)),
SLOT(AlbumSearchResult(int, SongList)));
connect(service_, SIGNAL(AlbumSearchResult(int, QList<SongList>)),
SLOT(AlbumSearchResult(int, QList<SongList>)));
connect(service_, SIGNAL(AlbumSongsLoaded(int, SongList)),
SLOT(AlbumSongsLoaded(int, SongList)));
@ -83,19 +83,28 @@ void GroovesharkSearchProvider::SearchDone(int id, const SongList& songs) {
MaybeSearchFinished(global_search_id);
}
void GroovesharkSearchProvider::AlbumSearchResult(int id, const SongList& songs) {
void GroovesharkSearchProvider::AlbumSearchResult(int id, const QList<SongList>& albums) {
// Map back to the original id.
const PendingState state = pending_searches_.take(id);
const int global_search_id = state.orig_id_;
ResultList ret;
foreach (const Song& s, songs) {
foreach (const SongList& a, albums) {
if (a.isEmpty())
continue;
Result result(this);
result.type_ = globalsearch::Type_Album;
result.metadata_ = s;
const QString& artist = a.last().artist();
const QString& album = a.last().album();
result.metadata_.set_album(album);
result.metadata_.set_artist(artist);
result.metadata_.set_art_automatic(a.last().art_automatic());
result.match_quality_ =
qMin(MatchQuality(state.tokens_, s.album()),
MatchQuality(state.tokens_, s.artist()));
qMin(MatchQuality(state.tokens_, album),
MatchQuality(state.tokens_, artist));
foreach (const Song& s, a) {
result.album_songs_ << s;
}
ret << result;
}
@ -140,9 +149,12 @@ void GroovesharkSearchProvider::LoadTracksAsync(int id, const Result& result) {
break;
}
case globalsearch::Type_Album:
FetchAlbum(id, result);
case globalsearch::Type_Album: {
InternetSongMimeData* mime_data = new InternetSongMimeData(service_);
mime_data->songs = result.album_songs_;
emit TracksLoaded(id, mime_data);
break;
}
default:
Q_ASSERT(0);
@ -158,10 +170,6 @@ void GroovesharkSearchProvider::ShowConfig() {
service_->ShowConfig();
}
void GroovesharkSearchProvider::FetchAlbum(int id, const Result& result) {
service_->FetchSongsForAlbum(id, result.metadata_.url());
}
void GroovesharkSearchProvider::AlbumSongsLoaded(int id, const SongList& songs) {
InternetSongMimeData* mime_data = new InternetSongMimeData(service_);
mime_data->songs = songs;

View File

@ -40,13 +40,12 @@ class GroovesharkSearchProvider : public SearchProvider {
private slots:
void SearchDone(int id, const SongList& songs);
void AlbumSearchResult(int id, const SongList& songs);
void AlbumSearchResult(int id, const QList<SongList>& songs);
void AlbumArtLoaded(quint64 id, const QImage& image);
void AlbumSongsLoaded(int id, const SongList& songs);
private:
void MaybeSearchFinished(int id);
void FetchAlbum(int id, const Result& result);
GroovesharkService* service_;
QMap<int, PendingState> pending_searches_;

View File

@ -228,7 +228,7 @@ void GroovesharkService::SearchAlbumsFinished(QNetworkReply* reply, int id) {
QVariantMap result = ExtractResult(reply);
QVariantList albums = result["albums"].toList();
SongList ret;
QList<SongList> ret;
foreach (const QVariant& v, albums) {
QVariantMap album = v.toMap();
quint64 album_id = album["AlbumID"].toULongLong();
@ -237,45 +237,22 @@ void GroovesharkService::SearchAlbumsFinished(QNetworkReply* reply, int id) {
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;
ret << GetAlbumSongs(album_id);
}
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) {
SongList GroovesharkService::GetAlbumSongs(quint64 album_id) {
QList<Param> parameters;
parameters << Param("albumID", album_id)
<< Param("country", "");
QNetworkReply* reply = CreateRequest("getAlbumSongs", parameters);
NewClosure(reply, SIGNAL(finished()),
this, SLOT(GetAlbumSongsFinished(QNetworkReply*,int)),
reply, id);
}
void GroovesharkService::GetAlbumSongsFinished(
QNetworkReply* reply, int id) {
reply->deleteLater();
if (!WaitForReply(reply))
return SongList();
QVariantMap result = ExtractResult(reply);
SongList songs = ExtractSongs(result);
emit AlbumSongsLoaded(id, songs);
return ExtractSongs(result);
}
void GroovesharkService::DoSearch() {

View File

@ -113,8 +113,7 @@ 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);
SongList GetAlbumSongs(quint64 album_id);
static const char* kServiceName;
static const char* kSettingsGroup;
@ -122,7 +121,7 @@ class GroovesharkService : public InternetService {
signals:
void LoginFinished(bool success);
void SimpleSearchResults(int id, SongList songs);
void AlbumSearchResult(int id, SongList songs);
void AlbumSearchResult(int id, QList<SongList> albums);
void AlbumSongsLoaded(int id, SongList songs);
public slots:
@ -151,7 +150,6 @@ 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 UserFavoritesRetrieved(QNetworkReply* reply, int task_id);