1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-05 21:57:41 +02:00

Create and load database-backed special dynamic playlists, and fix some debugs and stuff

This commit is contained in:
Leo Franchi
2011-07-30 15:35:32 -04:00
parent ca467fb5bc
commit c76fabbc2b
15 changed files with 169 additions and 50 deletions

View File

@@ -31,7 +31,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( QObject* parent
: DatabaseCommandLoggable( parent ) : DatabaseCommandLoggable( parent )
, m_report( true ) , m_report( true )
{ {
qDebug() << Q_FUNC_INFO << "def";
} }
@@ -41,7 +40,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( const source_ptr
, m_playlist( playlist ) , m_playlist( playlist )
, m_report( false ) //this ctor used when creating locally, reporting done elsewhere , m_report( false ) //this ctor used when creating locally, reporting done elsewhere
{ {
qDebug() << Q_FUNC_INFO;
} }
@@ -55,7 +53,6 @@ DatabaseCommand_CreatePlaylist::exec( DatabaseImpl* lib )
void void
DatabaseCommand_CreatePlaylist::postCommitHook() DatabaseCommand_CreatePlaylist::postCommitHook()
{ {
qDebug() << Q_FUNC_INFO;
if ( m_report == false ) if ( m_report == false )
return; return;
@@ -122,7 +119,6 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
cre.bindValue( ":creator", m.value( "creator" ) ); cre.bindValue( ":creator", m.value( "creator" ) );
cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) ); cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) );
} }
tDebug() << "CREATE PLAYLIST:" << cre.boundValues();
cre.exec(); cre.exec();
} }

View File

@@ -37,14 +37,13 @@ DatabaseCommand_GenericSelect::DatabaseCommand_GenericSelect( const QString& sql
void void
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi ) DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
{ {
Q_ASSERT( source()->isLocal() || source()->id() >= 1 );
TomahawkSqlQuery query = dbi->newquery(); TomahawkSqlQuery query = dbi->newquery();
query.exec( m_sqlSelect ); query.prepare( m_sqlSelect );
query.exec();
QList< query_ptr > queries; QList< query_ptr > queries;
// Expecting // Expecting
while ( query.next() ) while ( query.next() )
{ {
@@ -54,9 +53,20 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
QString artist, track, album; QString artist, track, album;
track = query.value( 0 ).toString(); track = query.value( 0 ).toString();
artist = query.value( 1 ).toString(); artist = query.value( 1 ).toString();
album = query.value( 2 ).toString();
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album, uuid(), true ); // Only auto-resolve non-local results
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, QString(), uuid(), true ); // Only auto-resolve non-local results
QVariantList extraData;
int count = 2;
while ( query.value( count ).isValid() )
{
extraData << query.value( count );
count++;
}
if( !extraData.isEmpty() )
qry->setProperty( "data", extraData );
queries << qry; queries << qry;
} }

View File

@@ -32,7 +32,9 @@
* that match. * that match.
* *
* In order for the conversion to query_ptr to work, the SELECT command should select the following items: * In order for the conversion to query_ptr to work, the SELECT command should select the following items:
* track.name, artist.name, album.name * track.name, artist.name [, optional extra values ]
*
* Any extra values in the resultset will be returned as a QVariantList attached to the "data" property of each query_ptr
* *
*/ */
class DLLEXPORT DatabaseCommand_GenericSelect : public DatabaseCommand class DLLEXPORT DatabaseCommand_GenericSelect : public DatabaseCommand

View File

@@ -40,6 +40,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
, m_type( type ) , m_type( type )
, m_mode( mode ) , m_mode( mode )
, m_controls( controls ) , m_controls( controls )
, m_playlist( 0 )
{ {
} }
@@ -56,6 +57,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
, m_type( type ) , m_type( type )
, m_mode( mode ) , m_mode( mode )
, m_controls( controls ) , m_controls( controls )
, m_playlist( 0 )
{ {
} }
@@ -100,21 +102,28 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() ); dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() );
if ( playlist.isNull() ) if ( playlist.isNull() )
playlist = source()->collection()->station( playlistguid() ); playlist = source()->collection()->station( playlistguid() );
// UGH we don't have a sharedptr from DynamicPlaylist+
DynamicPlaylist* rawPl = playlist.data();
if( playlist.isNull() ) // if it's neither an auto or station, it must not be auto-loaded, so we MUST have been told about it directly
rawPl = m_playlist;
// workaround a bug in pre-0.1.0 tomahawks. they created dynamic playlists in OnDemand mode *always*, and then set the mode to the real one. // workaround a bug in pre-0.1.0 tomahawks. they created dynamic playlists in OnDemand mode *always*, and then set the mode to the real one.
// now that we separate them, if we get them as one and then get a changed mode, the playlist ends up in the wrong bucket in Collection. // now that we separate them, if we get them as one and then get a changed mode, the playlist ends up in the wrong bucket in Collection.
// so here we fix it if we have to. // so here we fix it if we have to.
// HACK // HACK
tDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull(); tDebug() << "Does this need the 0.3->0.1 playlist category hack fix?" << ( rawPl->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() )
if( playlist->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here << ( rawPl->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() )
<< rawPl->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
if( rawPl->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here
source()->collection()->moveStationToAuto( playlistguid() ); source()->collection()->moveStationToAuto( playlistguid() );
else if ( playlist->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() ) // should be here else if ( rawPl->mode() == OnDemand && source()->collection()->station( playlistguid() ).isNull() ) // should be here
source()->collection()->moveAutoToStation( playlistguid() ); source()->collection()->moveAutoToStation( playlistguid() );
if ( playlist.isNull() ) if ( rawPl == 0 )
{ {
tLog() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static); tLog() <<"Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->collection()->name() << "and mode is static?:" << (m_mode == Static);
Q_ASSERT( !playlist.isNull() ); Q_ASSERT( false );
return; return;
} }
if ( !m_controlsV.isEmpty() && m_controls.isEmpty() ) if ( !m_controlsV.isEmpty() && m_controls.isEmpty() )
@@ -124,13 +133,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
controlMap << v.toMap(); controlMap << v.toMap();
if ( m_mode == OnDemand ) if ( m_mode == OnDemand )
playlist->setRevision( newrev(), rawPl->setRevision( newrev(),
true, // this *is* the newest revision so far true, // this *is* the newest revision so far
m_type, m_type,
controlMap, controlMap,
m_applied ); m_applied );
else else
playlist->setRevision( newrev(), rawPl->setRevision( newrev(),
orderedentriesguids, orderedentriesguids,
m_previous_rev_orderedguids, m_previous_rev_orderedguids,
m_type, m_type,
@@ -142,13 +151,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
else else
{ {
if ( m_mode == OnDemand ) if ( m_mode == OnDemand )
playlist->setRevision( newrev(), rawPl->setRevision( newrev(),
true, // this *is* the newest revision so far true, // this *is* the newest revision so far
m_type, m_type,
m_controls, m_controls,
m_applied ); m_applied );
else else
playlist->setRevision( newrev(), rawPl->setRevision( newrev(),
orderedentriesguids, orderedentriesguids,
m_previous_rev_orderedguids, m_previous_rev_orderedguids,
m_type, m_type,
@@ -251,3 +260,9 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
query2.exec(); query2.exec();
} }
} }
void
DatabaseCommand_SetDynamicPlaylistRevision::setPlaylist( DynamicPlaylist* pl )
{
m_playlist = pl;
}

View File

@@ -78,11 +78,16 @@ public:
void setType( const QString& type ) { m_type = type; } void setType( const QString& type ) { m_type = type; }
void setMode( int mode ) { m_mode = (GeneratorMode)mode; } void setMode( int mode ) { m_mode = (GeneratorMode)mode; }
void setPlaylist( DynamicPlaylist* pl ); // raw pointer b/c we don't have the shared pointer from inside the shared pointer
private: private:
QString m_type; QString m_type;
GeneratorMode m_mode; GeneratorMode m_mode;
QList< dyncontrol_ptr > m_controls; QList< dyncontrol_ptr > m_controls;
QList< QVariant > m_controlsV; QList< QVariant > m_controlsV;
// ARG i hate sharedpointers sometimes
DynamicPlaylist* m_playlist; // Only used if setting revision of a non-autoloaded playlist, as those aren't able to be looked up by guid
}; };
#endif // DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H #endif // DATABASECOMMAND_SETDYNAMICPLAYLISTREVISION_H

View File

@@ -59,7 +59,7 @@ public:
int e = t.elapsed(); int e = t.elapsed();
if ( e >= TOMAHAWK_QUERY_THRESHOLD ) if ( e >= TOMAHAWK_QUERY_THRESHOLD )
qDebug() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms"; tLog() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms";
return ret; return ret;
} }
@@ -67,11 +67,10 @@ public:
private: private:
void showError() void showError()
{ {
qDebug() tLog() << "\n" << "*** DATABASE ERROR ***" << "\n"
<< endl << "*** DATABASE ERROR ***" << endl << this->lastQuery() << "\n"
<< this->lastQuery() << endl << "boundValues:" << this->boundValues() << "\n"
<< "boundValues:" << this->boundValues() << endl << this->lastError().text() << "\n"
<< this->lastError().text() << endl
; ;
Q_ASSERT( false ); Q_ASSERT( false );
} }

View File

@@ -59,6 +59,7 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
int lastmod, int lastmod,
const QString& guid ) const QString& guid )
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid ) : Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
, m_autoLoad( false )
{ {
// qDebug() << "Creating Dynamic Playlist 1"; // qDebug() << "Creating Dynamic Playlist 1";
// TODO instantiate generator // TODO instantiate generator
@@ -75,8 +76,10 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
const QString& creator, const QString& creator,
const QString& type, const QString& type,
GeneratorMode mode, GeneratorMode mode,
bool shared ) bool shared,
bool autoLoad )
: Playlist ( author, guid, title, info, creator, shared ) : Playlist ( author, guid, title, info, creator, shared )
, m_autoLoad( autoLoad )
{ {
// qDebug() << "Creating Dynamic Playlist 2"; // qDebug() << "Creating Dynamic Playlist 2";
m_generator = geninterface_ptr( GeneratorFactory::create( type ) ); m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
@@ -127,14 +130,17 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author,
const QString& creator, const QString& creator,
GeneratorMode mode, GeneratorMode mode,
bool shared, bool shared,
const QString& type ) const QString& type,
bool autoLoad
)
{ {
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared ) ); dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared, autoLoad ) );
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist ); DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist, autoLoad );
connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
dynplaylist->reportCreated( dynplaylist ); if( autoLoad )
dynplaylist->reportCreated( dynplaylist );
return dynplaylist; return dynplaylist;
} }
@@ -187,6 +193,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
type, type,
Static, Static,
controls ); controls );
if( !m_autoLoad )
cmd->setPlaylist( this );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
} }
@@ -211,6 +220,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
type, type,
OnDemand, OnDemand,
controls ); controls );
if( !m_autoLoad )
cmd->setPlaylist( this );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) ); Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
} }

View File

@@ -69,6 +69,7 @@ class DLLEXPORT DynamicPlaylist : public Playlist
// :-( int becuase qjson chokes on my enums // :-( int becuase qjson chokes on my enums
Q_PROPERTY( int mode WRITE setMode READ mode ) Q_PROPERTY( int mode WRITE setMode READ mode )
Q_PROPERTY( QString type WRITE setType READ type ) Q_PROPERTY( QString type WRITE setType READ type )
Q_PROPERTY( bool autoLoad READ autoLoad )
friend class ::DatabaseCommand_SetDynamicPlaylistRevision; friend class ::DatabaseCommand_SetDynamicPlaylistRevision;
friend class ::DatabaseCommand_CreateDynamicPlaylist; friend class ::DatabaseCommand_CreateDynamicPlaylist;
@@ -86,7 +87,9 @@ public:
const QString& creator, const QString& creator,
GeneratorMode mode, GeneratorMode mode,
bool shared, bool shared,
const QString& type = QString() ); const QString& type = QString(),
bool autoLoad = true
);
static bool remove( const dynplaylist_ptr& playlist ); static bool remove( const dynplaylist_ptr& playlist );
virtual void loadRevision( const QString& rev = "" ); virtual void loadRevision( const QString& rev = "" );
@@ -95,6 +98,7 @@ public:
int mode() const; int mode() const;
QString type() const; QString type() const;
geninterface_ptr generator() const; geninterface_ptr generator() const;
bool autoLoad() const { return m_autoLoad; }
// Creates a new revision from the playlist in memory. Use this is you change the controls or // Creates a new revision from the playlist in memory. Use this is you change the controls or
// mode of a playlist and want to save it to db/others. // mode of a playlist and want to save it to db/others.
@@ -186,10 +190,13 @@ private:
const QString& creator, const QString& creator,
const QString& type, const QString& type,
GeneratorMode mode, GeneratorMode mode,
bool shared ); bool shared,
bool autoLoad = true );
QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV ); QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV );
geninterface_ptr m_generator; geninterface_ptr m_generator;
bool m_autoLoad;
}; };
}; // namespace }; // namespace

View File

@@ -36,7 +36,7 @@ DatabaseControl::DatabaseControl( const QString& selectedType, const QStringList
} }
DatabaseControl::DatabaseControl( const QString& sql, const QString& summary, const QStringList& typeSelectors, QObject* parent ) DatabaseControl::DatabaseControl( const QString& sql, const QString& summary, const QStringList& typeSelectors, QObject* parent )
: DynamicControl ( typeSelectors ) : DynamicControl ( "SQL", typeSelectors )
, m_sql( sql ) , m_sql( sql )
, m_sqlSummary( summary ) , m_sqlSummary( summary )
{ {

View File

@@ -53,7 +53,11 @@ DatabaseFactory::typeSelectors() const
DatabaseGenerator::DatabaseGenerator ( QObject* parent ) DatabaseGenerator::DatabaseGenerator ( QObject* parent )
: GeneratorInterface ( parent ) : GeneratorInterface ( parent )
, m_curCountRequested( 0 )
{ {
// defaults
m_type = "database";
m_mode = Static;
// m_logo.load( RESPATH "images ) // m_logo.load( RESPATH "images )
} }
@@ -85,41 +89,62 @@ void
DatabaseGenerator::generate( int number ) DatabaseGenerator::generate( int number )
{ {
tLog() << "Generating" << number << "tracks for this database dynamic playlist with" << m_controls.size() << "controls:"; tLog() << "Generating" << number << "tracks for this database dynamic playlist with" << m_controls.size() << "controls:";
if ( m_controls.isEmpty() )
{
qWarning() << "No controls, can't generate...!";
emit error( "Failed to generate tracks", "No controls!" );
return;
}
foreach ( const dyncontrol_ptr& ctrl, m_controls ) foreach ( const dyncontrol_ptr& ctrl, m_controls )
qDebug() << ctrl->selectedType() << ctrl->match() << ctrl->input(); qDebug() << ctrl->selectedType() << ctrl->match() << ctrl->input();
// TODO for now, we just support the special "SQL" control, not meant to be shown to the user. Just does a raw query. // TODO for now, we just support the special "SQL" control, not meant to be shown to the user. Just does a raw query.
bool isSql = false; bool hasSql = false;
bool hasOther = false;
foreach ( const dyncontrol_ptr& ctrl, m_controls ) foreach ( const dyncontrol_ptr& ctrl, m_controls )
{ {
if( ctrl->selectedType() == "SQL" ) if ( ctrl->selectedType() == "SQL" )
isSql = true; hasSql = true;
else if( !isSql ) else
{ hasOther = true;
qWarning() << "Cannot mix sql and non-sql controls!"; }
emit error( "Failed to generate tracks", "Cannot mix sql and non-sql controls" ); if ( hasSql == hasOther )
} {
qWarning() << "Cannot mix sql and non-sql controls!";
emit error( "Failed to generate tracks", "Cannot mix sql and non-sql controls" );
return;
} }
// TODO for now we just support 1 sql query if we're a sql type // TODO for now we just support 1 sql query if we're a sql type
if ( isSql ) if ( hasSql )
{ {
dyncontrol_ptr control = m_controls.first(); dyncontrol_ptr control = m_controls.first();
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( control.dynamicCast< DatabaseControl >()->sql(), this ); tDebug() << "Generated sql query:" << control.dynamicCast< DatabaseControl >()->sql();
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SIGNAL( tracksGenerated( QList<Tomahawk::query_ptr> ) ) ); DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( control.dynamicCast< DatabaseControl >()->sql() );
m_curCountRequested = number; // Can't set count on dbcmd itself as sender() in slot is 0
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
return; return;
} }
} }
void void
DatabaseGenerator::tracksGenerated ( const QList< query_ptr >& tracks ) DatabaseGenerator::tracksGenerated ( const QList< query_ptr >& tracks )
{ {
emit generated( tracks ); if( m_curCountRequested == 0 )
return;
if ( m_curCountRequested < tracks.size() )
emit generated( tracks.mid( 0, m_curCountRequested ) );
else
emit generated( tracks );
m_curCountRequested = 0;
} }

View File

@@ -73,6 +73,7 @@ namespace Tomahawk
private: private:
QPixmap m_logo; QPixmap m_logo;
int m_curCountRequested;
}; };
}; };

View File

@@ -22,6 +22,9 @@
#include "database/databasecommand_loaddynamicplaylist.h" #include "database/databasecommand_loaddynamicplaylist.h"
#include "database/database.h" #include "database/database.h"
#include "sourcelist.h" #include "sourcelist.h"
#include "dynamic/GeneratorInterface.h"
#include "dynamic/database/DatabaseGenerator.h"
#include "utils/logger.h"
#define COOLPLAYLIST_GUID "TOMAHAWK_COOLPLAYLISTOHAI_GUID" #define COOLPLAYLIST_GUID "TOMAHAWK_COOLPLAYLISTOHAI_GUID"
@@ -68,6 +71,9 @@ SocialPlaylistWidget::dynamicPlaylistLoaded ( const dynplaylist_ptr& ptr )
m_coolQuery1 = ptr; m_coolQuery1 = ptr;
tLog() << "SocialPlaylistWidget got dynplaylist loaded with currev: " << m_coolQuery1->currentrevision(); tLog() << "SocialPlaylistWidget got dynplaylist loaded with currev: " << m_coolQuery1->currentrevision();
connect( m_coolQuery1.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) ); connect( m_coolQuery1.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) );
connect( m_coolQuery1->generator().data(), SIGNAL(generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
connect( m_coolQuery1->generator().data(), SIGNAL(generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
m_coolQuery1->loadRevision( m_coolQuery1->currentrevision() ); m_coolQuery1->loadRevision( m_coolQuery1->currentrevision() );
} }
@@ -75,6 +81,11 @@ void
SocialPlaylistWidget::playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) SocialPlaylistWidget::playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision )
{ {
m_coolQuery1Model->loadPlaylist( m_coolQuery1 ); m_coolQuery1Model->loadPlaylist( m_coolQuery1 );
m_coolQuery1->resolve();
if ( m_coolQuery1->entries().isEmpty() ) // Generate some
m_coolQuery1->generator()->generate( 30 );
} }
void void
@@ -90,5 +101,38 @@ SocialPlaylistWidget::dynamicPlaylistLoadDone()
void void
SocialPlaylistWidget::createPlaylist() SocialPlaylistWidget::createPlaylist()
{ {
// TODO // Ok, lets create our playlist
/**
* select count(*) as counter, track.name, artist.name from (select track from playback_log group by track, source), track, artist where track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
s elect count(*) as counter, playback_log.track, track.name, artist.name from playback_log, track, artist where track.id = playback_log.track and artist.id = track.artist group by playback_log.track order by counter desc limit 0,10; *
select count(*) as counter, track.name, artist.name from (select track from playback_log group by track, source), track, artist where track not in (select track from playback_log where source is null group by track) and track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
select count(*) as counter, track.name, artist.name from (select track from playback_log where source > 0 group by track, source), track, artist where track.id = track and artist.id = track.artist group by track order by counter desc limit 0,20;
*/
m_coolQuery1 = DynamicPlaylist::create( SourceList::instance()->getLocal(), COOLPLAYLIST_GUID, "Cool Playlist!", QString(), QString(), Static, false, "database", false );
connect( m_coolQuery1.data(), SIGNAL( created() ), this, SLOT( playlist1Created() ) );
}
void
SocialPlaylistWidget::playlist1Created()
{
Q_ASSERT( m_coolQuery1->generator().dynamicCast< DatabaseGenerator >() );
QString sql = "select track.name, artist.name, count(*) as counter from (select track from playback_log group by track, source), track, artist where track.id = track and artist.id = track.artist group by track order by counter desc limit 0,100;";
dyncontrol_ptr control = m_coolQuery1->generator().dynamicCast< DatabaseGenerator >()->createControl( sql, "This is a cool playlist!" );
m_coolQuery1->createNewRevision( uuid() );
connect( m_coolQuery1.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ), this, SLOT( playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision ) ) );
connect( m_coolQuery1->generator().data(), SIGNAL(generated( QList<Tomahawk::query_ptr> ) ), this, SLOT( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
}
void
SocialPlaylistWidget::tracksGenerated( QList< query_ptr > queries )
{
if ( sender() == m_coolQuery1->generator().data() )
{
tDebug() << "Got generated tracks from playlist, adding" << queries.size() << "tracks";
m_coolQuery1Model->clear();
m_coolQuery1->addEntries( queries, m_coolQuery1->currentrevision() );
}
} }

View File

@@ -74,8 +74,11 @@ signals:
private slots: private slots:
void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& ptr ); void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& ptr );
void playlistRevisionLoaded ( Tomahawk::DynamicPlaylistRevision ); void playlistRevisionLoaded ( Tomahawk::DynamicPlaylistRevision );
void tracksGenerated ( QList<Tomahawk::query_ptr> );
void dynamicPlaylistLoadDone(); void dynamicPlaylistLoadDone();
void playlist1Created();
private: private:
void load(); void load();
void createPlaylist(); void createPlaylist();

View File

@@ -72,9 +72,6 @@ public:
virtual QIcon icon() const; virtual QIcon icon() const;
virtual QWidget* configWidget(); virtual QWidget* configWidget();
signals:
void avatarReceived( QString, QPixmap );
public slots: public slots:
virtual bool connectPlugin( bool startup ); virtual bool connectPlugin( bool startup );
void disconnectPlugin(); void disconnectPlugin();

View File

@@ -40,6 +40,7 @@
#include "sip/SipHandler.h" #include "sip/SipHandler.h"
#include "playlist/dynamic/GeneratorFactory.h" #include "playlist/dynamic/GeneratorFactory.h"
#include "playlist/dynamic/echonest/EchonestGenerator.h" #include "playlist/dynamic/echonest/EchonestGenerator.h"
#include "playlist/dynamic/database/DatabaseGenerator.h"
#include "web/api_v1.h" #include "web/api_v1.h"
#include "resolvers/scriptresolver.h" #include "resolvers/scriptresolver.h"
#include "resolvers/qtscriptresolver.h" #include "resolvers/qtscriptresolver.h"
@@ -175,6 +176,8 @@ TomahawkApp::init()
tDebug() << "Init Echonest Factory."; tDebug() << "Init Echonest Factory.";
GeneratorFactory::registerFactory( "echonest", new EchonestFactory ); GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
tDebug() << "Init Database Factory.";
GeneratorFactory::registerFactory( "database", new DatabaseFactory );
// Register shortcut handler for this platform // Register shortcut handler for this platform
#ifdef Q_WS_MAC #ifdef Q_WS_MAC