Clementine-audio-player-Mac.../3rdparty/libechonest/Artist.cpp

627 lines
18 KiB
C++

/****************************************************************************************
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 2 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
#include "Artist.h"
#include "Artist_p.h"
#include "ArtistTypes.h"
#include "Parsing_p.h"
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
Echonest::Artist::Artist()
: d( new ArtistData )
{
init();
}
Echonest::Artist::Artist( const QByteArray& id, const QString& name )
: d( new ArtistData )
{
init();
d->id = id;
d->name = name;
}
Echonest::Artist::Artist( const QString& name )
: d( new ArtistData )
{
init();
setName( name );
}
Echonest::Artist::Artist( const QByteArray& id )
: d( new ArtistData )
{
init();
setId( id );
}
Echonest::Artist::Artist(const Echonest::Artist& other)
: d( other.d )
{
init();
}
Echonest::Artist& Echonest::Artist::operator=(const Echonest::Artist& artist)
{
d = artist.d;
return *this;
}
Echonest::Artist::~Artist()
{
}
void Echonest::Artist::init()
{
qRegisterMetaType<Echonest::Artist>("Echonest::Artist");
}
QByteArray Echonest::Artist::id() const
{
return d->id;
}
QString Echonest::Artist::name() const
{
return d->name;
}
void Echonest::Artist::setId(const QByteArray& id)
{
d->id = id;
}
void Echonest::Artist::setName(const QString& name)
{
d->name = name;
}
Echonest::AudioList Echonest::Artist::audio() const
{
return d->audio;
}
void Echonest::Artist::setAudio(const Echonest::AudioList& audio)
{
d->audio = audio;
}
Echonest::BiographyList Echonest::Artist::biographies() const
{
return d->biographies;
}
void Echonest::Artist::setBiographies(const Echonest::BiographyList& bios )
{
d->biographies = bios;
}
Echonest::BlogList Echonest::Artist::blogs() const
{
return d->blogs;
}
void Echonest::Artist::setBlogs(const Echonest::BlogList& blogs )
{
d->blogs = blogs;
}
qreal Echonest::Artist::familiarity() const
{
return d->familiarity;
}
void Echonest::Artist::setFamiliarity(qreal familiar)
{
d->familiarity = familiar;
}
qreal Echonest::Artist::hotttnesss() const
{
return d->hotttnesss;
}
void Echonest::Artist::setHotttnesss(qreal hotttnesss)
{
d->hotttnesss = hotttnesss;
}
Echonest::ArtistImageList Echonest::Artist::images() const
{
return d->images;
}
void Echonest::Artist::setImages(const Echonest::ArtistImageList& imgs)
{
d->images = imgs;
}
Echonest::NewsList Echonest::Artist::news() const
{
return d->news;
}
void Echonest::Artist::setNews(const Echonest::NewsList& news)
{
d->news = news;
}
Echonest::ReviewList Echonest::Artist::reviews() const
{
return d->reviews;
}
void Echonest::Artist::setReviews(const Echonest::ReviewList& reviews)
{
d->reviews = reviews;
}
Echonest::SongList Echonest::Artist::songs() const
{
return d->songs;
}
void Echonest::Artist::setSongs(const Echonest::SongList& songs)
{
d->songs = songs;
}
Echonest::TermList Echonest::Artist::terms() const
{
return d->terms;
}
void Echonest::Artist::setTerms(const Echonest::TermList& terms)
{
d->terms = terms;
}
QUrl Echonest::Artist::amazonUrl() const
{
return d->amazon_url;
}
void Echonest::Artist::setVideos(const Echonest::VideoList& videos)
{
d->videos = videos;
}
void Echonest::Artist::setAmazonUrl(const QUrl& url)
{
d->amazon_url = url;
}
QUrl Echonest::Artist::aolMusicUrl() const
{
return d->aolmusic_url;
}
void Echonest::Artist::setAolMusicUrl(const QUrl& url)
{
d->aolmusic_url = url;
}
QUrl Echonest::Artist::itunesUrl() const
{
return d->itunes_url;
}
void Echonest::Artist::setItunesUrl( const QUrl& url )
{
d->itunes_url = url;
}
QUrl Echonest::Artist::lastFmUrl() const
{
return d->lastfm_url;
}
void Echonest::Artist::setLastFmUrl(const QUrl& url )
{
d->lastfm_url = url;
}
QUrl Echonest::Artist::myspaceUrl() const
{
return d->myspace_url;
}
void Echonest::Artist::setMyspaceUrl( const QUrl& url )
{
d->myspace_url = url;
}
QUrl Echonest::Artist::musicbrainzUrl() const
{
return d->mb_url;
}
void Echonest::Artist::setMusicbrainzUrl(const QUrl& url)
{
d->mb_url = url;
}
Echonest::VideoList Echonest::Artist::videos() const
{
return d->videos;
}
Echonest::ForeignIds Echonest::Artist::foreignIds() const
{
return d->foreign_ids;
}
void Echonest::Artist::setForeignIds(const Echonest::ForeignIds& ids)
{
d->foreign_ids = ids;
}
QNetworkReply* Echonest::Artist::fetchAudio(int numResults, int offset) const
{
QUrl url = setupQuery( "audio", numResults, offset );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchBiographies(const QString& license, int numResults, int offset) const
{
QUrl url = setupQuery( "biographies", numResults, offset );
if( !license.isEmpty() )
url.addQueryItem( QLatin1String( "license" ), license );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchBlogs( bool highRelevanceOnly, int numResults, int offset ) const
{
QUrl url = setupQuery( "blogs", numResults, offset );
if( highRelevanceOnly ) // false is default
url.addEncodedQueryItem( "high_relevance", "true" );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchFamiliarity() const
{
QUrl url = setupQuery( "familiarity", 0, -1 );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchHotttnesss(const QString& type) const
{
QUrl url = setupQuery( "hotttnesss", 0, -1 );
if( type != QLatin1String( "normal" ) )
url.addQueryItem( QLatin1String( "type" ), type );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchImages( const QString& license, int numResults, int offset ) const
{
QUrl url = setupQuery( "images", numResults, offset );
if( !license.isEmpty() )
url.addQueryItem( QLatin1String( "license" ), license );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchProfile(Echonest::ArtistInformation information) const
{
QUrl url = setupQuery( "profile", 0, -1 );
addQueryInformation( url, information );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchNews( bool highRelevanceOnly, int numResults, int offset ) const
{
QUrl url = setupQuery( "news", numResults, offset );
if( highRelevanceOnly ) // false is default
url.addEncodedQueryItem( "high_relevance", "true" );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchReviews(int numResults, int offset) const
{
QUrl url = setupQuery( "reviews", numResults, offset );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchSimilar(const Echonest::Artist::SearchParams& params, Echonest::ArtistInformation information, int numResults, int offset )
{
QUrl url = Echonest::baseGetQuery( "artist", "similar" );
addQueryInformation( url, information );
if( numResults > 0 )
url.addEncodedQueryItem( "results", QByteArray::number( numResults ) );
if( offset >= 0 )
url.addEncodedQueryItem( "start", QByteArray::number( offset ) );
Echonest::Artist::SearchParams::const_iterator iter = params.constBegin();
for( ; iter < params.constEnd(); ++iter )
url.addEncodedQueryItem( searchParamToString( iter->first ), Echonest::escapeSpacesAndPluses( iter->second.toString() ) );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchSongs( int numResults, int offset ) const
{
QUrl url = setupQuery( "songs", numResults, offset );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchTerms( Echonest::Artist::TermSorting sorting ) const
{
QUrl url = setupQuery( "terms", 0, -1 );
if( sorting == Echonest::Artist::Weight )
url.addEncodedQueryItem( "sort", "weight" );
else if( sorting == Echonest::Artist::Frequency )
url.addEncodedQueryItem( "sort", "frequency" );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchUrls() const
{
QUrl url = setupQuery( "urls", 0, -1 );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::fetchVideo(int numResults, int offset) const
{
QUrl url = setupQuery( "video", numResults, offset );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::search(const Echonest::Artist::SearchParams& params, Echonest::ArtistInformation information, bool limit)
{
QUrl url = Echonest::baseGetQuery( "artist", "search" );
Echonest::Artist::SearchParams::const_iterator iter = params.constBegin();
for( ; iter < params.constEnd(); ++iter )
url.addEncodedQueryItem( searchParamToString( iter->first ), Echonest::escapeSpacesAndPluses( iter->second.toString() ) );
url.addEncodedQueryItem( "limit", limit ? "true" : "false" );
addQueryInformation( url, information );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::topHottt(Echonest::ArtistInformation information, int numResults, int offset, bool limit)
{
QUrl url = Echonest::baseGetQuery( "artist", "top_hottt" );
addQueryInformation( url, information );
if( numResults > 0 )
url.addEncodedQueryItem( "results", QByteArray::number( numResults ) );
if( offset >= 0 )
url.addEncodedQueryItem( "start", QByteArray::number( offset ) );
url.addEncodedQueryItem( "limit", limit ? "true" : "false" );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::topTerms(int numResults)
{
QUrl url = Echonest::baseGetQuery( "artist", "top_terms" );
url.addEncodedQueryItem( "results", QByteArray::number( numResults ) );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::listTerms( const QString& type )
{
QUrl url = Echonest::baseGetQuery( "artist", "list_terms" );
url.addQueryItem( QLatin1String( "type" ), type );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Artist::suggest( const QString& name, int results )
{
QUrl url = Echonest::baseGetQuery( "artist", "suggest" );
QString realname = name;
url.addEncodedQueryItem( "name", Echonest::escapeSpacesAndPluses( realname ) );
url.addEncodedQueryItem( "results", QByteArray::number( results ) );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
int Echonest::Artist::parseProfile( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
int numResults = Echonest::Parser::parseArtistInfoOrProfile( xml, *this );
reply->deleteLater();
return numResults;
}
Echonest::Artists Echonest::Artist::parseSearch( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QByteArray data = reply->readAll();
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
Echonest::Artists artists = Echonest::Parser::parseArtists( xml );
reply->deleteLater();
return artists;
}
Echonest::Artists Echonest::Artist::parseSimilar( QNetworkReply* reply ) throw( Echonest::ParseError )
{
return parseSearch( reply );
}
Echonest::Artists Echonest::Artist::parseTopHottt( QNetworkReply* reply ) throw( Echonest::ParseError )
{
return parseSearch( reply );
}
Echonest::TermList Echonest::Artist::parseTopTerms( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::TermList terms = Echonest::Parser::parseTopTermList( xml );
reply->deleteLater();
return terms;
}
Echonest::Artists Echonest::Artist::parseSuggest( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::Artists artists = Echonest::Parser::parseArtistSuggestList( xml );
reply->deleteLater();
return artists;
}
QVector< QString > Echonest::Artist::parseTermList( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
QVector< QString > terms = Echonest::Parser::parseTermList( xml );
reply->deleteLater();
return terms;
}
QUrl Echonest::Artist::setupQuery( const QByteArray& methodName, int numResults, int start ) const
{
QUrl url = Echonest::baseGetQuery( "artist", methodName );
if( !d->id.isEmpty() )
url.addEncodedQueryItem( "id", d->id );
else if( !d->name.isEmpty() ) {
url.addEncodedQueryItem( "name", Echonest::escapeSpacesAndPluses( d->name ) );
} else {
qWarning() << "Artist method" << methodName << "called on an artist object without name or id!";
return QUrl();
}
if( numResults > 0 )
url.addEncodedQueryItem( "results", QByteArray::number( numResults ) );
if( start >= 0 )
url.addEncodedQueryItem( "start", QByteArray::number( start ) );
return url;
}
QByteArray Echonest::Artist::searchParamToString(Echonest::Artist::SearchParam param)
{
switch( param )
{
case Id:
return "id";
case Name:
return "name";
case Results:
return "results";
case Description:
return "description";
case FuzzyMatch:
return "fuzzy_match";
case MaxFamiliarity:
return "max_familiarity";
case MinFamiliarity:
return "min_familiarity";
case MaxHotttnesss:
return "max_hotttnesss";
case MinHotttnesss:
return "min_hotttnesss";
case Reverse:
return "reverse";
case Sort:
return "sort";
case Mood:
return "mood";
case IdSpace:
return "bucket";
default:
return "";
}
}
void Echonest::Artist::addQueryInformation(QUrl& url, Echonest::ArtistInformation information)
{
if( information.flags().testFlag( Echonest::ArtistInformation::Audio ) )
url.addEncodedQueryItem( "bucket", "audio" );
if( information.flags().testFlag( Echonest::ArtistInformation::Biographies ) )
url.addEncodedQueryItem( "bucket", "biographies" );
if( information.flags().testFlag( Echonest::ArtistInformation::Blogs ) )
url.addEncodedQueryItem( "bucket", "blogs" );
if( information.flags().testFlag( Echonest::ArtistInformation::Familiarity ) )
url.addEncodedQueryItem( "bucket", "familiarity" );
if( information.flags().testFlag( Echonest::ArtistInformation::Hotttnesss ) )
url.addEncodedQueryItem( "bucket", "hotttnesss" );
if( information.flags().testFlag( Echonest::ArtistInformation::Images ) )
url.addEncodedQueryItem( "bucket", "images" );
if( information.flags().testFlag( Echonest::ArtistInformation::News ) )
url.addEncodedQueryItem( "bucket", "news" );
if( information.flags().testFlag( Echonest::ArtistInformation::Reviews ) )
url.addEncodedQueryItem( "bucket", "reviews" );
if( information.flags().testFlag( Echonest::ArtistInformation::Terms ) )
url.addEncodedQueryItem( "bucket", "terms" );
if( information.flags().testFlag( Echonest::ArtistInformation::Urls ) )
url.addEncodedQueryItem( "bucket", "urls" );
if( information.flags().testFlag( Echonest::ArtistInformation::Videos ) )
url.addEncodedQueryItem( "bucket", "video" );
if( !information.idSpaces().isEmpty() ) {
foreach( const QString& idSpace, information.idSpaces() )
url.addEncodedQueryItem( "bucket", "id:" + idSpace.toUtf8() );
}
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Artist& artist)
{
return d.maybeSpace() << QString::fromLatin1( "Artist(%1, %2)" ).arg( artist.name() ).arg( QString::fromLatin1(artist.id()) );
}