mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 03:10:12 +02:00
Add dbmigrate scrip, other misc work
This commit is contained in:
10
data/sql/dbmigrate-26_to_27.sql
Normal file
10
data/sql/dbmigrate-26_to_27.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- Script to migate from db version 6 to 27
|
||||
-- Nothing to do
|
||||
|
||||
CREATE TABLE IF NOT EXISTS collection_attributes (
|
||||
id INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- source id, null for local source
|
||||
k TEXT NOT NULL,
|
||||
v TEXT NOT NULL
|
||||
);
|
||||
UPDATE settings SET v = '27' WHERE k == 'schema_version';
|
||||
|
@@ -108,6 +108,7 @@
|
||||
<file>data/sql/dbmigrate-23_to_24.sql</file>
|
||||
<file>data/sql/dbmigrate-24_to_25.sql</file>
|
||||
<file>data/sql/dbmigrate-25_to_26.sql</file>
|
||||
<file>data/sql/dbmigrate-26_to_27.sql</file>
|
||||
<file>data/js/tomahawk.js</file>
|
||||
<file>data/images/avatar_frame.png</file>
|
||||
<file>data/images/drop-all-songs.png</file>
|
||||
|
@@ -35,6 +35,8 @@ set( libSources
|
||||
playlistinterface.cpp
|
||||
LatchManager.cpp
|
||||
|
||||
EchonestCatalogSynchronizer.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
sip/SipModel.cpp
|
||||
@@ -95,6 +97,8 @@ set( libSources
|
||||
database/databasecommand_socialaction.cpp
|
||||
database/databasecommand_loadsocialactions.cpp
|
||||
database/databasecommand_genericselect.cpp
|
||||
database/databasecommand_setcollectionattributes.cpp
|
||||
database/databasecommand_collectionattributes.cpp
|
||||
database/database.cpp
|
||||
|
||||
infobar/infobar.cpp
|
||||
@@ -253,6 +257,8 @@ set( libHeaders
|
||||
album.h
|
||||
playlist.h
|
||||
|
||||
EchonestCatalogSynchronizer.h
|
||||
|
||||
sip/SipPlugin.h
|
||||
sip/SipHandler.h
|
||||
sip/SipModel.h
|
||||
@@ -313,6 +319,8 @@ set( libHeaders
|
||||
database/databasecommand_socialaction.h
|
||||
database/databasecommand_loadsocialactions.h
|
||||
database/databasecommand_genericselect.h
|
||||
database/databasecommand_setcollectionattributes.h
|
||||
database/databasecommand_collectionattributes.h
|
||||
|
||||
infobar/infobar.h
|
||||
|
||||
|
195
src/libtomahawk/EchonestCatalogSynchronizer.cpp
Normal file
195
src/libtomahawk/EchonestCatalogSynchronizer.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
|
||||
#include "database/database.h"
|
||||
#include "database/databasecommand_genericselect.h"
|
||||
#include "database/databasecommand_setcollectionattributes.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "sourcelist.h"
|
||||
|
||||
#include <echonest/CatalogUpdateEntry.h>
|
||||
#include <echonest/Config.h>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
EchonestCatalogSynchronizer* EchonestCatalogSynchronizer::s_instance = 0;
|
||||
|
||||
EchonestCatalogSynchronizer::EchonestCatalogSynchronizer( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
m_syncing = TomahawkSettings::instance()->enableEchonestCatalogs();
|
||||
|
||||
qRegisterMetaType<QList<QStringList> >("QList<QStringList>");
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), this, SLOT( checkSettingsChanged() ) );
|
||||
|
||||
const QByteArray artist = TomahawkSettings::instance()->value( "collection/artistCatalog" ).toByteArray();
|
||||
const QByteArray song = TomahawkSettings::instance()->value( "collection/songCatalog" ).toByteArray();
|
||||
if ( !artist.isEmpty() )
|
||||
m_artistCatalog.setId( artist );
|
||||
if ( !song.isEmpty() )
|
||||
m_songCatalog.setId( song );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::checkSettingsChanged()
|
||||
{
|
||||
if ( TomahawkSettings::instance()->enableEchonestCatalogs() && !m_syncing )
|
||||
{
|
||||
// enable, and upload whole db
|
||||
m_syncing = true;
|
||||
|
||||
tDebug() << "Echonest Catalog sync pref changed, uploading!!";
|
||||
uploadDb();
|
||||
} else if ( !TomahawkSettings::instance()->enableEchonestCatalogs() && m_syncing )
|
||||
{
|
||||
m_songCatalog.deleteCatalog();
|
||||
m_artistCatalog.deleteCatalog();
|
||||
m_syncing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::uploadDb()
|
||||
{
|
||||
// create two catalogs: uuid_song, and uuid_artist.
|
||||
QNetworkReply* r = Echonest::Catalog::create( QString( "%1_song" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Song );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( songCreateFinished() ) );
|
||||
|
||||
r = Echonest::Catalog::create( QString( "%1_artist" ).arg( Database::instance()->dbid() ), Echonest::CatalogTypes::Artist );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( artistCreateFinished() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::songCreateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
tDebug() << "Finished creating song catalog, updating data now!!";
|
||||
try
|
||||
{
|
||||
m_songCatalog = Echonest::Catalog::parseCreate( r );
|
||||
TomahawkSettings::instance()->setValue( "collection/songCatalog", m_songCatalog.id() );
|
||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( SourceList::instance()->getLocal(),
|
||||
DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
m_songCatalog.id() ) );
|
||||
Database::instance()->enqueue( cmd );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing song catalog create:" << e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
QString sql( "SELECT track.name, artist.name, album.name "
|
||||
"FROM file, artist, track, file_join "
|
||||
"LEFT OUTER JOIN album "
|
||||
"ON file_join.album = album.id "
|
||||
"WHERE file.id = file_join.file "
|
||||
"AND file_join.artist = artist.id "
|
||||
"AND file_join.track = track.id "
|
||||
"AND file.source IS NULL");
|
||||
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, true );
|
||||
connect( cmd, SIGNAL( rawData( QList< QStringList > ) ), this, SLOT( rawTracks( QList< QStringList > ) ) );
|
||||
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::artistCreateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try
|
||||
{
|
||||
m_artistCatalog = Echonest::Catalog::parseCreate( r );
|
||||
TomahawkSettings::instance()->setValue( "collection/artistCatalog", m_artistCatalog.id() );
|
||||
|
||||
// QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_SetCollectionAttributes( SourceList::instance()->getLocal(),
|
||||
// DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog,
|
||||
// m_songCatalog.id() ) );
|
||||
// Database::instance()->enqueue( cmd );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing artist catalog create:" << e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::rawTracks( const QList< QStringList >& tracks )
|
||||
{
|
||||
tDebug() << "Got raw tracks, num:" << tracks.size();
|
||||
Echonest::CatalogUpdateEntries entries( tracks.size() );
|
||||
for ( int i = 0; i < tracks.size(); i++ )
|
||||
{
|
||||
if ( tracks[ i ][ 0 ].isEmpty() || tracks[ i ][ 1 ].isEmpty() )
|
||||
continue;
|
||||
|
||||
Echonest::CatalogUpdateEntry entry;
|
||||
entry.setAction( Echonest::CatalogTypes::Update );
|
||||
entry.setSongName( tracks[ i ][ 0 ] );
|
||||
entry.setArtistName( tracks[ i ][ 1 ] );
|
||||
entry.setRelease( tracks[ i ][ 2 ] );
|
||||
entry.setItemId( uuid().toUtf8() );
|
||||
|
||||
entries.append( entry );
|
||||
}
|
||||
|
||||
QNetworkReply* updateJob = m_songCatalog.update( entries );
|
||||
connect( updateJob, SIGNAL( finished() ), this, SLOT( songUpdateFinished() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::songUpdateFinished()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try
|
||||
{
|
||||
QByteArray ticket = m_songCatalog.parseTicket( r );
|
||||
QNetworkReply* tJob = m_songCatalog.status( ticket );
|
||||
connect( tJob, SIGNAL( finished() ), this, SLOT( checkTicket() ) );
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing catalog update finished:" << e.what();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestCatalogSynchronizer::checkTicket()
|
||||
{
|
||||
QNetworkReply* r = qobject_cast< QNetworkReply* >( sender() );
|
||||
Q_ASSERT( r );
|
||||
|
||||
try
|
||||
{
|
||||
Echonest::CatalogStatus status = m_songCatalog.parseStatus( r );
|
||||
|
||||
tLog() << "Catalog status update:" << status.status << status.details << status.items;
|
||||
} catch ( const Echonest::ParseError& e )
|
||||
{
|
||||
tLog() << "Echonest threw an exception parsing catalog create:" << e.what();
|
||||
return;
|
||||
}
|
||||
}
|
71
src/libtomahawk/EchonestCatalogSynchronizer.h
Normal file
71
src/libtomahawk/EchonestCatalogSynchronizer.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ECHONESTCATALOGSYNCHRONIZER_H
|
||||
#define ECHONESTCATALOGSYNCHRONIZER_H
|
||||
|
||||
#include <echonest/Catalog.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class EchonestCatalogSynchronizer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static EchonestCatalogSynchronizer* instance() {
|
||||
if ( !s_instance )
|
||||
{
|
||||
s_instance = new EchonestCatalogSynchronizer;
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
explicit EchonestCatalogSynchronizer(QObject *parent = 0);
|
||||
|
||||
Echonest::Catalog songCatalog() const { return m_songCatalog; }
|
||||
Echonest::Catalog artistCatalog() const { return m_artistCatalog; }
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void checkSettingsChanged();
|
||||
|
||||
void songCreateFinished();
|
||||
void artistCreateFinished();
|
||||
void songUpdateFinished();
|
||||
|
||||
void checkTicket();
|
||||
|
||||
void rawTracks( const QList< QStringList >& tracks );
|
||||
private:
|
||||
void uploadDb();
|
||||
|
||||
bool m_syncing;
|
||||
|
||||
Echonest::Catalog m_songCatalog;
|
||||
Echonest::Catalog m_artistCatalog;
|
||||
|
||||
static EchonestCatalogSynchronizer* s_instance;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // ECHONESTCATALOGSYNCHRONIZER_H
|
@@ -0,0 +1,59 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "DatabaseCommand_CollectionAttributes.h"
|
||||
|
||||
#include "databaseimpl.h"
|
||||
#include "source.h"
|
||||
|
||||
DatabaseCommand_CollectionAttributes::DatabaseCommand_CollectionAttributes( DatabaseCommand_SetCollectionAttributes::AttributeType type )
|
||||
: DatabaseCommand()
|
||||
, m_type( type )
|
||||
{
|
||||
qRegisterMetaType< PairList >("PairList");
|
||||
}
|
||||
|
||||
void
|
||||
DatabaseCommand_CollectionAttributes::exec( DatabaseImpl *lib )
|
||||
{
|
||||
TomahawkSqlQuery query = lib->newquery();
|
||||
|
||||
// QString sourceStr;
|
||||
// if ( source().isNull() )
|
||||
// sourceStr = "id IS NULL";
|
||||
// else
|
||||
// sourceStr = QString( "id == %1" ).arg( source()->id() );
|
||||
|
||||
QString typeStr;
|
||||
if ( m_type == DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog )
|
||||
typeStr = "echonest_song";
|
||||
else if ( m_type == DatabaseCommand_SetCollectionAttributes::EchonestArtistCatalog )
|
||||
typeStr = "echonest_artist";
|
||||
|
||||
QString queryStr = QString( "SELECT k, v FROM collection_attributes WHERE k = \"%1\"" ).arg( typeStr );
|
||||
qDebug() << "Doing queryL" << queryStr;
|
||||
query.exec( queryStr );
|
||||
PairList data;
|
||||
while ( query.next() )
|
||||
{
|
||||
QPair< QString, QString > part;
|
||||
part.first = query.value( 0 ).toString();
|
||||
part.second = query.value( 1 ).toString();
|
||||
data << part;
|
||||
}
|
||||
emit data;
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_ECHONESTCATALOG_H
|
||||
#define DATABASECOMMAND_ECHONESTCATALOG_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommand.h"
|
||||
#include "databasecommand_setcollectionattributes.h"
|
||||
#include <QByteArray>
|
||||
|
||||
typedef QList< QPair< QString, QString > > PairList;
|
||||
|
||||
class DatabaseCommand_CollectionAttributes : public DatabaseCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
DatabaseCommand_CollectionAttributes( DatabaseCommand_SetCollectionAttributes::AttributeType type );
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return false; }
|
||||
|
||||
virtual QString commandname() const { return "setcollectionattributes"; }
|
||||
|
||||
signals:
|
||||
void collectionAttributes( PairList );
|
||||
|
||||
private:
|
||||
DatabaseCommand_SetCollectionAttributes::AttributeType m_type;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(PairList)
|
||||
#endif
|
@@ -32,9 +32,18 @@ DatabaseCommand_GenericSelect::DatabaseCommand_GenericSelect( const QString& sql
|
||||
, m_sqlSelect( sqlSelect )
|
||||
, m_queryType( type )
|
||||
, m_limit( limit )
|
||||
, m_raw( false )
|
||||
{
|
||||
}
|
||||
|
||||
DatabaseCommand_GenericSelect::DatabaseCommand_GenericSelect( const QString& sqlSelect, QueryType type, bool rawData, QObject* parent )
|
||||
: DatabaseCommand( parent )
|
||||
, m_sqlSelect( sqlSelect )
|
||||
, m_queryType( type )
|
||||
, m_limit( -1 )
|
||||
, m_raw( rawData )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
||||
@@ -48,6 +57,26 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
||||
QList< artist_ptr > arts;
|
||||
QList< album_ptr > albs;
|
||||
|
||||
if ( m_raw )
|
||||
{
|
||||
QList< QStringList > rawDataItems;
|
||||
|
||||
while( query.next() )
|
||||
{
|
||||
|
||||
QStringList rawRow;
|
||||
int count = 0;
|
||||
while ( query.value( count ).isValid() )
|
||||
{
|
||||
rawRow << query.value( count ).toString();
|
||||
++count;
|
||||
}
|
||||
rawDataItems << rawRow;
|
||||
}
|
||||
emit rawData( rawDataItems );
|
||||
return;
|
||||
}
|
||||
|
||||
// Expecting
|
||||
while ( query.next() )
|
||||
{
|
||||
|
@@ -24,6 +24,9 @@
|
||||
#include "databasecommand.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
/**
|
||||
@@ -60,6 +63,7 @@ public:
|
||||
};
|
||||
|
||||
explicit DatabaseCommand_GenericSelect( const QString& sqlSelect, QueryType type, int limitResults = -1, QObject* parent = 0 );
|
||||
explicit DatabaseCommand_GenericSelect( const QString& sqlSelect, QueryType type, bool rawData, QObject* parent = 0 );
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return false; }
|
||||
|
||||
@@ -70,10 +74,14 @@ signals:
|
||||
void artists( const QList< Tomahawk::artist_ptr >& artists );
|
||||
void albums( const QList< Tomahawk::album_ptr >& albums );
|
||||
|
||||
void rawData( const QList< QStringList >& data );
|
||||
private:
|
||||
QString m_sqlSelect;
|
||||
QueryType m_queryType;
|
||||
int m_limit;
|
||||
bool m_raw;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QList<QStringList>);
|
||||
|
||||
#endif // DATABASECOMMAND_GENERICSELECT_H
|
||||
|
@@ -0,0 +1,50 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "DatabaseCommand_SetCollectionAttributes.h"
|
||||
|
||||
#include "databaseimpl.h"
|
||||
#include "source.h"
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes::DatabaseCommand_SetCollectionAttributes( const Tomahawk::source_ptr& source, AttributeType type, const QByteArray& id )
|
||||
: DatabaseCommandLoggable( source )
|
||||
, m_id( id )
|
||||
, m_type( type )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
||||
{
|
||||
TomahawkSqlQuery query = lib->newquery();
|
||||
|
||||
QString sourceStr;
|
||||
if ( source().isNull() || source()->isLocal() )
|
||||
sourceStr = "NULL";
|
||||
else
|
||||
sourceStr = QString( "%1" ).arg( source()->id() );
|
||||
|
||||
QString typeStr;
|
||||
if ( m_type == EchonestSongCatalog )
|
||||
typeStr = "echonest_song";
|
||||
else if ( m_type == EchonestArtistCatalog )
|
||||
typeStr = "echonest_artist";
|
||||
|
||||
QString queryStr = QString( "REPLACE INTO collection_attributes ( id, k, v ) VALUES( %1, \"%2\", \"%3\" )" ).arg( sourceStr ).arg( typeStr ).arg( QString::fromUtf8( m_id ) );
|
||||
qDebug() << "Doing query:" << queryStr;
|
||||
query.exec( queryStr );
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk 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 Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
||||
#define DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "databasecommandloggable.h"
|
||||
#include <QByteArray>
|
||||
|
||||
class DatabaseCommand_SetCollectionAttributes : public DatabaseCommandLoggable
|
||||
{
|
||||
public:
|
||||
enum AttributeType {
|
||||
EchonestSongCatalog = 0,
|
||||
EchonestArtistCatalog = 1
|
||||
};
|
||||
|
||||
DatabaseCommand_SetCollectionAttributes( const Tomahawk::source_ptr& source, AttributeType type, const QByteArray& id );
|
||||
virtual void exec( DatabaseImpl* lib );
|
||||
virtual bool doesMutates() const { return true; }
|
||||
|
||||
virtual QString commandname() const { return "saveechonestcatalog"; }
|
||||
|
||||
private:
|
||||
AttributeType m_type;
|
||||
QByteArray m_id;
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_SAVEECHONESTCATALOG_H
|
@@ -39,7 +39,7 @@
|
||||
*/
|
||||
#include "schema.sql.h"
|
||||
|
||||
#define CURRENT_SCHEMA_VERSION 26
|
||||
#define CURRENT_SCHEMA_VERSION 27
|
||||
|
||||
|
||||
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
|
@@ -228,6 +228,14 @@ CREATE TABLE IF NOT EXISTS track_attributes (
|
||||
CREATE INDEX track_attrib_id ON track_attributes(id);
|
||||
CREATE INDEX track_attrib_k ON track_attributes(k);
|
||||
|
||||
-- Collection attributes, tied to a source. An example might be an echonest song catalog
|
||||
|
||||
CREATE TABLE IF NOT EXISTS collection_attributes (
|
||||
id INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- source id, null for local source
|
||||
k TEXT NOT NULL,
|
||||
v TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- social attributes connected to the track.
|
||||
-- like love, hate, comments, recommendations
|
||||
-- love=[comment], hate=[comment], comment=Some text
|
||||
@@ -283,4 +291,4 @@ CREATE TABLE IF NOT EXISTS settings (
|
||||
v TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '26');
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '27');
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
This file was automatically generated from schema.sql on Mon Jul 25 20:38:55 EDT 2011.
|
||||
This file was automatically generated from ./schema.sql on Sun Sep 25 10:36:01 EDT 2011.
|
||||
*/
|
||||
|
||||
static const char * tomahawk_schema_sql =
|
||||
@@ -152,6 +152,11 @@ static const char * tomahawk_schema_sql =
|
||||
");"
|
||||
"CREATE INDEX track_attrib_id ON track_attributes(id);"
|
||||
"CREATE INDEX track_attrib_k ON track_attributes(k);"
|
||||
"CREATE TABLE IF NOT EXISTS collection_attributes ("
|
||||
" id INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, "
|
||||
" k TEXT NOT NULL,"
|
||||
" v TEXT NOT NULL"
|
||||
"};"
|
||||
"CREATE TABLE IF NOT EXISTS social_attributes ("
|
||||
" id INTEGER REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, "
|
||||
" source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE, "
|
||||
@@ -184,7 +189,7 @@ static const char * tomahawk_schema_sql =
|
||||
" k TEXT NOT NULL PRIMARY KEY,"
|
||||
" v TEXT NOT NULL DEFAULT ''"
|
||||
");"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '26');"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '27');"
|
||||
;
|
||||
|
||||
const char * get_tomahawk_sql()
|
||||
|
@@ -198,6 +198,29 @@ Tomahawk::EchonestControl::updateWidgets()
|
||||
input->hide();
|
||||
m_match = QWeakPointer< QWidget >( match );
|
||||
m_input = QWeakPointer< QWidget >( input );
|
||||
} else if( selectedType() == "Catalog Radio" ) {
|
||||
m_currentType = Echonest::DynamicPlaylist::SourceCatalog;
|
||||
|
||||
QLabel* match = new QLabel( tr( "from user" ) );
|
||||
QComboBox* combo = new QComboBox();
|
||||
|
||||
foreach( const QString& str, EchonestGenerator::userCatalogs() )
|
||||
{
|
||||
combo->addItem( str, EchonestGenerator::catalogId( str ) );
|
||||
}
|
||||
combo->addItem( "lfranchi@gmail.com", "CATNEQO132A15A6C7A" );
|
||||
|
||||
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 );
|
||||
m_input = QWeakPointer< QWidget >( combo );
|
||||
} else if( selectedType() == "Song" ) {
|
||||
m_currentType = Echonest::DynamicPlaylist::SongId;
|
||||
|
||||
@@ -230,6 +253,27 @@ Tomahawk::EchonestControl::updateWidgets()
|
||||
m_matchData = match->text();
|
||||
|
||||
|
||||
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( updateData() ) );
|
||||
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( editingFinished() ) );
|
||||
|
||||
match->hide();
|
||||
input->hide();
|
||||
m_match = QWeakPointer< QWidget >( match );
|
||||
m_input = QWeakPointer< QWidget >( input );
|
||||
} else if( selectedType() == "Adventurousness" ) {
|
||||
m_currentType = Echonest::DynamicPlaylist::Adventurousness;
|
||||
|
||||
QLabel* match = new QLabel( tr( "is" ) );
|
||||
LabeledSlider* input = new LabeledSlider( tr( "Less" ), tr( "More" ) );
|
||||
input->slider()->setRange( 0, 10000 );
|
||||
input->slider()->setTickInterval( 1 );
|
||||
input->slider()->setTracking( false );
|
||||
input->slider()->setValue( 10000 * .2 );
|
||||
|
||||
m_matchString = match->text();
|
||||
m_matchData = match->text();
|
||||
|
||||
|
||||
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( updateData() ) );
|
||||
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( editingFinished() ) );
|
||||
|
||||
@@ -440,7 +484,7 @@ Tomahawk::EchonestControl::updateData()
|
||||
m_data.first = m_currentType;
|
||||
m_data.second = edit->text();
|
||||
}
|
||||
} else if( selectedType() == "Variety" ) {
|
||||
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) {
|
||||
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
|
||||
if( s ) {
|
||||
m_data.first = m_currentType;
|
||||
@@ -450,7 +494,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" || selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog Radio" ) {
|
||||
updateFromLabelAndCombo();
|
||||
} else if( selectedType() == "Sorting" ) {
|
||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||
@@ -513,7 +557,7 @@ Tomahawk::EchonestControl::updateWidgetsFromData()
|
||||
QLineEdit* edit = qobject_cast<QLineEdit*>( m_input.data() );
|
||||
if( edit )
|
||||
edit->setText( m_data.second.toString() );
|
||||
} else if( selectedType() == "Variety" ) {
|
||||
} else if( selectedType() == "Variety" || selectedType() == "Adventurousness" ) {
|
||||
LabeledSlider* s = qobject_cast<LabeledSlider*>( m_input.data() );
|
||||
if( s )
|
||||
s->slider()->setValue( m_data.second.toDouble() * 10000 );
|
||||
@@ -521,7 +565,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" || selectedType() == "Mood" || selectedType() == "Style" ) {
|
||||
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog Radio" ) {
|
||||
updateToLabelAndCombo();
|
||||
} else if( selectedType() == "Sorting" ) {
|
||||
QComboBox* match = qobject_cast<QComboBox*>( m_match.data() );
|
||||
|
@@ -21,6 +21,9 @@
|
||||
#include "dynamic/echonest/EchonestSteerer.h"
|
||||
#include "query.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "database/databasecommand_collectionattributes.h"
|
||||
#include "database/database.h"
|
||||
#include "utils/logger.h"
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
@@ -33,6 +36,9 @@ QStringList EchonestGenerator::s_styles = QStringList();
|
||||
QNetworkReply* EchonestGenerator::s_moodsJob = 0;
|
||||
QNetworkReply* EchonestGenerator::s_stylesJob = 0;
|
||||
|
||||
bool EchonestGenerator::s_catalogsFetched = false;
|
||||
QHash< QString, QString > EchonestGenerator::s_catalogs = QHash< QString, QString >();
|
||||
|
||||
|
||||
EchonestFactory::EchonestFactory()
|
||||
{
|
||||
@@ -56,9 +62,16 @@ EchonestFactory::createControl( const QString& controlType )
|
||||
QStringList
|
||||
EchonestFactory::typeSelectors() const
|
||||
{
|
||||
return QStringList() << "Artist" << "Artist Description" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
||||
QStringList types = QStringList() << "Artist" << "Artist Description" << "Song" << "Mood" << "Style" << "Variety" << "Tempo" << "Duration" << "Loudness"
|
||||
<< "Danceability" << "Energy" << "Artist Familiarity" << "Artist Hotttnesss" << "Song Hotttnesss"
|
||||
<< "Longitude" << "Latitude" << "Mode" << "Key" << "Sorting";
|
||||
|
||||
if ( TomahawkSettings::instance()->enableEchonestCatalogs() )
|
||||
{
|
||||
types.insert( 2, "Catalog Radio" );
|
||||
types.insert( 3, "Adventurousness" );
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +85,17 @@ EchonestGenerator::EchonestGenerator ( QObject* parent )
|
||||
m_logo.load( RESPATH "/images/echonest_logo.png" );
|
||||
|
||||
loadStylesAndMoods();
|
||||
if ( s_catalogs.isEmpty() && TomahawkSettings::instance()->enableEchonestCatalogs() )
|
||||
{
|
||||
if ( !s_catalogsFetched )
|
||||
{
|
||||
QSharedPointer< DatabaseCommand > cmd( new DatabaseCommand_CollectionAttributes( DatabaseCommand_SetCollectionAttributes::EchonestSongCatalog ) );
|
||||
connect( cmd.data(), SIGNAL(collectionAttributes(PairList)),
|
||||
this, SLOT(collectionAttributes(PairList) ) );
|
||||
Database::instance()->enqueue( cmd );
|
||||
s_catalogsFetched = true;
|
||||
}
|
||||
}
|
||||
// qDebug() << "ECHONEST:" << m_logo.size();
|
||||
}
|
||||
|
||||
@@ -356,6 +380,27 @@ EchonestGenerator::resetSteering()
|
||||
m_steerData.second = QString();
|
||||
}
|
||||
|
||||
void
|
||||
EchonestGenerator::collectionAttributes(PairList data)
|
||||
{
|
||||
QPair<QString, QString> part;
|
||||
foreach ( part, data )
|
||||
{
|
||||
s_catalogs.insert( part.first, part.second );
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray
|
||||
EchonestGenerator::catalogId(const QString &collectionId)
|
||||
{
|
||||
return s_catalogs.value( collectionId ).toUtf8();
|
||||
}
|
||||
|
||||
QStringList
|
||||
EchonestGenerator::userCatalogs()
|
||||
{
|
||||
return s_catalogs.keys();
|
||||
}
|
||||
|
||||
bool
|
||||
EchonestGenerator::onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error )
|
||||
@@ -389,12 +434,17 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p
|
||||
*
|
||||
*/
|
||||
|
||||
/// 1. artist: If all the artist controls are Limit-To. If some were but not all, error out.
|
||||
/// 2. artist-description: If all the artist entries are Description. If some were but not all, error out.
|
||||
/// 3. artist-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
||||
/// 4. song-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
||||
if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistType ) )
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistType ) );
|
||||
/// 1. catalog-radio: If any the entries are catalog types.
|
||||
/// 2. artist: If all the artist controls are Limit-To. If some were but not all, error out.
|
||||
/// 3. artist-description: If all the artist entries are Description. If some were but not all, error out.
|
||||
/// 4. artist-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;
|
||||
foreach( const dyncontrol_ptr& control, m_controls ) {
|
||||
someCatalog = true;
|
||||
}
|
||||
if( someCatalog )
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::CatalogRadioType ) );
|
||||
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistDescriptionType ) )
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistRadioType ) )
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "playlist/dynamic/GeneratorInterface.h"
|
||||
#include "playlist/dynamic/GeneratorFactory.h"
|
||||
#include "playlist/dynamic/DynamicControl.h"
|
||||
#include "database/databasecommand_collectionattributes.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
@@ -61,6 +62,8 @@ public:
|
||||
|
||||
static QStringList styles();
|
||||
static QStringList moods();
|
||||
static QStringList userCatalogs();
|
||||
static QByteArray catalogId( const QString& collectionId );
|
||||
|
||||
signals:
|
||||
void paramsGenerated( const Echonest::DynamicPlaylist::PlaylistParams& );
|
||||
@@ -80,6 +83,7 @@ private slots:
|
||||
|
||||
void stylesReceived();
|
||||
void moodsReceived();
|
||||
void collectionAttributes(PairList);
|
||||
|
||||
void songLookupFinished();
|
||||
private:
|
||||
@@ -101,6 +105,9 @@ private:
|
||||
static QNetworkReply* s_stylesJob;
|
||||
static QNetworkReply* s_moodsJob;
|
||||
|
||||
static bool s_catalogsFetched;
|
||||
static QHash< QString, QString > s_catalogs;
|
||||
|
||||
// used for the intermediary song id lookup
|
||||
QSet< QNetworkReply* > m_waiting;
|
||||
Echonest::DynamicPlaylist::PlaylistParams m_storedParams;
|
||||
|
@@ -473,6 +473,20 @@ TomahawkSettings::setShowOfflineSources( bool show )
|
||||
setValue( "collection/sources/showoffline", show );
|
||||
}
|
||||
|
||||
bool
|
||||
TomahawkSettings::enableEchonestCatalogs() const
|
||||
{
|
||||
return value( "collection/enable_catalogs", false ).toBool();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setEnableEchonestCatalogs( bool enable )
|
||||
{
|
||||
setValue( "collection/enable_catalogs", enable );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
QByteArray
|
||||
TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const
|
||||
{
|
||||
|
@@ -76,6 +76,9 @@ public:
|
||||
bool showOfflineSources() const;
|
||||
void setShowOfflineSources( bool show );
|
||||
|
||||
bool enableEchonestCatalogs() const;
|
||||
void setEnableEchonestCatalogs( bool enable );
|
||||
|
||||
/// Playlist stuff
|
||||
QByteArray playlistColumnSizes( const QString& playlistid ) const;
|
||||
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
|
||||
|
@@ -136,6 +136,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
||||
|
||||
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
||||
ui->scannerTimeSpinBox->setValue( s->scannerTime() );
|
||||
ui->enableEchonestCatalog->setChecked( s->enableEchonestCatalogs() );
|
||||
|
||||
connect( ui->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
connect( ui->scannerDirModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
connect( ui->scannerFileModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||
@@ -239,6 +241,7 @@ SettingsDialog::~SettingsDialog()
|
||||
s->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() );
|
||||
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
||||
s->setScannerMode( ui->scannerFileModeButton->isChecked() ? TomahawkSettings::Files : TomahawkSettings::Dirs );
|
||||
s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() );
|
||||
|
||||
s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
|
||||
|
||||
@@ -510,7 +513,6 @@ SettingsDialog::onLastFmFinished()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsDialog::addScriptResolver()
|
||||
{
|
||||
|
@@ -66,9 +66,6 @@ public:
|
||||
explicit SettingsDialog( QWidget* parent = 0 );
|
||||
~SettingsDialog();
|
||||
|
||||
signals:
|
||||
void settingsChanged();
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* e );
|
||||
|
||||
|
@@ -211,6 +211,13 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableEchonestCatalog">
|
||||
<property name="text">
|
||||
<string>Upload catalog to The Echo Nest to enable recommended radios.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
||||
<property name="sizePolicy">
|
||||
|
@@ -56,6 +56,7 @@
|
||||
#include "pipeline.h"
|
||||
#include "utils/spotifyparser.h"
|
||||
#include "dropjob.h"
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
|
||||
#include "audio/audioengine.h"
|
||||
#include "utils/xspfloader.h"
|
||||
@@ -264,6 +265,8 @@ TomahawkApp::init()
|
||||
// Make sure to init GAM in the gui thread
|
||||
GlobalActionManager::instance();
|
||||
|
||||
// Set up echonest catalog synchronizer
|
||||
Tomahawk::EchonestCatalogSynchronizer::instance();
|
||||
// check if our spotify playlist api server is up and running, and enable spotify playlist drops if so
|
||||
QNetworkReply* r = TomahawkUtils::nam()->get( QNetworkRequest( QUrl( SPOTIFY_PLAYLIST_API_URL "/playlist/test" ) ) );
|
||||
connect( r, SIGNAL( finished() ), this, SLOT( spotifyApiCheckFinished() ) );
|
||||
|
Reference in New Issue
Block a user