From 228cab7080a66853adb763c3454908e99dbcd1ca Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sat, 4 Dec 2010 16:52:26 -0500 Subject: [PATCH] add echonest generator beginnings --- src/dynamic/echonest/echonestcontrol.cpp | 86 +++++++++++++++++++ src/dynamic/echonest/echonestcontrol.h | 59 +++++++++++++ src/dynamic/echonest/echonestgenerator.cpp | 99 ++++++++++++++++++++++ src/dynamic/echonest/echonestgenerator.h | 55 ++++++++++++ 4 files changed, 299 insertions(+) create mode 100644 src/dynamic/echonest/echonestcontrol.cpp create mode 100644 src/dynamic/echonest/echonestcontrol.h create mode 100644 src/dynamic/echonest/echonestgenerator.cpp create mode 100644 src/dynamic/echonest/echonestgenerator.h diff --git a/src/dynamic/echonest/echonestcontrol.cpp b/src/dynamic/echonest/echonestcontrol.cpp new file mode 100644 index 000000000..0fb56b058 --- /dev/null +++ b/src/dynamic/echonest/echonestcontrol.cpp @@ -0,0 +1,86 @@ +/**************************************************************************************** + * Copyright (c) 2010 Leo Franchi * + * * + * 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 . * + ****************************************************************************************/ + +#include "echonest/echonestcontrol.h" + +#include + +#include +#include + + +Tomahawk::EchonestControl::EchonestControl( const QString& type, const QStringList& typeSelectors, QObject* parent ) + : DynamicControl ( type, typeSelectors, parent ) +{ + updateWidgets(); +} + +QWidget* +Tomahawk::EchonestControl::inputField() +{ + return m_input.data(); +} + +QWidget* +Tomahawk::EchonestControl::matchSelector() +{ + return m_match.data(); +} + +void +Tomahawk::EchonestControl::setSelectedType ( const QString& type ) +{ + Tomahawk::DynamicControl::setSelectedType ( type ); +} + +Echonest::DynamicPlaylist::PlaylistParamData +Tomahawk::EchonestControl::toENParam() const +{ + return m_data; +} + +void +Tomahawk::EchonestControl::updateWidgets() +{ + // make sure the widgets are the proper kind for the selected type, and hook up to their slots + if( selectedType() == "Artist" ) { + QComboBox* match = new QComboBox(); + QLineEdit* input = new QLineEdit(); + + match->addItem( "Limit To", Echonest::DynamicPlaylist::ArtistType ); + match->addItem( "Similar To", Echonest::DynamicPlaylist::ArtistRadioType ); + + input->setPlaceholderText( "Artist name" ); + + connect( match, SIGNAL( currentIndexChanged(int) ), this, SLOT( updateData() ) ); + connect( input, SIGNAL( textChanged(QString) ), this, SLOT( updateData() ) ); + + m_match = QWeakPointer< QWidget >( match ); + m_input = QWeakPointer< QWidget >( input ); + } +} + +void Tomahawk::EchonestControl::updateData() +{ + if( selectedType() == "Artist" ) { + QWeakPointer combo = qWeakPointerCast( m_match ); + if( !combo.isNull() ) + m_data.first = static_cast( combo.data()->itemData( combo->currentIndex() ) ); + QWeakPointer edit = qWeakPointerCast( m_input ); + if( !edit.isNull() ) + m_data.second = qWeakPointerCast->text(); + } +} diff --git a/src/dynamic/echonest/echonestcontrol.h b/src/dynamic/echonest/echonestcontrol.h new file mode 100644 index 000000000..f68e51b87 --- /dev/null +++ b/src/dynamic/echonest/echonestcontrol.h @@ -0,0 +1,59 @@ +/**************************************************************************************** + * Copyright (c) 2010 Leo Franchi * + * * + * 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 . * + ****************************************************************************************/ + +#ifndef ECHONEST_CONTROL_H +#define ECHONEST_CONTROL_H + +#include + +#include "dynamic/dynamiccontrol.h" + +namespace Tomahawk +{ + +class EchonestControl : public DynamicControl +{ + Q_OBJECT +public: + virtual QWidget* inputField(); + virtual QWidget* matchSelector(); + + /// Converts this to an echonest suitable parameter + Echonest::DynamicPlaylist::PlaylistParamData toENParam() const; + +public slots: + virtual void setSelectedType ( const QString& type ); + +protected: + explicit EchonestControl( const QString& type, const QStringList& typeSelectors, QObject* parent = 0 ); + +private slots: + void updateData(); + +private: + void updateWidgets(); + + QWeakPointer< QWidget > m_input; + QWeakPointer< QWidget > m_match; + + Echonest::DynamicPlaylist::PlaylistParamData m_data; +}; + +typedef QSharedPointer encontrol_ptr; + +}; + +#endif diff --git a/src/dynamic/echonest/echonestgenerator.cpp b/src/dynamic/echonest/echonestgenerator.cpp new file mode 100644 index 000000000..bc2ce455a --- /dev/null +++ b/src/dynamic/echonest/echonestgenerator.cpp @@ -0,0 +1,99 @@ +/**************************************************************************************** + * Copyright (c) 2010 Leo Franchi * + * * + * 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 . * + ****************************************************************************************/ + +#include "echonest/echonestgenerator.h" +#include "echonest/echonestcontrol.h" +#include "query.h" + +using namespace Tomahawk; + + +EchonestFactory::GeneratorFactoryInterface() +{} + +GeneratorInterface* +EchonestFactory::create() +{ + return new EchonestGenerator(); +} + +EchonestGenerator::EchonestGenerator ( QObject* parent ) + : GeneratorInterface ( parent ) + , m_type( "echonest" ) + , m_mode( OnDemand ) +{ + m_typeSelectors << "Variety" << "Artist" << "Description" << "Tempo" << "Duration" << "Loudness" + << "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Familiarity" + << "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting"; + +} + +EchonestGenerator::~EchonestGenerator() +{ + +} + +dyncontrol_ptr +EchonestGenerator::createControl( const QString& type ) const +{ + return dyncontrol_ptr( new EchonestControl( type, m_typeSelectors ) ); +} + +void +EchonestGenerator::generate ( int number ) +{ + // convert to an echonest query, and fire it off + if( number < 0 ) { // dynamic + + } else { // static + Echonest::DynamicPlaylist::PlaylistParams params; + foreach( const dyncontrol_ptr& control, m_controls ) + params.append( control.dynamicCast()->toENParam() ); + + QNetworkReply* reply = Echonest::DynamicPlaylist::staticPlaylist( params ); + connect( reply, SIGNAL( finished() ), this, SLOT( staticFinished() ) ); + } +} + +void +EchonestGenerator::staticFinished() +{ + Q_ASSERT( sender() ); + Q_ASSERT( qobject_cast< QNetworkReply* >( sender() ) ); + + QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() ); + + Echonest::SongList songs; + try { + songs = Echonest::DynamicPlaylist::parseStaticPlaylist( reply ); + } catch( const Echonest::ParseError& e ) { + qWarning() << "libechonest threw an error trying to parse the static playlist!" << e.errorType() << e.what(); + + return; + } + + QList< query_ptr > queries; + foreach( const Echonest::Song& song, songs ) { + qDebug() << "EchonestGenerator got song:" << song; + QVariantMap track; + track[ "artist" ] = song.artistName(); +// track[ "album" ] = song.release(); // TODO should we include it? can be quite specific + track[ "track" ] = song.title(); + queries << query_ptr( new Query( track ) ); + } + + emit generated( queries ); +} diff --git a/src/dynamic/echonest/echonestgenerator.h b/src/dynamic/echonest/echonestgenerator.h new file mode 100644 index 000000000..aef705558 --- /dev/null +++ b/src/dynamic/echonest/echonestgenerator.h @@ -0,0 +1,55 @@ +/**************************************************************************************** + * Copyright (c) 2010 Leo Franchi * + * * + * 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 . * + ****************************************************************************************/ + +#ifndef ECHONEST_GENERATOR_H +#define ECHONEST_GENERATOR_H + +#include + +#include "dynamic/generatorinterface.h" +#include "dynamic/generatorfactory.h" + + +namespace Tomahawk +{ + +class EchonestFactory : public GeneratorFactoryInterface +{ +public: + EchonestFactory(); + + virtual GeneratorInterface* create(); + +}; + +class EchonestGenerator : public GeneratorInterface +{ + Q_OBJECT +public: + explicit EchonestGenerator( QObject* parent ); + virtual ~EchonestGenerator(); + + virtual dyncontrol_ptr createControl( const QString& type = QString() ) const; + + virtual void generate ( int number = -1 ); + +private slots: + void staticFinished(); +}; + +}; + +#endif