1 /****************************************************************************************
2  * Copyright (c) 2010-2012 Leo Franchi <lfranchi@kde.org>                               *
3  *                                                                                      *
4  * This program is free software; you can redistribute it and/or modify it under        *
5  * the terms of the GNU General Public License as published by the Free Software        *
6  * Foundation; either version 2 of the License, or (at your option) any later           *
7  * version.                                                                             *
8  *                                                                                      *
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
11  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
12  *                                                                                      *
13  * You should have received a copy of the GNU General Public License along with         *
14  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
15  ****************************************************************************************/
16 
17 #include "Playlist.h"
18 #include "Playlist_p.h"
19 #include "Parsing_p.h"
20 
21 #include <QNetworkReply>
22 
DynamicPlaylist()23 Echonest::DynamicPlaylist::DynamicPlaylist()
24     : d( new DynamicPlaylistData )
25 {
26 
27 }
28 
DynamicPlaylist(const Echonest::DynamicPlaylist & other)29 Echonest::DynamicPlaylist::DynamicPlaylist(const Echonest::DynamicPlaylist& other)
30     : d( other.d )
31 {
32 
33 }
34 
~DynamicPlaylist()35 Echonest::DynamicPlaylist::~DynamicPlaylist()
36 {
37 
38 }
39 
40 
operator =(const Echonest::DynamicPlaylist & playlist)41 Echonest::DynamicPlaylist& Echonest::DynamicPlaylist::operator=(const Echonest::DynamicPlaylist& playlist)
42 {
43     d = playlist.d;
44     return *this;
45 }
46 
create(const Echonest::DynamicPlaylist::PlaylistParams & params) const47 QNetworkReply* Echonest::DynamicPlaylist::create(const Echonest::DynamicPlaylist::PlaylistParams& params) const
48 {
49     // params are the same, if user passes in format parsing will throw, but it should be expected..
50     return generateInternal( params, "dynamic/create" );
51 }
52 
parseCreate(QNetworkReply * reply)53 void Echonest::DynamicPlaylist::parseCreate(QNetworkReply* reply) throw( Echonest::ParseError )
54 {
55     Echonest::Parser::checkForErrors( reply );
56     QByteArray data = reply->readAll();
57 //     qDebug() << data;
58     QXmlStreamReader xml( data );
59 
60     Echonest::Parser::readStatus( xml );
61     d->sessionId = Echonest::Parser::parsePlaylistSessionId( xml );
62 
63 
64     Q_ASSERT( !d->sessionId.isEmpty() );
65 }
66 
restart(const Echonest::DynamicPlaylist::PlaylistParams & params) const67 QNetworkReply* Echonest::DynamicPlaylist::restart(const Echonest::DynamicPlaylist::PlaylistParams& params) const
68 {
69     return generateInternal( params, "dynamic/restart" );
70 }
71 
sessionId() const72 QByteArray Echonest::DynamicPlaylist::sessionId() const
73 {
74     return d->sessionId;
75 }
76 
setSessionId(const QByteArray & id)77 void Echonest::DynamicPlaylist::setSessionId(const QByteArray& id)
78 {
79     d->sessionId = id;
80 }
81 
currentSong() const82 Echonest::Song Echonest::DynamicPlaylist::currentSong() const
83 {
84     return d->currentSong;
85 }
86 
setCurrentSong(const Echonest::Song & song)87 void Echonest::DynamicPlaylist::setCurrentSong(const Echonest::Song& song)
88 {
89     d->currentSong = song;
90 }
91 
next(int results,int lookahead) const92 QNetworkReply* Echonest::DynamicPlaylist::next( int results, int lookahead ) const
93 {
94     QUrl url = Echonest::baseGetQuery( "playlist/dynamic", "next" );
95 
96     urlAddQueryItem( url,  QLatin1String( "session_id" ), QString::fromLatin1( d->sessionId ) );
97     urlAddQueryItem( url,  QLatin1String( "results" ), QString::number( results ) );
98     urlAddQueryItem( url,  QLatin1String( "lookahead" ), QString::number( lookahead ) );
99 
100     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
101 }
102 
fetchInfo() const103 QNetworkReply* Echonest::DynamicPlaylist::fetchInfo() const
104 {
105     QUrl url = Echonest::baseGetQuery( "playlist/dynamic", "info" );
106 
107     urlAddQueryItem( url, QLatin1String( "session_id" ), QString::fromLatin1( d->sessionId ) );
108 
109     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
110 }
111 
112 
parseNext(QNetworkReply * reply)113 Echonest::DynamicPlaylist::FetchPair Echonest::DynamicPlaylist::parseNext(QNetworkReply* reply) throw( Echonest::ParseError )
114 {
115     Echonest::Parser::checkForErrors( reply );
116 
117 //     const QByteArray data = reply->readAll();
118 //     qDebug() << data;
119     QXmlStreamReader xml( reply->readAll() );
120 
121     Echonest::Parser::readStatus( xml );
122 
123     Echonest::SongList lookahead = Echonest::Parser::parseDynamicLookahead( xml );
124     Echonest::SongList results = Echonest::Parser::parseSongList( xml );
125 
126     reply->deleteLater();
127 
128     return qMakePair(results, lookahead);
129 }
130 
feedback(const Echonest::DynamicPlaylist::DynamicFeedback & feedback) const131 QNetworkReply* Echonest::DynamicPlaylist::feedback(const Echonest::DynamicPlaylist::DynamicFeedback& feedback) const
132 {
133     QUrl url = Echonest::baseGetQuery( "playlist/dynamic", "feedback" );
134 
135     urlAddQueryItem( url, QLatin1String( "session_id" ), QString::fromLatin1( d->sessionId ) );
136 
137     foreach( const Echonest::DynamicPlaylist::DynamicFeedbackParamData& param, feedback ) {
138         urlAddQueryItem( url, QString::fromLatin1( dynamicFeedbackToString(param.first) ), QString::fromLatin1( param.second ) );
139     }
140 
141     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
142 }
143 
parseFeedback(QNetworkReply * reply) const144 void Echonest::DynamicPlaylist::parseFeedback(QNetworkReply* reply) const throw( Echonest::ParseError )
145 {
146     Echonest::Parser::checkForErrors( reply );
147 
148     QXmlStreamReader xml( reply->readAll() );
149 
150     Echonest::Parser::readStatus( xml );
151 
152     reply->deleteLater();
153 }
154 
steer(const Echonest::DynamicPlaylist::PlaylistParams & steerParams) const155 QNetworkReply* Echonest::DynamicPlaylist::steer(const Echonest::DynamicPlaylist::PlaylistParams& steerParams) const
156 {
157     QUrl url = Echonest::baseGetQuery( "playlist/dynamic", "steer" );
158 
159     urlAddQueryItem( url, QLatin1String( "session_id" ), QString::fromLatin1( d->sessionId ) );
160 
161     foreach( const Echonest::DynamicPlaylist::PlaylistParamData& param, steerParams ) {
162         // HACK ARG min/max functions for steering are min_foo_bar, but params for static/initial seeds are foo_min_bar. can't reuse :(
163         QByteArray str;
164         switch ( param.first )
165         {
166             case Echonest::DynamicPlaylist::ArtistMinFamiliarity:
167                 str = "min_artist_familiarity";
168                 break;
169             case Echonest::DynamicPlaylist::ArtistMaxFamiliarity:
170                 str = "max_artist_familiarity";
171                 break;
172             case Echonest::DynamicPlaylist::ArtistMinHotttnesss:
173                 str = "min_artist_hotttnesss";
174                 break;
175             case Echonest::DynamicPlaylist::ArtistMaxHotttnesss:
176                 str = "max_artist_hotttnesss";
177                 break;
178             case Echonest::DynamicPlaylist::SongMinHotttnesss:
179                 str = "min_song_hotttnesss";
180                 break;
181             case Echonest::DynamicPlaylist::SongMaxHotttnesss:
182                 str = "max_song_hotttnesss";
183                 break;
184             case Echonest::DynamicPlaylist::MinEnergy:
185                 str = "min_energy";
186                 break;
187             case Echonest::DynamicPlaylist::MaxEnergy:
188                 str = "max_energy";
189                 break;
190             case Echonest::DynamicPlaylist::MinDanceability:
191                 str = "min_danceability";
192                 break;
193             case Echonest::DynamicPlaylist::MaxDanceability:
194                 str = "max_danceability";
195                 break;
196             case Echonest::DynamicPlaylist::MinLoudness:
197                 str = "min_loudness";
198                 break;
199             case Echonest::DynamicPlaylist::MaxLoudness:
200                 str = "max_loudness";
201                 break;
202             case Echonest::DynamicPlaylist::MinTempo:
203                 str = "min_tempo";
204                 break;
205             case Echonest::DynamicPlaylist::MaxTempo:
206                 str = "max_tempo";
207                 break;
208             default:
209                 str = playlistParamToString( param.first );
210         }
211         urlAddQueryItem( url, QString::fromLatin1( str ), param.second.toString());
212     }
213 
214     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
215 }
216 
parseSteer(QNetworkReply * reply) const217 void Echonest::DynamicPlaylist::parseSteer(QNetworkReply* reply) const throw( Echonest::ParseError )
218 {
219     Echonest::Parser::checkForErrors( reply );
220 
221     QXmlStreamReader xml( reply->readAll() );
222 
223     Echonest::Parser::readStatus( xml );
224 
225     reply->deleteLater();
226 }
227 
parseInfo(QNetworkReply * reply)228 Echonest::SessionInfo Echonest::DynamicPlaylist::parseInfo(QNetworkReply* reply) throw( Echonest::ParseError )
229 {
230     Echonest::Parser::checkForErrors( reply );
231 
232     QXmlStreamReader xml( reply->readAll() );
233 
234     Echonest::Parser::readStatus( xml );
235 
236     reply->deleteLater();
237     return Echonest::Parser::parseSessionInfo( xml );
238 
239 }
240 
deleteSession() const241 QNetworkReply* Echonest::DynamicPlaylist::deleteSession() const
242 {
243     QUrl url = Echonest::baseGetQuery( "playlist/dynamic", "delete" );
244 
245     urlAddQueryItem( url, QLatin1String( "session_id" ), QString::fromLatin1( d->sessionId ) );
246 
247     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
248 }
249 
parseDeleteSession(QNetworkReply * reply)250 void Echonest::DynamicPlaylist::parseDeleteSession(QNetworkReply* reply)
251 {
252     Echonest::Parser::checkForErrors( reply );
253 
254     QXmlStreamReader xml( reply->readAll() );
255 
256     Echonest::Parser::readStatus( xml );
257 
258     d->sessionId.clear();
259 
260     reply->deleteLater();
261 }
262 
staticPlaylist(const Echonest::DynamicPlaylist::PlaylistParams & params)263 QNetworkReply* Echonest::DynamicPlaylist::staticPlaylist(const Echonest::DynamicPlaylist::PlaylistParams& params)
264 {
265     return Echonest::DynamicPlaylist::generateInternal( params, "static" );
266 }
267 
parseStaticPlaylist(QNetworkReply * reply)268 Echonest::SongList Echonest::DynamicPlaylist::parseStaticPlaylist(QNetworkReply* reply) throw( Echonest::ParseError )
269 {
270     Echonest::Parser::checkForErrors( reply );
271 
272     QXmlStreamReader xml( reply->readAll() );
273 
274     Echonest::Parser::readStatus( xml );
275 
276     Echonest::SongList songs = Echonest::Parser::parseSongList( xml );
277     reply->deleteLater();
278     return songs;
279 }
280 
parseXSPFPlaylist(QNetworkReply * reply)281 QByteArray Echonest::DynamicPlaylist::parseXSPFPlaylist(QNetworkReply* reply) throw( Echonest::ParseError )
282 {
283     QByteArray data = reply->readAll();
284     Echonest::Parser::checkForErrors( reply );
285 
286     reply->deleteLater();
287     return data;
288 }
289 
generateInternal(const Echonest::DynamicPlaylist::PlaylistParams & params,const QByteArray & type)290 QNetworkReply* Echonest::DynamicPlaylist::generateInternal(const Echonest::DynamicPlaylist::PlaylistParams& params, const QByteArray& type)
291 {
292     QUrl url = Echonest::baseGetQuery( "playlist", type );
293 
294 
295     Echonest::DynamicPlaylist::PlaylistParams::const_iterator iter = params.constBegin();
296     for( ; iter < params.constEnd(); ++iter ) {
297         if( iter->first == Format ) // If it's a format, we have to remove the xml format we automatically specify
298             urlRemoveQueryItem( url, QString::fromLatin1( "format" ) );
299 
300         if( iter->first == Type ) { // convert type enum to string
301             switch( static_cast<Echonest::DynamicPlaylist::ArtistTypeEnum>( iter->second.toInt() ) )
302             {
303             case ArtistType:
304                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "artist" ) );
305                 break;
306             case ArtistRadioType:
307                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "artist-radio" ) );
308                 break;
309             case ArtistDescriptionType:
310                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "artist-description" ) );
311                 break;
312             case CatalogType:
313                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "catalog" ) );
314                 break;
315             case CatalogRadioType:
316                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "catalog-radio" ) );
317                 break;
318             case SongRadioType:
319                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "song-radio" ) );
320                 break;
321             case GenreRadioType:
322                 urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QLatin1String( "genre-radio" ) );
323                 break;
324             }
325 
326         } else if( iter->first == Sort ) {
327             urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QString::fromLatin1( playlistSortToString( static_cast<Echonest::DynamicPlaylist::SortingType>( iter->second.toInt() ) ) ) );
328         } else if( iter->first == Pick ) {
329             urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QString::fromLatin1( playlistArtistPickToString( static_cast<Echonest::DynamicPlaylist::ArtistPick>( iter->second.toInt() ) ) ) );
330         } else if( iter->first == SongInformation ) {
331             Echonest::Song::addQueryInformation( url, Echonest::SongInformation( iter->second.value< Echonest::SongInformation >() ) );
332         } else if ( iter->first == GenrePreset ) {
333             urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QString::fromLatin1( playlistGenrePresetToString( static_cast<Echonest::DynamicPlaylist::GenrePresetParam>( iter->second.toInt() ) ) ) );
334         } else {
335             urlAddQueryItem( url, QString::fromLatin1( playlistParamToString( iter->first ) ), QString::fromLatin1( Echonest::escapeSpacesAndPluses( iter->second.toString() ) ) );
336         }
337     }
338 
339     return Echonest::Config::instance()->nam()->get( QNetworkRequest( url ) );
340 }
341 
342 
playlistParamToString(Echonest::DynamicPlaylist::PlaylistParam param)343 QByteArray Echonest::DynamicPlaylist::playlistParamToString(Echonest::DynamicPlaylist::PlaylistParam param)
344 {
345     switch( param )
346     {
347         case Echonest::DynamicPlaylist::Type :
348             return "type";
349         case Echonest::DynamicPlaylist::Format :
350             return "format";
351         case Echonest::DynamicPlaylist::Pick:
352             return "artist_pick";
353         case Echonest::DynamicPlaylist::Variety :
354             return "variety";
355         case Echonest::DynamicPlaylist::ArtistId :
356             return "artist_id";
357         case Echonest::DynamicPlaylist::Artist :
358             return "artist";
359         case Echonest::DynamicPlaylist::ArtistSeedCatalog :
360             return "artist_seed_catalog";
361         case Echonest::DynamicPlaylist::SourceCatalog :
362             return "seed_catalog";
363         case Echonest::DynamicPlaylist::SongId :
364             return "song_id";
365         case Echonest::DynamicPlaylist::Description :
366             return "description";
367         case Echonest::DynamicPlaylist::Results :
368             return "results";
369         case Echonest::DynamicPlaylist::MaxTempo :
370             return "max_tempo";
371         case Echonest::DynamicPlaylist::MinTempo :
372             return "min_tempo";
373         case Echonest::DynamicPlaylist::MaxDuration :
374             return "max_duration";
375         case Echonest::DynamicPlaylist::MinDuration :
376             return "min_duration";
377         case Echonest::DynamicPlaylist::MaxLoudness :
378             return "max_loudness";
379         case Echonest::DynamicPlaylist::MinLoudness :
380             return "min_loudness";
381         case Echonest::DynamicPlaylist::ArtistMaxFamiliarity :
382             return "artist_max_familiarity";
383         case Echonest::DynamicPlaylist::ArtistMinFamiliarity :
384             return "artist_min_familiarity";
385         case Echonest::DynamicPlaylist::MinDanceability :
386             return "min_danceability";
387         case Echonest::DynamicPlaylist::MaxDanceability :
388             return "max_danceability";
389         case Echonest::DynamicPlaylist::MinEnergy :
390             return "min_energy";
391         case Echonest::DynamicPlaylist::MaxEnergy :
392             return "max_energy";
393         case Echonest::DynamicPlaylist::ArtistMaxHotttnesss :
394             return "artist_max_hotttnesss";
395         case Echonest::DynamicPlaylist::ArtistMinHotttnesss :
396             return "artist_min_hotttnesss";
397         case Echonest::DynamicPlaylist::SongMaxHotttnesss :
398             return "song_max_hotttnesss";
399         case Echonest::DynamicPlaylist::SongMinHotttnesss :
400             return "song_min_hotttnesss";
401         case Echonest::DynamicPlaylist::ArtistMinLongitude :
402             return "min_longitude";
403         case Echonest::DynamicPlaylist::ArtistMaxLongitude :
404             return "max_longitude";
405         case Echonest::DynamicPlaylist::ArtistMinLatitude  :
406             return "min_latitude";
407         case Echonest::DynamicPlaylist::ArtistMaxLatitude :
408             return "max_latitude";
409         case Echonest::DynamicPlaylist::Mode :
410             return "mode";
411         case Echonest::DynamicPlaylist::Key :
412             return "key";
413         case Echonest::DynamicPlaylist::SongInformation:
414             return "bucket";
415         case Echonest::DynamicPlaylist::Sort :
416             return "sort";
417         case Echonest::DynamicPlaylist::Limit :
418             return "limit";
419         case Echonest::DynamicPlaylist::Audio :
420             return "audio";
421         case Echonest::DynamicPlaylist::DMCA :
422             return "dmca";
423         case Echonest::DynamicPlaylist::ChainXSPF :
424             return "chain_xspf";
425         case Echonest::DynamicPlaylist::Mood :
426             return "mood";
427         case Echonest::DynamicPlaylist::Style :
428             return "style";
429         case Echonest::DynamicPlaylist::Adventurousness :
430             return "adventurousness";
431         case Echonest::DynamicPlaylist::MoreLikeThis :
432             return "more_like_this";
433         case Echonest::DynamicPlaylist::LessLikeThis :
434             return "less_like_this";
435         case Echonest::DynamicPlaylist::TargetTempo :
436             return "target_tempo";
437         case Echonest::DynamicPlaylist::TargetDanceability :
438             return "target_danceability";
439         case Echonest::DynamicPlaylist::TargetEnergy :
440             return "target_energy";
441         case Echonest::DynamicPlaylist::TargetLoudness :
442             return "target_loudness";
443         case Echonest::DynamicPlaylist::TargetArtistFamiliarity :
444             return "target_artist_familiarity";
445         case Echonest::DynamicPlaylist::TargetArtistHotttnesss :
446             return "target_artist_hotttnesss";
447         case Echonest::DynamicPlaylist::TargetSongHotttnesss :
448             return "target_song_hotttnesss";
449         case Echonest::DynamicPlaylist::SongType :
450             return "song_type";
451         case Echonest::DynamicPlaylist::Genre :
452             return "genre";
453         case Echonest::DynamicPlaylist::ArtistStartYearBefore:
454             return "artist_start_year_before";
455         case Echonest::DynamicPlaylist::ArtistStartYearAfter:
456             return "artist_start_year_after";
457         case Echonest::DynamicPlaylist::ArtistEndYearBefore:
458             return "artist_end_year_before";
459         case Echonest::DynamicPlaylist::ArtistEndYearAfter:
460             return "artist_end_year_after";
461         case Echonest::DynamicPlaylist::MaxAcousticness:
462             return "max_accousticness";
463         case Echonest::DynamicPlaylist::MinAcousticness:
464             return "min_accousticness";
465         case Echonest::DynamicPlaylist::MaxSpeechiness:
466             return "max_speechiness";
467         case Echonest::DynamicPlaylist::MinSpeechiness:
468             return "min_speechiness";
469         case Echonest::DynamicPlaylist::MaxLiveness:
470             return "max_liveness";
471         case Echonest::DynamicPlaylist::MinLiveness:
472             return "min_liveness";
473         case Echonest::DynamicPlaylist::MaxValence:
474             return "max_valence";
475         case Echonest::DynamicPlaylist::MinValence:
476             return "min_valence";
477         case Echonest::DynamicPlaylist::Distribution:
478             return "distribution";
479         case Echonest::DynamicPlaylist::GenrePreset:
480             return "genre_preset";
481     }
482     return QByteArray();
483 }
484 
playlistArtistPickToString(Echonest::DynamicPlaylist::ArtistPick pick)485 QByteArray Echonest::DynamicPlaylist::playlistArtistPickToString(Echonest::DynamicPlaylist::ArtistPick pick)
486 {
487     switch( pick )
488     {
489         case PickSongHotttnesssAscending:
490             return "song_hotttnesss-asc";
491         case PickTempoAscending:
492             return "tempo-asc";
493         case PickDurationAscending:
494             return "duration-asc";
495         case PickLoudnessAscending:
496             return "loudness-asc";
497         case PickModeAscending:
498             return "mode-asc";
499         case PickKeyAscending:
500             return "key-asc";
501         case PickSongHotttnesssDescending:
502             return "song_hotttnesss-desc";
503         case PickTempoDescending:
504             return "tempo-desc";
505         case PickDurationDescending:
506             return "duration-desc";
507         case PickLoudnessDescending:
508             return "loudness-desc";
509         case PickModeDescending:
510             return "mode-desc";
511         case PickKeyDescending:
512             return "key-desc";
513     }
514     return QByteArray();
515 }
516 
playlistSortToString(Echonest::DynamicPlaylist::SortingType sorting)517 QByteArray Echonest::DynamicPlaylist::playlistSortToString(Echonest::DynamicPlaylist::SortingType sorting)
518 {
519     switch( sorting )
520     {
521         case SortTempoAscending:
522             return "tempo-asc";
523         case SortTempoDescending:
524             return "tempo-desc";
525         case SortDurationAscending:
526             return "duration-asc";
527         case SortDurationDescending:
528             return "duration-desc";
529         case SortLoudnessAscending:
530             return "loudness-asc";
531         case SortLoudnessDescending:
532             return "loudness-desc";
533         case SortArtistFamiliarityAscending:
534             return "artist_familiarity-asc";
535         case SortArtistFamiliarityDescending:
536             return "artist_familiarity-desc";
537         case SortArtistHotttnessAscending:
538             return "artist_hotttnesss-asc";
539         case SortArtistHotttnessDescending:
540             return "artist_hotttnesss-desc";
541         case SortSongHotttnesssAscending:
542             return "song_hotttnesss-asc";
543         case SortSongHotttnesssDescending:
544             return "song_hotttnesss-desc";
545         case SortLatitudeAscending:
546             return "latitude-asc";
547         case SortLatitudeDescending:
548             return "latitude-desc";
549         case SortLongitudeAscending:
550             return "longitude-asc";
551         case SortLongitudeDescending:
552             return "longitude-desc";
553         case SortModeAscending:
554             return "mode-asc";
555         case SortModeDescending:
556             return "mode-desc";
557         case SortKeyAscending:
558             return "key-asc";
559         case SortKeyDescending:
560             return "key-desc";
561         case SortEnergyAscending:
562             return "energy-asc";
563         case SortEnergyDescending:
564             return "energy-desc";
565         case SortDanceabilityAscending:
566             return "danceability-asc";
567         case SortDanceabilityDescending:
568             return "danceability-desc";
569         case SortAcousticnessAscending:
570             return "acousticness-asc";
571         case SortAcousticnessDescending:
572             return "acousticness-desc";
573         case SortSpeechinessAscending:
574             return "speechiness-asc";
575         case SortSpeechinessDescending:
576             return "speechiness-desc";
577         case SortLivenessAscending:
578             return "liveness-asc";
579         case SortLivenessDescending:
580             return "liveness-desc";
581         case SortValenceAscending:
582             return "valence-asc";
583         case SortValenceDescending:
584             return "valence-desc";
585     }
586     return QByteArray();
587 }
588 
dynamicFeedbackToString(Echonest::DynamicPlaylist::DynamicFeedbackParam param)589 QByteArray Echonest::DynamicPlaylist::dynamicFeedbackToString(Echonest::DynamicPlaylist::DynamicFeedbackParam param)
590 {
591     switch( param )
592     {
593         case BanArtist:
594             return "ban_artist";
595         case FavoriteArtist:
596             return "favorite_artist";
597         case BanSong:
598             return "ban_song";
599         case FavoriteSong:
600             return "favorite_song";
601         case SkipSong:
602             return "skip_song";
603         case PlaySong:
604             return "play_song";
605         case UnplaySong:
606             return "unplay_song";
607         case RateSong:
608             return "rate_song";
609         default:
610             Q_ASSERT(false);
611             return "";
612     }
613 }
614 
playlistGenrePresetToString(Echonest::DynamicPlaylist::GenrePresetParam param)615 QByteArray Echonest::DynamicPlaylist::playlistGenrePresetToString(Echonest::DynamicPlaylist::GenrePresetParam param)
616 {
617     switch( param )
618     {
619         case CoreBest:
620             return "core-best";
621         case CoreShuffled:
622             return "core-shuffled";
623         case EmergingBest:
624             return "emerging-best";
625         case EmerginShuffled:
626             return "emerging-shuffled";
627         default:
628             Q_ASSERT(false);
629             return "";
630     }
631 }
632 
633 
operator <<(QDebug d,const Echonest::DynamicPlaylist & playlist)634 QDebug Echonest::operator<<(QDebug d, const Echonest::DynamicPlaylist& playlist)
635 {
636     d << QString::fromLatin1( "DynamicPlaylist(%1, %2)" ).arg( QLatin1String( playlist.sessionId() ), playlist.currentSong().toString() );
637     return d.maybeSpace();
638 }
639