mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-07 22:56:42 +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-23_to_24.sql</file>
|
||||||
<file>data/sql/dbmigrate-24_to_25.sql</file>
|
<file>data/sql/dbmigrate-24_to_25.sql</file>
|
||||||
<file>data/sql/dbmigrate-25_to_26.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/js/tomahawk.js</file>
|
||||||
<file>data/images/avatar_frame.png</file>
|
<file>data/images/avatar_frame.png</file>
|
||||||
<file>data/images/drop-all-songs.png</file>
|
<file>data/images/drop-all-songs.png</file>
|
||||||
|
@@ -35,6 +35,8 @@ set( libSources
|
|||||||
playlistinterface.cpp
|
playlistinterface.cpp
|
||||||
LatchManager.cpp
|
LatchManager.cpp
|
||||||
|
|
||||||
|
EchonestCatalogSynchronizer.cpp
|
||||||
|
|
||||||
sip/SipPlugin.cpp
|
sip/SipPlugin.cpp
|
||||||
sip/SipHandler.cpp
|
sip/SipHandler.cpp
|
||||||
sip/SipModel.cpp
|
sip/SipModel.cpp
|
||||||
@@ -95,6 +97,8 @@ set( libSources
|
|||||||
database/databasecommand_socialaction.cpp
|
database/databasecommand_socialaction.cpp
|
||||||
database/databasecommand_loadsocialactions.cpp
|
database/databasecommand_loadsocialactions.cpp
|
||||||
database/databasecommand_genericselect.cpp
|
database/databasecommand_genericselect.cpp
|
||||||
|
database/databasecommand_setcollectionattributes.cpp
|
||||||
|
database/databasecommand_collectionattributes.cpp
|
||||||
database/database.cpp
|
database/database.cpp
|
||||||
|
|
||||||
infobar/infobar.cpp
|
infobar/infobar.cpp
|
||||||
@@ -253,6 +257,8 @@ set( libHeaders
|
|||||||
album.h
|
album.h
|
||||||
playlist.h
|
playlist.h
|
||||||
|
|
||||||
|
EchonestCatalogSynchronizer.h
|
||||||
|
|
||||||
sip/SipPlugin.h
|
sip/SipPlugin.h
|
||||||
sip/SipHandler.h
|
sip/SipHandler.h
|
||||||
sip/SipModel.h
|
sip/SipModel.h
|
||||||
@@ -313,6 +319,8 @@ set( libHeaders
|
|||||||
database/databasecommand_socialaction.h
|
database/databasecommand_socialaction.h
|
||||||
database/databasecommand_loadsocialactions.h
|
database/databasecommand_loadsocialactions.h
|
||||||
database/databasecommand_genericselect.h
|
database/databasecommand_genericselect.h
|
||||||
|
database/databasecommand_setcollectionattributes.h
|
||||||
|
database/databasecommand_collectionattributes.h
|
||||||
|
|
||||||
infobar/infobar.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_sqlSelect( sqlSelect )
|
||||||
, m_queryType( type )
|
, m_queryType( type )
|
||||||
, m_limit( limit )
|
, 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
|
void
|
||||||
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
||||||
@@ -48,6 +57,26 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
|||||||
QList< artist_ptr > arts;
|
QList< artist_ptr > arts;
|
||||||
QList< album_ptr > albs;
|
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
|
// Expecting
|
||||||
while ( query.next() )
|
while ( query.next() )
|
||||||
{
|
{
|
||||||
|
@@ -24,6 +24,9 @@
|
|||||||
#include "databasecommand.h"
|
#include "databasecommand.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
#include "dllmacro.h"
|
#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, 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 void exec( DatabaseImpl* lib );
|
||||||
virtual bool doesMutates() const { return false; }
|
virtual bool doesMutates() const { return false; }
|
||||||
|
|
||||||
@@ -70,10 +74,14 @@ signals:
|
|||||||
void artists( const QList< Tomahawk::artist_ptr >& artists );
|
void artists( const QList< Tomahawk::artist_ptr >& artists );
|
||||||
void albums( const QList< Tomahawk::album_ptr >& albums );
|
void albums( const QList< Tomahawk::album_ptr >& albums );
|
||||||
|
|
||||||
|
void rawData( const QList< QStringList >& data );
|
||||||
private:
|
private:
|
||||||
QString m_sqlSelect;
|
QString m_sqlSelect;
|
||||||
QueryType m_queryType;
|
QueryType m_queryType;
|
||||||
int m_limit;
|
int m_limit;
|
||||||
|
bool m_raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QList<QStringList>);
|
||||||
|
|
||||||
#endif // DATABASECOMMAND_GENERICSELECT_H
|
#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"
|
#include "schema.sql.h"
|
||||||
|
|
||||||
#define CURRENT_SCHEMA_VERSION 26
|
#define CURRENT_SCHEMA_VERSION 27
|
||||||
|
|
||||||
|
|
||||||
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
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_id ON track_attributes(id);
|
||||||
CREATE INDEX track_attrib_k ON track_attributes(k);
|
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.
|
-- social attributes connected to the track.
|
||||||
-- like love, hate, comments, recommendations
|
-- like love, hate, comments, recommendations
|
||||||
-- love=[comment], hate=[comment], comment=Some text
|
-- love=[comment], hate=[comment], comment=Some text
|
||||||
@@ -283,4 +291,4 @@ CREATE TABLE IF NOT EXISTS settings (
|
|||||||
v TEXT NOT NULL DEFAULT ''
|
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 =
|
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_id ON track_attributes(id);"
|
||||||
"CREATE INDEX track_attrib_k ON track_attributes(k);"
|
"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 ("
|
"CREATE TABLE IF NOT EXISTS social_attributes ("
|
||||||
" id INTEGER REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, "
|
" 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, "
|
" 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,"
|
" k TEXT NOT NULL PRIMARY KEY,"
|
||||||
" v TEXT NOT NULL DEFAULT ''"
|
" 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()
|
const char * get_tomahawk_sql()
|
||||||
|
@@ -198,6 +198,29 @@ 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" ) {
|
||||||
|
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" ) {
|
} else if( selectedType() == "Song" ) {
|
||||||
m_currentType = Echonest::DynamicPlaylist::SongId;
|
m_currentType = Echonest::DynamicPlaylist::SongId;
|
||||||
|
|
||||||
@@ -230,6 +253,27 @@ Tomahawk::EchonestControl::updateWidgets()
|
|||||||
m_matchData = match->text();
|
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( updateData() ) );
|
||||||
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( editingFinished() ) );
|
connect( input->slider(), SIGNAL( valueChanged( int ) ), this, SLOT( editingFinished() ) );
|
||||||
|
|
||||||
@@ -440,7 +484,7 @@ Tomahawk::EchonestControl::updateData()
|
|||||||
m_data.first = m_currentType;
|
m_data.first = m_currentType;
|
||||||
m_data.second = edit->text();
|
m_data.second = edit->text();
|
||||||
}
|
}
|
||||||
} else if( selectedType() == "Variety" ) {
|
} 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 ) {
|
||||||
m_data.first = m_currentType;
|
m_data.first = m_currentType;
|
||||||
@@ -450,7 +494,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" ) {
|
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog 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() );
|
||||||
@@ -513,7 +557,7 @@ 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() == "Variety" ) {
|
} 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 )
|
||||||
s->slider()->setValue( m_data.second.toDouble() * 10000 );
|
s->slider()->setValue( m_data.second.toDouble() * 10000 );
|
||||||
@@ -521,7 +565,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" ) {
|
} else if( selectedType() == "Mode" || selectedType() == "Key" || selectedType() == "Mood" || selectedType() == "Style" || selectedType() == "Catalog Radio" ) {
|
||||||
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() );
|
||||||
|
@@ -21,6 +21,9 @@
|
|||||||
#include "dynamic/echonest/EchonestSteerer.h"
|
#include "dynamic/echonest/EchonestSteerer.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "utils/tomahawkutils.h"
|
#include "utils/tomahawkutils.h"
|
||||||
|
#include "tomahawksettings.h"
|
||||||
|
#include "database/databasecommand_collectionattributes.h"
|
||||||
|
#include "database/database.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -33,6 +36,9 @@ 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;
|
||||||
|
QHash< QString, QString > EchonestGenerator::s_catalogs = QHash< QString, QString >();
|
||||||
|
|
||||||
|
|
||||||
EchonestFactory::EchonestFactory()
|
EchonestFactory::EchonestFactory()
|
||||||
{
|
{
|
||||||
@@ -56,9 +62,16 @@ EchonestFactory::createControl( const QString& controlType )
|
|||||||
QStringList
|
QStringList
|
||||||
EchonestFactory::typeSelectors() const
|
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"
|
<< "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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +85,17 @@ 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() )
|
||||||
|
{
|
||||||
|
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();
|
// qDebug() << "ECHONEST:" << m_logo.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,6 +380,27 @@ EchonestGenerator::resetSteering()
|
|||||||
m_steerData.second = QString();
|
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
|
bool
|
||||||
EchonestGenerator::onlyThisArtistType( Echonest::DynamicPlaylist::ArtistTypeEnum type ) const throw( std::runtime_error )
|
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.
|
/// 1. catalog-radio: If any the entries are catalog types.
|
||||||
/// 2. artist-description: If all the artist entries are Description. If some were but not all, error out.
|
/// 2. artist: If all the artist controls are Limit-To. 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.
|
/// 3. artist-description: If all the artist entries are Description. 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.
|
/// 4. artist-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
||||||
if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistType ) )
|
/// 5. song-radio: If all the artist entries are Similar To. If some were but not all, error out.
|
||||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistType ) );
|
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 ) )
|
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistDescriptionType ) )
|
||||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||||
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistRadioType ) )
|
else if( onlyThisArtistType( Echonest::DynamicPlaylist::ArtistRadioType ) )
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "playlist/dynamic/GeneratorInterface.h"
|
#include "playlist/dynamic/GeneratorInterface.h"
|
||||||
#include "playlist/dynamic/GeneratorFactory.h"
|
#include "playlist/dynamic/GeneratorFactory.h"
|
||||||
#include "playlist/dynamic/DynamicControl.h"
|
#include "playlist/dynamic/DynamicControl.h"
|
||||||
|
#include "database/databasecommand_collectionattributes.h"
|
||||||
|
|
||||||
#include "dllmacro.h"
|
#include "dllmacro.h"
|
||||||
|
|
||||||
@@ -61,6 +62,8 @@ public:
|
|||||||
|
|
||||||
static QStringList styles();
|
static QStringList styles();
|
||||||
static QStringList moods();
|
static QStringList moods();
|
||||||
|
static QStringList userCatalogs();
|
||||||
|
static QByteArray catalogId( const QString& collectionId );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void paramsGenerated( const Echonest::DynamicPlaylist::PlaylistParams& );
|
void paramsGenerated( const Echonest::DynamicPlaylist::PlaylistParams& );
|
||||||
@@ -80,6 +83,7 @@ private slots:
|
|||||||
|
|
||||||
void stylesReceived();
|
void stylesReceived();
|
||||||
void moodsReceived();
|
void moodsReceived();
|
||||||
|
void collectionAttributes(PairList);
|
||||||
|
|
||||||
void songLookupFinished();
|
void songLookupFinished();
|
||||||
private:
|
private:
|
||||||
@@ -101,6 +105,9 @@ private:
|
|||||||
static QNetworkReply* s_stylesJob;
|
static QNetworkReply* s_stylesJob;
|
||||||
static QNetworkReply* s_moodsJob;
|
static QNetworkReply* s_moodsJob;
|
||||||
|
|
||||||
|
static bool s_catalogsFetched;
|
||||||
|
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;
|
||||||
Echonest::DynamicPlaylist::PlaylistParams m_storedParams;
|
Echonest::DynamicPlaylist::PlaylistParams m_storedParams;
|
||||||
|
@@ -473,6 +473,20 @@ TomahawkSettings::setShowOfflineSources( bool show )
|
|||||||
setValue( "collection/sources/showoffline", 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
|
QByteArray
|
||||||
TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const
|
TomahawkSettings::playlistColumnSizes( const QString& playlistid ) const
|
||||||
{
|
{
|
||||||
|
@@ -76,6 +76,9 @@ public:
|
|||||||
bool showOfflineSources() const;
|
bool showOfflineSources() const;
|
||||||
void setShowOfflineSources( bool show );
|
void setShowOfflineSources( bool show );
|
||||||
|
|
||||||
|
bool enableEchonestCatalogs() const;
|
||||||
|
void setEnableEchonestCatalogs( bool enable );
|
||||||
|
|
||||||
/// Playlist stuff
|
/// Playlist stuff
|
||||||
QByteArray playlistColumnSizes( const QString& playlistid ) const;
|
QByteArray playlistColumnSizes( const QString& playlistid ) const;
|
||||||
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
|
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
|
||||||
|
@@ -136,6 +136,8 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
|
|
||||||
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
ui->checkBoxWatchForChanges->setChecked( s->watchForChanges() );
|
||||||
ui->scannerTimeSpinBox->setValue( s->scannerTime() );
|
ui->scannerTimeSpinBox->setValue( s->scannerTime() );
|
||||||
|
ui->enableEchonestCatalog->setChecked( s->enableEchonestCatalogs() );
|
||||||
|
|
||||||
connect( ui->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
connect( ui->checkBoxWatchForChanges, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||||
connect( ui->scannerDirModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
connect( ui->scannerDirModeButton, SIGNAL( clicked( bool ) ), SLOT( updateScanOptionsView() ) );
|
||||||
connect( ui->scannerFileModeButton, 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->setWatchForChanges( ui->checkBoxWatchForChanges->isChecked() );
|
||||||
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
||||||
s->setScannerMode( ui->scannerFileModeButton->isChecked() ? TomahawkSettings::Files : TomahawkSettings::Dirs );
|
s->setScannerMode( ui->scannerFileModeButton->isChecked() ? TomahawkSettings::Files : TomahawkSettings::Dirs );
|
||||||
|
s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() );
|
||||||
|
|
||||||
s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
|
s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
|
||||||
|
|
||||||
@@ -510,7 +513,6 @@ SettingsDialog::onLastFmFinished()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsDialog::addScriptResolver()
|
SettingsDialog::addScriptResolver()
|
||||||
{
|
{
|
||||||
|
@@ -66,9 +66,6 @@ public:
|
|||||||
explicit SettingsDialog( QWidget* parent = 0 );
|
explicit SettingsDialog( QWidget* parent = 0 );
|
||||||
~SettingsDialog();
|
~SettingsDialog();
|
||||||
|
|
||||||
signals:
|
|
||||||
void settingsChanged();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent( QEvent* e );
|
void changeEvent( QEvent* e );
|
||||||
|
|
||||||
|
@@ -211,6 +211,13 @@
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<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>
|
<item>
|
||||||
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
<widget class="QCheckBox" name="checkBoxWatchForChanges">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@@ -56,6 +56,7 @@
|
|||||||
#include "pipeline.h"
|
#include "pipeline.h"
|
||||||
#include "utils/spotifyparser.h"
|
#include "utils/spotifyparser.h"
|
||||||
#include "dropjob.h"
|
#include "dropjob.h"
|
||||||
|
#include "EchonestCatalogSynchronizer.h"
|
||||||
|
|
||||||
#include "audio/audioengine.h"
|
#include "audio/audioengine.h"
|
||||||
#include "utils/xspfloader.h"
|
#include "utils/xspfloader.h"
|
||||||
@@ -264,6 +265,8 @@ TomahawkApp::init()
|
|||||||
// Make sure to init GAM in the gui thread
|
// Make sure to init GAM in the gui thread
|
||||||
GlobalActionManager::instance();
|
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
|
// 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" ) ) );
|
QNetworkReply* r = TomahawkUtils::nam()->get( QNetworkRequest( QUrl( SPOTIFY_PLAYLIST_API_URL "/playlist/test" ) ) );
|
||||||
connect( r, SIGNAL( finished() ), this, SLOT( spotifyApiCheckFinished() ) );
|
connect( r, SIGNAL( finished() ), this, SLOT( spotifyApiCheckFinished() ) );
|
||||||
|
Reference in New Issue
Block a user