mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 03:10:12 +02:00
add support for Echo Nest "style" and "mood" parameters to playlists
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include "EchonestGenerator.h"
|
||||
|
||||
|
||||
Tomahawk::EchonestControl::EchonestControl( const QString& selectedType, const QStringList& typeSelectors, QObject* parent )
|
||||
@@ -315,6 +316,31 @@ Tomahawk::EchonestControl::updateWidgets()
|
||||
connect( combo, SIGNAL( activated( int ) ), this, SLOT( updateData() ) );
|
||||
connect( combo, SIGNAL( activated( int ) ), this, SLOT( editingFinished() ) );
|
||||
|
||||
match->hide();
|
||||
combo->hide();
|
||||
m_match = QWeakPointer< QWidget >( match );
|
||||
m_input = QWeakPointer< QWidget >( combo );
|
||||
} else if( selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
if( selectedType() == "Mood" )
|
||||
m_currentType = Echonest::DynamicPlaylist::Mood;
|
||||
else
|
||||
m_currentType = Echonest::DynamicPlaylist::Style;
|
||||
|
||||
QLabel* match = new QLabel( tr( "is" ) );
|
||||
|
||||
QComboBox* combo = new QComboBox;
|
||||
QVector< QString > src = selectedType() == "Mood" ? EchonestGenerator::moods() : EchonestGenerator::styles();
|
||||
foreach( const QString& item, src ) {
|
||||
combo->addItem( item, item );
|
||||
}
|
||||
|
||||
m_matchString = match->text();
|
||||
m_matchData = match->text();
|
||||
|
||||
|
||||
connect( combo, SIGNAL( activated( int ) ), this, SLOT( updateData() ) );
|
||||
connect( combo, SIGNAL( activated( int ) ), this, SLOT( editingFinished() ) );
|
||||
|
||||
match->hide();
|
||||
combo->hide();
|
||||
m_match = QWeakPointer< QWidget >( match );
|
||||
@@ -384,7 +410,7 @@ Tomahawk::EchonestControl::updateData()
|
||||
updateFromComboAndSlider();
|
||||
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
||||
updateFromComboAndSlider( true );
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" ) {
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
updateFromLabelAndCombo();
|
||||
} else if( selectedType() == "Sorting" ) {
|
||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||
@@ -453,7 +479,7 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
|
||||
updateToComboAndSlider();
|
||||
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
||||
updateToComboAndSlider( true );
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" ) {
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
updateToLabelAndCombo();
|
||||
} else if( selectedType() == "Sorting" ) {
|
||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||
@@ -564,6 +590,11 @@ Tomahawk::EchonestControl::calculateSummary()
|
||||
QString ascdesc = qobject_cast< QComboBox* >( m_match.data() )->currentText().toLower();
|
||||
|
||||
summary = QString( "sorted in %1 %2 order" ).arg( ascdesc ).arg( sortType );
|
||||
} else if( selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
Q_ASSERT( !m_input.isNull() );
|
||||
Q_ASSERT( qobject_cast< QComboBox* >( m_input.data() ) );
|
||||
QString text = qobject_cast< QComboBox* >( m_input.data() )->currentText().toLower();
|
||||
summary = QString( "with %1 %2" ).arg( selectedType() == "Mood" ? "mood" : "style" ).arg( text );
|
||||
}
|
||||
m_summary = summary;
|
||||
}
|
||||
|
@@ -24,6 +24,9 @@
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
QVector< QString > EchonestGenerator::s_moods = QVector< QString >();
|
||||
QVector< QString > EchonestGenerator::s_styles = QVector< QString >();
|
||||
|
||||
EchonestFactory::EchonestFactory()
|
||||
{}
|
||||
|
||||
@@ -42,7 +45,7 @@ EchonestFactory::createControl( const QString& controlType )
|
||||
QStringList
|
||||
EchonestFactory::typeSelectors() const
|
||||
{
|
||||
return QStringList() << "Artist" << "Artist Description" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
||||
return QStringList() << "Artist" << "Artist Description" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
||||
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss"
|
||||
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting";
|
||||
}
|
||||
@@ -55,6 +58,14 @@ EchonestGenerator::EchonestGenerator ( QObject* parent )
|
||||
m_type = "echonest";
|
||||
m_mode = OnDemand;
|
||||
m_logo.load( RESPATH "/images/echonest_logo.png" );
|
||||
|
||||
// fetch style and moods
|
||||
QNetworkReply* style = Echonest::Artist::listTerms( "style" );
|
||||
connect( style, SIGNAL( finished() ), this, SLOT( stylesReceived() ) );
|
||||
|
||||
QNetworkReply* moods = Echonest::Artist::listTerms( "mood" );
|
||||
connect( moods, SIGNAL( finished() ), this, SLOT( moodsReceived() ) );
|
||||
|
||||
// qDebug() << "ECHONEST:" << m_logo.size();
|
||||
}
|
||||
|
||||
@@ -408,3 +419,40 @@ EchonestGenerator::sentenceSummary()
|
||||
return sentence;
|
||||
}
|
||||
|
||||
QVector< QString >
|
||||
EchonestGenerator::moods()
|
||||
{
|
||||
return s_moods;
|
||||
}
|
||||
|
||||
void
|
||||
EchonestGenerator::moodsReceived()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try {
|
||||
s_moods = Echonest::Artist::parseTermList( r );
|
||||
} catch( Echonest::ParseError& e ) {
|
||||
qWarning() << "Echonest failed to parse moods list";
|
||||
}
|
||||
}
|
||||
|
||||
QVector< QString >
|
||||
EchonestGenerator::styles()
|
||||
{
|
||||
return s_styles;
|
||||
}
|
||||
|
||||
void
|
||||
EchonestGenerator::stylesReceived()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try {
|
||||
s_styles = Echonest::Artist::parseTermList( r );
|
||||
} catch( Echonest::ParseError& e ) {
|
||||
qWarning() << "Echonest failed to parse styles list";
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
namespace Tomahawk
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class EchonestSteerer;
|
||||
@@ -37,19 +37,19 @@ class DLLEXPORT EchonestFactory : public GeneratorFactoryInterface
|
||||
{
|
||||
public:
|
||||
EchonestFactory();
|
||||
|
||||
|
||||
virtual GeneratorInterface* create();
|
||||
virtual dyncontrol_ptr createControl( const QString& controlType = QString() );
|
||||
virtual QStringList typeSelectors() const;
|
||||
};
|
||||
|
||||
|
||||
class EchonestGenerator : public GeneratorInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EchonestGenerator( QObject* parent = 0 );
|
||||
virtual ~EchonestGenerator();
|
||||
|
||||
|
||||
virtual dyncontrol_ptr createControl( const QString& type = QString() );
|
||||
virtual QPixmap logo();
|
||||
virtual void generate ( int number = -1 );
|
||||
@@ -58,26 +58,34 @@ public:
|
||||
virtual QString sentenceSummary();
|
||||
virtual bool onDemandSteerable() const { return true; }
|
||||
virtual QWidget* steeringWidget();
|
||||
|
||||
|
||||
static QVector< QString > styles();
|
||||
static QVector< QString > moods();
|
||||
private slots:
|
||||
void staticFinished();
|
||||
void dynamicStarted();
|
||||
void dynamicFetched();
|
||||
|
||||
|
||||
// steering controls
|
||||
void steerField( const QString& field );
|
||||
void steerDescription( const QString& desc );
|
||||
void resetSteering();
|
||||
|
||||
|
||||
void stylesReceived();
|
||||
void moodsReceived();
|
||||
|
||||
private:
|
||||
Echonest::DynamicPlaylist::PlaylistParams getParams() const throw( std::runtime_error );
|
||||
query_ptr queryFromSong( const Echonest::Song& song );
|
||||
void appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& params ) const throw( std::runtime_error );
|
||||
bool onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error );
|
||||
|
||||
|
||||
Echonest::DynamicPlaylist* m_dynPlaylist;
|
||||
QPixmap m_logo;
|
||||
|
||||
|
||||
static QVector< QString > s_styles;
|
||||
static QVector< QString > s_moods;
|
||||
|
||||
QWeakPointer<EchonestSteerer> m_steerer;
|
||||
bool m_steeredSinceLastTrack;
|
||||
Echonest::DynamicPlaylist::DynamicControl m_steerData;
|
||||
|
Reference in New Issue
Block a user