mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-25 01:02:37 +01:00
281 lines
13 KiB
C++
281 lines
13 KiB
C++
/****************************************************************************************
|
|
* Copyright (c) 2010 Leo Franchi <lfranchi@kde.org> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify it under *
|
|
* the terms of the GNU General Public License as published by the Free Software *
|
|
* Foundation; either version 2 of the License, or (at your option) any later *
|
|
* version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
|
|
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License along with *
|
|
* this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
****************************************************************************************/
|
|
|
|
|
|
#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
|