mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-06 14:16:32 +02:00
Handle catalogs more gracefully in dynamic playlists
Standardize some code Propertify Misc catalog fixes Clean up by hacking
This commit is contained in:
@@ -369,5 +369,12 @@ EchonestCatalogSynchronizer::trackAttributes( PairList attributes )
|
|||||||
QByteArray
|
QByteArray
|
||||||
EchonestCatalogSynchronizer::escape( const QString &in ) const
|
EchonestCatalogSynchronizer::escape( const QString &in ) const
|
||||||
{
|
{
|
||||||
return QUrl::toPercentEncoding( in );
|
// TODO echonest chokes on some chars in the output. But if we percent-encode those chars it works
|
||||||
|
// We can't percent-encode the whole string, because then any UTF-8 chars that have been url-encoded, fail.
|
||||||
|
// God this sucks. It's going to break...
|
||||||
|
QString clean = in;
|
||||||
|
clean.replace( "&", "%25" );
|
||||||
|
clean.replace( ";", "%3B" );
|
||||||
|
return clean.toUtf8();
|
||||||
|
//return QUrl::toPercentEncoding( in. );
|
||||||
}
|
}
|
||||||
|
@@ -50,6 +50,7 @@ public:
|
|||||||
Echonest::Catalog artistCatalog() const { return m_artistCatalog; }
|
Echonest::Catalog artistCatalog() const { return m_artistCatalog; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void knownCatalogsChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void checkSettingsChanged();
|
void checkSettingsChanged();
|
||||||
@@ -83,6 +84,8 @@ private:
|
|||||||
QQueue< QList< QPair< QID, QString > > > m_queuedTrackInfo;
|
QQueue< QList< QPair< QID, QString > > > m_queuedTrackInfo;
|
||||||
|
|
||||||
static EchonestCatalogSynchronizer* s_instance;
|
static EchonestCatalogSynchronizer* s_instance;
|
||||||
|
|
||||||
|
friend class ::DatabaseCommand_SetCollectionAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "network/servent.h"
|
#include "network/servent.h"
|
||||||
#include "sourcelist.h"
|
#include "sourcelist.h"
|
||||||
|
#include "EchonestCatalogSynchronizer.h"
|
||||||
|
|
||||||
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id )
|
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id )
|
||||||
: DatabaseCommandLoggable( )
|
: DatabaseCommandLoggable( )
|
||||||
@@ -72,5 +73,10 @@ DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
|||||||
void
|
void
|
||||||
DatabaseCommand_SetCollectionAttributes::postCommitHook()
|
DatabaseCommand_SetCollectionAttributes::postCommitHook()
|
||||||
{
|
{
|
||||||
Servent::instance()->triggerDBSync();
|
if ( m_type == EchonestSongCatalog ||
|
||||||
|
m_type == EchonestArtistCatalog )
|
||||||
|
Tomahawk::EchonestCatalogSynchronizer::instance()->knownCatalogsChanged();
|
||||||
|
|
||||||
|
if ( source()->isLocal() )
|
||||||
|
Servent::instance()->triggerDBSync();
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ class DatabaseCommand_SetCollectionAttributes : public DatabaseCommandLoggable
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY( QByteArray id READ id WRITE setId )
|
Q_PROPERTY( QByteArray id READ id WRITE setId )
|
||||||
Q_PROPERTY( int type READ type WRITE setType )
|
Q_PROPERTY( int type READ type WRITE setType )
|
||||||
|
Q_PROPERTY( bool del READ del WRITE setDel )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum AttributeType {
|
enum AttributeType {
|
||||||
@@ -38,8 +39,7 @@ public:
|
|||||||
DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id );
|
DatabaseCommand_SetCollectionAttributes( AttributeType type, const QByteArray& id );
|
||||||
// Delete all attributes for the source+type
|
// Delete all attributes for the source+type
|
||||||
DatabaseCommand_SetCollectionAttributes( AttributeType type, bool toDelete );
|
DatabaseCommand_SetCollectionAttributes( AttributeType type, bool toDelete );
|
||||||
|
DatabaseCommand_SetCollectionAttributes() : m_delete( false ) {} // JSON
|
||||||
DatabaseCommand_SetCollectionAttributes() {} // JSON
|
|
||||||
virtual void exec( DatabaseImpl* lib );
|
virtual void exec( DatabaseImpl* lib );
|
||||||
virtual bool doesMutates() const { return true; }
|
virtual bool doesMutates() const { return true; }
|
||||||
virtual void postCommitHook();
|
virtual void postCommitHook();
|
||||||
@@ -52,6 +52,8 @@ public:
|
|||||||
void setType( int type ) { m_type = (AttributeType)type; }
|
void setType( int type ) { m_type = (AttributeType)type; }
|
||||||
int type() const { return (int)m_type; }
|
int type() const { return (int)m_type; }
|
||||||
|
|
||||||
|
void setDel( bool del ) { m_delete = del; }
|
||||||
|
bool del() const { return m_delete; }
|
||||||
private:
|
private:
|
||||||
bool m_delete;
|
bool m_delete;
|
||||||
AttributeType m_type;
|
AttributeType m_type;
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "EchonestGenerator.h"
|
#include "EchonestGenerator.h"
|
||||||
|
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
#include <sourcelist.h>
|
||||||
|
|
||||||
|
|
||||||
QHash< QString, QStringList > Tomahawk::EchonestControl::s_suggestCache = QHash< QString, QStringList >();
|
QHash< QString, QStringList > Tomahawk::EchonestControl::s_suggestCache = QHash< QString, QStringList >();
|
||||||
@@ -198,7 +199,7 @@ Tomahawk::EchonestControl::updateWidgets()
|
|||||||
input->hide();
|
input->hide();
|
||||||
m_match = QWeakPointer< QWidget >( match );
|
m_match = QWeakPointer< QWidget >( match );
|
||||||
m_input = QWeakPointer< QWidget >( input );
|
m_input = QWeakPointer< QWidget >( input );
|
||||||
} else if( selectedType() == "Catalog Radio" ) {
|
} else if( selectedType() == "User Radio" ) {
|
||||||
m_currentType = Echonest::DynamicPlaylist::SourceCatalog;
|
m_currentType = Echonest::DynamicPlaylist::SourceCatalog;
|
||||||
|
|
||||||
QLabel* match = new QLabel( tr( "from user" ) );
|
QLabel* match = new QLabel( tr( "from user" ) );
|
||||||
@@ -209,6 +210,12 @@ Tomahawk::EchonestControl::updateWidgets()
|
|||||||
combo->addItem( str, EchonestGenerator::catalogId( str ) );
|
combo->addItem( str, EchonestGenerator::catalogId( str ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( EchonestGenerator::userCatalogs().isEmpty() )
|
||||||
|
combo->addItem( tr( "No users with Echo Nest Catalogs enabled. Try enabling option in Collection settings" ) );
|
||||||
|
|
||||||
|
if ( combo->findData( m_data.second ) < 0 )
|
||||||
|
combo->setCurrentIndex( 0 );
|
||||||
|
|
||||||
m_matchString = match->text();
|
m_matchString = match->text();
|
||||||
m_matchData = match->text();
|
m_matchData = match->text();
|
||||||
|
|
||||||
@@ -493,7 +500,7 @@ Tomahawk::EchonestControl::updateData()
|
|||||||
updateFromComboAndSlider();
|
updateFromComboAndSlider();
|
||||||
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
||||||
updateFromComboAndSlider( true );
|
updateFromComboAndSlider( true );
|
||||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog Radio" ) {
|
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "User Radio" ) {
|
||||||
updateFromLabelAndCombo();
|
updateFromLabelAndCombo();
|
||||||
} else if( selectedType() == "Sorting" ) {
|
} else if( selectedType() == "Sorting" ) {
|
||||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||||
@@ -556,6 +563,26 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
|
|||||||
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
|
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
|
||||||
if( edit )
|
if( edit )
|
||||||
edit->setText( m_data.second.toString() );
|
edit->setText( m_data.second.toString() );
|
||||||
|
} else if ( selectedType() == "User Radio" )
|
||||||
|
{
|
||||||
|
QComboBox* combo = qobject_cast< QComboBox* >( m_input.data() );
|
||||||
|
if ( combo )
|
||||||
|
{
|
||||||
|
combo->clear();
|
||||||
|
|
||||||
|
foreach( const QString& str, EchonestGenerator::userCatalogs() )
|
||||||
|
{
|
||||||
|
combo->addItem( str, EchonestGenerator::catalogId( str ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( EchonestGenerator::userCatalogs().isEmpty() )
|
||||||
|
combo->addItem( tr( "No users with Echo Nest Catalogs enabled. Try enabling option in Collection settings" ) );
|
||||||
|
|
||||||
|
if ( combo->findData( m_data.second ) < 0 )
|
||||||
|
combo->setCurrentIndex( 0 );
|
||||||
|
|
||||||
|
combo->setCurrentIndex( combo->findData( m_data.second ) );
|
||||||
|
}
|
||||||
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) {
|
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) {
|
||||||
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
|
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
|
||||||
if( s )
|
if( s )
|
||||||
@@ -564,7 +591,7 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
|
|||||||
updateToComboAndSlider();
|
updateToComboAndSlider();
|
||||||
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
} else if( selectedType() == "Danceability" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Artist Hotttnesss" || selectedType() == "Song Hotttnesss" ) {
|
||||||
updateToComboAndSlider( true );
|
updateToComboAndSlider( true );
|
||||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog Radio" ) {
|
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style") {
|
||||||
updateToLabelAndCombo();
|
updateToLabelAndCombo();
|
||||||
} else if( selectedType() == "Sorting" ) {
|
} else if( selectedType() == "Sorting" ) {
|
||||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||||
@@ -714,6 +741,24 @@ Tomahawk::EchonestControl::calculateSummary()
|
|||||||
summary = QString( "similar to ~%1" ).arg( m_data.second.toString() );
|
summary = QString( "similar to ~%1" ).arg( m_data.second.toString() );
|
||||||
} else if( selectedType() == "Artist Description" ) {
|
} else if( selectedType() == "Artist Description" ) {
|
||||||
summary = QString( "with genre ~%1" ).arg( m_data.second.toString() );
|
summary = QString( "with genre ~%1" ).arg( m_data.second.toString() );
|
||||||
|
} else if( selectedType() == "User Radio" ) {
|
||||||
|
QComboBox* b = qobject_cast< QComboBox* >( m_input.data() );
|
||||||
|
if ( b )
|
||||||
|
{
|
||||||
|
if ( b->currentText().isEmpty() || b->itemData( b->currentIndex() ).isNull() )
|
||||||
|
summary = "from no one";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString subSum;
|
||||||
|
if ( b->currentText() == "My Collection" )
|
||||||
|
subSum = "my";
|
||||||
|
else
|
||||||
|
subSum = b->currentText();
|
||||||
|
summary = QString( "from %1 radio" ).arg( subSum );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
summary = "from no one";
|
||||||
} else if( selectedType() == "Artist Description" || selectedType() == "Song" ) {
|
} else if( selectedType() == "Artist Description" || selectedType() == "Song" ) {
|
||||||
summary = QString( "similar to ~%1" ).arg( m_data.second.toString() );
|
summary = QString( "similar to ~%1" ).arg( m_data.second.toString() );
|
||||||
} else if( selectedType() == "Variety" || selectedType() == "Danceability" || selectedType() == "Artist Hotttnesss" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Song Hotttnesss" ) {
|
} else if( selectedType() == "Variety" || selectedType() == "Danceability" || selectedType() == "Artist Hotttnesss" || selectedType() == "Energy" || selectedType() == "Artist Familiarity" || selectedType() == "Song Hotttnesss" ) {
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include <echonest/Playlist.h>
|
#include <echonest/Playlist.h>
|
||||||
|
|
||||||
#include "dynamic/DynamicControl.h"
|
#include "dynamic/DynamicControl.h"
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "sourcelist.h"
|
#include "sourcelist.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <EchonestCatalogSynchronizer.h>
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
@@ -37,8 +38,7 @@ QStringList EchonestGenerator::s_styles = QStringList();
|
|||||||
QNetworkReply* EchonestGenerator::s_moodsJob = 0;
|
QNetworkReply* EchonestGenerator::s_moodsJob = 0;
|
||||||
QNetworkReply* EchonestGenerator::s_stylesJob = 0;
|
QNetworkReply* EchonestGenerator::s_stylesJob = 0;
|
||||||
|
|
||||||
bool EchonestGenerator::s_catalogsFetched = false;
|
CatalogManager* EchonestGenerator::s_catalogs = 0;
|
||||||
QHash< QString, QString > EchonestGenerator::s_catalogs = QHash< QString, QString >();
|
|
||||||
|
|
||||||
|
|
||||||
EchonestFactory::EchonestFactory()
|
EchonestFactory::EchonestFactory()
|
||||||
@@ -63,18 +63,54 @@ EchonestFactory::createControl( const QString& controlType )
|
|||||||
QStringList
|
QStringList
|
||||||
EchonestFactory::typeSelectors() const
|
EchonestFactory::typeSelectors() const
|
||||||
{
|
{
|
||||||
QStringList types = QStringList() << "Artist" << "Artist Description" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
QStringList types = QStringList() << "Artist" << "Artist Description" << "User Radio" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
||||||
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss"
|
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss"
|
||||||
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting";
|
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting";
|
||||||
|
|
||||||
if ( TomahawkSettings::instance()->enableEchonestCatalogs() )
|
|
||||||
{
|
|
||||||
types.insert( 2, "Catalog Radio" );
|
|
||||||
types.insert( 3, "Adventurousness" );
|
|
||||||
}
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CatalogManager::CatalogManager( QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
{
|
||||||
|
connect( EchonestCatalogSynchronizer::instance(), SIGNAL( knownCatalogsChanged() ), this, SLOT( doCatalogUpdate() ) );
|
||||||
|
connect( SourceList::instance(), SIGNAL( ready() ), this, SLOT( doCatalogUpdate() ) );
|
||||||
|
|
||||||
|
doCatalogUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CatalogManager::collectionAttributes( const PairList& data )
|
||||||
|
{
|
||||||
|
QPair<QString, QString> part;
|
||||||
|
m_catalogs.clear();
|
||||||
|
|
||||||
|
foreach ( part, data )
|
||||||
|
{
|
||||||
|
if ( SourceList::instance()->get( part.first.toInt() ).isNull() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QString name = SourceList::instance()->get( part.first.toInt() )->friendlyName();
|
||||||
|
m_catalogs.insert( name, part.second );
|
||||||
|
}
|
||||||
|
|
||||||
|
emit catalogsUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CatalogManager::doCatalogUpdate()
|
||||||
|
{
|
||||||
|
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_CollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog ) );
|
||||||
|
connect( cmd.data(), SIGNAL( collectionAttributes( PairList ) ), this, SLOT( collectionAttributes( PairList ) ) );
|
||||||
|
Database::instance()->enqueue( cmd );
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash< QString, QString >
|
||||||
|
CatalogManager::catalogs() const
|
||||||
|
{
|
||||||
|
return m_catalogs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EchonestGenerator::EchonestGenerator ( QObject* parent )
|
EchonestGenerator::EchonestGenerator ( QObject* parent )
|
||||||
: GeneratorInterface ( parent )
|
: GeneratorInterface ( parent )
|
||||||
@@ -86,17 +122,13 @@ EchonestGenerator::EchonestGenerator ( QObject* parent )
|
|||||||
m_logo.load( RESPATH "/images/echonest_logo.png" );
|
m_logo.load( RESPATH "/images/echonest_logo.png" );
|
||||||
|
|
||||||
loadStylesAndMoods();
|
loadStylesAndMoods();
|
||||||
if ( s_catalogs.isEmpty() && TomahawkSettings::instance()->enableEchonestCatalogs() )
|
|
||||||
{
|
// TODO Yes this is a race condition. If multiple threads initialize echonestgenerator at the exact same time we could run into some issues.
|
||||||
if ( !s_catalogsFetched )
|
// not dealing with that right now.
|
||||||
{
|
if ( s_catalogs == 0 )
|
||||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_CollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog ) );
|
s_catalogs = new CatalogManager( this );
|
||||||
connect( cmd.data(), SIGNAL(collectionAttributes(PairList)),
|
|
||||||
this, SLOT(collectionAttributes(PairList) ) );
|
connect( s_catalogs, SIGNAL( catalogsUpdated() ), this, SLOT( knownCatalogsChanged() ) );
|
||||||
Database::instance()->enqueue( cmd );
|
|
||||||
s_catalogsFetched = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// qDebug() << "ECHONEST:" << m_logo.size();
|
// qDebug() << "ECHONEST:" << m_logo.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +152,16 @@ QPixmap EchonestGenerator::logo()
|
|||||||
return m_logo;
|
return m_logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EchonestGenerator::knownCatalogsChanged()
|
||||||
|
{
|
||||||
|
// Refresh all contrls
|
||||||
|
foreach( const dyncontrol_ptr& control, m_controls )
|
||||||
|
{
|
||||||
|
control.staticCast< EchonestControl >()->updateWidgetsFromData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EchonestGenerator::generate( int number )
|
EchonestGenerator::generate( int number )
|
||||||
@@ -381,30 +423,17 @@ EchonestGenerator::resetSteering()
|
|||||||
m_steerData.second = QString();
|
m_steerData.second = QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
EchonestGenerator::collectionAttributes(PairList data)
|
|
||||||
{
|
|
||||||
QPair<QString, QString> part;
|
|
||||||
foreach ( part, data )
|
|
||||||
{
|
|
||||||
if ( SourceList::instance()->get( part.first.toInt() ).isNull() )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const QString name = SourceList::instance()->get( part.first.toInt() )->friendlyName();
|
|
||||||
s_catalogs.insert( name, part.second );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray
|
QByteArray
|
||||||
EchonestGenerator::catalogId(const QString &collectionId)
|
EchonestGenerator::catalogId(const QString &collectionId)
|
||||||
{
|
{
|
||||||
return s_catalogs.value( collectionId ).toUtf8();
|
return s_catalogs->catalogs().value( collectionId ).toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList
|
||||||
EchonestGenerator::userCatalogs()
|
EchonestGenerator::userCatalogs()
|
||||||
{
|
{
|
||||||
return s_catalogs.keys();
|
return s_catalogs->catalogs().keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -446,7 +475,7 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p
|
|||||||
/// 5. song-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
/// 5. song-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
||||||
bool someCatalog = false;
|
bool someCatalog = false;
|
||||||
foreach( const dyncontrol_ptr& control, m_controls ) {
|
foreach( const dyncontrol_ptr& control, m_controls ) {
|
||||||
if ( control->selectedType() == "Catalog Radio" )
|
if ( control->selectedType() == "User Radio" )
|
||||||
someCatalog = true;
|
someCatalog = true;
|
||||||
}
|
}
|
||||||
if( someCatalog )
|
if( someCatalog )
|
||||||
|
@@ -34,6 +34,25 @@ namespace Tomahawk
|
|||||||
|
|
||||||
class EchonestSteerer;
|
class EchonestSteerer;
|
||||||
|
|
||||||
|
class CatalogManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CatalogManager( QObject* parent );
|
||||||
|
|
||||||
|
QHash< QString, QString > catalogs() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void catalogsUpdated();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void doCatalogUpdate();
|
||||||
|
void collectionAttributes( const PairList& );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash< QString, QString > m_catalogs;
|
||||||
|
};
|
||||||
|
|
||||||
class DLLEXPORT EchonestFactory : public GeneratorFactoryInterface
|
class DLLEXPORT EchonestFactory : public GeneratorFactoryInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -83,7 +102,7 @@ private slots:
|
|||||||
|
|
||||||
void stylesReceived();
|
void stylesReceived();
|
||||||
void moodsReceived();
|
void moodsReceived();
|
||||||
void collectionAttributes(PairList);
|
void knownCatalogsChanged();
|
||||||
|
|
||||||
void songLookupFinished();
|
void songLookupFinished();
|
||||||
private:
|
private:
|
||||||
@@ -105,8 +124,7 @@ private:
|
|||||||
static QNetworkReply* s_stylesJob;
|
static QNetworkReply* s_stylesJob;
|
||||||
static QNetworkReply* s_moodsJob;
|
static QNetworkReply* s_moodsJob;
|
||||||
|
|
||||||
static bool s_catalogsFetched;
|
static CatalogManager* s_catalogs;
|
||||||
static QHash< QString, QString > s_catalogs;
|
|
||||||
|
|
||||||
// used for the intermediary song id lookup
|
// used for the intermediary song id lookup
|
||||||
QSet< QNetworkReply* > m_waiting;
|
QSet< QNetworkReply* > m_waiting;
|
||||||
|
Reference in New Issue
Block a user