Remove our copy of libechonest.

This commit is contained in:
John Maguire 2015-02-06 15:55:07 +01:00
parent 1f15df9936
commit c55c6130a0
46 changed files with 2 additions and 9125 deletions

View File

@ -1,626 +0,0 @@
/****************************************************************************************
* 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()) );
}

View File

@ -1,395 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_ARTIST_H
#define ECHONEST_ARTIST_H
#include "ArtistTypes.h"
#include "Config.h"
#include "echonest_export.h"
#include "TypeInformation.h"
#include "Song.h"
#include <QDebug>
#include <QSharedData>
#include <QUrl>
class QNetworkReply;
class ArtistData;
class Term;
namespace Echonest{
class Biography;
class Catalog;
class Artist;
typedef QVector< Artist > Artists;
/**
* This encapsulates an Echo Nest artist---it always holds the basic info of artist id and
* artist name, and can be queried for more data.
*
* It is also possible to fetch more information from a given artist name or ID by creating an Artist
* object yourself and calling the fetch() functions directly.
*/
class ECHONEST_EXPORT Artist
{
public:
enum TermSorting {
Weight,
Frequency
} ;
/**
* The following are the various search parameters to the search() and similar() functions.
*
* Not all are acceptable for each API call, check the API documentation at
* http://developer.echonest.com/docs/v4/artist.html#search for details.
*
* - id QVector< QByteArray > A list of the artist IDs to be searched (e.g. [ARH6W4X1187B99274F, musicbrainz:artist:a74b1b7f-71a5-4011-9441-d0b5e4122711 ,ARH6W4X1187B99274F^2])
* - name QVector< QString > A list of artist names to be searched (e.g. [Weezer, the beatles ,the beatles^0.5])
* - description QVector< QString > A list of descriptors [ alt-rock,-emo,harp^2 ]
* - results 0 < results < 200, (Default=15) The number of results desired
* - min_results 0 < results < 200, (Default=0) Indicates the minimum number of results to be returned regardless of constraints
* - max_familiarity 0.0 < familiarity < 1.0 The maximum familiarity for returned artists
* - min_familiarity 0.0 < familiarity < 1.0 The minimum familiarity for returned artists
* - max_hotttnesss 0.0 < hotttnesss < 1.0 The maximum hotttnesss for returned artists
* - min_hotttness 0.0 < hotttnesss < 1.0 The minimum hotttnesss for returned artists
* - reverse [true, false] If true, return artists that are disimilar to the seeds
* -sort QString How to sort the results. Options: familiarity-asc, hotttnesss-asc, familiarity-desc, hotttnesss-desc.
*
*/
enum SearchParam {
Id,
Name,
Results,
Description,
FuzzyMatch,
MaxFamiliarity,
MinFamiliarity,
MaxHotttnesss,
MinHotttnesss,
Reverse,
Sort,
IdSpace,
Mood
};
typedef QPair< Echonest::Artist::SearchParam, QVariant > SearchParamEntry;
typedef QVector< SearchParamEntry > SearchParams;
Artist();
Artist( const QByteArray& id, const QString& name );
explicit Artist( const QString& name );
explicit Artist( const QByteArray& id );
Artist( const Artist& other );
Artist& operator=( const Artist& artist );
virtual ~Artist();
void init();
QByteArray id() const;
void setId( const QByteArray& id );
QString name() const;
void setName( const QString& name );
/**
* The following require fetching from The Echo Nest, so return a QNetworkReply*
* that is ready for parsing when the finished() signal is emitted.
*
* Call parseProfile() on the Artist object to populate it with the result of the
* query.
*
*/
/**
* A list of audio files on the web for this artist.
*/
AudioList audio() const;
void setAudio( const AudioList& );
/**
* A list of biographies for this artist.
*/
BiographyList biographies() const;
void setBiographies( const BiographyList& );
/**
* Blogs about this artist, around the web.
*/
BlogList blogs() const;
void setBlogs( const BlogList& );
/**
* How familiar this artist is.
*/
qreal familiarity() const;
void setFamiliarity( qreal familiar );
/**
* The hotttness of this artist.
*/
qreal hotttnesss() const;
void setHotttnesss( qreal hotttnesss );
/**
* Images related to this artist.
*/
ArtistImageList images() const;
void setImages( const ArtistImageList& );
/**
* News about this artist.
*/
NewsList news() const;
void setNews( const NewsList& );
/**
* Reviews of this artist
*/
ReviewList reviews() const;
void setReviews( const ReviewList& );
/**
* Echo Nest song objects belonging to this artist.
*/
SongList songs() const;
void setSongs( const SongList& );
/**
* Terms describing this artist.
*/
TermList terms() const;
void setTerms( const TermList& );
/**
* Urls pointing to this artists' basic information around the web.
*/
QUrl lastFmUrl() const;
void setLastFmUrl( const QUrl& );
QUrl aolMusicUrl() const;
void setAolMusicUrl( const QUrl& );
QUrl amazonUrl() const;
void setAmazonUrl( const QUrl& );
QUrl itunesUrl() const;
void setItunesUrl( const QUrl& );
QUrl myspaceUrl() const;
void setMyspaceUrl( const QUrl& );
QUrl musicbrainzUrl() const;
void setMusicbrainzUrl( const QUrl& url );
/**
* Videos related to this artist.
*/
VideoList videos() const;
void setVideos( const VideoList& );
/**
* The list of foreign ids for this artist, if fetched.
*/
ForeignIds foreignIds() const;
void setForeignIds( const ForeignIds& ids );
/**
* Fetch a list of audio documents found on the web that are related to this artist.
*
* @param numResults Limit how many results are returned
* @param offset The offset of the results, if paging through results in increments.
*/
QNetworkReply* fetchAudio( int numResults = 0, int offset = -1 ) const;
/**
* Fetch a list of biographies for this artist from various places on the web.
*/
QNetworkReply* fetchBiographies( const QString& license = QString(), int numResults = 0, int offset = -1 ) const;
/**
* Fetch a list of blog articles relating to this artist.
*/
QNetworkReply* fetchBlogs( bool highRelevanceOnly = false, int numResults = 0, int offset = -1 ) const;
/**
* Fetch The Echo Nest's numerical estimate of how familiar this artist is to the world.
*/
QNetworkReply* fetchFamiliarity() const;
/**
* Fetch the numerical description of how hot this artist is.
*
* Currently the only supported type is 'normal'
*/
QNetworkReply* fetchHotttnesss( const QString& type = QLatin1String( "normal" ) ) const;
/**
* Fetch a list of images related to this artist.
*/
QNetworkReply* fetchImages( const QString& license = QString(), int numResults = 0, int offset = -1 ) const;
/**
* Fetch a list of news articles found on the web related to this artist.
*/
QNetworkReply* fetchNews( bool highRelevanceOnly = false, int numResults = 0, int offset = -1 ) const;
/**
* Fetch any number of pieces of artist information all at once.
*/
QNetworkReply* fetchProfile( ArtistInformation information = ArtistInformation() ) const;
/**
* Fetch reviews related to the artist.
*/
QNetworkReply* fetchReviews( int numResults = 0, int offset = -1 ) const;
/**
* Fetch a list of songs created by this artist.
*/
QNetworkReply* fetchSongs( int numResults = 0, int offset = -1 ) const;
/**
* Fetch a list of the most descriptive terms for this artist.
*/
QNetworkReply* fetchTerms( TermSorting sorting = Frequency ) const;
/**
* Fetch links to the artist's official site, MusicBrainz site, MySpace site, Wikipedia article, Amazon list, and iTunes page.
*/
QNetworkReply* fetchUrls() const;
/**
* Fetch a list of video documents found on the web related to an artist.
*/
QNetworkReply* fetchVideo( int numResults = 0, int offset = -1 ) const;
/**
* Parse a completed QNetworkReply* that has fetched more information about this artist.
* This will update the artist object with the new values that have been fetched.
*
* @return The number of results available on the server.
*/
int parseProfile( QNetworkReply* ) throw( ParseError );
/**
* Fetch a list of similar artists given one or more artists for comparison.
*
* Up to five artist names or ids can be included for the similarity search.
*
*
* So they are passed as a list of [paramname, paramvalue] to be included in the query.
*
* Boosting: This method can take multiple seed artists. You an give a seed artist more or less weight by boosting the artist. A boost is an
* affinity for a seed that gives it more or less weight when making calculations based on the argument. In case seeds are not meant to be equally
* valued, the boost can help clarify where along a spectrum each argument falls. The boost is a positive floating point value, where 1 gives the normal
* weight. It is signified by appending a caret and weight to the argument.
*
* See http://developer.echonest.com/docs/v4/artist.html#similar for boosting examples.
*
* Call parseSimilar() once the returned QNetworkReply* has emitted its finished() signal
*/
static QNetworkReply* fetchSimilar( const SearchParams& params, ArtistInformation information = ArtistInformation(), int numResults = 0, int offset = -1 );
/**
* Search for artists.
*
* Warning: If limit is set to true, at least one idspace must also be provided.
*
* One of name or description is required, but only one can be used in a query at one time
*
*/
static QNetworkReply* search( const SearchParams& params, ArtistInformation information = ArtistInformation(), bool limit = false );
/**
* Fetch a list of the current top artists in terms of hotttnesss.
*
* Warning If limit is set to true, at least one idspace must also be provided in the bucket parameter.
*
*/
static QNetworkReply* topHottt( ArtistInformation information = ArtistInformation(), int numResults = 0, int offset = -1, bool limit = false );
/**
* Fetch a list of the top overall terms.
*/
static QNetworkReply* topTerms( int numResults = 15 );
/**
* Suggest artists based on a partial name.
*
* \param results How many results to return, between 0 and 15. Default is 10
*/
static QNetworkReply* suggest( const QString& name, int results = 10 );
/**
* Returns a list of terms of the given type, for use in other calls.
*
* \param type Which type of term to return, at the moment only 'style' or 'mood'
*/
static QNetworkReply* listTerms( const QString& type = QLatin1String("style") );
/**
* Parse the result of a fetchSimilar() call, which returns a list of artists similar to the
* original pair.
*/
static Artists parseSimilar( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of an artist search.
*/
static Artists parseSearch( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of a top hottness query.
*/
static Artists parseTopHottt( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of a top terms query.
*/
static TermList parseTopTerms( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of a suggest query
*
* Returns a list of suggested artists
*/
static Artists parseSuggest( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of a termList query. Returns the list of values returned.
*/
static QVector< QString > parseTermList( QNetworkReply* ) throw( ParseError );
private:
QUrl setupQuery( const QByteArray& methodName, int numResults = 0, int start = -1 ) const;
static QByteArray searchParamToString( SearchParam param );
static void addQueryInformation( QUrl& url, ArtistInformation information );
QSharedDataPointer<ArtistData> d;
friend class Catalog;
};
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Artist& artist);
} // namespace
Q_DECLARE_METATYPE( Echonest::Artist )
#endif

View File

@ -1,572 +0,0 @@
/****************************************************************************************
* 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 "ArtistTypes.h"
#include "ArtistTypes_p.h"
#include <QUrl>
#include <QDateTime>
Echonest::ArtistImage::ArtistImage() : d( new ArtistImageData )
{
}
Echonest::ArtistImage::ArtistImage(const Echonest::ArtistImage& other)
{
d = other.d;
}
Echonest::ArtistImage& Echonest::ArtistImage::operator=(const Echonest::ArtistImage& img)
{
d = img.d;
return *this;
}
Echonest::ArtistImage::~ArtistImage()
{
}
QUrl Echonest::ArtistImage::url() const
{
return d->url;
}
void Echonest::ArtistImage::setUrl(const QUrl& url)
{
d->url = url;
}
Echonest::License Echonest::ArtistImage::license() const
{
return d->license;
}
void Echonest::ArtistImage::setLicense(const Echonest::License& license)
{
d->license = license;
}
Echonest::AudioFile::AudioFile() : d( new AudioFileData )
{
}
Echonest::AudioFile::AudioFile(const Echonest::AudioFile& other)
{
d = other.d;
}
Echonest::AudioFile& Echonest::AudioFile::operator=(const Echonest::AudioFile& artist)
{
d = artist.d;
return *this;
}
Echonest::AudioFile::~AudioFile()
{
}
void Echonest::AudioFile::setTitle(const QString& title)
{
d->title = title;
}
QString Echonest::AudioFile::title() const
{
return d->title;
}
QString Echonest::AudioFile::artist() const
{
return d->artist;
}
void Echonest::AudioFile::setArtist(const QString& artist)
{
d->artist = artist;
}
QDateTime Echonest::AudioFile::date() const
{
return d->date;
}
void Echonest::AudioFile::setDate(const QDateTime& date)
{
d->date = date;
}
QString Echonest::AudioFile::release() const
{
return d->release;
}
void Echonest::AudioFile::setRelease(const QString& release)
{
d->release = release;
}
QByteArray Echonest::AudioFile::id() const
{
return d->id;
}
void Echonest::AudioFile::setId(const QByteArray& id)
{
d->id = id;
}
qreal Echonest::AudioFile::length() const
{
return d->length;
}
void Echonest::AudioFile::setLength(qreal length)
{
d->length = length;
}
QUrl Echonest::AudioFile::link() const
{
return d->link;
}
void Echonest::AudioFile::setLink(const QUrl& url)
{
d->link = url;
}
QUrl Echonest::AudioFile::url() const
{
return d->url;
}
void Echonest::AudioFile::setUrl(const QUrl& url)
{
d->url = url;
}
Echonest::Biography::Biography() : d( new BiographyData )
{
}
Echonest::Biography::Biography(const Echonest::Biography& other)
{
d = other.d;
}
Echonest::Biography& Echonest::Biography::operator=(const Echonest::Biography& biblio)
{
d = biblio.d;
return *this;
}
Echonest::Biography::~Biography()
{
}
Echonest::License Echonest::Biography::license() const
{
return d->license;
}
void Echonest::Biography::setLicense(const Echonest::License& license)
{
d->license = license;
}
QString Echonest::Biography::site() const
{
return d->site;
}
void Echonest::Biography::setSite(const QString& site)
{
d->site = site;
}
QString Echonest::Biography::text() const
{
return d->text;
}
void Echonest::Biography::setText(const QString& text)
{
d->text = text;
}
QUrl Echonest::Biography::url() const
{
return d->url;
}
void Echonest::Biography::setUrl(const QUrl& url)
{
d->url = url;
}
Echonest::Blog::Blog() : d( new BlogData )
{
}
Echonest::Blog::Blog(const Echonest::Blog& other) : d( other.d )
{
}
Echonest::Blog& Echonest::Blog::operator=(const Echonest::Blog& other)
{
d = other.d;
return *this;
}
Echonest::Blog::~Blog()
{
}
QDateTime Echonest::Blog::dateFound() const
{
return d->date_found;
}
void Echonest::Blog::setDateFound(const QDateTime& date)
{
d->date_found = date;
}
QDateTime Echonest::Blog::datePosted() const
{
return d->date_posted;
}
void Echonest::Blog::setDatePosted(const QDateTime& date)
{
d->date_posted = date;
}
QByteArray Echonest::Blog::id() const
{
return d->id;
}
void Echonest::Blog::setId(const QByteArray& id)
{
d->id = id;
}
QString Echonest::Blog::name() const
{
return d->name;
}
void Echonest::Blog::setName(const QString& name)
{
d->name = name;
}
QString Echonest::Blog::summary() const
{
return d->summary;
}
void Echonest::Blog::setSummary(const QString& text)
{
d->summary = text;
}
QUrl Echonest::Blog::url() const
{
return d->url;
}
void Echonest::Blog::setUrl(const QUrl& url)
{
d->url = url;
}
Echonest::Review::Review() : d( new ReviewData )
{
}
Echonest::Review::Review(const Echonest::Review& other) : d( other.d )
{
}
Echonest::Review& Echonest::Review::operator=(const Echonest::Review& other)
{
d = other.d;
return *this;
}
Echonest::Review::~Review()
{
}
QDateTime Echonest::Review::dateFound() const
{
return d->date_found;
}
void Echonest::Review::setDateFound(const QDateTime& date)
{
d->date_found = date;
}
QDateTime Echonest::Review::dateReviewed() const
{
return d->date_reviewed;
}
void Echonest::Review::setDateReviewed(const QDateTime& date)
{
d->date_reviewed = date;
}
QByteArray Echonest::Review::id() const
{
return d->id;
}
void Echonest::Review::setId(const QByteArray& id)
{
d->id = id;
}
QUrl Echonest::Review::imageUrl() const
{
return d->image_url;
}
void Echonest::Review::setImageUrl(const QUrl& imageUrl)
{
d->image_url = imageUrl;
}
QString Echonest::Review::name() const
{
return d->name;
}
void Echonest::Review::setName(const QString& name)
{
d->name = name;
}
QString Echonest::Review::release() const
{
return d->release;
}
void Echonest::Review::setRelease(const QString& release)
{
d->release = release;
}
QString Echonest::Review::summary() const
{
return d->summary;
}
void Echonest::Review::setSummary(const QString& text)
{
d->summary = text;
}
QUrl Echonest::Review::url() const
{
return d->url;
}
void Echonest::Review::setUrl(const QUrl& url)
{
d->url = url;
}
Echonest::Term::Term() : d( new TermData )
{
}
Echonest::Term::Term(const Echonest::Term& other) : d( other.d )
{
}
Echonest::Term& Echonest::Term::operator=(const Echonest::Term& other)
{
d = other.d;
return *this;
}
Echonest::Term::~Term()
{
}
qreal Echonest::Term::frequency() const
{
return d->frequency;
}
void Echonest::Term::setFrequency(qreal freq)
{
d->frequency = freq;
}
QString Echonest::Term::name() const
{
return d->name;
}
void Echonest::Term::setName(const QString& name)
{
d->name = name;
}
qreal Echonest::Term::weight() const
{
return d->weight;
}
void Echonest::Term::setWeight(qreal weight)
{
d->weight = weight;
}
Echonest::Video::Video() : d( new VideoData )
{
}
Echonest::Video::Video(const Echonest::Video& other) : d( other.d )
{
}
Echonest::Video& Echonest::Video::operator=(const Echonest::Video& other)
{
d = other.d;
return *this;
}
Echonest::Video::~Video()
{
}
QDateTime Echonest::Video::dateFound() const
{
return d->date_found;
}
void Echonest::Video::setDateFound(const QDateTime& date)
{
d->date_found = date;
}
QByteArray Echonest::Video::id() const
{
return d->id;
}
void Echonest::Video::setId(const QByteArray& id)
{
d->id = id;
}
QUrl Echonest::Video::imageUrl() const
{
return d->image_url;
}
void Echonest::Video::setImageUrl(const QUrl& imageUrl)
{
d->image_url = imageUrl;
}
QString Echonest::Video::site() const
{
return d->site;
}
void Echonest::Video::setSite(const QString& site)
{
d->site = site;
}
QString Echonest::Video::title() const
{
return d->title;
}
void Echonest::Video::setTitle(const QString& title)
{
d->title = title;
}
QUrl Echonest::Video::url() const
{
return d->url;
}
void Echonest::Video::setUrl(const QUrl& url)
{
d->url = url;
}
QDebug Echonest::operator<<(QDebug d, const Echonest::AudioFile& audio)
{
return d.maybeSpace() << QString::fromLatin1( "AudioFile [%1, %2, %3, %4]" ).arg( audio.title() ) .arg( audio.artist() ).arg( audio.release() ).arg( audio.url().toString() );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Biography& biblio)
{
return d.maybeSpace() << QString::fromLatin1( "Bibliography [%1, %2, %3, %4]" ).arg( biblio.site() ).arg( biblio.url().toString() ).arg( biblio.license().type ).arg( biblio.text().left( 100 ) );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Blog& blog)
{
return d.maybeSpace() << QString::fromLatin1( "Blog [%1, %2, %3, %4, %5, %6]" ).arg( blog.name() ).arg( blog.datePosted().toString() ).arg( blog.dateFound().toString() ).arg( blog.url().toString() ).arg( QLatin1String( blog.id() ) ).arg( blog.summary().left( 100 ) );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::ArtistImage& img)
{
return d.maybeSpace() << QString::fromLatin1( "ArtistImage [%1, %2]" ).arg( img.url().toString() ).arg( img.license().type );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Review& review)
{
return d.maybeSpace() << QString::fromLatin1( "Review [%1, %2, %3]" ).arg( review.name() ).arg( review.release() ).arg( review.summary().left( 100 ) );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Term& term)
{
return d.maybeSpace() << QString::fromLatin1( "Term [%1, %2, %3]" ).arg( term.name() ).arg( term.frequency() ).arg( term.weight() );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Video& video)
{
return d.maybeSpace() << QString::fromLatin1( "Video [%1, %2, %3]" ).arg( video.title() ).arg( video.site() ).arg( video.url().toString() );
}

View File

@ -1,390 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_ARTISTTYPES_H
#define ECHONEST_ARTISTTYPES_H
#include "echonest_export.h"
#include "Util.h"
#include <QDebug>
#include <QSharedData>
class QDateTime;
class QUrl;
class AudioFileData;
class BiographyData;
class BlogData;
class ArtistImageData;
class ReviewData;
class TermData;
class VideoData;
namespace Echonest{
/**
* A link to an audio file related to an artist on the web.
*/
class ECHONEST_EXPORT AudioFile
{
public:
AudioFile();
AudioFile( const AudioFile& other );
AudioFile& operator=( const AudioFile& artist );
~AudioFile();
/**
* The title of the audio file.
*/
QString title() const;
void setTitle( const QString& title );
/**
* The artist name that this audio file is related to.
*/
QString artist() const;
void setArtist( const QString& );
/**
* The URL pointing to the audio file.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The length of the referenced audio file.
*/
qreal length() const;
void setLength( qreal length );
/**
* The link to the website where the audio file is from.
*/
QUrl link() const;
void setLink( const QUrl& url );
/**
* The date that this audio was posted.
*/
QDateTime date() const;
void setDate( const QDateTime& );
/**
* The released album name of this audio file.
*/
QString release() const;
void setRelease( const QString& release );
/**
* The unique identifier for this artist audio file.
*/
QByteArray id() const;
void setId( const QByteArray& id );
private:
QSharedDataPointer<AudioFileData> d;
};
/**
* A biography of an artist, including the full text content
* of the biography itself.
*/
class ECHONEST_EXPORT Biography {
public:
Biography();
Biography( const Biography& other );
Biography& operator=( const Biography& biblio );
~Biography();
/**
* The URL to the biography.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The text contents of the biography. May be very long.
*/
QString text() const;
void setText( const QString& text );
/**
* The site that this biography is from.
*/
QString site() const;
void setSite( const QString& site );
/**
* The license that this biography is licensed under.
*/
License license() const;
void setLicense( const License& license );
private:
QSharedDataPointer<BiographyData> d;
};
/**
* A blog post about a certain artist or track.
*/
class ECHONEST_EXPORT Blog {
public:
Blog();
Blog( const Blog& other );
Blog& operator=( const Blog& other );
~Blog();
/**
* The name of the blog or news article.
*/
QString name() const;
void setName( const QString& name );
/**
* The URL to the blog post or news article.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The date when the blog post or news article was posted.
*/
QDateTime datePosted() const;
void setDatePosted( const QDateTime& date );
/**
* The date when this blog post or news article was found by The Echo Nest.
*/
QDateTime dateFound() const;
void setDateFound( const QDateTime& date );
/**
* A short summary of the blog or article.
*/
QString summary() const;
void setSummary( const QString& text );
/**
* The unique identifier for this entry.
*/
QByteArray id() const;
void setId( const QByteArray& id );
private:
QSharedDataPointer<BlogData> d;
};
/**
* A news article about an artist.
*/
typedef Blog NewsArticle;
/**
* An image related to an artist.
*/
class ECHONEST_EXPORT ArtistImage {
public:
ArtistImage();
ArtistImage( const ArtistImage& other );
ArtistImage& operator=( const ArtistImage& img );
~ArtistImage();
/**
* The image url.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The license that governs this image.
*/
License license() const;
void setLicense( const License& license );
private:
QSharedDataPointer<ArtistImageData> d;
};
/**
* A review of an artist, album, or track.
*/
class ECHONEST_EXPORT Review {
public:
Review();
Review( const Review& other );
Review& operator=( const Review& other );
~Review();
/**
* The name of the review site.
*/
QString name() const;
void setName( const QString& name );
/**
* The URL to the review.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The date when the review was posted.
*/
QDateTime dateReviewed() const;
void setDateReviewed( const QDateTime& date );
/**
* The date when this review was found and indexed by The Echo Nest
*/
QDateTime dateFound() const;
void setDateFound( const QDateTime& date );
/**
* A summary of the review.
*/
QString summary() const;
void setSummary( const QString& text );
/**
* The url to an image associated with the review, if it exists.
*/
QUrl imageUrl() const;
void setImageUrl( const QUrl& imageUrl );
/**
* The album being reviewed if it is an album review, including specific release info, if it exists.
*/
QString release() const;
void setRelease( const QString& release );
/**
* The unique identifier for this entry.
*/
QByteArray id() const;
void setId( const QByteArray& id );
private:
QSharedDataPointer<ReviewData> d;
};
/**
* A term used to describe an artist or track.
*/
class ECHONEST_EXPORT Term {
public:
Term();
Term( const Term& other );
Term& operator=( const Term& img );
~Term();
/**
* The term name.
*/
QString name() const;
void setName( const QString& name );
/**
* The frequency that this term is mentioned in relation to the artist/track.
*/
qreal frequency() const;
void setFrequency( qreal freq );
/**
* The weight that The Echo Nest assigns to this term.
*/
qreal weight() const;
void setWeight( qreal weight );
private:
QSharedDataPointer<TermData> d;
};
/**
* A link to a video related to an artist.
*/
class ECHONEST_EXPORT Video {
public:
Video();
Video( const Video& other );
Video& operator=( const Video& other );
~Video();
/**
* The title of the video
*/
QString title() const;
void setTitle( const QString& title );
/**
* The URL to the title.
*/
QUrl url() const;
void setUrl( const QUrl& url );
/**
* The site that the video is from.
*/
QString site() const;
void setSite( const QString& site );
/**
* The date when this video was found
*/
QDateTime dateFound() const;
void setDateFound( const QDateTime& date );
/**
* The url to an image associated with this video, if it exists.
*/
QUrl imageUrl() const;
void setImageUrl( const QUrl& imageUrl );
/**
* The unique identifier for this video.
*/
QByteArray id() const;
void setId( const QByteArray& id );
private:
QSharedDataPointer<VideoData> d;
};
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::AudioFile& artist);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Biography& biblio);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Blog& blog);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::ArtistImage& img);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Review& review);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Term& term);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Video& video);
typedef QVector< AudioFile > AudioList;
typedef QVector< Biography > BiographyList;
typedef QVector< Blog > BlogList;
typedef QVector< ArtistImage > ArtistImageList;
typedef QVector< NewsArticle > NewsList;
typedef QVector< Review > ReviewList;
typedef QVector< Term > TermList;
typedef QVector< Video > VideoList;
} // namespace
#endif

View File

@ -1,166 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_ARTISTTYPES_P_H
#define ECHONEST_ARTISTTYPES_P_H
#include "Util.h"
#include <QSharedData>
#include <QString>
#include <QVector>
#include <QDate>
#include <QUrl>
class AudioFileData : public QSharedData
{
public:
AudioFileData() {}
AudioFileData( const AudioFileData& other ) : QSharedData( other ) {
title = other.title;
artist = other.artist;
url = other.url;
length = other.length;
link = other.link;
date = other.date;
id = other.id;
release = other.release;
}
QString title;
QString artist;
QUrl url;
qreal length;
QUrl link;
QDateTime date;
QString release;
QByteArray id;
};
class BiographyData : public QSharedData
{
public:
BiographyData() {}
BiographyData( const BiographyData& other ) : QSharedData( other ) {
url = other.url;
text = other.text;
site = other.site;
license = other.license;
}
QUrl url;
QString text;
QString site;
Echonest::License license;
};
class BlogData : public QSharedData
{
public:
BlogData() {}
BlogData( const BlogData& other ) : QSharedData( other ) {
name = other.name;
url = other.url;
date_posted = other.date_posted;
date_found = other.date_found;
summary = other.summary;
id = other.id;
}
QString name;
QUrl url;
QDateTime date_posted;
QDateTime date_found;
QString summary;
QByteArray id;
};
class ArtistImageData : public QSharedData
{
public:
ArtistImageData() {}
ArtistImageData( const ArtistImageData& other ) : QSharedData( other ) {
url = other.url;
license = other.license;
}
QUrl url;
Echonest::License license;
};
class ReviewData : public QSharedData
{
public:
ReviewData() {}
ReviewData( const ReviewData& other ) : QSharedData( other ) {
name = other.name;
url = other.url;
summary = other.summary;
date_reviewed = other.date_reviewed;
date_found = other.date_found;
image_url = other.image_url;
release = other.release;
id = other.id;
}
QString name;
QUrl url;
QString summary;
QDateTime date_reviewed;
QDateTime date_found;
QUrl image_url;
QString release;
QByteArray id;
};
class TermData : public QSharedData
{
public:
TermData() {}
TermData( const TermData& other ) : QSharedData( other ) {
name = other.name;
frequency = other.frequency;
weight = other.weight;
}
QString name;
qreal frequency;
qreal weight;
};
class VideoData : public QSharedData
{
public:
VideoData() {}
VideoData( const VideoData& other ) : QSharedData( other ) {
title = other.title;
url = other.url;
site = other.site;
date_found = other.date_found;
image_url = other.image_url;
id = other.id;
}
QString title;
QUrl url;
QString site;
QDateTime date_found;
QUrl image_url;
QByteArray id;
};
#endif

View File

@ -1,97 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_ARTIST_P_H
#define ECHONEST_ARTIST_P_H
#include "Song.h"
#include "ArtistTypes.h"
#include <QSharedData>
#include <QString>
#include <QVector>
namespace Echonest {
class Artist;
}
class ArtistData : public QSharedData
{
public:
ArtistData() : familiarity( -1 ), hotttnesss( -1 ) {}
ArtistData( const QByteArray& id, const QString& name ) : id( id ), name( name ), familiarity( -1 ), hotttnesss( -1 ) {}
ArtistData(const ArtistData& other) : QSharedData( other )
{
id = other.id;
name = other.name;
audio = other.audio;
biographies = other.biographies;
blogs = other.blogs;
familiarity = other.familiarity;
hotttnesss = other.hotttnesss;
images = other.images;
news = other.news;
reviews = other.reviews;
songs = other.songs;
similar = other.similar;
terms = other.terms;
videos = other.videos;
lastfm_url = other.lastfm_url;
aolmusic_url = other.aolmusic_url;
myspace_url = other.myspace_url;
amazon_url = other.amazon_url;
itunes_url = other.itunes_url;
mb_url = other.mb_url;
foreign_ids = other.foreign_ids;
}
// The following exist in all valid Artist objects
QByteArray id;
QString name;
//The following are populated on demand, and may not exist
Echonest::AudioList audio;
Echonest::BiographyList biographies;
Echonest::BlogList blogs;
qreal familiarity;
qreal hotttnesss;
Echonest::ArtistImageList images;
Echonest::NewsList news;
Echonest::ReviewList reviews;
Echonest::SongList songs;
QVector<Echonest::Artist> similar;
Echonest::TermList terms;
Echonest::VideoList videos;
QUrl lastfm_url;
QUrl aolmusic_url;
QUrl myspace_url;
QUrl amazon_url;
QUrl itunes_url;
QUrl mb_url;
Echonest::ForeignIds foreign_ids;
};
#endif

View File

@ -1,339 +0,0 @@
/****************************************************************************************
* 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 "AudioSummary.h"
#include "AudioSummary_p.h"
#include "Config.h"
#include "Parsing_p.h"
#include <QNetworkReply>
Echonest::AudioSummary::AudioSummary()
: d( new AudioSummaryData )
{
}
Echonest::AudioSummary::AudioSummary(const Echonest::AudioSummary& other)
:d( other.d )
{
}
Echonest::AudioSummary::~AudioSummary()
{}
QDebug Echonest::operator<<(QDebug d, const Echonest::AudioSummary& summary)
{
// d << summary
return d.maybeSpace();
}
Echonest::AudioSummary& Echonest::AudioSummary::operator=(const Echonest::AudioSummary& audio)
{
d = audio.d;
return *this;
}
int Echonest::AudioSummary::analysisStatus() const
{
return d->status;
}
void Echonest::AudioSummary::setAnalysisStatus(int status)
{
d->status = status;
}
qreal Echonest::AudioSummary::analysisTime() const
{
return d->analysis_time;
}
void Echonest::AudioSummary::setAnalysisTime(qreal time)
{
d->analysis_time = time;
}
QString Echonest::AudioSummary::analyzerVersion() const
{
return d->analyzer_version;
}
void Echonest::AudioSummary::setAnalyzerVersion(QString version)
{
d->analyzer_version = version;
}
Echonest::BarList Echonest::AudioSummary::bars() const
{
return d->bars;
}
void Echonest::AudioSummary::setBars(const Echonest::BarList& bars)
{
d->bars = bars;
}
Echonest::BeatList Echonest::AudioSummary::beats() const
{
return d->beats;
}
void Echonest::AudioSummary::setBeats(const Echonest::BeatList& beats)
{
d->beats = beats;
}
QString Echonest::AudioSummary::detailedStatus() const
{
return d->detailed_status;
}
void Echonest::AudioSummary::setDetailedStatus( const QString& status )
{
d->detailed_status = status;
}
qreal Echonest::AudioSummary::duration() const
{
return d->duration;
}
void Echonest::AudioSummary::setDuration(qreal duration)
{
d->duration = duration;
}
qreal Echonest::AudioSummary::endOfFadeIn() const
{
return d->end_of_fade_in;
}
void Echonest::AudioSummary::setEndOfFadeIn(qreal time)
{
d->end_of_fade_in = time;
}
QNetworkReply* Echonest::AudioSummary::fetchFullAnalysis() const
{
return Echonest::Config::instance()->nam()->get( QNetworkRequest( QUrl( d->analysis_url ) ) );
}
int Echonest::AudioSummary::key() const
{
return d->key;
}
void Echonest::AudioSummary::setKey(int key)
{
d->key = key;
}
qreal Echonest::AudioSummary::keyConfidence() const
{
return d->key_confidence;
}
void Echonest::AudioSummary::setKeyConfidence(qreal confidence)
{
d->key_confidence = confidence;
}
qreal Echonest::AudioSummary::loudness() const
{
return d->loudness;
}
void Echonest::AudioSummary::setLoudness(qreal loudness)
{
d->loudness = loudness;
}
qreal Echonest::AudioSummary::modeConfidence() const
{
return d->mode_confidence;
}
void Echonest::AudioSummary::setModeConfidence(qreal confidence)
{
d->mode_confidence = confidence;
}
qint64 Echonest::AudioSummary::numSamples() const
{
return d->num_samples;
}
void Echonest::AudioSummary::setNumSamples(qint64 num)
{
d->num_samples = num;
}
void Echonest::AudioSummary::parseFullAnalysis( QNetworkReply* reply ) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
Echonest::Parser::parseDetailedAudioSummary( reply, *this );
reply->deleteLater();
}
QString Echonest::AudioSummary::sampleMD5() const
{
return d->sample_md5;
}
void Echonest::AudioSummary::setSampleMD5(const QString& md5)
{
d->sample_md5 = md5;
}
qreal Echonest::AudioSummary::sampleRate() const
{
return d->samplerate;
}
void Echonest::AudioSummary::setSampleRate(qreal sampleRate)
{
d->samplerate = sampleRate;
}
Echonest::SectionList Echonest::AudioSummary::sections() const
{
return d->sections;
}
void Echonest::AudioSummary::setSections(const Echonest::SectionList& sections)
{
d->sections = sections;
}
Echonest::SegmentList Echonest::AudioSummary::segments() const
{
return d->segments;
}
void Echonest::AudioSummary::setSegments(const Echonest::SegmentList& segments)
{
d->segments = segments;
}
void Echonest::AudioSummary::setStartOfFadeOut(qreal time)
{
d->start_of_fade_out = time;
}
Echonest::TatumList Echonest::AudioSummary::tatums() const
{
return d->tatums;
}
void Echonest::AudioSummary::setTatums(const Echonest::TatumList& tatums)
{
d->tatums = tatums;
}
qreal Echonest::AudioSummary::startOfFadeOut() const
{
return d->start_of_fade_out;
}
qreal Echonest::AudioSummary::tempo() const
{
return d->tempo;
}
void Echonest::AudioSummary::setTempo(qreal tempo)
{
d->tempo = tempo;
}
qreal Echonest::AudioSummary::tempoConfidence() const
{
return d->tempo_confidence;
}
void Echonest::AudioSummary::setTempoConfidence(qreal confidence)
{
d->tempo_confidence = confidence;
}
int Echonest::AudioSummary::timeSignature() const
{
return d->time_signature;
}
void Echonest::AudioSummary::setTimeSignature(int timeSignature)
{
d->time_signature = timeSignature;
}
qreal Echonest::AudioSummary::timeSignatureConfidence() const
{
return d->time_signature_confidence;
}
void Echonest::AudioSummary::setTimeSignatureConfidence(qreal confidence)
{
d->time_signature_confidence = confidence;
}
void Echonest::AudioSummary::setTimestamp(qreal timestamp)
{
d->timestamp = timestamp;
}
qreal Echonest::AudioSummary::timestamp() const
{
return d->timestamp;
}
int Echonest::AudioSummary::mode() const
{
return d->mode;
}
void Echonest::AudioSummary::setAnalysisUrl(const QUrl& analysisUrl)
{
d->analysis_url = analysisUrl;
}
void Echonest::AudioSummary::setMode(int mode)
{
d->mode = mode;
}
qreal Echonest::AudioSummary::danceability() const
{
return d->danceability;
}
void Echonest::AudioSummary::setDanceability(qreal dance)
{
d->danceability = dance;
}
qreal Echonest::AudioSummary::energy() const
{
return d->energy;
}
void Echonest::AudioSummary::setEnergy(qreal energy)
{
d->energy = energy;
}

View File

@ -1,243 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_AUDIOSUMMARY_H
#define ECHONEST_AUDIOSUMMARY_H
#include "echonest_export.h"
#include <QSharedData>
#include <QDebug>
#include "Util.h"
#include "Util.h"
#include "Config.h"
class QNetworkReply;
class QNetworkReply;
class AudioSummaryData;
namespace Echonest{
/**
* This encapsulates the audio summary of an Echo Nest track or song.
*
* It has two batches of data: the more generic acoustic information about the
* song is always populated, and additional detailed information about the song
* such as bars, beats, segments, tatus, and sections, can be fetched as well as
* an additional step.
*
* This class is implicitly shared.
*/
class ECHONEST_EXPORT AudioSummary
{
public:
AudioSummary();
AudioSummary( const AudioSummary& other );
~AudioSummary();
AudioSummary& operator=( const AudioSummary& audio );
int key() const;
void setKey( int key );
/**
* The track's tempo.
*/
qreal tempo() const;
void setTempo( qreal tempo );
/**
* The track's mode.
*/
int mode() const;
void setMode( int mode );
/**
* The track's time signature, or -1 if it there is one, or 1 if it is
* too complex.
*/
int timeSignature() const;
void setTimeSignature( int timeSignature );
/**
* The duration of the song, in msecs.
*/
qreal duration() const;
void setDuration( qreal duration );
/**
* The loudness of the song, in dB.
*/
qreal loudness() const;
void setLoudness( qreal loudness );
/**
* The danceability of this track, from 0 to 1.
*/
qreal danceability() const;
void setDanceability( qreal dance );
/**
* The energy of this song, from 0 to 1.
*/
qreal energy() const;
void setEnergy( qreal energy );
/// The following require additional fetching to read ///
/** TODO: implement **/
/**
* If you wish to use any of the more detailed track analysis data,
* use this method to begin the fetch. One the returned QNetworkReply*
* has emitted the finished() signal, call parseFullAnalysis.
*/
QNetworkReply* fetchFullAnalysis() const;
/**
* Parses the result of a fetchFullAnalysis() call. This contains
* information such as mode, fadein/fadeout, confidence metrics,
* and the division of the song into bars, beats, sections, and segments.
*/
void parseFullAnalysis( QNetworkReply* reply ) throw( ParseError );
/// The following methods *ALL REQUIRE THAT parseFullAnalysis be called first*
/**
* How long it took to analyze this track.
*/
qreal analysisTime() const;
void setAnalysisTime( qreal time );
/**
* The version of the analyzer used on this track.
*/
QString analyzerVersion() const;
void setAnalyzerVersion( QString version );
/**
* Detailed status information about the analysis
*/
QString detailedStatus() const;
void setDetailedStatus( const QString& status );
/**
* The status code of the analysis
*/
int analysisStatus() const;
void setAnalysisStatus( int status );
/**
* The timestamp of the analysis.
*/
qreal timestamp() const;
void setTimestamp( qreal timestamp );
/** ECHONEST_EXPORT
* The sample rate of the track.
*/
qreal sampleRate() const;
void setSampleRate( qreal sampleRate );
/**
* The end of the track's fade in in msec.
*/
qreal endOfFadeIn() const;
void setEndOfFadeIn( qreal time );
/**
* The start of the fade out in msec.
*/
qreal startOfFadeOut() const;
void setStartOfFadeOut( qreal time );
/**
* The confidence of the key item.
*/
qreal keyConfidence() const;
void setKeyConfidence( qreal confidence );
/**
* The confidence of the mode item.
*/
qreal modeConfidence() const;
void setModeConfidence( qreal confidence );
/**
* The confidence of the tempo item.
*/
qreal tempoConfidence() const;
void setTempoConfidence( qreal confidence );
/**
* The confidence of the time signature item.
*/
qreal timeSignatureConfidence() const;
void setTimeSignatureConfidence( qreal confidence );
/**
* The number of samples in this track.
*/
qint64 numSamples() const;
void setNumSamples( qint64 num );
/**
* The MD5 of the sample.
*/
QString sampleMD5() const;
void setSampleMD5( const QString& md5 );
/**
* List of bars that are in the track.
*/
BarList bars() const;
void setBars( const BarList& bars );
/**
* List of beats in the track.
*/
BeatList beats() const;
void setBeats( const BeatList& beats );
/**
* List of sections in the track.
*/
SectionList sections() const;
void setSections( const SectionList& sections );
/**
* List of tatums in the track
*/
TatumList tatums() const;
void setTatums( const TatumList& tatums );
/**
* List of segments in the track with associated acoustic data.
*/
SegmentList segments() const;
void setSegments( const SegmentList& segments );
void setAnalysisUrl( const QUrl& analysisUrl );
private:
QSharedDataPointer<AudioSummaryData> d;
};
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::AudioSummary& summary);
} // namespace
#endif

View File

@ -1,105 +0,0 @@
/****************************************************************************************
* 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 "Util.h"
#include <QSharedData>
#include <QString>
#include <QUrl>
#include <QVector>
class AudioSummaryData : public QSharedData
{
public:
AudioSummaryData() : key( -1 ), tempo( -1 ), mode( -1 ), time_signature( -1 ), duration( -1 ), loudness( -1 ), samplerate( -1 ), danceability( -1 ), energy( -1 ),
analysis_time( -1 ), status( -1 ), timestamp( -1 ), end_of_fade_in( -1 ), key_confidence( -1 ), mode_confidence( -1 ), num_samples( -1 ),
start_of_fade_out( -1 ), tempo_confidence( -1 ), time_signature_confidence( -1 ) {}
AudioSummaryData(const AudioSummaryData& other) : QSharedData( other )
{
key = other.key;
tempo = other.tempo;
mode = other.mode;
time_signature = other.time_signature;
duration = other.duration;
loudness = other.loudness;
samplerate = other.samplerate;
danceability = other.danceability;
energy = other.energy;
analysis_url = other.analysis_url;
analysis_time = other.analysis_time;
analyzer_version = other.analyzer_version;
detailed_status = other.detailed_status;
status = other.status;
timestamp = other.timestamp;
end_of_fade_in = other.end_of_fade_in;
key_confidence = other.key_confidence;
loudness = other.loudness;
mode_confidence = other.mode_confidence;
num_samples = other.num_samples;
sample_md5 = other.sample_md5;
start_of_fade_out = other.start_of_fade_out;
tempo_confidence = other.tempo_confidence;
time_signature = other.time_signature;
time_signature_confidence = other.time_signature_confidence;
bars = other.bars;
beats = other.beats;
sections = other.sections;
tatums = other.tatums;
segments = other.segments;
}
// basic data that always exists in an Audio Summary object
int key;
qreal tempo;
int mode;
int time_signature;
qreal duration;
qreal loudness;
int samplerate;
qreal danceability;
qreal energy;
QUrl analysis_url; // used to fetch the following pieces of data
// meta section
qreal analysis_time;
QString analyzer_version;
QString detailed_status;
int status;
qreal timestamp;
// track section
qreal end_of_fade_in;
qreal key_confidence;
qreal mode_confidence;
qint64 num_samples;
QString sample_md5;
qreal start_of_fade_out;
qreal tempo_confidence;
qreal time_signature_confidence;
Echonest::BarList bars;
Echonest::BeatList beats;
Echonest::SectionList sections;
Echonest::TatumList tatums;
Echonest::SegmentList segments;
};

View File

@ -1,62 +0,0 @@
include_directories( ${QJSON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR} )
set( LIBECHONEST_SRC
Track.cpp
Song.cpp
Artist.cpp
Playlist.cpp
Config.cpp
Parsing.cpp
AudioSummary.cpp
Util.cpp
ArtistTypes.cpp
Generator.cpp
Catalog.cpp
CatalogUpdateEntry.cpp
CatalogSong.cpp
CatalogArtist.cpp
CatalogItem.cpp
TypeInformation.cpp
)
set( LIBECHONEST_H
echonest_export.h
Track.h
Song.h
Artist.h
Playlist.h
Config.h
AudioSummary.h
ArtistTypes.h
Util.h
Catalog.h
CatalogUpdateEntry.h
CatalogSong.h
CatalogArtist.h
CatalogItem.h
TypeInformation.h
)
QT4_WRAP_CPP( ${LIBECHONEST_H} )
if (CMAKE_COMPILER_IS_GNUCXX)
add_definitions( -Werror )
endif (CMAKE_COMPILER_IS_GNUCXX)
SET( OS_SPECIFIC_LINK_LIBRARIES "" )
IF( APPLE OR MINGW )
SET( OS_SPECIFIC_LINK_LIBRARIES ${QJSON_LIBRARIES} )
ELSE( APPLE OR MINGW )
SET( OS_SPECIFIC_LINK_LIBRARIES ${QJSON_LDFLAGS} )
ENDIF( APPLE OR MINGW )
add_library( echonest STATIC ${LIBECHONEST_SRC} )
target_link_libraries( echonest ${OS_SPECIFIC_LINK_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTNETWORK_LIBRARY} )
foreach(file ${LIBECHONEST_H} echonest_export.h Util.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${file}
${CMAKE_CURRENT_BINARY_DIR}/echonest/${file}
COPYONLY)
endforeach(file ${LIBECHONEST_H})

View File

@ -1,334 +0,0 @@
/****************************************************************************************
* 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 "Catalog.h"
#include "Catalog_p.h"
#include "Parsing_p.h"
#include "Generator_p.h"
#include "Track_p.h"
Echonest::Catalog::Catalog()
: d( new CatalogData )
{
}
Echonest::Catalog::Catalog( const QByteArray& id )
: d( new CatalogData )
{
d->id = id;
}
Echonest::Catalog::Catalog( const Echonest::Catalog& catalog )
: d( catalog.d )
{
}
Echonest::Catalog& Echonest::Catalog::operator=( const Echonest::Catalog& other )
{
d = other.d;
return *this;
}
Echonest::Catalog::~Catalog()
{
}
Echonest::CatalogArtists Echonest::Catalog::artists() const
{
return d->artists;
}
void Echonest::Catalog::setArtists(const Echonest::CatalogArtists& artists)
{
d->artists = artists;
}
QByteArray Echonest::Catalog::id() const
{
return d->id;
}
void Echonest::Catalog::setId(const QByteArray& id)
{
d->id = id;
}
QString Echonest::Catalog::name() const
{
return d->name;
}
void Echonest::Catalog::setName(const QString& name)
{
d->name = name;
}
int Echonest::Catalog::resolved() const
{
return d->resolved;
}
void Echonest::Catalog::setResolved(int resolved)
{
d->resolved = resolved;
}
int Echonest::Catalog::pendingTickets() const
{
// return d->pending_tickets;
return 0;
}
void Echonest::Catalog::setPendingTickets(int pending)
{
// d->pending_tickets = pending;
}
Echonest::CatalogSongs Echonest::Catalog::songs() const
{
return d->songs;
}
void Echonest::Catalog::setSongs(const Echonest::CatalogSongs& songs)
{
d->songs = songs;
}
int Echonest::Catalog::total() const
{
return d->total;
}
void Echonest::Catalog::setTotal(int total)
{
d->total = total;
}
Echonest::CatalogTypes::Type Echonest::Catalog::type() const
{
return d->type;
}
void Echonest::Catalog::setType(Echonest::CatalogTypes::Type type)
{
d->type = type;
}
QNetworkReply* Echonest::Catalog::create(const QString& name, Echonest::CatalogTypes::Type type)
{
QUrl url = Echonest::baseGetQuery( "catalog", "create" );
url.addQueryItem( QLatin1String( "name" ), name );
url.addEncodedQueryItem( "type", Echonest::catalogTypeToLiteral( type ) );
QNetworkRequest request = QNetworkRequest( url );
request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "multipart/form-data" ) );
qDebug() << "Sending create url:" << url.toString();
return Echonest::Config::instance()->nam()->post( request, QByteArray() );
}
QNetworkReply* Echonest::Catalog::deleteCatalog() const
{
QUrl url = Echonest::baseGetQuery( "catalog", "delete" );
Q_ASSERT( !d->id.isEmpty() );
url.addEncodedQueryItem( "id", d->id );
return Echonest::doPost( url );
}
QNetworkReply* Echonest::Catalog::list(int results, int start)
{
QUrl url = Echonest::baseGetQuery( "catalog", "list" );
addLimits( url, results, start );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Catalog::profile() const
{
QUrl url = Echonest::baseGetQuery( "catalog", "profile" );
if( !d->id.isEmpty() )
url.addEncodedQueryItem( "id", d->id );
else if( !d->name.isEmpty() )
url.addQueryItem( QLatin1String( "name" ), d->name );
else
Q_ASSERT_X( false, "Catalog", "Not enough information!" );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Catalog::status(const QByteArray& ticket)
{
QUrl url = Echonest::baseGetQuery( "catalog", "status" );
url.addEncodedQueryItem( "ticket", ticket );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Catalog::update(const Echonest::CatalogUpdateEntries& entries) const
{
QUrl url = Echonest::baseGetQuery( "catalog", "update" );
Q_ASSERT( !d->id.isEmpty() );
url.addEncodedQueryItem( "id", d->id );
return Echonest::Catalog::updatePrivate( url, entries );
}
QNetworkReply* Echonest::Catalog::updateAndCreate(const Echonest::CatalogUpdateEntries& entries)
{
QUrl url = Echonest::baseGetQuery( "catalog", "update" );
return Echonest::Catalog::updatePrivate( url, entries );
}
QNetworkReply* Echonest::Catalog::readArtistCatalog(Echonest::ArtistInformation info, int results, int start) const
{
QUrl url = Echonest::baseGetQuery( "catalog", "read" );
Artist::addQueryInformation( url, info );
return readPrivate( url, results, start );
}
QNetworkReply* Echonest::Catalog::readSongCatalog(Echonest::SongInformation info, int results, int start) const
{
QUrl url = Echonest::baseGetQuery( "catalog", "read" );
Song::addQueryInformation( url, info );
return readPrivate( url, results, start );
}
QPair< QString, QByteArray > Echonest::Catalog::parseDelete( QNetworkReply* reply ) throw( Echonest::ParseError )
{
QByteArray data = reply->readAll();
// qDebug() << "DATA:" << data;
QPair< QString, QByteArray > asd;
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
// TODO, after create works :)
reply->deleteLater();
return asd;
}
Echonest::Catalogs Echonest::Catalog::parseList(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::Catalogs catalogs = Echonest::Parser::parseCatalogList( xml );
reply->deleteLater();
return catalogs;
}
void Echonest::Catalog::parseProfile(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::Catalog catalog = Echonest::Parser::parseCatalog( xml, true );
d = catalog.d;
reply->deleteLater();
}
void Echonest::Catalog::parseRead(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::Catalog catalog = Echonest::Parser::parseCatalog( xml, true );
d = catalog.d;
reply->deleteLater();
}
Echonest::CatalogStatus Echonest::Catalog::parseStatus(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QByteArray data = reply->readAll();
// qDebug() << data;
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
Echonest::CatalogStatus status = Echonest::Parser::parseCatalogStatus( xml );
reply->deleteLater();
return status;
}
QByteArray Echonest::Catalog::parseTicket(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QByteArray data = reply->readAll();
// qDebug() << data;
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
QByteArray ticket = Echonest::Parser::parseCatalogTicket( xml );
reply->deleteLater();
return ticket;
}
Echonest::Catalog Echonest::Catalog::parseCreate(QNetworkReply* reply) throw( Echonest::ParseError )
{
QByteArray data = reply->readAll();
// qDebug() << data;
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
Catalog c = Echonest::Parser::parseNewCatalog( xml );
reply->deleteLater();
return c;
}
QNetworkReply* Echonest::Catalog::updatePrivate( QUrl& url, const Echonest::CatalogUpdateEntries& entries)
{
url.addEncodedQueryItem( "data_type", "json" );
QByteArray payload = Generator::catalogEntriesToJson( entries );
url.addEncodedQueryItem( "data", payload );
return Echonest::doPost( url );
}
void Echonest::Catalog::addLimits(QUrl& url, int results, int start)
{
if( results != 30 )
url.addEncodedQueryItem( "results", QString::number( results ).toLatin1() );
if( start > -1 )
url.addEncodedQueryItem( "start", QString::number( start ).toLatin1() );
}
QNetworkReply* Echonest::Catalog::readPrivate(QUrl& url, int results, int start) const
{
Q_ASSERT( !d->id.isEmpty() );
url.addEncodedQueryItem( "id", d->id );
addLimits( url, results, start );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Catalog& catalog)
{
return d.maybeSpace() << QString::fromLatin1( "Catalog(%1, %2, %3, %4)" ).arg( catalog.name() ).arg( QLatin1String( catalog.id() ) )
.arg( QString::fromLatin1( Echonest::catalogTypeToLiteral( catalog.type() ) ) ).arg( catalog.total() ) << catalog.artists() << catalog.songs();
}

View File

@ -1,225 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_H
#define ECHONEST_CATALOG_H
#include "Artist.h"
#include "CatalogUpdateEntry.h"
#include "echonest_export.h"
#include "Song.h"
#include "TypeInformation.h"
#include "Util.h"
#include <QSharedDataPointer>
#include <QString>
#include "CatalogSong.h"
#include "CatalogArtist.h"
class QNetworkReply;
class CatalogData;
namespace Echonest
{
class Catalog;
typedef QVector< Catalog > Catalogs;
class ECHONEST_EXPORT Catalog
{
public:
Catalog();
explicit Catalog( const QByteArray& id );
Catalog( const Catalog& );
virtual ~Catalog();
Catalog& operator=( const Catalog& );
/// Basic information about the catalog
/**
* The name of this catalog.
*/
QString name() const;
void setName( const QString& name );
/**
* The id of this catalog.
*/
QByteArray id() const;
void setId( const QByteArray& id );
/**
* The type of this catalog.
*/
CatalogTypes::Type type() const;
void setType( CatalogTypes::Type type );
/**
* The total number of items in this catalog.
*/
int total() const;
void setTotal( int total );
/// The following fields only have data if the appropriate parse* methods have been called
/**
* The number of resolved items in the catalog.
*/
int resolved() const;
void setResolved( int resolved );
/**
* The number of pending tickets still to be resolved
*/
int pendingTickets() const;
void setPendingTickets( int pending );
/**
* The songs in this catalog, if this is a song catalog.
*/
CatalogSongs songs() const;
void setSongs( const CatalogSongs& songs );
/**
* The artists in this catalog, if it is an artist catalog.
*/
CatalogArtists artists() const;
void setArtists( const CatalogArtists& artists );
/**
* Update this catalog with the given items. Each item has an associated action, default is Update.
* Call parseTicket() to access the result ticket from this call.
*
* See more information about this api call at http://developer.echonest.com/docs/v4/catalog.html#update
*
* Requires catalog id.
*
* \param entries The list of entries to update the catalog with.
*/
QNetworkReply* update( const CatalogUpdateEntries& entries ) const;
/**
* Get basic information on a catalog. Only requires one of catalog id or name.
*/
QNetworkReply* profile() const;
/**
* Fetch the full list of data from this catalog. It is possible to specify specific audio
* information that you wish to have included with each item. Use the appropriate artist- or
* song-specific method calls in order to achieve this.
*
* \param info The list of desired information to be included with each item.
* \param results How many results to return in total
* \param start The index of the first result
*/
QNetworkReply* readArtistCatalog( ArtistInformation info = ArtistInformation(), int results = 30, int start = -1 ) const;
QNetworkReply* readSongCatalog( SongInformation info = SongInformation(), int results = 30, int start = -1 ) const;
/**
* Deletes this catalog from The Echo Nest. Only the API key used to create a catalog can delete it.
*/
QNetworkReply* deleteCatalog() const;
/**
* Create a new catalog with the given name and type.
*
* Parse the finished QNetworkReply with parseCreate()
*
* \param name The name of the catalog to create
* \param type The type of the catalog to create
*/
static QNetworkReply* create( const QString& name, CatalogTypes::Type type );
/**
* Returns a list of catalogs created with this key.
*/
static QNetworkReply* list( int results = 30, int start = -1 );
/**
* Creates a new catalog with the given items.
* See more information about this api call at http://developer.echonest.com/docs/v4/catalog.html#update
*
* Call parseTicket() to access the result ticket from this call.
*
* \param entries The list of entries to populate the catalog with.
*
*/
static QNetworkReply* updateAndCreate( const CatalogUpdateEntries& entries );
/**
* Checks the status of a catalog operation given a catalog ticket.
*
* Parse the result with parseStatus()
*
* \param ticket The catalog ticket returned from an update() or updateAndCreate() call
*/
static QNetworkReply* status( const QByteArray& ticket );
/**
* Parses the result of a status call, returning the status information along with information on
* item resolution if available.
*/
static CatalogStatus parseStatus( QNetworkReply* ) throw( Echonest::ParseError );
/**
* Parses the result of a profile() call. Saves the data to this catalog object.
*/
void parseProfile( QNetworkReply* ) throw( Echonest::ParseError );
/**
* Parses the result of the read*Catalog() calls. Saves the catalog data to this object.
*/
void parseRead( QNetworkReply * ) throw( Echonest::ParseError );
/**
* Parse the result of a delete call. Will throw if the catalog was not successfully deleted,
* and returns the name/id pair.
*
* \return QPair of catalogName, catalogId that was just deleted.
*/
QPair< QString, QByteArray > parseDelete( QNetworkReply* ) throw( Echonest::ParseError );
/**
* Parse the result of the list() API call. Will return a list of catalogs---each catalog only
* has id, name, type, and total tracks information.
*/
static Catalogs parseList( QNetworkReply* ) throw( Echonest::ParseError );
/**
* Parse the result of a catalog call. The calls return a ticket that can be used to check the status
* of the call with status()
*/
static QByteArray parseTicket( QNetworkReply* ) throw( Echonest::ParseError );
/**
* Parse the result of a create() call.
*/
static Catalog parseCreate( QNetworkReply* reply ) throw( Echonest::ParseError );
private:
static QNetworkReply* updatePrivate( QUrl&, const CatalogUpdateEntries& entries );
QNetworkReply* readPrivate( QUrl& url, int results, int start ) const;
static void addLimits( QUrl&, int results, int start );
QSharedDataPointer< CatalogData > d;
};
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Catalog &catalog);
}
Q_DECLARE_METATYPE( Echonest::Catalog )
#endif

View File

@ -1,59 +0,0 @@
/****************************************************************************************
* 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 "CatalogArtist.h"
#include "CatalogItem_p.h"
Echonest::CatalogArtist::CatalogArtist()
{
}
Echonest::CatalogArtist::CatalogArtist(const QString& name)
: Artist( name )
{
}
Echonest::CatalogArtist::CatalogArtist(const QByteArray& id, const QString& name)
: Artist(id, name)
{
}
Echonest::CatalogArtist::CatalogArtist(const Echonest::CatalogArtist& other)
: Artist( other )
, CatalogItem( other )
{
}
Echonest::CatalogArtist::~CatalogArtist()
{
}
Echonest::CatalogArtist& Echonest::CatalogArtist::operator=(const Echonest::CatalogArtist& other)
{
Artist::operator=( other );
CatalogItem::operator=( other );
return *this;
}
Echonest::CatalogTypes::Type Echonest::CatalogArtist::type() const
{
return Echonest::CatalogTypes::Artist;
}

View File

@ -1,50 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_ARTIST_H
#define ECHONEST_CATALOG_ARTIST_H
#include "echonest_export.h"
#include "Artist.h"
#include "CatalogItem.h"
class CatalogArtistData;
namespace Echonest {
/**
* An artist that includes some additional information returned when getting an artist from a catalog listing.
*/
class ECHONEST_EXPORT CatalogArtist : public Artist, public CatalogItem
{
public:
CatalogArtist();
explicit CatalogArtist(const QString& name);
CatalogArtist(const QByteArray& id, const QString& name);
CatalogArtist(const Echonest::CatalogArtist& other);
virtual ~CatalogArtist();
CatalogArtist& operator=( const CatalogArtist& other );
/**
* The type of this catalog item: Artist.
*/
virtual CatalogTypes::Type type() const;
};
typedef QVector< CatalogArtist > CatalogArtists;
}
Q_DECLARE_METATYPE( Echonest::CatalogArtist )
#endif

View File

@ -1,93 +0,0 @@
/****************************************************************************************
* 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 "CatalogItem.h"
#include "CatalogItem_p.h"
// just an interface.
Echonest::CatalogItem::CatalogItem()
: dd( new CatalogItemData )
{
}
Echonest::CatalogItem::CatalogItem(const Echonest::CatalogItem& other)
: dd( other.dd )
{
}
Echonest::CatalogItem::~CatalogItem()
{
}
Echonest::CatalogItem& Echonest::CatalogItem::operator=(const Echonest::CatalogItem& other)
{
dd = other.dd;
return *this;
}
QDateTime Echonest::CatalogItem::dateAdded() const
{
return dd->date_added;
}
void Echonest::CatalogItem::setDateAdded(const QDateTime& dt)
{
dd->date_added = dt;
}
QByteArray Echonest::CatalogItem::foreignId() const
{
return dd->foreign_id;
}
void Echonest::CatalogItem::setForeignId(const QByteArray& id)
{
dd->foreign_id = id;
}
Echonest::CatalogUpdateEntry Echonest::CatalogItem::request() const
{
return dd->request;
}
void Echonest::CatalogItem::setRequest(const Echonest::CatalogUpdateEntry& request)
{
dd->request = request;
}
int Echonest::CatalogItem::rating() const
{
return dd->rating;
}
void Echonest::CatalogItem::setRating(int rating)
{
dd->rating = rating;
}
int Echonest::CatalogItem::playCount() const
{
return dd->play_count;
}
void Echonest::CatalogItem::setPlayCount(int count)
{
dd->play_count = count;
}

View File

@ -1,90 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_ITEM_H
#define ECHONEST_CATALOG_ITEM_H
#include "CatalogUpdateEntry.h"
#include "echonest_export.h"
#include "Util.h"
#include <QMetaType>
#include <QSharedPointer>
#include <QDateTime>
class CatalogItemData;
namespace Echonest {
/**
* Since catalog items can be artists or songs, and we don't know sometimes until after we parse them,
* but we need to gather a list of them. A poor man's traits class? A rich man's interface? Far from either.
*/
class ECHONEST_EXPORT CatalogItem
{
public:
CatalogItem();
CatalogItem( const CatalogItem& other );
CatalogItem& operator=( const CatalogItem& other );
virtual ~CatalogItem();
/**
* The type of this item.
*/
virtual Echonest::CatalogTypes::Type type() const = 0;
/**
* The foreign id of this item in the catalog. e.g. CAOFUDS12BB066268E:artist:ARUI8651187B9ACF52
*
* See The Echo Nest API docs for more information.
*/
QByteArray foreignId() const;
void setForeignId( const QByteArray& id );
/**
* The request that generated this catalog item
*/
CatalogUpdateEntry request() const;
void setRequest( const CatalogUpdateEntry& request );
/**
* The date and time when this item was added to the catalog
*/
QDateTime dateAdded() const;
void setDateAdded( const QDateTime& dt );
/**
* The rating of this item.
*/
int rating() const;
void setRating( int rating );
/**
* The play count of this item.
*/
int playCount() const;
void setPlayCount( int count );
protected:
QSharedPointer<CatalogItemData> dd;
};
typedef QVector< CatalogItem > CatalogItems;
}
#endif

View File

@ -1,51 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_ITEM_P_H
#define ECHONEST_CATALOG_ITEM_P_H
#include "Song_p.h"
#include <QSharedData>
#include <QString>
#include <QVector>
#include <QDateTime>
#include "CatalogUpdateEntry.h"
class CatalogItemData : public QSharedData
{
public:
CatalogItemData() {}
CatalogItemData(const CatalogItemData& other) : QSharedData( other )
{
foreign_id = other.foreign_id;
request = other.request;
date_added = other.date_added;
rating = other.rating;
play_count = other.play_count;
}
~CatalogItemData() {}
Echonest::CatalogUpdateEntry request;
QByteArray foreign_id;
QDateTime date_added;
int rating;
int play_count;
};
#endif

View File

@ -1,54 +0,0 @@
/****************************************************************************************
* 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 "CatalogSong.h"
#include "CatalogItem_p.h"
Echonest::CatalogSong::CatalogSong()
{
}
Echonest::CatalogSong::CatalogSong(const QByteArray& id, const QString& title, const QByteArray& artistId, const QString& artistName)
: Song(id, title, artistId, artistName)
{
}
Echonest::CatalogSong::CatalogSong(const Echonest::CatalogSong& other)
: Song(other)
, CatalogItem( other )
{
}
Echonest::CatalogSong& Echonest::CatalogSong::operator=(const Echonest::CatalogSong& other)
{
Song::operator=( other );
CatalogItem::operator=( other );
return *this;
}
Echonest::CatalogSong::~CatalogSong()
{
}
Echonest::CatalogTypes::Type Echonest::CatalogSong::type() const
{
return Echonest::CatalogTypes::Song;
}

View File

@ -1,49 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_SONG_H
#define ECHONEST_CATALOG_SONG_H
#include "echonest_export.h"
#include "Song.h"
#include "CatalogItem.h"
class CatalogSongData;
namespace Echonest {
/**
* A song that includes some additional information returned when getting a song from a catalog listing.
*/
class ECHONEST_EXPORT CatalogSong : public Song, public CatalogItem
{
public:
CatalogSong();
CatalogSong(const QByteArray& id, const QString& title, const QByteArray& artistId, const QString& artistName);
CatalogSong(const Echonest::CatalogSong& other);
virtual ~CatalogSong();
CatalogSong& operator=( const CatalogSong& other );
/**
* The type of this item: Song.
*/
virtual CatalogTypes::Type type() const;
};
typedef QVector< CatalogSong > CatalogSongs;
}
Q_DECLARE_METATYPE( Echonest::CatalogSong )
#endif

View File

@ -1,232 +0,0 @@
/****************************************************************************************
* 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 "CatalogUpdateEntry.h"
#include "CatalogUpdateEntry_p.h"
Echonest::CatalogUpdateEntry::CatalogUpdateEntry()
: d( new CatalogUpdateEntryData )
{
}
Echonest::CatalogUpdateEntry::CatalogUpdateEntry( CatalogTypes::Action action )
: d( new CatalogUpdateEntryData )
{
d->action = action;
}
Echonest::CatalogUpdateEntry::CatalogUpdateEntry( const Echonest::CatalogUpdateEntry& other )
: d( other.d )
{
}
Echonest::CatalogUpdateEntry::~CatalogUpdateEntry()
{
}
Echonest::CatalogUpdateEntry& Echonest::CatalogUpdateEntry::operator=(const Echonest::CatalogUpdateEntry& other)
{
d = other.d;
return *this;
}
QByteArray Echonest::CatalogUpdateEntry::itemId() const
{
return d->item_id;
}
void Echonest::CatalogUpdateEntry::setItemId(const QByteArray& id)
{
d->item_id = id;
}
Echonest::CatalogTypes::Action Echonest::CatalogUpdateEntry::action() const
{
return d->action;
}
void Echonest::CatalogUpdateEntry::setAction(Echonest::CatalogTypes::Action action)
{
d->action = action;
}
QByteArray Echonest::CatalogUpdateEntry::artistId() const
{
return d->artist_id;
}
void Echonest::CatalogUpdateEntry::setArtistId(const QByteArray& id)
{
d->artist_id = id;
}
QByteArray Echonest::CatalogUpdateEntry::fingerprint() const
{
return d->fp_code;
}
void Echonest::CatalogUpdateEntry::setFingerprint(const QByteArray& id)
{
d->fp_code = id;
}
void Echonest::CatalogUpdateEntry::setFingerpring(const QByteArray& id)
{
setFingerprint(id);
}
QString Echonest::CatalogUpdateEntry::artistName() const
{
return d->artist_name;
}
void Echonest::CatalogUpdateEntry::setArtistName(const QString& name)
{
d->artist_name = name;
}
bool Echonest::CatalogUpdateEntry::banned() const
{
return d->banned;
}
void Echonest::CatalogUpdateEntry::setBanned(bool banned)
{
d->bannedSet = true;
d->banned = banned;
}
int Echonest::CatalogUpdateEntry::discNumber() const
{
return d->disc_number;
}
void Echonest::CatalogUpdateEntry::setDiscNumber(int disc)
{
d->disc_number = disc;
}
bool Echonest::CatalogUpdateEntry::favorite() const
{
return d->favorite;
}
void Echonest::CatalogUpdateEntry::setFavorite(bool fav)
{
d->favoriteSet = true;
d->favorite = fav;
}
QString Echonest::CatalogUpdateEntry::genre() const
{
return d->genre;
}
void Echonest::CatalogUpdateEntry::setGenre(const QString& genre)
{
d->genre = genre;
}
int Echonest::CatalogUpdateEntry::playCount() const
{
return d->play_count;
}
void Echonest::CatalogUpdateEntry::setPlayCount(int playCount)
{
d->play_count = playCount;
}
int Echonest::CatalogUpdateEntry::rating() const
{
return d->rating;
}
void Echonest::CatalogUpdateEntry::setRating(int rating)
{
d->rating = rating;
}
QString Echonest::CatalogUpdateEntry::release() const
{
return d->release;
}
void Echonest::CatalogUpdateEntry::setRelease(const QString& release)
{
d->release = release;
}
int Echonest::CatalogUpdateEntry::skipCount() const
{
return d->skip_count;
}
void Echonest::CatalogUpdateEntry::setSkipCount(int skipCount)
{
d->skip_count = skipCount;
}
QByteArray Echonest::CatalogUpdateEntry::songId() const
{
return d->song_id;
}
void Echonest::CatalogUpdateEntry::setSongId(const QByteArray& id)
{
d->song_id = id;
}
QString Echonest::CatalogUpdateEntry::songName() const
{
return d->song_name;
}
void Echonest::CatalogUpdateEntry::setSongName(const QString& name)
{
d->song_name = name;
}
int Echonest::CatalogUpdateEntry::trackNumber() const
{
return d->track_number;
}
void Echonest::CatalogUpdateEntry::setTrackNumber(int trackNum)
{
d->track_number = trackNum;
}
QString Echonest::CatalogUpdateEntry::url() const
{
return d->url;
}
void Echonest::CatalogUpdateEntry::setUrl(const QString& url)
{
d->url = url;
}
bool Echonest::CatalogUpdateEntry::bannedSet() const
{
return d->bannedSet;
}
bool Echonest::CatalogUpdateEntry::favoriteSet() const
{
return d->favoriteSet;
}

View File

@ -1,174 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_ENTRY_H
#define ECHONEST_CATALOG_ENTRY_H
#include "echonest_export.h"
#include "Util.h"
#include <QByteArray>
#include <QSharedDataPointer>
#include <QString>
#include <QVector>
class CatalogUpdateEntryData;
namespace Echonest {
/**
* This rather simple struct collects information about a status update
*/
typedef QVector< QPair< QByteArray, QString > > CatalogStatusItem;
typedef struct CatalogStatusStruct {
CatalogTypes::TicketStatus status;
QString details;
int items_updated;
CatalogStatusItem items; // List of [ item_id, info ]
// int percent_complete;
CatalogStatusStruct() : status( CatalogTypes::Unknown ), items_updated( -1 ) {}
} CatalogStatus;
/**
* This class described a catalog entry for use in the Catalog update() call.
* All data fields are optional except Action, and only the ones specified will be sent.
*/
class ECHONEST_EXPORT CatalogUpdateEntry
{
public:
CatalogUpdateEntry();
CatalogUpdateEntry( CatalogTypes::Action action );
virtual ~CatalogUpdateEntry();
CatalogUpdateEntry( const CatalogUpdateEntry& other );
CatalogUpdateEntry& operator=( const CatalogUpdateEntry& );
/**
* Optional, the item id for the catalog entry. hash( catalog_id + item_id )
* MUST be unique. If this is not set, a unique id will be generated internally.
*/
QByteArray itemId() const;
void setItemId( const QByteArray& id );
/**
* The type of action that this item represents, required.
*/
CatalogTypes::Action action() const;
void setAction( CatalogTypes::Action action );
/**
* The Echo Nest fingerprint.
*/
QByteArray fingerprint() const;
void setFingerprint( const QByteArray& id );
// deprecated
void setFingerpring( const QByteArray& id );
/**
* The song id. Rosetta id or Echo Nest ID.
*/
QByteArray songId() const;
void setSongId( const QByteArray& id );
/**
* The song name. Mutually exclusive with song id.
*/
QString songName() const;
void setSongName( const QString& name );
/**
* The artist id, either a rosetta stone ID or an Echo Nest ID.
*/
QByteArray artistId() const;
void setArtistId( const QByteArray& id );
/**
* The artist name, mutually exclusive with artist id.
*/
QString artistName() const;
void setArtistName( const QString& name );
/**
* The release, or album, name.
*/
QString release() const;
void setRelease( const QString& release );
/**
* The genre of the item.
*/
QString genre() const;
void setGenre( const QString& genre );
/**
* The track number.
*/
int trackNumber() const;
void setTrackNumber( int trackNum );
/**
* The disc number of this item.
*/
int discNumber() const;
void setDiscNumber( int disc );
/**
* The url or the local filename or remote url.
*/
QString url() const;
void setUrl( const QString& url );
/**
* If this song was marked as a favorite or not
*/
bool favorite() const;
void setFavorite( bool fav );
/**
* If this song was banned.
*/
bool banned() const;
void setBanned( bool banned );
/**
* The play count of this item.
*/
int playCount() const;
void setPlayCount( int playCount );
/**
* The skip count of this item.
*/
int skipCount() const;
void setSkipCount( int skipCount );
/**
* The rating of this item, from 1 to 10.
*/
int rating() const;
void setRating( int rating );
bool favoriteSet() const;
bool bannedSet() const;
private:
QSharedDataPointer<CatalogUpdateEntryData> d;
};
typedef QVector<CatalogUpdateEntry> CatalogUpdateEntries;
}
#endif

View File

@ -1,88 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef CATALOG_UPDATE_ENTRY_H
#define CATALOG_UPDATE_ENTRY_H
#include "Util.h"
#include <QSharedData>
#include <QByteArray>
#include <QString>
class CatalogUpdateEntryData : public QSharedData {
public:
CatalogUpdateEntryData() : action( Echonest::CatalogTypes::Update ), track_number( -1 ), disc_number( -1 ), favorite( false ),
banned( false ), play_count( -1 ), skip_count( -1 ), rating( -1 ),
favoriteSet( false ), bannedSet( false )
{}
CatalogUpdateEntryData( const CatalogUpdateEntryData& other ) : QSharedData( other ) {
item_id = other.item_id;
action = other.action;
fp_code = other.fp_code;
song_id = other.song_id;
song_name = other.song_name;
artist_id = other.artist_id;
artist_name = other.artist_name;
release = other.release;
genre = other.genre;
track_number = other.track_number;
disc_number = other.disc_number;
url = other.url;
favorite = other.favorite;
banned = other.banned;
play_count = other.play_count;
skip_count = other.skip_count;
rating = other.rating;
favoriteSet = other.favoriteSet;
bannedSet = other.banned;
}
Echonest::CatalogTypes::Action action;
QByteArray item_id;
QByteArray fp_code;
QByteArray song_id;
QString song_name;
QByteArray artist_id;
QString artist_name;
QString release;
QString genre;
int track_number;
int disc_number;
QString url;
bool favorite;
bool banned;
int play_count;
int skip_count;
int rating;
// internal
bool favoriteSet;
bool bannedSet;
};
#endif

View File

@ -1,57 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CATALOG_P_H
#define ECHONEST_CATALOG_P_H
#include "CatalogArtist.h"
#include "CatalogSong.h"
#include "Util.h"
#include <QSharedData>
class CatalogData : public QSharedData
{
public:
CatalogData() : total( 0 ), resolved( 0 ) {}
CatalogData( const CatalogData& other ) : QSharedData( other ) {
name = other.name;
id = other.id;
type = other.type;
total = other.total;
resolved = other.resolved;
songs = other.songs;
artists = other.artists;
}
~CatalogData() {}
// Fields we always get in a catalog object
QString name;
QByteArray id;
Echonest::CatalogTypes::Type type;
int total;
// Fields we sometimes get depending on the query
int resolved;
// pending_tickets
Echonest::CatalogSongs songs; // either has songs, or artists
Echonest::CatalogArtists artists;
};
#endif

View File

@ -1,213 +0,0 @@
/****************************************************************************************
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
* Copyright (c) 2011 Jeff Mitchell <mitchell@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 "Config.h"
#include <QNetworkAccessManager>
#include <QThread>
#include <QDebug>
#include <QMutex>
Echonest::Config* Echonest::Config::s_instance = 0;
QUrl Echonest::baseUrl()
{
QUrl url;
url.setScheme( QLatin1String( "http" ) );
url.setHost( QLatin1String( "developer.echonest.com" ) );
return url;
}
QUrl Echonest::baseGetQuery(const QByteArray& type, const QByteArray& method)
{
QUrl url = baseUrl();
url.setPath( QString::fromLatin1( "/api/v4/%1/%2" ).arg( QLatin1String( type ) ).arg( QLatin1String( method ) ) );
url.addEncodedQueryItem( "api_key", Echonest::Config::instance()->apiKey() );
url.addEncodedQueryItem( "format", "xml" );
return url;
}
Echonest::ParseError::ParseError(Echonest::ErrorType error): exception()
{
type = error;
whatData = createWhatData();
}
Echonest::ParseError::ParseError(Echonest::ErrorType error, const QString& text): exception()
{
type = error;
extraText = text;
whatData = createWhatData();
}
QByteArray Echonest::ParseError::createWhatData() const throw()
{
// If we have specific error text, use that first
if( !extraText.isEmpty() )
return extraText.toLatin1();
switch( type )
{
case UnknownError:
return "Unknown Echo Nest Error";
case NoError:
return "No Error";
case MissingAPIKey:
return "Missing Echo Nest API Key";
case NotAllowed:
return "Method not allowed";
case RateLimitExceeded:
return "Rate limit exceeded";
case MissingParameter:
return "Missing parameter";
case InvalidParameter:
return "Invalid parameter";
case UnfinishedQuery:
return "Unfinished query object";
case EmptyResult:
return "No results";
case NetworkError:
return "Network Error";
case UnknownParseError:
return "Unknown Parse Error";
}
return QByteArray();
}
Echonest::ParseError::~ParseError() throw()
{}
Echonest::ErrorType Echonest::ParseError::errorType() const throw()
{
return type;
}
void Echonest::ParseError::setNetworkError( QNetworkReply::NetworkError error ) throw()
{
nError = error;
}
const char* Echonest::ParseError::what() const throw()
{
return whatData.constData();
}
QNetworkReply::NetworkError Echonest::ParseError::networkError() const throw()
{
return nError;
}
class Echonest::ConfigPrivate {
public:
ConfigPrivate()
{
threadNamHash[ QThread::currentThread() ] = new QNetworkAccessManager();
}
~ConfigPrivate()
{
QThread *currThread = QThread::currentThread();
if( threadNamHash.contains( currThread ) )
{
if ( ourNamSet.contains( currThread ) )
delete threadNamHash[ currThread ];
threadNamHash.remove( currThread );
ourNamSet.remove( currThread );
}
}
QMutex accessMutex;
QHash< QThread*, QNetworkAccessManager* > threadNamHash;
QSet< QThread* > ourNamSet;
QByteArray apikey;
};
Echonest::Config::Config()
: d( new Echonest::ConfigPrivate )
{
}
Echonest::Config::~Config()
{
delete d;
}
void Echonest::Config::setAPIKey(const QByteArray& apiKey)
{
d->apikey = apiKey;
}
QByteArray Echonest::Config::apiKey() const
{
return d->apikey;
}
void Echonest::Config::setNetworkAccessManager(QNetworkAccessManager* nam)
{
if( !nam )
return;
QMutexLocker l( &d->accessMutex );
QThread* currThread = QThread::currentThread();
QNetworkAccessManager* oldNam = 0;
if( d->threadNamHash.contains( currThread ) && d->ourNamSet.contains( currThread ) )
oldNam = d->threadNamHash[ currThread ];
if( oldNam == nam )
{
// If we're being passed back our own NAM, assume they want to
// ensure that we don't delete it out from under them
d->ourNamSet.remove( currThread );
return;
}
d->threadNamHash[ currThread ] = nam;
d->ourNamSet.remove( currThread );
if( oldNam )
delete oldNam;
}
QNetworkAccessManager* Echonest::Config::nam() const
{
QMutexLocker l( &d->accessMutex );
QThread* currThread = QThread::currentThread();
if( !d->threadNamHash.contains( currThread ) )
{
QNetworkAccessManager *newNam = new QNetworkAccessManager();
d->threadNamHash[ currThread ] = newNam;
d->ourNamSet.insert( currThread );
return newNam;
}
return d->threadNamHash[ currThread ];
}
Echonest::Config* Echonest::Config::instance() {
if ( !s_instance ) {
s_instance = new Config;
}
return s_instance;
}

View File

@ -1,130 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_CONFIG_H
#define ECHONEST_CONFIG_H
#include "echonest_export.h"
#include <QByteArray>
#include <QUrl>
#include <exception>
#include <QNetworkReply>
class QNetworkAccessManager;
namespace Echonest{
/// Creates the base URL for all GET and POST requests
QUrl baseUrl();
/// Creates the base URL for GET requests.
QUrl baseGetQuery( const QByteArray& type, const QByteArray& method );
enum ErrorType {
/**
* Echo Nest API errors
*/
UnknownError = -1,
NoError = 0,
MissingAPIKey = 1,
NotAllowed = 2,
RateLimitExceeded = 3,
MissingParameter = 4,
InvalidParameter = 5,
/// libechonest errors
UnfinishedQuery = 6, /// An unfinished QNetworkReply* was passed to the parse function
EmptyResult = 7,
UnknownParseError = 8,
/// QNetworkReply errors
NetworkError = 9
};
class ECHONEST_EXPORT ParseError : public std::exception
{
public:
explicit ParseError( ErrorType error );
ParseError( ErrorType error, const QString& text );
virtual ~ParseError() throw();
ErrorType errorType() const throw();
/**
* If the ErrorType is NetworkError, this value contains the QNetworkReply
* error code that was returned.
*/
void setNetworkError( QNetworkReply::NetworkError error ) throw();
QNetworkReply::NetworkError networkError() const throw();
virtual const char* what() const throw ();
private:
QByteArray createWhatData() const throw();
ErrorType type;
QString extraText;
QNetworkReply::NetworkError nError;
QByteArray whatData;
};
class ConfigPrivate;
/**
* This singleton contains miscellaneous settings used to access The Echo Nest
*/
class ECHONEST_EXPORT Config {
public:
static Config* instance();
/**
* Set the API key to be used for all API requests. This MUST be set in order
* for any web service calls to work!
*/
void setAPIKey( const QByteArray& apiKey );
QByteArray apiKey() const;
/**
* Set the QNetworkAccessManager to use to make web service requests to
* The Echo Nest.
*
* This will register the given QNAM for the current thread. If you call this from
* the main thread and only make calls to libechonest from the main thread, you don't
* have to do any more work. However, if you are using multiple QNAMs in different threads,
* you must call this for each QNAM in each thread so that libechonest can use the proper
* thread-local QNAM. This function is thread-safe.
*
* Note that in all threads, if you do not set a QNAM, a default one is created and returned.
* In addition, if you set your own QNAM, you are responsible for deleting it.
*
* This will take over control of the object.
*/
void setNetworkAccessManager( QNetworkAccessManager* nam );
QNetworkAccessManager* nam() const;
private:
Config();
~Config();
static Config* s_instance;
ConfigPrivate* d;
};
}
#endif

View File

@ -1,119 +0,0 @@
/****************************************************************************************
* 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 "Generator_p.h"
#include "CatalogUpdateEntry.h"
// QJSon
#include <qjson/serializer.h>
#include <QVariant>
#include <quuid.h>
#include <QDebug>
QByteArray Echonest::Generator::catalogEntriesToJson( const Echonest::CatalogUpdateEntries& items )
{
QJson::Serializer s;
QVariant itms = catalogEntriesToVariant( items );
QByteArray serialized = s.serialize( itms );
// qDebug() << "Serialized:" << serialized;
return serialized;
}
QByteArray Echonest::Generator::catalogEntryToJson( const Echonest::CatalogUpdateEntry& item )
{
QJson::Serializer s;
QVariant itm = catalogEntryToVariant( item );
QByteArray serialized = s.serialize( itm );
// qDebug() << "Serialized:" << serialized;
return serialized;
}
QVariantList Echonest::Generator::catalogEntriesToVariant( const Echonest::CatalogUpdateEntries& items )
{
// copy the catalog item into a QVariant
QVariantList itemList;
foreach( const Echonest::CatalogUpdateEntry& item, items )
itemList << catalogEntryToVariant( item );
qDebug() << "Generated " << itemList.size() << "entries to catalog variant!";
return itemList;
}
QVariant Echonest::Generator::catalogEntryToVariant( const Echonest::CatalogUpdateEntry& item )
{
QVariantMap itemMap;
QVariantMap itm;
itemMap[ QLatin1String( "action" ) ] = Echonest::catalogUpdateActionToLiteral( item.action() );
if( item.itemId().isEmpty() )
itm[ QLatin1String( "item_id" ) ] = QUuid::createUuid().toString().replace( QLatin1Char( '{' ), QString() ).replace( QLatin1Char( '}' ), QString() );
else
itm[ QLatin1String( "item_id" ) ] = item.itemId();
if( !item.fingerprint().isEmpty() )
itm[ QLatin1String( "fp_code" ) ] = item.fingerprint();
if( !item.songId().isEmpty() )
itm[ QLatin1String( "song_id" ) ] = item.songId();
if( !item.songName().isEmpty() )
itm[ QLatin1String( "song_name" ) ] = item.songName();
if( !item.artistId().isEmpty() )
itm[ QLatin1String( "artist_id" ) ] = item.artistId();
if( !item.artistName().isEmpty() )
itm[ QLatin1String( "artist_name" ) ] = item.artistName();
if( !item.release().isEmpty() )
itm[ QLatin1String( "release" ) ] = item.release();
if( !item.genre().isEmpty() )
itm[ QLatin1String( "genre" ) ] = item.genre();
if( item.trackNumber() > -1 )
itm[ QLatin1String( "track_number" ) ] = item.trackNumber();
if( item.discNumber() > -1 )
itm[ QLatin1String( "disc_number" ) ] = item.discNumber();
if( !item.url().isEmpty() )
itm[ QLatin1String( "url" ) ] = item.url();
if( item.favoriteSet() )
itm[ QLatin1String( "favorite" ) ] = item.favorite();
if( item.bannedSet() )
itm[ QLatin1String( "banned" ) ] = item.banned();
if( item.playCount() > -1 )
itm[ QLatin1String( "play_count" ) ] = item.playCount();
if( item.skipCount() > -1 )
itm[ QLatin1String( "skip_count" ) ] = item.skipCount();
if( item.rating() > -1 )
itm[ QLatin1String( "rating" ) ] = item.rating();
itemMap[ QLatin1String( "item" ) ] = itm;
return itemMap;
}

View File

@ -1,40 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef LIBECHONEST_GENERATOR_H
#define LIBECHONEST_GENERATOR_H
#include <QByteArray>
#include "CatalogUpdateEntry.h"
#include <QVariant>
namespace Echonest {
namespace Generator {
/**
* Miscellaneous functions for generating JSON to send to The Echo Nest
*/
QByteArray catalogEntriesToJson( const CatalogUpdateEntries& items );
QByteArray catalogEntryToJson( const CatalogUpdateEntry& item );
QVariantList catalogEntriesToVariant( const CatalogUpdateEntries& items );
QVariant catalogEntryToVariant( const CatalogUpdateEntry& item );
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_PARSING_P_H
#define ECHONEST_PARSING_P_H
#include "Config.h"
#include <QtXml/QXmlStreamReader>
#include "Song.h"
#include "Artist.h"
#include "Catalog.h"
#include "Playlist.h"
class QNetworkReply;
namespace Echonest
{
namespace Parser
{
/**
* Internal helper parsing functions for QXmlStreamParser
*/
void checkForErrors( QNetworkReply* reply ) throw( ParseError );
// read the start element and then the status element, throwing
// if the result code is not Success
void readStatus( QXmlStreamReader& xml ) throw( ParseError );
// parses a <songs></songs> block and turns them into a list of Song object
QVector< Song > parseSongList( QXmlStreamReader& xml ) throw( ParseError );
// parses a <song></song> block
Song parseSong( QXmlStreamReader& xml ) throw( ParseError );
// parses a <artist_location> block
ArtistLocation parseSongArtistLocation( QXmlStreamReader& xml ) throw( ParseError );
// parses a <track></track> block
Track parseTrack( QXmlStreamReader& xml ) throw( ParseError );
// parses a <tracks> chunk when asking for a song with tracks bucket
Tracks parseSongTrackBucket( QXmlStreamReader& xml ) throw( ParseError );
// parses an <audio_summary> chunk
AudioSummary parseAudioSummary( QXmlStreamReader& xml ) throw( ParseError );
// parses the json of the detailed audio summary
void parseDetailedAudioSummary( QNetworkReply* reply, AudioSummary& summary ) throw( ParseError );
// parses a list of artists in an <artists></artists> block
Echonest::Artists parseArtists( QXmlStreamReader& xml ) throw( ParseError );
// parses the contents of an artist fetch result, expects to be positioned after the readStatus() call
// it could be a profile query, in which case it has a bunch of different artist attributes
// or it could be a single fetch, in which case it starts with result number and offset.
// the results are saved back into the artist
int parseArtistInfoOrProfile( QXmlStreamReader&, Echonest::Artist& artist ) throw( ParseError );
// parse the individual artist attributes
void parseArtistInfo( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
// parse each type of artist attribute
void parseAudio( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseBiographies( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseImages( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseNewsOrBlogs( QXmlStreamReader& xml, Echonest::Artist& artist, bool news = true ) throw( ParseError );
void parseReviews( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseTerms( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseUrls( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseArtistSong( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseVideos( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
void parseForeignArtistIds( QXmlStreamReader& xml, Echonest::Artist& artist ) throw( ParseError );
// parse a list of terms
TermList parseTopTermList( QXmlStreamReader& xml ) throw( ParseError );
QVector< QString > parseTermList( QXmlStreamReader& xml ) throw( ParseError );
Artists parseArtistSuggestList( QXmlStreamReader& xml ) throw( ParseError );
License parseLicense( QXmlStreamReader& xml ) throw( ParseError );
QByteArray parsePlaylistSessionId( QXmlStreamReader& xml ) throw( ParseError );
// Catalog functions
Catalogs parseCatalogList( QXmlStreamReader& xml ) throw( ParseError );
Catalog parseCatalog( QXmlStreamReader& xml, bool justOne = false /* the catalog API is ugly :( */ ) throw( ParseError );
QList<CatalogItem*> parseCatalogItems( QXmlStreamReader& xml ) throw( ParseError );
void parseCatalogRequestItem( QXmlStreamReader& xml, Echonest::CatalogArtist&, Echonest::CatalogSong& ) throw( ParseError );
void saveArtistList( Catalog& catalog, QList<CatalogItem*>& );
void saveSongList( Catalog& catalog, QList<CatalogItem*>& );
Echonest::CatalogStatus parseCatalogStatus( QXmlStreamReader& xml ) throw( ParseError );
Echonest::CatalogStatusItem parseTicketUpdateInfo( QXmlStreamReader& xml ) throw( ParseError );
QByteArray parseCatalogTicket( QXmlStreamReader& xml ) throw( ParseError );
Catalog parseNewCatalog( QXmlStreamReader& xml ) throw( ParseError );
// parses a <tracks> chunk when asking for a song with tracks bucket in a catalog.read call
Tracks parseCatalogSongTracks( QXmlStreamReader& xml ) throw( ParseError );
SessionInfo parseSessionInfo( QXmlStreamReader& xml ) throw( ParseError );
QVector< QString > parseRulesList( QXmlStreamReader& xml ) throw( ParseError );
QVector< SessionItem > parseSessionSongItem( QXmlStreamReader& xml, const QString& type ) throw( ParseError );
}
}
#endif

View File

@ -1,422 +0,0 @@
/****************************************************************************************
* 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 "Playlist.h"
#include "Playlist_p.h"
#include "Parsing_p.h"
#include <QtNetwork/QNetworkReply>
Echonest::DynamicPlaylist::DynamicPlaylist()
: d( new DynamicPlaylistData )
{
}
Echonest::DynamicPlaylist::DynamicPlaylist(const Echonest::DynamicPlaylist& other)
: d( other.d )
{
}
Echonest::DynamicPlaylist::~DynamicPlaylist()
{
}
Echonest::DynamicPlaylist& Echonest::DynamicPlaylist::operator=(const Echonest::DynamicPlaylist& playlist)
{
d = playlist.d;
return *this;
}
QNetworkReply* Echonest::DynamicPlaylist::start(const Echonest::DynamicPlaylist::PlaylistParams& params) const
{
// params are the same, if user passes in format parsing will throw, but it should be expected..
return generateInternal( params, "dynamic" );
}
Echonest::Song Echonest::DynamicPlaylist::parseStart(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QByteArray data = reply->readAll();
// qDebug() << data;
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
d->sessionId = Echonest::Parser::parsePlaylistSessionId( xml );
Echonest::SongList songs = Echonest::Parser::parseSongList( xml );
if( !songs.size() == 1 )
throw Echonest::ParseError( UnknownParseError );
d->currentSong = songs.front();
reply->deleteLater();
return d->currentSong;
}
QByteArray Echonest::DynamicPlaylist::sessionId() const
{
return d->sessionId;
}
void Echonest::DynamicPlaylist::setSessionId(const QByteArray& id)
{
d->sessionId = id;
}
Echonest::Song Echonest::DynamicPlaylist::currentSong() const
{
return d->currentSong;
}
void Echonest::DynamicPlaylist::setCurrentSong(const Echonest::Song& song)
{
d->currentSong = song;
}
QNetworkReply* Echonest::DynamicPlaylist::fetchNextSong(int rating) const
{
QUrl url = Echonest::baseGetQuery( "playlist", "dynamic" );
url.addEncodedQueryItem( "session_id", d->sessionId );
if( rating > 0 )
url.addEncodedQueryItem( "rating", QByteArray::number( rating ) );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::DynamicPlaylist::fetchNextSong(const DynamicControls& controls) const
{
QUrl url = Echonest::baseGetQuery( "playlist", "dynamic" );
url.addEncodedQueryItem( "session_id", d->sessionId );
DynamicControls::const_iterator iter = controls.begin();
for( ; iter != controls.end(); ++iter ) {
QString value = iter->second;
url.addEncodedQueryItem( dynamicControlToString( iter->first ), Echonest::escapeSpacesAndPluses( value ) );
}
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::DynamicPlaylist::fetchSessionInfo() const
{
QUrl url = Echonest::baseGetQuery( "playlist", "session_info" );
url.addEncodedQueryItem( "session_id", d->sessionId );
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
Echonest::Song Echonest::DynamicPlaylist::parseNextSong(QNetworkReply* reply)
{
return parseStart( reply );
}
Echonest::SessionInfo Echonest::DynamicPlaylist::parseSessionInfo(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
reply->deleteLater();
return Echonest::Parser::parseSessionInfo( xml );
}
QNetworkReply* Echonest::DynamicPlaylist::staticPlaylist(const Echonest::DynamicPlaylist::PlaylistParams& params)
{
return Echonest::DynamicPlaylist::generateInternal( params, "static" );
}
Echonest::SongList Echonest::DynamicPlaylist::parseStaticPlaylist(QNetworkReply* reply) throw( Echonest::ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
Echonest::SongList songs = Echonest::Parser::parseSongList( xml );
reply->deleteLater();
return songs;
}
QByteArray Echonest::DynamicPlaylist::parseXSPFPlaylist(QNetworkReply* reply) throw( Echonest::ParseError )
{
QByteArray data = reply->readAll();
Echonest::Parser::checkForErrors( reply );
reply->deleteLater();
return data;
}
QNetworkReply* Echonest::DynamicPlaylist::generateInternal(const Echonest::DynamicPlaylist::PlaylistParams& params, const QByteArray& type)
{
QUrl url = Echonest::baseGetQuery( "playlist", type );
Echonest::DynamicPlaylist::PlaylistParams::const_iterator iter = params.constBegin();
for( ; iter < params.constEnd(); ++iter ) {
if( iter->first == Format ) // If it's a format, we have to remove the xml format we automatically specify
url.removeEncodedQueryItem( "format" );
if( iter->first == Type ) { // convert type enum to string
switch( static_cast<Echonest::DynamicPlaylist::ArtistTypeEnum>( iter->second.toInt() ) )
{
case ArtistType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "artist" );
break;
case ArtistRadioType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "artist-radio" );
break;
case ArtistDescriptionType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "artist-description" );
break;
case CatalogType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "catalog" );
break;
case CatalogRadioType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "catalog-radio" );
break;
case SongRadioType:
url.addEncodedQueryItem( playlistParamToString( iter->first ), "song-radio" );
break;
}
} else if( iter->first == Sort ) {
url.addEncodedQueryItem( playlistParamToString( iter->first ), playlistSortToString( static_cast<Echonest::DynamicPlaylist::SortingType>( iter->second.toInt() ) ) );
} else if( iter->first == Pick ) {
url.addEncodedQueryItem( playlistParamToString( iter->first ), playlistArtistPickToString( static_cast<Echonest::DynamicPlaylist::ArtistPick>( iter->second.toInt() ) ) );
} else if( iter->first == SongInformation ){
Echonest::Song::addQueryInformation( url, Echonest::SongInformation( iter->second.value< Echonest::SongInformation >() ) );
} else {
url.addEncodedQueryItem( playlistParamToString( iter->first ), Echonest::escapeSpacesAndPluses( iter->second.toString() ) );
}
}
qDebug() << "Creating playlist URL" << url;
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QByteArray Echonest::DynamicPlaylist::playlistParamToString(Echonest::DynamicPlaylist::PlaylistParam param)
{
switch( param )
{
case Echonest::DynamicPlaylist::Type :
return "type";
case Echonest::DynamicPlaylist::Format :
return "format";
case Echonest::DynamicPlaylist::Pick:
return "artist_pick";
case Echonest::DynamicPlaylist::Variety :
return "variety";
case Echonest::DynamicPlaylist::ArtistId :
return "artist_id";
case Echonest::DynamicPlaylist::Artist :
return "artist";
case Echonest::DynamicPlaylist::ArtistSeedCatalog :
return "artist_seed_catalog";
case Echonest::DynamicPlaylist::SourceCatalog :
return "seed_catalog";
case Echonest::DynamicPlaylist::SongId :
return "song_id";
case Echonest::DynamicPlaylist::Description :
return "description";
case Echonest::DynamicPlaylist::Results :
return "results";
case Echonest::DynamicPlaylist::MaxTempo :
return "max_tempo";
case Echonest::DynamicPlaylist::MinTempo :
return "min_tempo";
case Echonest::DynamicPlaylist::MaxDuration :
return "max_duration";
case Echonest::DynamicPlaylist::MinDuration :
return "min_duration";
case Echonest::DynamicPlaylist::MaxLoudness :
return "max_loudness";
case Echonest::DynamicPlaylist::MinLoudness :
return "min_loudness";
case Echonest::DynamicPlaylist::ArtistMaxFamiliarity :
return "artist_max_familiarity";
case Echonest::DynamicPlaylist::ArtistMinFamiliarity :
return "artist_min_familiarity";
case Echonest::DynamicPlaylist::MinDanceability :
return "min_danceability";
case Echonest::DynamicPlaylist::MaxDanceability :
return "max_danceability";
case Echonest::DynamicPlaylist::MinEnergy :
return "min_energy";
case Echonest::DynamicPlaylist::MaxEnergy :
return "max_energy";
case Echonest::DynamicPlaylist::ArtistMaxHotttnesss :
return "artist_max_hotttnesss";
case Echonest::DynamicPlaylist::ArtistMinHotttnesss :
return "artist_min_hotttnesss";
case Echonest::DynamicPlaylist::SongMaxHotttnesss :
return "song_max_hotttnesss";
case Echonest::DynamicPlaylist::SongMinHotttnesss :
return "song_min_hotttnesss";
case Echonest::DynamicPlaylist::ArtistMinLongitude :
return "min_longitude";
case Echonest::DynamicPlaylist::ArtistMaxLongitude :
return "max_longitude";
case Echonest::DynamicPlaylist::ArtistMinLatitude :
return "min_latitude";
case Echonest::DynamicPlaylist::ArtistMaxLatitude :
return "max_latitude";
case Echonest::DynamicPlaylist::Mode :
return "mode";
case Echonest::DynamicPlaylist::Key :
return "key";
case Echonest::DynamicPlaylist::SongInformation:
return "bucket";
case Echonest::DynamicPlaylist::Sort :
return "sort";
case Echonest::DynamicPlaylist::Limit :
return "limit";
case Echonest::DynamicPlaylist::Audio :
return "audio";
case Echonest::DynamicPlaylist::DMCA :
return "dmca";
case Echonest::DynamicPlaylist::ChainXSPF :
return "chain_xspf";
case Echonest::DynamicPlaylist::Mood :
return "mood";
case Echonest::DynamicPlaylist::Style :
return "style";
case Echonest::DynamicPlaylist::Adventurousness :
return "adventurousness";
}
return QByteArray();
}
QByteArray Echonest::DynamicPlaylist::playlistArtistPickToString(Echonest::DynamicPlaylist::ArtistPick pick)
{
switch( pick )
{
case PickSongHotttnesssAscending:
return "song_hotttnesss-asc";
case PickTempoAscending:
return "tempo-asc";
case PickDurationAscending:
return "duration-asc";
case PickLoudnessAscending:
return "loudness-asc";
case PickModeAscending:
return "mode-asc";
case PickKeyAscending:
return "key-asc";
case PickSongHotttnesssDescending:
return "song_hotttnesss-desc";
case PickTempoDescending:
return "tempo-desc";
case PickDurationDescending:
return "duration-desc";
case PickLoudnessDescending:
return "loudness-desc";
case PickModeDescending:
return "mode-desc";
case PickKeyDescending:
return "key-desc";
}
return QByteArray();
}
QByteArray Echonest::DynamicPlaylist::playlistSortToString(Echonest::DynamicPlaylist::SortingType sorting)
{
switch( sorting )
{
case SortTempoAscending:
return "tempo-asc";
case SortTempoDescending:
return "tempo-desc";
case SortDurationAscending:
return "duration-asc";
case SortDurationDescending:
return "duration-desc";
case SortLoudnessAscending:
return "loudness-asc";
case SortLoudnessDescending:
return "loudness-desc";
case SortArtistFamiliarityAscending:
return "artist_familiarity-asc";
case SortArtistFamiliarityDescending:
return "artist_familiarity-desc";
case SortArtistHotttnessAscending:
return "artist_hotttnesss-asc";
case SortArtistHotttnessDescending:
return "artist_hotttnesss-desc";
case SortSongHotttnesssAscending:
return "song_hotttnesss-asc";
case SortSongHotttnesssDescending:
return "song_hotttnesss-desc";
case SortLatitudeAscending:
return "latitude-asc";
case SortLatitudeDescending:
return "latitude-desc";
case SortLongitudeAscending:
return "longitude-asc";
case SortLongitudeDescending:
return "longitude-desc";
case SortModeAscending:
return "mode-asc";
case SortModeDescending:
return "mode-desc";
case SortKeyAscending:
return "key-asc";
case SortKeyDescending:
return "key-desc";
case SortEnergyAscending:
return "energy-asc";
case SortEnergyDescending:
return "energy-desc";
case SortDanceabilityAscending:
return "danceability-asc";
case SortDanceabilityDescending:
return "danceability-desc";
}
return QByteArray();
}
QByteArray Echonest::DynamicPlaylist::dynamicControlToString(Echonest::DynamicPlaylist::DynamicControlItem control)
{
switch( control )
{
case Steer:
return "steer";
case SteerDescription:
return "steer_description";
case Rating:
return "rating";
case Ban:
return "ban";
default:
return "";
}
}
QDebug Echonest::operator<<(QDebug d, const Echonest::DynamicPlaylist& playlist)
{
d << QString::fromLatin1( "DynamicPlaylist(%1, %2)" ).arg( QLatin1String( playlist.sessionId() ), playlist.currentSong().toString() );
return d.maybeSpace();
}

View File

@ -1,280 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_PLAYLIST_H
#define ECHONEST_PLAYLIST_H
#include "echonest_export.h"
#include "Song.h"
#include <QSharedData>
#include <QDebug>
#include "Artist.h"
#include <QtCore/QString>
#include "Catalog.h"
class QNetworkReply;
class DynamicPlaylistData;
namespace Echonest{
typedef struct {
qreal served_time;
QByteArray artist_id;
QByteArray id;
QString artist_name;
QString title;
int rating;
} SessionItem;
typedef struct {
TermList terms;
SongList seed_songs;
// description .. what data is in here?
Artists banned_artists;
QVector< QString > rules;
QByteArray session_id;
Artists seeds;
QVector< SessionItem > skipped_songs;
QVector< SessionItem > banned_songs;
QString playlist_type;
Catalogs seed_catalogs;
QVector< SessionItem > rated_songs;
QVector< SessionItem > history;
} SessionInfo;
/**
* This encapsulates an Echo Nest dynamic playlist. It contains a playlist ID and
* the current song, and can fetch the next song.
*
* See http://developer.echonest.com/docs/v4/playlist.html#dynamic
* for more information
*/
class ECHONEST_EXPORT DynamicPlaylist
{
public:
/**
* The types of playlist that can be generated. Artist plays songs for the given artist,
* ArtistRadio takes into account similar artists, and ArtistDescription plays songs matching
* the given description.
*/
enum ArtistTypeEnum {
ArtistType,
ArtistRadioType,
ArtistDescriptionType,
CatalogType,
CatalogRadioType,
SongRadioType
};
/**
* Different ways to sort a generated playlist
*/
enum SortingType {
SortTempoAscending,
SortTempoDescending,
SortDurationAscending,
SortDurationDescending,
SortArtistFamiliarityAscending,
SortArtistFamiliarityDescending,
SortArtistHotttnessAscending,
SortArtistHotttnessDescending,
SortSongHotttnesssAscending,
SortSongHotttnesssDescending,
SortLatitudeAscending,
SortLatitudeDescending,
SortLongitudeAscending,
SortLongitudeDescending,
SortModeAscending,
SortModeDescending,
SortKeyAscending,
SortKeyDescending,
SortLoudnessAscending,
SortLoudnessDescending,
SortEnergyAscending,
SortEnergyDescending,
SortDanceabilityAscending,
SortDanceabilityDescending
};
/**
* Different ways of picking artists in Artist radios.
*/
enum ArtistPick {
PickSongHotttnesssAscending,
PickTempoAscending,
PickDurationAscending,
PickLoudnessAscending,
PickModeAscending,
PickKeyAscending,
PickSongHotttnesssDescending,
PickTempoDescending,
PickDurationDescending,
PickLoudnessDescending,
PickModeDescending,
PickKeyDescending
};
/**
* The various parameters that can be passed to the playlist building
* functions.
*/
enum PlaylistParam {
Type, /// The type of playlist to generate. Value is the DynamicPlaylist::ArtistTypeEnum enum
Format, /// Either xml (default) or xspf. If the result is xspf, the raw xspf playlist is returned, else the xml is parsed and exposed programmatically. If using XSPF, you must specify a catalog, the tracks bucket, and limit = true
Pick, /// How the artists are picked for each artist in ArtistType playlists. Value is Playlist::ArtistPick enum value.
Variety, /// 0 < variety < 1 The maximum variety of artists to be represented in the playlist. A higher number will allow for more variety in the artists.
ArtistId, /// ID(s) of seed artist(s) for the playlist
Artist, /// Artist names of seeds for playlist
ArtistSeedCatalog, /// ID of seed artist catalog for the playlist
SourceCatalog, /// ID of catalog (artist or song) for catalog type playlists
SongId, /// IDs of seed songs for the playlist
Description, /// Textual description for sort of songs that can be included in the playlist
Results, /// 0-100, how many sonsg to include in the playlist, default 15
MaxTempo, /// 0.0 < tempo < 500.0 (BPM) The maximum tempo for any included songs
MinTempo, /// 0.0 < tempo < 500.0 (BPM) the minimum tempo for any included songs
MaxDuration, /// 0.0 < duration < 3600.0 (seconds) the maximum duration of any song on the playlist
MinDuration, /// 0.0 < duration < 3600.0 (seconds) the minimum duration of any song on the playlist
MaxLoudness, /// -100.0 < loudness < 100.0 (dB) the maximum loudness of any song on the playlist
MinLoudness, /// -100.0 < loudness < 100.0 (dB) the minimum loudness of any song on the playlist
MinDanceability, /// 0 < danceability < 1 a measure of the minimum danceability of the song
MaxDanceability, /// 0 < danceability < 1 a measure of the maximum danceability of the song
MinEnergy, /// 0 < danceability < 1 a measure of the maximum energy of the song
MaxEnergy, /// 0 < danceability < 1 a measure of the maximum energy of the song
ArtistMaxFamiliarity, /// 0.0 < familiarity < 1.0 the maximum artist familiarity for songs in the playlist
ArtistMinFamiliarity, /// 0.0 < familiarity < 1.0 the minimum artist familiarity for songs in the playlist
ArtistMaxHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for artists in the playlist
ArtistMinHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for artists in the playlist
SongMaxHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for songs in the playlist
SongMinHotttnesss, /// 0.0 < hotttnesss < 1.0 the maximum hotttnesss for songs in the playlist
ArtistMinLongitude, /// -180.0 < longitude < 180.0 the minimum longitude for the location of artists in the playlist
ArtistMaxLongitude, /// -180.0 < longitude < 180.0 the maximum longitude for the location of artists in the playlist
ArtistMinLatitude, /// -90.0 < latitude < 90.0 the minimum latitude for the location of artists in the playlist
ArtistMaxLatitude, /// -90.0 < latitude < 90.0 the maximum latitude for the location of artists in the playlist
Mode, /// (minor, major) 0, 1 the mode of songs in the playlist
Key, /// (c, c-sharp, d, e-flat, e, f, f-sharp, g, a-flat, a, b-flat, b) 0 - 11 the key of songs in the playlist
SongInformation, /// what sort of song information should be returned. Should be an Echonest::SongInformation object
Sort, /// SortingType enum, the type of sorting to use,
Limit, /// true, false if true songs will be limited to those that appear in the catalog specified by the id: bucket
Audio, /// true, false, if true songs will be limited to those that have associated audio
DMCA, /// true, false Only valid for dynamic playlists. Sets if playlist will follow DMCA rules (see web api doc for details)
ChainXSPF, /// true, false If true, returns an xspf for this dynamic playlist with 2 items. The second item will be a link to the API call for the next track in the chain. Please note that this sidesteps libechonest's handling of the tracks.
Mood, /// A mood to limit this playlist to, for example "happy" or "sad". Multiples of this param are okay. See the method Artist::listTerms for details on what moods are currently available
Style, /// A style to limit this playlist to, for example "happy" or "sad". Multiples of this param are okay. See the method Artist::listTerms for details on what styles are currently available
Adventurousness
};
typedef QPair< PlaylistParam, QVariant > PlaylistParamData;
typedef QVector< PlaylistParamData > PlaylistParams;
/**
* The various controls for a dynamic playlist.
*
* Please see The Echo Nest API documentation for more information
*/
enum DynamicControlItem {
Steer = 0,
SteerDescription,
Rating,
Ban
};
typedef QPair< DynamicControlItem, QString > DynamicControl;
typedef QVector< DynamicControl > DynamicControls;
DynamicPlaylist();
virtual ~DynamicPlaylist();
DynamicPlaylist( const DynamicPlaylist& other );
DynamicPlaylist& operator=( const DynamicPlaylist& playlist );
/**
* Start a dynamic playlist with the given parameters.
* Once the QNetworkReply has finished, pass it to parseStart()
* and the inital song will be populated and returned. The sessionId(), currentSong(),
* and fetchNextSong() methods will then be useful.
*/
QNetworkReply* start( const PlaylistParams& params ) const;
Song parseStart( QNetworkReply* ) throw( ParseError );
/**
* The session id of this dynamic playlist. If the playlist has ended, or has not been started,
* the result is empty.
*
*/
QByteArray sessionId() const;
void setSessionId( const QByteArray& id );
/**
* The current song of this dynamic playlist. Once this song has been played,
* or whenever is desired, call fetchNextSong() to get the next song.
*/
Song currentSong() const;
void setCurrentSong( const Song& song );
/**
* Queries The Echo Nest for the next playable song in this
* dynamic playlist.
*
* Once the query has emitted the finished() signal, pass it to parseNextSong(), which will
* return the new song to play. It will also set the current song to the newly parsed song.
*
* If the playlist has no more songs, the returned song object will be have no name nor id.
*
* @param rating The rating for the song that was just played. Ranges from 1 (lowest) to 5 (highest)
* @param controls The controls to apply when fetching the next track.
*
*/
QNetworkReply* fetchNextSong( int rating = -1 ) const;
QNetworkReply* fetchNextSong( const DynamicControls& controls ) const;
Song parseNextSong( QNetworkReply* reply );
/**
* Returns a description of this dynamic playlist session
*/
QNetworkReply* fetchSessionInfo() const;
SessionInfo parseSessionInfo( QNetworkReply* reply ) throw( ParseError );
/**
* Generate a static playlist, according to the desired criteria. Use parseXSPFPlaylist if
* you pass format=xspf to \c staticPlaylist().
*/
static QNetworkReply* staticPlaylist( const PlaylistParams& params );
static SongList parseStaticPlaylist( QNetworkReply* reply ) throw( ParseError );
/**
* Parse an xspf playlist. Returns the full xspf content with no modifications.
*/
static QByteArray parseXSPFPlaylist( QNetworkReply* reply ) throw( ParseError );
private:
static QByteArray playlistParamToString( PlaylistParam param );
static QNetworkReply* generateInternal( const PlaylistParams& params, const QByteArray& type );
static QByteArray playlistSortToString(SortingType sorting);
static QByteArray playlistArtistPickToString(ArtistPick pick);
static QByteArray dynamicControlToString(DynamicControlItem control);
QSharedDataPointer<DynamicPlaylistData> d;
};
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::DynamicPlaylist& playlist);
} // namespace
Q_DECLARE_METATYPE( Echonest::DynamicPlaylist )
#endif

View File

@ -1,34 +0,0 @@
/****************************************************************************************
* 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 "Song.h"
#include <QSharedData>
#include <QString>
class DynamicPlaylistData : public QSharedData
{
public:
DynamicPlaylistData() {}
DynamicPlaylistData(const DynamicPlaylistData& other) : QSharedData(other)
{
sessionId = other.sessionId;
currentSong = other.currentSong;
}
QByteArray sessionId;
Echonest::Song currentSong;
};

View File

@ -1,432 +0,0 @@
/****************************************************************************************
* 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 "Song.h"
#include "Config.h"
#include "Song_p.h"
#include "AudioSummary.h"
#include <QNetworkReply>
#include <QDebug>
#include <QtNetwork/QNetworkReply>
#include "Parsing_p.h"
#include <qxmlstream.h>
#include <qjson/serializer.h>
#include <qjson/parser.h>
Echonest::Song::Song()
: d( new SongData )
{}
Echonest::Song::Song(const QByteArray& id, const QString& title, const QByteArray& artistId, const QString& artistName)
:d( new SongData )
{
d->id = id;
d->title = title;
d->artistId = artistId;
d->artistName = artistName;
}
Echonest::Song::Song(const QByteArray& id)
:d( new SongData )
{
d->id = id;
}
Echonest::Song::Song(const Echonest::Song& other)
: d( other.d )
{
}
Echonest::Song::~Song()
{
}
Echonest::Song& Echonest::Song::operator=(const Echonest::Song& song)
{
d = song.d;
return *this;
}
QByteArray Echonest::Song::id() const
{
return d->id;
}
void Echonest::Song::setId(const QByteArray& id)
{
d->id = id;
}
QString Echonest::Song::title() const
{
return d->title;
}
void Echonest::Song::setTitle(const QString& title)
{
d->title = title;
}
QByteArray Echonest::Song::artistId() const
{
return d->artistId;
}
void Echonest::Song::setArtistId(const QByteArray& artistId)
{
d->artistId = artistId;
}
QString Echonest::Song::artistName() const
{
return d->artistName;
}
void Echonest::Song::setArtistName(const QString& artistName)
{
d->artistName = artistName;
}
QString Echonest::Song::release() const
{
return d->release;
}
void Echonest::Song::setRelease(const QString& release)
{
d->release = release;
}
QVector< Echonest::Track > Echonest::Song::tracks() const
{
return d->tracks;
}
void Echonest::Song::setTracks(const QVector< Echonest::Track >& tracks)
{
d->tracks = tracks;
}
qreal Echonest::Song::hotttnesss() const
{
return d->hotttnesss;
}
void Echonest::Song::setHotttnesss(qreal hotttnesss)
{
d->hotttnesss = hotttnesss;
}
qreal Echonest::Song::artistHotttnesss() const
{
return d->artistHotttnesss;
}
void Echonest::Song::setArtistHotttnesss(qreal artistHotttnesss)
{
d->artistHotttnesss = artistHotttnesss;
}
Echonest::AudioSummary Echonest::Song::audioSummary() const
{
return d->audioSummary;
}
void Echonest::Song::setAudioSummary(const Echonest::AudioSummary& summary)
{
d->audioSummary = summary;
}
qreal Echonest::Song::artistFamiliarity() const
{
return d->artistFamiliarity;
}
void Echonest::Song::setArtistFamiliarity(qreal artistFamiliarity)
{
d->artistFamiliarity = artistFamiliarity;
}
Echonest::ArtistLocation Echonest::Song::artistLocation() const
{
return d->artistLocation;
}
void Echonest::Song::setArtistLocation(const Echonest::ArtistLocation& artistLocation)
{
d->artistLocation = artistLocation;
}
QNetworkReply* Echonest::Song::fetchInformation( Echonest::SongInformation information ) const
{
QUrl url = Echonest::baseGetQuery( "song", "profile" );
url.addEncodedQueryItem( "id", d->id );
addQueryInformation( url, information );
qDebug() << "Creating fetchInformation URL" << url;
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Song::search( const Echonest::Song::SearchParams& params, Echonest::SongInformation information )
{
QUrl url = Echonest::baseGetQuery( "song", "search" );
addQueryInformation( url, information );
SearchParams::const_iterator iter = params.constBegin();
for( ; iter < params.constEnd(); ++iter )
url.addEncodedQueryItem( searchParamToString( iter->first ), Echonest::escapeSpacesAndPluses( iter->second.toString() ) );
qDebug() << "Creating search URL" << url;
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Song::identify( const Echonest::Song::IdentifyParams& params, const Echonest::SongInformation& information )
{
QVariantMap query;
QVariantMap metadata;
IdentifyParams::const_iterator iter = params.constBegin();
for( ; iter < params.constEnd(); ++iter ) {
if( iter->first == Code )
query[ QLatin1String( identifyParamToString( iter->first ) ) ] = iter->second;
else
metadata[ QLatin1String( identifyParamToString( iter->first ) ) ] = iter->second.toString();
}
metadata[ QLatin1String( "version" ) ] = QLatin1String( "4.12" );
query[ QLatin1String( "metadata" ) ] = metadata;
QJson::Serializer s;
QByteArray data = s.serialize( query );
QUrl url = Echonest::baseGetQuery( "song", "identify" );
addQueryInformation( url, information );
qDebug() << "Creating identify URL" << url;
QNetworkRequest request( url );
request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/octet-stream" ) );
// qDebug() << "Uploading local file to" << url;
return Echonest::Config::instance()->nam()->post( request, data );
}
Echonest::SongList Echonest::Song::parseIdentify( QNetworkReply* reply ) throw( ParseError )
{
Echonest::Parser::checkForErrors( reply );
QByteArray data = reply->readAll();
QJson::Parser p;
QVariantMap res = p.parse( data ).toMap();
// qDebug() << "Got data from identify call:" << data << res;
qDebug() << res[ QLatin1String( "response" ) ].toMap()[ QLatin1String( "songs" ) ].toList();
if( !res.contains( QLatin1String( "response" ) ) || !res[ QLatin1String( "response" ) ].toMap().contains( QLatin1String( "songs" ) ) ) {
qDebug() << "No response or songs elemnt in json...";
throw ParseError( UnknownParseError, QLatin1String( "Invalid json response" ) );
}
SongList songs;
QVariantList songsV = res[ QLatin1String( "response" ) ].toMap()[ QLatin1String( "songs" ) ].toList();
foreach( const QVariant& s, songsV ) {
QVariantMap sM = s.toMap();
Echonest::Song song;
if( sM.contains( QLatin1String( "title" ) ) )
song.setTitle( sM[ QLatin1String( "title" ) ].toString() );
if( sM.contains( QLatin1String( "artist_id" ) ) )
song.setArtistId( sM[ QLatin1String( "artist_id" ) ].toByteArray() );
if( sM.contains( QLatin1String( "artist_name" ) ) )
song.setArtistName( sM[ QLatin1String( "artist_name" ) ].toString() );
if( sM.contains( QLatin1String( "id" ) ) )
song.setId( sM[ QLatin1String( "id" ) ].toByteArray() );
songs.append( song );
}
reply->deleteLater();
return songs;
}
void Echonest::Song::parseInformation( QNetworkReply* reply ) throw( ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
// we'll just take the new data. it is given as a list even though it can only have 1 song as we specify the song id
QVector< Echonest::Song > songs = Echonest::Parser::parseSongList( xml );
if( !songs.size() == 1 ) { // no data for this song. returned empty.
return;
}
// copy any non-default values
Echonest::Song newSong = songs.at( 0 );
if( newSong.hotttnesss() >= 0 )
setHotttnesss( newSong.hotttnesss() );
if( newSong.artistHotttnesss() >= 0 )
setArtistHotttnesss( newSong.artistHotttnesss() );
if( newSong.artistFamiliarity() >= 0 )
setArtistFamiliarity( newSong.artistFamiliarity() );
if( !newSong.artistLocation().location.isEmpty() )
setArtistLocation( newSong.artistLocation() );
reply->deleteLater();
}
QVector< Echonest::Song > Echonest::Song::parseSearch( QNetworkReply* reply ) throw( ParseError )
{
Echonest::Parser::checkForErrors( reply );
QXmlStreamReader xml( reply->readAll() );
Echonest::Parser::readStatus( xml );
QVector<Echonest::Song> songs = Echonest::Parser::parseSongList( xml );
reply->deleteLater();
return songs;
}
QByteArray Echonest::Song::searchParamToString( Echonest::Song::SearchParam param )
{
switch( param )
{
case Echonest::Song::Title:
return "title";
case Echonest::Song::Artist:
return "artist";
case Echonest::Song::Combined:
return "combined";
case Echonest::Song::Description:
return "description";
case Echonest::Song::ArtistId:
return "artist_id";
case Echonest::Song::Start:
return "start";
case Echonest::Song::Results:
return "results";
case Echonest::Song::MaxTempo:
return "max_tempo";
case Echonest::Song::MinTempo:
return "min_tempo";
case Echonest::Song::MaxDanceability:
return "max_danceability";
case Echonest::Song::MinDanceability:
return "min_danceability";
case Echonest::Song::MaxComplexity:
return "max_complexity";
case Echonest::Song::MinComplexity:
return "min_complexity";
case Echonest::Song::MaxDuration:
return "max_duration";
case Echonest::Song::MinDuration:
return "min_duration";
case Echonest::Song::MaxLoudness:
return "max_loudness";
case Echonest::Song::MinLoudness:
return "min_loudness";
case Echonest::Song::MaxFamiliarity:
return "max_familiarity";
case Echonest::Song::MinFamiliarity:
return "min_familiarity";
case Echonest::Song::MaxHotttnesss:
return "max_hotttnesss";
case Echonest::Song::MinHotttnesss:
return "min_hotttnesss";
case Echonest::Song::MaxLongitude:
return "max_longitude";
case Echonest::Song::MinLongitude:
return "min_longitude";
case Echonest::Song::MinEnergy:
return "min_energy";
case Echonest::Song::MaxEnergy:
return "max_energy";
case Echonest::Song::Mode:
return "mode";
case Echonest::Song::Key:
return "key";
case Echonest::Song::Sort:
return "sort";
}
return QByteArray();
}
QByteArray Echonest::Song::identifyParamToString( Echonest::Song::IdentifyParam param )
{
switch( param )
{
case Echonest::Song::Code:
return "code";
case Echonest::Song::IdentifyArtist:
return "artist";
case Echonest::Song::IdentifyDuration:
return "duration";
case Echonest::Song::IdentifyGenre:
return "genre";
case Echonest::Song::IdentifyRelease:
return "release";
case Echonest::Song::IdentifyTitle:
return "title";
}
return QByteArray();
}
void Echonest::Song::addQueryInformation(QUrl& url, Echonest::SongInformation information)
{
if( information.flags().testFlag( Echonest::SongInformation::AudioSummaryInformation ) )
url.addEncodedQueryItem( "bucket", "audio_summary" );
if( information.flags().testFlag( Echonest::SongInformation::Tracks ) )
url.addEncodedQueryItem( "bucket", "tracks" );
if( information.flags().testFlag( Echonest::SongInformation::Hotttnesss ) )
url.addEncodedQueryItem( "bucket", "song_hotttnesss" );
if( information.flags().testFlag( Echonest::SongInformation::ArtistHotttnesss ) )
url.addEncodedQueryItem( "bucket", "artist_hotttnesss" );
if( information.flags().testFlag( Echonest::SongInformation::ArtistFamiliarity ) )
url.addEncodedQueryItem( "bucket", "artist_familiarity" );
if( information.flags().testFlag( Echonest::SongInformation::ArtistLocation ) )
url.addEncodedQueryItem( "bucket", "artist_location" );
if( !information.idSpaces().isEmpty() ) {
foreach( const QString& idSpace, information.idSpaces() )
url.addEncodedQueryItem( "bucket", "id:" + idSpace.toUtf8() );
}
}
QString Echonest::Song::toString() const
{
return QString::fromLatin1( "Song(%1, %2, %3, %4)" ).arg( title() ).arg( artistName() ).arg( QString::fromLatin1( id() ) ).arg( QString::fromLatin1( artistId() ) );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Song& song)
{
d << song.toString();
return d.maybeSpace();
}

View File

@ -1,243 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_SONG_H
#define ECHONEST_SONG_H
#include "echonest_export.h"
#include "Track.h"
#include "TypeInformation.h"
#include <QSharedData>
#include <QHash>
#include <QVariant>
#include <QDebug>
#include <QVector>
#include "Config.h"
class QNetworkReply;
class SongData;
namespace Echonest{
class DynamicPlaylist; // forward declare for friend declaration
class Catalog;
class AudioSummary;
/**
* This encapsulates an Echo Nest song---use it if you wish to get information about a song,
* search for a song, etc.
*
* This class is implicitly shared.
*/
class ECHONEST_EXPORT Song
{
public:
enum SearchParam {
Title,
Artist,
Combined,
Description,
ArtistId,
Start,
Results,
MaxTempo,
MinTempo,
MaxDanceability,
MinDanceability,
MaxComplexity,
MinComplexity,
MaxDuration,
MinDuration,
MaxLoudness,
MinLoudness,
MaxFamiliarity,
MinFamiliarity,
MaxHotttnesss,
MinHotttnesss,
MaxLongitude,
MinLongitude,
MaxEnergy,
MinEnergy,
Mode,
Key,
Sort
};
typedef QPair< Echonest::Song::SearchParam, QVariant > SearchParamData;
typedef QVector< SearchParamData > SearchParams;
enum IdentifyParam {
Code,
IdentifyArtist,
IdentifyTitle,
IdentifyRelease,
IdentifyDuration,
IdentifyGenre
};
typedef QPair< Echonest::Song::IdentifyParam, QVariant > IdentifyParamData;
typedef QVector< IdentifyParamData > IdentifyParams;
Song();
Song( const QByteArray& id, const QString& title, const QByteArray& artistId, const QString& artistName );
Song( const QByteArray& id );
Song( const Song& other );
Song& operator=(const Song& song);
virtual ~Song();
/**
* The following pieces of data are present in all Song objects, and do not require
* on-demand fetching.
*/
QByteArray id() const;
void setId( const QByteArray& id );
QString title() const;
void setTitle( const QString& title );
QString artistName() const;
void setArtistName( const QString& artistName );
QByteArray artistId() const;
void setArtistId( const QByteArray& artistId );
QString release() const;
void setRelease( const QString& release );
/**
* The following require fetching from The Echo Nest, so call
* fetchInformation() with the type of data you want first.
*
* If you ask for this information before calling parseInformation()
* with the respective data, the result is undefined.
*/
/**
* The full audio summary and analysis of this song.
*
* NOTE: This will return a copy of the AudioSummary object, which
* is implicitly shared. If you make modifications to the returned
* summary, for example by calling parseFullAnalysis(), it will detach
* and you will have to call setAudioSummary() to save the changes back
* to this Song object.
*/
AudioSummary audioSummary() const;
void setAudioSummary( const AudioSummary& summary );
/**
* The associated Track objects with acoustic track information
*/
QVector< Track > tracks() const;
void setTracks( const QVector< Track >& tracks );
/**
* The "hotttnesss" metric of this song.
*/
qreal hotttnesss() const;
void setHotttnesss( qreal hotttnesss );
/**
* The "hotttnesss" metric of this song's artist.
*/
qreal artistHotttnesss() const;
void setArtistHotttnesss( qreal artistHotttnesss );
/**
* The familiarity metric of this song's artist.
*/
qreal artistFamiliarity() const;
void setArtistFamiliarity( qreal artistFamiliarity );
/**
* The location of this artist.
*/
ArtistLocation artistLocation() const;
void setArtistLocation( const ArtistLocation& artistLocation );
/**
* This fetches the data from The Echo Nest for the requested data, so it
* returns a QNetworkReply*. When the finished() signal is emitted
* from the QNetworkReply object call parseInformation() to save the
* data back to this Song object.
*
*/
QNetworkReply* fetchInformation( SongInformation information = SongInformation() ) const;
/**
* Search for a song from The Echo Nest with the given search parameters. See
* http://developer.echonest.com/docs/v4/song.html#search for a description of the
* parameters and data types.
*
* The result will contain the requested information from the SongInformation flags, and
* can be extracted in the parseSearch() function.
*
*/
static QNetworkReply* search( const SearchParams& params, SongInformation information = SongInformation() );
/**
* Identify a song from a given Echo Nest fingerprint hash code.
* NOTE: SongInformation is currently not parsed yet.
*
*/
static QNetworkReply* identify( const IdentifyParams& params, const SongInformation& information = SongInformation() );
/**
* Identify a song from the Echoprint hash code, this time using the output of the 'echoprint-codegen' command-line
* tool
*/
// static QNetworkReply* identify( const QByteArray& jsonData );
/**
* Parses the reply of the identify call and returns a list of songs found.
*
*/
static QVector< Song > parseIdentify( QNetworkReply* ) throw( ParseError );
/**
* Parse the result of the fetchInformation() call.
* For each requested SongInformationFlag in the original request, the respective
* data will be saved to this Song object.
*/
void parseInformation( QNetworkReply* reply ) throw( ParseError );
/**
* Parse the result of the search() call.
*/
static QVector<Song> parseSearch( QNetworkReply* reply ) throw( ParseError );
QString toString() const;
friend class DynamicPlaylist;
friend class Catalog; // for access to searchParamToString
private:
static QByteArray searchParamToString( SearchParam param );
static QByteArray identifyParamToString( IdentifyParam param );
static void addQueryInformation( QUrl& url, SongInformation information );
QSharedDataPointer<SongData> d;
};
typedef QVector< Song > SongList;
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Song &song);
} // namespace
Q_DECLARE_METATYPE( Echonest::Song )
#endif

View File

@ -1,67 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_SONG_P_H
#define ECHONEST_SONG_P_H
#include "Track.h"
#include "AudioSummary.h"
#include <QSharedData>
#include <QString>
#include <QVector>
class SongData : public QSharedData
{
public:
SongData() : hotttnesss( -1 ), artistHotttnesss( -1 ), artistFamiliarity( -1 ) { artistLocation.latitude = -1; artistLocation.longitude = -1; }
SongData(const SongData& other) : QSharedData( other )
{
id = other.id;
title = other.title;
artistName = other.artistName;
artistId = other.artistId;
audioSummary = other.audioSummary;
tracks = other.tracks;
hotttnesss = other.hotttnesss;
artistHotttnesss = other.artistHotttnesss;
artistFamiliarity = other.artistFamiliarity;
artistLocation = other.artistLocation;
}
~SongData() {}
QByteArray id;
QString title;
QString artistName;
QByteArray artistId;
QString release;
// The rest are optional that require manual fetching to populate
Echonest::AudioSummary audioSummary;
QVector<Echonest::Track> tracks;
qreal hotttnesss;
qreal artistHotttnesss;
qreal artistFamiliarity;
Echonest::ArtistLocation artistLocation;
};
#endif

View File

@ -1,310 +0,0 @@
/****************************************************************************************
* 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 "Track.h"
#include "Track_p.h"
#include <QNetworkReply>
#include "Config.h"
#include "Song.h"
#include <qfileinfo.h>
#include "Parsing_p.h"
Echonest::Track::Track()
: d( new TrackData )
{
}
Echonest::Track::Track(const Echonest::Track& other)
: d( other.d )
{}
Echonest::Track::Track(const QByteArray& id)
: d( new TrackData )
{
d->id = id;
}
Echonest::Track::~Track()
{
}
Echonest::Track& Echonest::Track::operator=(const Echonest::Track& track)
{
d = track.d;
return *this;
}
QString Echonest::Track::artist() const
{
return d->artist;
}
void Echonest::Track::setArtist(const QString& artist)
{
d->artist = artist;
}
QString Echonest::Track::title() const
{
return d->title;
}
void Echonest::Track::setTitle(const QString& title)
{
d->title = title;
}
QByteArray Echonest::Track::id() const
{
return d->id;
}
void Echonest::Track::setId(const QByteArray& id)
{
d->id = id;
}
QByteArray Echonest::Track::md5() const
{
return d->md5;
}
void Echonest::Track::setMD5(const QByteArray& md5)
{
d->md5 = md5;
}
QString Echonest::Track::release() const
{
return d->release;
}
void Echonest::Track::setRelease(const QString& release)
{
d->release = release;
}
QString Echonest::Track::analyzerVersion() const
{
return d->analyzer_version;
}
void Echonest::Track::setAnalyzerVersion(const QString& analyzerVersion)
{
d->analyzer_version = analyzerVersion;
}
int Echonest::Track::bitrate() const
{
return d->bitrate;
}
void Echonest::Track::setBitrate(int bitrate)
{
d->bitrate = bitrate;
}
int Echonest::Track::samplerate() const
{
return d->samplerate;
}
void Echonest::Track::setSamplerate(int samplerate)
{
d->samplerate = samplerate;
}
QByteArray Echonest::Track::audioMD5() const
{
return d->audio_md5;
}
void Echonest::Track::setAudioMD5(const QByteArray& md5)
{
d->audio_md5 = md5;
}
Echonest::Analysis::AnalysisStatus Echonest::Track::status() const
{
return Echonest::statusToEnum( d->status );
}
void Echonest::Track::setStatus( Echonest::Analysis::AnalysisStatus status )
{
d->status = Echonest::statusToString( status );
}
Echonest::AudioSummary Echonest::Track::audioSummary() const
{
return d->audio_summary;
}
void Echonest::Track::setAudioSummary( const Echonest::AudioSummary& summary )
{
d->audio_summary = summary;
}
QString Echonest::Track::catalog() const
{
return d->catalog;
}
void Echonest::Track::setCatalog(const QString& catalog)
{
d->catalog = catalog;
}
QByteArray Echonest::Track::foreignId() const
{
return d->foreign_id;
}
void Echonest::Track::setForeignId(const QByteArray& id)
{
d->foreign_id = id;
}
QUrl Echonest::Track::previewUrl() const
{
return d->preview_url;
}
void Echonest::Track::setPreviewUrl(const QUrl& preview)
{
d->preview_url = preview;
}
QUrl Echonest::Track::releaseImage() const
{
return d->release_image;
}
void Echonest::Track::setReleaseImage(const QUrl& imgUrl)
{
d->release_image = imgUrl;
}
Echonest::Song Echonest::Track::song() const
{
return d->song;
}
void Echonest::Track::setSong(const Echonest::Song& song)
{
d->song = song;
}
QNetworkReply* Echonest::Track::profileFromTrackId( const QByteArray& id )
{
QUrl url = Echonest::baseGetQuery( "track", "profile" );
url.addEncodedQueryItem( "id", id );
url.addEncodedQueryItem( "bucket", "audio_summary" );
qDebug() << "Creating profileFromTrackId URL" << url;
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Track::profileFromMD5( const QByteArray& md5 )
{
QUrl url = Echonest::baseGetQuery( "track", "profile" );
url.addEncodedQueryItem( "md5", md5 );
url.addEncodedQueryItem( "bucket", "audio_summary" );
qDebug() << "Creating profileFromMD5 URL" << url;
return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
}
QNetworkReply* Echonest::Track::uploadLocalFile( const QUrl& localFile, const QByteArray& data, bool waitForResult )
{
QUrl url = Echonest::baseGetQuery( "track", "upload" );
QFileInfo info( localFile.path() );
url.addQueryItem( QLatin1String( "filetype" ), info.suffix() );
url.addEncodedQueryItem( "bucket", "audio_summary" );
url.addEncodedQueryItem( "wait", ( waitForResult ? "true" : "false" ) );
QNetworkRequest request( url );
request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/octet-stream" ) );
// qDebug() << "Uploading local file to" << url;
return Echonest::Config::instance()->nam()->post( request, data );
}
QNetworkReply* Echonest::Track::uploadURL( const QUrl& remoteURL, bool waitForResult )
{
QUrl url = Echonest::baseGetQuery( "track", "upload" );
url.addEncodedQueryItem( "url", remoteURL.toEncoded() );
url.addEncodedQueryItem( "bucket", "audio_summary" );
url.addEncodedQueryItem( "wait", ( waitForResult ? "true" : "false" ) );
qDebug() << "Uploading URL:" << url;
QNetworkRequest req( url );
req.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/x-www-form-urlencoded" ) );
return Echonest::Config::instance()->nam()->post( req, QByteArray() );
}
QNetworkReply* Echonest::Track::analyzeTrackId( const QByteArray& id, bool wait )
{
QUrl url = Echonest::baseGetQuery( "track", "analyze" );
url.addEncodedQueryItem( "id", id );
url.addEncodedQueryItem( "bucket", "audio_summary" );
url.addEncodedQueryItem( "wait", ( wait ? "true" : "false" ) );
qDebug() << "Creating analyzeTrackId URL" << url;
return Echonest::doPost( url );
// return Echonest::Config::instance()->nam()->post( QNetworkRequest( url ), QByteArray() );
}
QNetworkReply* Echonest::Track::analyzeTrackMD5( const QByteArray& md5, bool wait )
{
QUrl url = Echonest::baseGetQuery( "track", "analyze" );
url.addEncodedQueryItem( "md5", md5 );
url.addEncodedQueryItem( "bucket", "audio_summary" );
url.addEncodedQueryItem( "wait", ( wait ? "true" : "false" ) );
qDebug() << "Creating analyzeTrackMD5 URL" << url;
return Echonest::doPost( url );
// return Echonest::Config::instance()->nam()->post( QNetworkRequest( url ), QByteArray() );
}
Echonest::Track Echonest::Track::parseProfile( QNetworkReply* finishedReply ) throw( Echonest::ParseError )
{
QByteArray data = finishedReply->readAll();
qDebug() << data;
Echonest::Parser::checkForErrors( finishedReply );
QXmlStreamReader xml( data );
Echonest::Parser::readStatus( xml );
Echonest::Track track = Echonest::Parser::parseTrack( xml );
finishedReply->deleteLater();
return track;
}
QDebug Echonest::operator<<(QDebug d, const Echonest::Track& track)
{
d << QString::fromLatin1( "Track(%1, %2, %3, %4)" ).arg( QLatin1String( track.id() ) ).arg( track.title() ).arg( track.artist() ).arg( track.release() );
return d.maybeSpace();
}

View File

@ -1,229 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_TRACK_H
#define ECHONEST_TRACK_H
#include "AudioSummary.h"
#include "echonest_export.h"
#include "Util.h"
#include <QObject>
#include <QString>
#include <QDebug>
#include <QSharedData>
#include <QUrl>
#include "Config.h"
class QNetworkReply;
class TrackData;
namespace Echonest
{
class Song;
/**
* Upload-based Echo Nest Track API. If you want to search The Echo Nest for songs, use the Song API.
* If you want to upload your own files and retrieve the acoustic information about them, use this Track
* class. You can also fetch acoustic information from a track if you have the Track ID or MD5 of the file.
*
* A Track encapsulates the audio analysis from The Echo Nest.
*
* This class is implicitly shared.
*
*/
class ECHONEST_EXPORT Track
{
public:
Track();
explicit Track( const QByteArray& id );
Track( const Track& other );
Track& operator=( const Track& track );
~Track();
/**
* The track's artist.
*/
QString artist() const;
void setArtist( const QString& artist );
/**
* The track's title.
*/
QString title() const;
void setTitle( const QString& title );
/**
* The Echo Nest artist ID for this track.
*/
QByteArray id() const;
void setId( const QByteArray& id );
/**
* The MD5 hash of the track.
*/
QByteArray md5() const;
void setMD5( const QByteArray& md5 );
/**
* The album name of this track.
*/
QString release() const;
void setRelease( const QString& release );
/**
* The MD5 hashsum of the audio data.
*/
QByteArray audioMD5() const;
void setAudioMD5( const QByteArray& md5 );
/**
* The analyzer version that was used in this track's analysis.
*/
QString analyzerVersion() const;
void setAnalyzerVersion( const QString& analyzerVersion );
/**
* The samplerate of the track
*/
int samplerate() const;
void setSamplerate( int samplerate );
/**
* The bitrate of the track
*/
int bitrate() const;
void setBitrate( int );
/**
* If this track is fetched from a tracks bucket of a song search, the following information
* will be populated for some id spaces.
*/
/**
* The catalog this track is from, if not a native Echo Nest track
*/
QString catalog() const;
void setCatalog( const QString& catalog );
/**
* The foreign id of this track, that is in the \c catalog catalog.
*/
QByteArray foreignId() const;
void setForeignId( const QByteArray& id );
/**
* The release image associated with this track
*/
QUrl releaseImage() const;
void setReleaseImage( const QUrl& imgUrl );
/**
* The preview url for this track, if it exists
*/
QUrl previewUrl() const;
void setPreviewUrl( const QUrl& preview );
/**
* The Echo Nest song associated with this track, if it exists
*/
Song song() const;
void setSong( const Song& song );
/**
* The analysis status
*/
Analysis::AnalysisStatus status() const;
void setStatus( Analysis::AnalysisStatus );
/**
* The full audio summary of the track. This contains information about the track's bars,
* beats, sections, and detailed segment information as well as more metadata about the song's
* acoustic properties.
*
* Information about how to interpret the results of the audio summary can be found here:
* http://developer.echonest.com/docs/v4/_static/AnalyzeDocumentation_2.2.pdf
*
* NOTE: This will return a copy of the AudioSummary object, which
* is implicitly shared. If you make modifications to the returned
* summary, for example by calling parseFullAnalysis(), it will detach
* and you will have to call setAudioSummary() to save the changes back
* to this Song object.
*/
AudioSummary audioSummary() const;
void setAudioSummary( const AudioSummary& summary );
/**
* Get a track object from the md5 hash of a song's contents.
*
* Call parseProfile() to get the track itself once the
* QNetworkReply() emits the finished() signal.
*/
static QNetworkReply* profileFromMD5( const QByteArray& md5 );
/**
* Get a track object from an Echo Nest track id.
*
* Call parseProfile() to get the track itself once the
* QNetworkReply() emits the finished() signal.
*/
static QNetworkReply* profileFromTrackId( const QByteArray& id );
/**
* Upload a track to The Echo Nest for analysis. The file can either be
* a local filetype and include the file data as a parameter, or a url to a file on the internet.
*
* When the QNetworkReply emits its finished() signal, you can call parseProfile()
* to get the resulting Track object. Be sure to check the status of the new track,
* as it might be 'pending', which means it is still being analyzed and must be asked
* for again later.
*
* Note that in the case of uploading a local file, the data QByteArray must stay in scope for the
* whole completion of the upload operation.
*/
static QNetworkReply* uploadLocalFile( const QUrl& localFile, const QByteArray& data, bool waitForResult = true );
static QNetworkReply* uploadURL( const QUrl& remoteURL, bool waitForResult = true );
/**
* Analyze a previously uploaded track with the current version of the analyzer.
* It can be referenced by either track ID or file md5.
*/
static QNetworkReply* analyzeTrackId( const QByteArray& id, bool wait = true );
static QNetworkReply* analyzeTrackMD5( const QByteArray& id, bool wait = true );
/**
* Parse the result of a track request, and turn it into a
* Track object.
*
* Call this function after the QNetworkReply* object returned
* from the parse*, upload*, and analyze* emits its finished() signal
*/
static Track parseProfile( QNetworkReply* ) throw( ParseError );
private:
QSharedDataPointer<TrackData> d;
};
typedef QVector<Track> Tracks;
ECHONEST_EXPORT QDebug operator<<(QDebug d, const Echonest::Track& track);
} // namespace
#endif

View File

@ -1,96 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_TRACK_P_H
#define ECHONEST_TRACK_P_H
#include "AudioSummary.h"
#include "Config.h"
#include "Song.h"
#include <QSharedData>
#include <QString>
#include <QNetworkReply>
namespace Echonest {
inline QNetworkReply* doPost(const QUrl& url)
{
// UGLY :( Build url, then extract the encded query items, put them in the POST body, and send that to the url minus the encoded params.
// The final data
QByteArray data;
int size = url.encodedQueryItems().size();
for( int i = 0; i < size; i++ ) {
const QPair< QByteArray, QByteArray > item = url.encodedQueryItems().at( i );
data.append( item.first + "=" + item.second + "&" );
}
data.truncate( data.size() - 1 ); // remove extra &
//qDebug() << "Sending data:" << data << "for method:" << url.path();
// strip the extras
QUrl url2( url.toString().mid( 0, url.toString().indexOf( QLatin1Char( '?' ) ) ) );
QNetworkRequest request = QNetworkRequest( url2 );
request.setHeader( QNetworkRequest::ContentTypeHeader, QLatin1String( "application/x-www-form-urlencoded" ) );
return Echonest::Config::instance()->nam()->post( request, data );
}
}
class TrackData : public QSharedData
{
public:
TrackData() {}
TrackData(const TrackData& other) : QSharedData( other )
{
analyzer_version = other.analyzer_version;
artist = other.artist;
bitrate = other.bitrate;
id = other.id;
md5 = other.md5;
release = other.release;
samplerate = other.samplerate;
status = other.status;
title = other.title;
catalog = other.catalog;
foreign_id = other.foreign_id;
release_image = other.release_image;
preview_url = other.preview_url;
}
QString artist;
QString analyzer_version;
int bitrate;
QByteArray id;
QByteArray md5;
QString release;
QByteArray audio_md5;
int samplerate;
QString status;
QString title;
// used when fetched as a foreign id in a tracks bucket
QString catalog;
QByteArray foreign_id;
QUrl release_image;
QUrl preview_url;
// song tracks have an associated song
Echonest::Song song;
Echonest::AudioSummary audio_summary;
};
#endif

View File

@ -1,183 +0,0 @@
/****************************************************************************************
* 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 "TypeInformation.h"
#include <QStringList>
namespace Echonest {
class ArtistInformationPrivate
{
public:
ArtistInformationPrivate() : flags( ArtistInformation::NoInformation )
{}
Echonest::ArtistInformation::ArtistInformationFlags flags;
QStringList idSpaces;
};
class SongInformationPrivate
{
public:
SongInformationPrivate() : flags( SongInformation::NoInformation )
{}
SongInformation::SongInformationFlags flags;
QStringList idSpaces;
};
} // namespace
Echonest::ArtistInformation::ArtistInformation()
: d_ptr( new Echonest::ArtistInformationPrivate )
{
Q_D( ArtistInformation );
d->flags = Echonest::ArtistInformation::NoInformation;
}
Echonest::ArtistInformation::ArtistInformation( ArtistInformationFlags flags )
: d_ptr( new Echonest::ArtistInformationPrivate )
{
Q_D( ArtistInformation );
d->flags = flags;
}
Echonest::ArtistInformation::ArtistInformation( ArtistInformation::ArtistInformationFlags flags, const QStringList& idSpaces )
: d_ptr( new Echonest::ArtistInformationPrivate )
{
Q_D( Echonest::ArtistInformation );
d->flags = flags;
d->idSpaces = idSpaces;
}
Echonest::ArtistInformation::ArtistInformation( const Echonest::ArtistInformation& other )
: d_ptr( new Echonest::ArtistInformationPrivate( *other.d_ptr ) )
{
}
Echonest::ArtistInformation::~ArtistInformation()
{
delete d_ptr;
}
Echonest::ArtistInformation& Echonest::ArtistInformation::operator=( const Echonest::ArtistInformation& typeInfo )
{
d_ptr = new Echonest::ArtistInformationPrivate( *typeInfo.d_ptr );
return *this;
}
Echonest::ArtistInformation::ArtistInformationFlags Echonest::ArtistInformation::flags() const
{
Q_D( const Echonest::ArtistInformation );
return d->flags;
}
void Echonest::ArtistInformation::setArtistInformationFlags( ArtistInformationFlags flags)
{
Q_D( Echonest::ArtistInformation );
d->flags = flags;
}
QStringList Echonest::ArtistInformation::idSpaces() const
{
Q_D( const Echonest::ArtistInformation );
return d->idSpaces;
}
void Echonest::ArtistInformation::setIdSpaces(const QStringList& idspaces)
{
Q_D( Echonest::ArtistInformation );
d->idSpaces = idspaces;
}
Echonest::SongInformation::SongInformation()
: d_ptr( new Echonest::SongInformationPrivate )
{
Q_D( Echonest::SongInformation );
d->flags = Echonest::SongInformation::NoInformation;
}
Echonest::SongInformation::SongInformation( SongInformationFlags flags )
: d_ptr( new Echonest::SongInformationPrivate )
{
Q_D( SongInformation );
d->flags = flags;
}
Echonest::SongInformation::SongInformation( SongInformation::SongInformationFlags flags, const QStringList& idSpaces )
: d_ptr( new Echonest::SongInformationPrivate )
{
Q_D( Echonest::SongInformation );
d->flags = flags;
d->idSpaces = idSpaces;
}
Echonest::SongInformation::SongInformation( const Echonest::SongInformation& other )
: d_ptr( new Echonest::SongInformationPrivate( *other.d_ptr ) )
{
}
Echonest::SongInformation::~SongInformation()
{
delete d_ptr;
}
Echonest::SongInformation& Echonest::SongInformation::operator=( const Echonest::SongInformation& info )
{
d_ptr = new Echonest::SongInformationPrivate( *info.d_ptr );
return *this;
}
Echonest::SongInformation::SongInformationFlags Echonest::SongInformation::flags() const
{
Q_D( const Echonest::SongInformation );
return d->flags;
}
void Echonest::SongInformation::setSongInformationFlags( SongInformationFlags flags )
{
Q_D( Echonest::SongInformation );
d->flags = flags;
}
QStringList Echonest::SongInformation::idSpaces() const
{
Q_D( const Echonest::SongInformation );
return d->idSpaces;
}
void Echonest::SongInformation::setIdSpaces(const QStringList& idspaces)
{
Q_D( Echonest::SongInformation );
d->idSpaces = idspaces;
}

View File

@ -1,135 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_TYPEINFORMATION_H
#define ECHONEST_TYPEINFORMATION_H
#include "echonest_export.h"
#include <qglobal.h>
#include <QStringList>
#include <QMetaType>
namespace Echonest {
class ArtistInformationPrivate;
class SongInformationPrivate;
/**
* This class describes what artist information to return with a query.
*
* The default behaviour is NoInformation.
*/
class ECHONEST_EXPORT ArtistInformation
{
public:
enum ArtistInformationFlag {
NoInformation = 0x0000,
Audio = 0x0001,
Biographies = 0x0002,
Blogs = 0x0004,
Familiarity = 0x0008,
Hotttnesss = 0x0010,
Images = 0x0020,
News = 0x0040,
Reviews = 0x0080,
Terms = 0x0100,
Urls = 0x200,
Videos = 0x0400
};
Q_DECLARE_FLAGS( ArtistInformationFlags, ArtistInformationFlag )
ArtistInformation();
ArtistInformation( ArtistInformationFlags flags );
ArtistInformation( ArtistInformationFlags flags, const QStringList& idSpaces );
ArtistInformation( const ArtistInformation& other );
~ArtistInformation();
ArtistInformation& operator=( const ArtistInformation& typeInfo );
/**
* The individual pieces of information to fetch for this artist.
*
* Use \c setIdSpaces to set an id space for this query.
*/
ArtistInformationFlags flags() const;
void setArtistInformationFlags( ArtistInformationFlags flags );
/**
* The id spaces to limit this to. Do not include the "id:" prefix.
*/
QStringList idSpaces() const;
void setIdSpaces( const QStringList& idspaces );
private:
ArtistInformationPrivate* d_ptr;
Q_DECLARE_PRIVATE( ArtistInformation )
};
Q_DECLARE_OPERATORS_FOR_FLAGS( ArtistInformation::ArtistInformationFlags )
/**
* This class describes what song information to return with a query.
*
* The default behaviour is NoInformation.
*/
class ECHONEST_EXPORT SongInformation
{
public:
enum SongInformationFlag {
AudioSummaryInformation = 0x001,
Tracks = 0x002,
Hotttnesss = 0x04,
ArtistHotttnesss = 0x008,
ArtistFamiliarity = 0x010,
ArtistLocation = 0x020,
NoInformation = 0x800
};
Q_DECLARE_FLAGS( SongInformationFlags, SongInformationFlag )
SongInformation();
SongInformation( SongInformationFlags flags );
SongInformation( SongInformationFlags flags, const QStringList& idSpaces );
SongInformation( const SongInformation& other );
~SongInformation();
SongInformation& operator=( const SongInformation& info );
/**
* The individual pieces of information to fetch for this song.
* If id spaces are desired,see \c setIdSpaces for more information.
*/
SongInformationFlags flags() const;
void setSongInformationFlags( SongInformationFlags flags );
/**
* The id spaces to limit this to. Do not include the "id:" prefix.
*/
QStringList idSpaces() const;
void setIdSpaces( const QStringList& idspaces );
private:
SongInformationPrivate* d_ptr;
Q_DECLARE_PRIVATE( SongInformation )
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SongInformation::SongInformationFlags)
}
Q_DECLARE_METATYPE( Echonest::ArtistInformation )
Q_DECLARE_METATYPE( Echonest::SongInformation )
#endif

View File

@ -1,139 +0,0 @@
/****************************************************************************************
* 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 "Util.h"
#include <QString>
QByteArray Echonest::escapeSpacesAndPluses(const QString& in)
{
// Echonest wants " " treated as "+", so we force QUrl to encode spaces as +es rather than %20
QByteArray escaped = QUrl::toPercentEncoding( in, " " );
escaped.replace( " ", "+" );
return escaped;
}
Echonest::Analysis::AnalysisStatus Echonest::statusToEnum(const QString& status)
{
if( status == QLatin1String("unknown") ) {
return Echonest::Analysis::Unknown;
} else if( status == QLatin1String("pending") ) {
return Echonest::Analysis::Pending;
} else if( status == QLatin1String("complete") ) {
return Echonest::Analysis::Complete;
} else if( status == QLatin1String("error" )) {
return Echonest::Analysis::Error;
}
return Echonest::Analysis::Unknown;
}
QString Echonest::statusToString(Echonest::Analysis::AnalysisStatus status)
{
switch( status )
{
case Echonest::Analysis::Unknown:
return QLatin1String( "unknown" );
case Echonest::Analysis::Pending:
return QLatin1String( "pending" );
case Echonest::Analysis::Complete:
return QLatin1String( "complete" );
case Echonest::Analysis::Error:
return QLatin1String( "error" );
}
return QString();
}
QByteArray Echonest::catalogTypeToLiteral(Echonest::CatalogTypes::Type type)
{
switch( type )
{
case Echonest::CatalogTypes::Artist:
return "artist";
case Echonest::CatalogTypes::Song:
return "song";
default:
return "";
}
}
Echonest::CatalogTypes::Type Echonest::literalToCatalogType( const QByteArray& type )
{
if( type == "artist" )
return Echonest::CatalogTypes::Artist;
else if( type == "song" )
return Echonest::CatalogTypes::Song;
else
return Echonest::CatalogTypes::Artist;
}
QByteArray Echonest::catalogStatusToLiteral(Echonest::CatalogTypes::TicketStatus status)
{
return statusToString( static_cast<Echonest::Analysis::AnalysisStatus>( status ) ).toLatin1();
}
Echonest::CatalogTypes::TicketStatus Echonest::literalToCatalogStatus(const QByteArray& type)
{
return static_cast<Echonest::CatalogTypes::TicketStatus>( statusToEnum( QLatin1String( type ) ) );
}
/**
* Delete,
U pda*te,
Play,
Skip */
QByteArray Echonest::catalogUpdateActionToLiteral(Echonest::CatalogTypes::Action action)
{
switch( action )
{
case Echonest::CatalogTypes::Delete:
return "delete";
case Echonest::CatalogTypes::Play:
return "play";
case Echonest::CatalogTypes::Update:
return "update";
case Echonest::CatalogTypes::Skip:
return "skip";
default:
return "";
}
}
Echonest::CatalogTypes::Action Echonest::literalToCatalogUpdateAction(const QByteArray& type)
{
if( type == "delete" )
return Echonest::CatalogTypes::Delete;
else if( type == "play" )
return Echonest::CatalogTypes::Play;
else if( type == "update" )
return Echonest::CatalogTypes::Update;
else if( type == "skip" )
return Echonest::CatalogTypes::Skip;
return Echonest::CatalogTypes::Update;
}
QDebug Echonest::operator<<(QDebug d, const Echonest::ForeignId& id)
{
return d.maybeSpace() << QString::fromLatin1( "Foreign Id(%1, %2)" ).arg( id.catalog ).arg( id.foreign_id );
}
QDebug Echonest::operator<<(QDebug d, const Echonest::ArtistLocation& loc)
{
return d.maybeSpace() << QString::fromLatin1( "Artist Location(%1, %2, %3)" ).arg( loc.location ).arg( loc.latitude ).arg( loc.longitude );
}

View File

@ -1,132 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_UTIL_H
#define ECHONEST_UTIL_H
#include "echonest_export.h"
#include <QDebug>
#include <QVector>
#include <QUrl>
/**
* Some shared declarations
*/
namespace Echonest
{
namespace Analysis
{
enum AnalysisStatus {
Unknown = 0,
Pending = 1,
Complete = 2,
Error = 4
};
}
namespace CatalogTypes
{
enum Type {
Artist = 0,
Song = 1
};
enum Action {
Delete,
Update,
Play,
Skip
};
enum TicketStatus {
Unknown = 0,
Pending = 1,
Complete = 2,
Error = 4
};
}
typedef struct
{
qreal confidence;
qreal duration;
qreal start;
} AudioChunk;
typedef AudioChunk Bar;
typedef AudioChunk Beat;
typedef AudioChunk Section;
typedef AudioChunk Tatum;
typedef struct
{
qreal confidence;
qreal duration;
qreal loudness_max;
qreal loudness_max_time;
qreal loudness_start;
QVector< qreal > pitches;
qreal start;
QVector< qreal > timbre;
} Segment;
typedef QVector< Bar > BarList;
typedef QVector< Beat > BeatList;
typedef QVector< Section > SectionList;
typedef QVector< Tatum > TatumList;
typedef QVector< Segment > SegmentList;
typedef struct {
QUrl url;
QString attribution;
QString type;
} License;
typedef struct {
QString catalog;
QString foreign_id;
} ForeignId;
typedef struct {
qreal latitude;
qreal longitude;
QString location;
} ArtistLocation;
typedef QVector< ForeignId > ForeignIds;
QByteArray escapeSpacesAndPluses( const QString& in );
Analysis::AnalysisStatus statusToEnum( const QString& status );
QString statusToString( Analysis::AnalysisStatus status );
QByteArray catalogTypeToLiteral( CatalogTypes::Type );
CatalogTypes::Type literalToCatalogType( const QByteArray& type );
QByteArray catalogStatusToLiteral( CatalogTypes::TicketStatus );
CatalogTypes::TicketStatus literalToCatalogStatus( const QByteArray& type );
QByteArray catalogUpdateActionToLiteral( CatalogTypes::Action );
CatalogTypes::Action literalToCatalogUpdateAction( const QByteArray& type );
ECHONEST_EXPORT QDebug operator<<(QDebug d, const ForeignId& id);
ECHONEST_EXPORT QDebug operator<<(QDebug d, const ArtistLocation& id);
}
#endif

View File

@ -1,28 +0,0 @@
/****************************************************************************************
* 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/>. *
****************************************************************************************/
#ifndef ECHONEST_EXPORT_H
#define ECHONEST_EXPORT_H
#ifdef _WIN32
#define ECHONEST_EXPORT __declspec(dllexport)
#elif __GNUC__ >= 4
#define ECHONEST_EXPORT __attribute__ ((visibility("default")))
#else
#define ECHONEST_EXPORT
#endif
#endif

View File

@ -358,14 +358,8 @@ else (USE_SYSTEM_QXT)
endif (NOT APPLE)
endif (USE_SYSTEM_QXT)
# Use system libechonest if it's available
find_path(ECHONEST_INCLUDE_DIRS echonest/echonest_export.h)
find_library(ECHONEST_LIBRARIES echonest)
if(NOT ECHONEST_INCLUDE_DIRS OR NOT ECHONEST_LIBRARIES)
add_subdirectory(3rdparty/libechonest)
set(ECHONEST_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/3rdparty/libechonest)
set(ECHONEST_LIBRARIES echonest)
endif(NOT ECHONEST_INCLUDE_DIRS OR NOT ECHONEST_LIBRARIES)
# Use system gmock if it's available
# We need to look for both gmock and gtest

1
debian/control vendored
View File

@ -15,6 +15,7 @@ Build-Depends: debhelper (>= 7),
libboost-serialization-dev,
libcdio-cdda1,
libchromaprint-dev,
libechonest-dev,
libglew1.5-dev |
libglew-dev,
libqt4-dev,

View File

@ -14,7 +14,7 @@ BuildRequires: qt4-devel boost-devel gcc-c++ glew-devel libgpod-devel
BuildRequires: cmake gstreamer1-devel gstreamer1-plugins-base-devel
BuildRequires: libmtp-devel protobuf-devel protobuf-compiler libcdio-devel
BuildRequires: qjson-devel qca2-devel fftw-devel sparsehash-devel
BuildRequires: sqlite-devel pulseaudio-libs-devel
BuildRequires: sqlite-devel pulseaudio-libs-devel libechonest-devel
Requires: libgpod protobuf-lite libcdio qjson qca-ossl sqlite