mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-02 20:28:14 +02:00
MusicBrainzPlugin: Make more use of Musicbrainz search api features.
This offloads filtering and sorting of the results to musicbrainz and makes the artistID retrieval step obsolte and should speed things up.
This commit is contained in:
@@ -62,7 +62,6 @@ MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
|||||||
{
|
{
|
||||||
case InfoArtistReleases:
|
case InfoArtistReleases:
|
||||||
{
|
{
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||||
criteria["artist"] = hash["artist"];
|
criteria["artist"] = hash["artist"];
|
||||||
|
|
||||||
@@ -72,7 +71,6 @@ MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
|||||||
|
|
||||||
case InfoAlbumSongs:
|
case InfoAlbumSongs:
|
||||||
{
|
{
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||||
criteria["artist"] = hash["artist"];
|
criteria["artist"] = hash["artist"];
|
||||||
criteria["album"] = hash["album"];
|
criteria["album"] = hash["album"];
|
||||||
@@ -94,31 +92,103 @@ MusicBrainzPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
|||||||
void
|
void
|
||||||
MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData )
|
MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData )
|
||||||
{
|
{
|
||||||
|
QString querySt;
|
||||||
switch ( requestData.type )
|
switch ( requestData.type )
|
||||||
{
|
{
|
||||||
case InfoArtistReleases:
|
case InfoArtistReleases:
|
||||||
{
|
{
|
||||||
QString requestString( "http://musicbrainz.org/ws/2/artist" );
|
querySt.append( QString( "artist:\"%1\"" ).arg(criteria["artist"]) );
|
||||||
|
querySt.append( " AND (type:album OR type:ep)" );
|
||||||
|
querySt.append( " AND status:official" );
|
||||||
|
querySt.append( " AND NOT secondarytype:live" );
|
||||||
|
querySt.append( " AND NOT secondarytype:compilation" );
|
||||||
|
// we dont handle more than 100 results atm, but not even the beatles have more than 100 ep+albums, so its probably safe
|
||||||
|
|
||||||
|
QString requestString( "http://musicbrainz.org/ws/2/release-group" );
|
||||||
QUrl url( requestString );
|
QUrl url( requestString );
|
||||||
url.addQueryItem( "query", criteria["artist"] );
|
url.addQueryItem( "query", querySt );
|
||||||
|
url.addQueryItem( "limit", "100" );
|
||||||
|
tDebug() << Q_FUNC_INFO << url.toString();
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||||
|
|
||||||
connect( reply, SIGNAL( finished() ), SLOT( artistSearchSlot() ) );
|
connect( reply, SIGNAL( finished() ), SLOT( gotReleaseGroupsSlot() ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case InfoAlbumSongs:
|
case InfoAlbumSongs:
|
||||||
{
|
{
|
||||||
QString requestString( "http://musicbrainz.org/ws/2/artist" );
|
querySt.append( QString( "release:\"%1\"" ).arg(criteria["album"]) );
|
||||||
|
querySt.append( QString( " AND artist:\"%1\"" ).arg(criteria["artist"]) );
|
||||||
|
// not pre-filtering will yield more than 100 results which we dont handle atm. But since we only take the first result anyway that wont hurt
|
||||||
|
|
||||||
|
QString requestString( "http://musicbrainz.org/ws/2/release" );
|
||||||
QUrl url( requestString );
|
QUrl url( requestString );
|
||||||
url.addQueryItem( "query", criteria["artist"] );
|
url.addQueryItem( "query", querySt );
|
||||||
|
url.addQueryItem( "limit", "100" );
|
||||||
|
tDebug() << Q_FUNC_INFO << url.toString();
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
QNetworkReply* reply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||||
|
|
||||||
connect( reply, SIGNAL( finished() ), SLOT( albumSearchSlot() ) );
|
connect( reply, SIGNAL( finished() ), SLOT( gotReleasesSlot() ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Q_ASSERT( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
MusicBrainzPlugin::gotReleaseGroupsSlot()
|
||||||
|
{
|
||||||
|
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||||
|
if ( !oldReply )
|
||||||
|
return; //timeout will handle it
|
||||||
|
|
||||||
|
QDomDocument doc;
|
||||||
|
doc.setContent( oldReply->readAll() );
|
||||||
|
QDomNodeList releaseGroupsNL = doc.elementsByTagName( "release-group" );
|
||||||
|
if ( releaseGroupsNL.isEmpty() )
|
||||||
|
{
|
||||||
|
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||||
|
tDebug() << Q_FUNC_INFO << doc.toString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::InfoSystem::InfoRequestData requestData = oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||||
|
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||||
|
switch ( requestData.type )
|
||||||
|
{
|
||||||
|
case InfoArtistReleases:
|
||||||
|
{
|
||||||
|
QStringList albums;
|
||||||
|
for ( int i = 0; i < releaseGroupsNL.count(); i++ )
|
||||||
|
{
|
||||||
|
QString groupTitle = releaseGroupsNL.at(i).firstChildElement("title").text();
|
||||||
|
QString a = releaseGroupsNL.at(i).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).firstChildElement( "name" ).text();
|
||||||
|
if ( !albums.contains( groupTitle ) && hash["artist"] == a )
|
||||||
|
{
|
||||||
|
albums << groupTitle;
|
||||||
|
tDebug() << Q_FUNC_INFO << groupTitle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantMap returnedData;
|
||||||
|
returnedData["albums"] = albums;
|
||||||
|
emit info( requestData, returnedData );
|
||||||
|
|
||||||
|
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
|
||||||
|
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||||
|
criteria["artist"] = origData["artist"];
|
||||||
|
emit updateCache( criteria, 0, requestData.type, returnedData );
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -130,7 +200,7 @@ MusicBrainzPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requ
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MusicBrainzPlugin::artistSearchSlot()
|
MusicBrainzPlugin::gotReleasesSlot()
|
||||||
{
|
{
|
||||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||||
if ( !oldReply )
|
if ( !oldReply )
|
||||||
@@ -138,101 +208,44 @@ MusicBrainzPlugin::artistSearchSlot()
|
|||||||
|
|
||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
doc.setContent( oldReply->readAll() );
|
doc.setContent( oldReply->readAll() );
|
||||||
QDomNodeList domNodeList = doc.elementsByTagName( "artist" );
|
QDomNodeList releasesNL = doc.elementsByTagName( "release" );
|
||||||
if ( domNodeList.isEmpty() )
|
if ( releasesNL.isEmpty() )
|
||||||
{
|
{
|
||||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||||
tDebug() << Q_FUNC_INFO << doc.toString();
|
tDebug() << Q_FUNC_INFO << doc.toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString artist_id = domNodeList.at( 0 ).toElement().attribute( "id" );
|
|
||||||
QString requestString( "http://musicbrainz.org/ws/2/release-group" );
|
|
||||||
QUrl url( requestString );
|
|
||||||
url.addQueryItem( "artist", artist_id );
|
|
||||||
url.addQueryItem( "type", "album|ep" );
|
|
||||||
url.addQueryItem( "limit", "100" );
|
|
||||||
|
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
|
||||||
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
|
||||||
connect( newReply, SIGNAL( finished() ), SLOT( albumFoundSlot() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MusicBrainzPlugin::albumSearchSlot()
|
|
||||||
{
|
|
||||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
|
||||||
if ( !oldReply )
|
|
||||||
return; //timeout will handle it
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent( oldReply->readAll() );
|
|
||||||
QDomNodeList domNodeList = doc.elementsByTagName( "artist" );
|
|
||||||
if ( domNodeList.isEmpty() )
|
|
||||||
{
|
|
||||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString artist_id = domNodeList.at( 0 ).toElement().attribute( "id" );
|
|
||||||
QString requestString( "http://musicbrainz.org/ws/2/release-group" );
|
|
||||||
QUrl url( requestString );
|
|
||||||
url.addQueryItem( "artist", artist_id );
|
|
||||||
url.addQueryItem( "type", "album|ep" );
|
|
||||||
url.addQueryItem( "limit", "100" );
|
|
||||||
|
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
|
||||||
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
|
||||||
connect( newReply, SIGNAL( finished() ), SLOT( tracksSearchSlot() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MusicBrainzPlugin::tracksSearchSlot()
|
|
||||||
{
|
|
||||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
|
||||||
if ( !oldReply )
|
|
||||||
return; //timeout will handle it
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent( oldReply->readAll() );
|
|
||||||
QDomNodeList domNodeList = doc.elementsByTagName( "release" );
|
|
||||||
if ( domNodeList.isEmpty() )
|
|
||||||
{
|
|
||||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoRequestData requestData = oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
Tomahawk::InfoSystem::InfoRequestData requestData = oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||||
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
switch ( requestData.type )
|
||||||
|
|
||||||
QDomElement element;
|
|
||||||
for ( int i = 0; i < domNodeList.count(); i++ )
|
|
||||||
{
|
{
|
||||||
QDomNodeList albumNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
|
case InfoAlbumSongs:
|
||||||
if ( albumNodeList.at( 0 ).toElement().text() == hash["album"] )
|
|
||||||
element = domNodeList.at( i ).toElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( element.isNull() )
|
|
||||||
{
|
{
|
||||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
// we can simply use the first result as they are sorted by score
|
||||||
return;
|
QString release_id = releasesNL.at(0).toElement().attribute( "id" );
|
||||||
}
|
|
||||||
|
|
||||||
QString release_id = element.attribute( "id" );
|
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1" ).arg( release_id );
|
||||||
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1?inc=recordings" ).arg( release_id );
|
|
||||||
QUrl url( requestString );
|
QUrl url( requestString );
|
||||||
|
url.addQueryItem( "inc", "recordings" );
|
||||||
|
tDebug() << Q_FUNC_INFO << url.toString();
|
||||||
|
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||||
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
||||||
connect( newReply, SIGNAL( finished() ), SLOT( tracksFoundSlot() ) );
|
connect( newReply, SIGNAL( finished() ), SLOT( gotRecordingsSlot() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Q_ASSERT( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MusicBrainzPlugin::albumFoundSlot()
|
MusicBrainzPlugin::gotRecordingsSlot()
|
||||||
{
|
{
|
||||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||||
if ( !reply )
|
if ( !reply )
|
||||||
@@ -240,75 +253,26 @@ MusicBrainzPlugin::albumFoundSlot()
|
|||||||
|
|
||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
doc.setContent( reply->readAll() );
|
doc.setContent( reply->readAll() );
|
||||||
QDomNodeList groups = doc.elementsByTagName( "release-group" );
|
QDomNodeList mediumList = doc.elementsByTagName( "medium-list" );
|
||||||
if ( groups.isEmpty() )
|
if ( mediumList.isEmpty() )
|
||||||
{
|
{
|
||||||
emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||||
|
tDebug() << Q_FUNC_INFO << doc.toString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList albums;
|
|
||||||
for ( int i = 0; i < groups.count(); i++ )
|
QDomNodeList tracksNL = mediumList.at(0).toElement().elementsByTagName( "track" );
|
||||||
|
QStringList tracksSL;
|
||||||
|
for ( int i = 0; i < tracksNL.count(); i++ )
|
||||||
{
|
{
|
||||||
QDomElement group = groups.at(i).toElement();
|
QString track = tracksNL.at(i).firstChildElement( "recording" ).firstChildElement( "title" ).text();
|
||||||
QDomNodeList secTypesDL = group.elementsByTagName("secondary-type");
|
tracksSL << track;
|
||||||
QStringList secTypesSL;
|
|
||||||
for ( int i = 0; i < secTypesDL.count(); i++ )
|
|
||||||
{
|
|
||||||
secTypesSL.append(secTypesDL.at(i).toElement().text());
|
|
||||||
}
|
|
||||||
if ( !secTypesSL.contains("Live") && !secTypesSL.contains("Compilation") )
|
|
||||||
{
|
|
||||||
QString album = group.firstChildElement("title").text();
|
|
||||||
if ( !albums.contains( album ) )
|
|
||||||
albums << album;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||||
QVariantMap returnedData;
|
QVariantMap returnedData;
|
||||||
returnedData["albums"] = albums;
|
returnedData["tracks"] = tracksSL;
|
||||||
emit info( requestData, returnedData );
|
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
|
|
||||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
|
||||||
criteria["artist"] = origData["artist"];
|
|
||||||
emit updateCache( criteria, 0, requestData.type, returnedData );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
MusicBrainzPlugin::tracksFoundSlot()
|
|
||||||
{
|
|
||||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
|
||||||
if ( !reply )
|
|
||||||
return; //timeout will handle it
|
|
||||||
|
|
||||||
QDomDocument doc;
|
|
||||||
doc.setContent( reply->readAll() );
|
|
||||||
QDomNodeList domNodeList = doc.elementsByTagName( "recording" );
|
|
||||||
if ( domNodeList.isEmpty() )
|
|
||||||
{
|
|
||||||
emit info( reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList tracks;
|
|
||||||
for ( int i = 0; i < domNodeList.count(); i++ )
|
|
||||||
{
|
|
||||||
QDomNodeList trackNodeList = domNodeList.at( i ).toElement().elementsByTagName( "title" );
|
|
||||||
|
|
||||||
for ( int j = 0; j < trackNodeList.count(); j++ )
|
|
||||||
{
|
|
||||||
QString track = trackNodeList.at( j ).toElement().text();
|
|
||||||
if ( !tracks.contains( track ) )
|
|
||||||
tracks << track;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
|
||||||
QVariantMap returnedData;
|
|
||||||
returnedData["tracks"] = tracks;
|
|
||||||
emit info( requestData, returnedData );
|
emit info( requestData, returnedData );
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
|
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
|
||||||
@@ -318,5 +282,5 @@ MusicBrainzPlugin::tracksFoundSlot()
|
|||||||
emit updateCache( criteria, 0, requestData.type, returnedData );
|
emit updateCache( criteria, 0, requestData.type, returnedData );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN2( Tomahawk::InfoSystem::InfoPlugin, Tomahawk::InfoSystem::MusicBrainzPlugin )
|
Q_EXPORT_PLUGIN2( Tomahawk::InfoSystem::InfoPlugin, Tomahawk::InfoSystem::MusicBrainzPlugin )
|
||||||
|
|
||||||
|
@@ -53,12 +53,10 @@ protected slots:
|
|||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void artistSearchSlot();
|
|
||||||
void albumSearchSlot();
|
|
||||||
void tracksSearchSlot();
|
|
||||||
|
|
||||||
void albumFoundSlot();
|
void gotReleaseGroupsSlot();
|
||||||
void tracksFoundSlot();
|
void gotReleasesSlot();
|
||||||
|
void gotRecordingsSlot();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user