mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-16 11:04:01 +02:00
Merge pull request #123 from crabmanX/musicbrainz_overhaul
Make more use of Musicbrainz search api features
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,106 @@ 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:
|
||||||
|
{
|
||||||
|
QString popularId = releaseGroupsNL.at(0).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||||
|
|
||||||
|
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();
|
||||||
|
QString id = releaseGroupsNL.at(i).firstChildElement( "artist-credit" ).firstChildElement( "name-credit" ).firstChildElement( "artist" ).attribute( "id" );
|
||||||
|
if ( !albums.contains( groupTitle ) && hash["artist"] == a && id == popularId )
|
||||||
|
{
|
||||||
|
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 +203,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 +211,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();
|
// we can simply use the first result as they are sorted by score
|
||||||
|
QString release_id = releasesNL.at(0).toElement().attribute( "id" );
|
||||||
|
|
||||||
|
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1" ).arg( release_id );
|
||||||
|
QUrl url( requestString );
|
||||||
|
url.addQueryItem( "inc", "recordings" );
|
||||||
|
tDebug() << Q_FUNC_INFO << url.toString();
|
||||||
|
|
||||||
|
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
||||||
|
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
||||||
|
connect( newReply, SIGNAL( finished() ), SLOT( gotRecordingsSlot() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
Q_ASSERT( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( element.isNull() )
|
|
||||||
{
|
|
||||||
emit info( oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString release_id = element.attribute( "id" );
|
|
||||||
QString requestString = QString( "http://musicbrainz.org/ws/2/release/%1?inc=recordings" ).arg( release_id );
|
|
||||||
QUrl url( requestString );
|
|
||||||
|
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( QNetworkRequest( url ) );
|
|
||||||
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
|
||||||
connect( newReply, SIGNAL( finished() ), SLOT( tracksFoundSlot() ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
MusicBrainzPlugin::albumFoundSlot()
|
MusicBrainzPlugin::gotRecordingsSlot()
|
||||||
{
|
{
|
||||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||||
if ( !reply )
|
if ( !reply )
|
||||||
@@ -240,75 +256,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 +285,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