mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-04-22 00:42:04 +02:00
Create and load database-backed special dynamic playlists, and fix some debugs and stuff
This commit is contained in:
parent
ca467fb5bc
commit
c76fabbc2b
src
libtomahawk
database
databasecommand_createplaylist.cppdatabasecommand_genericselect.cppdatabasecommand_genericselect.hdatabasecommand_setdynamicplaylistrevision.cppdatabasecommand_setdynamicplaylistrevision.htomahawksqlquery.h
playlist/dynamic
widgets
sip/twitter
tomahawkapp.cpp@ -31,7 +31,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( QObject* parent
|
||||
: DatabaseCommandLoggable( parent )
|
||||
, m_report( true )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "def";
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +40,6 @@ DatabaseCommand_CreatePlaylist::DatabaseCommand_CreatePlaylist( const source_ptr
|
||||
, m_playlist( playlist )
|
||||
, 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
|
||||
DatabaseCommand_CreatePlaylist::postCommitHook()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( m_report == false )
|
||||
return;
|
||||
|
||||
@ -122,7 +119,6 @@ DatabaseCommand_CreatePlaylist::createPlaylist( DatabaseImpl* lib, bool dynamic)
|
||||
cre.bindValue( ":creator", m.value( "creator" ) );
|
||||
cre.bindValue( ":lastmodified", m.value( "lastmodified", 0 ) );
|
||||
}
|
||||
tDebug() << "CREATE PLAYLIST:" << cre.boundValues();
|
||||
|
||||
cre.exec();
|
||||
}
|
||||
|
@ -37,14 +37,13 @@ DatabaseCommand_GenericSelect::DatabaseCommand_GenericSelect( const QString& sql
|
||||
void
|
||||
DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
Q_ASSERT( source()->isLocal() || source()->id() >= 1 );
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
|
||||
query.exec( m_sqlSelect );
|
||||
query.prepare( m_sqlSelect );
|
||||
query.exec();
|
||||
|
||||
QList< query_ptr > queries;
|
||||
|
||||
|
||||
// Expecting
|
||||
while ( query.next() )
|
||||
{
|
||||
@ -54,9 +53,20 @@ DatabaseCommand_GenericSelect::exec( DatabaseImpl* dbi )
|
||||
QString artist, track, album;
|
||||
track = query.value( 0 ).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;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,9 @@
|
||||
* that match.
|
||||
*
|
||||
* 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
|
||||
|
@ -40,6 +40,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
|
||||
, m_type( type )
|
||||
, m_mode( mode )
|
||||
, m_controls( controls )
|
||||
, m_playlist( 0 )
|
||||
{
|
||||
|
||||
}
|
||||
@ -56,6 +57,7 @@ DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRe
|
||||
, m_type( type )
|
||||
, m_mode( mode )
|
||||
, m_controls( controls )
|
||||
, m_playlist( 0 )
|
||||
{
|
||||
|
||||
}
|
||||
@ -100,21 +102,28 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
dynplaylist_ptr playlist = source()->collection()->autoPlaylist( playlistguid() );
|
||||
if ( playlist.isNull() )
|
||||
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.
|
||||
// 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.
|
||||
// HACK
|
||||
tDebug() << "Does this need FIXING?" << playlist->mode() << source()->collection()->autoPlaylist( playlistguid() ).isNull() << source()->collection()->station( playlistguid() ).isNull();
|
||||
if( playlist->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() ) // should be here
|
||||
tDebug() << "Does this need the 0.3->0.1 playlist category hack fix?" << ( rawPl->mode() == Static && source()->collection()->autoPlaylist( playlistguid() ).isNull() )
|
||||
<< ( 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() );
|
||||
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() );
|
||||
|
||||
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);
|
||||
Q_ASSERT( !playlist.isNull() );
|
||||
Q_ASSERT( false );
|
||||
return;
|
||||
}
|
||||
if ( !m_controlsV.isEmpty() && m_controls.isEmpty() )
|
||||
@ -124,13 +133,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
controlMap << v.toMap();
|
||||
|
||||
if ( m_mode == OnDemand )
|
||||
playlist->setRevision( newrev(),
|
||||
rawPl->setRevision( newrev(),
|
||||
true, // this *is* the newest revision so far
|
||||
m_type,
|
||||
controlMap,
|
||||
m_applied );
|
||||
else
|
||||
playlist->setRevision( newrev(),
|
||||
rawPl->setRevision( newrev(),
|
||||
orderedentriesguids,
|
||||
m_previous_rev_orderedguids,
|
||||
m_type,
|
||||
@ -142,13 +151,13 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
else
|
||||
{
|
||||
if ( m_mode == OnDemand )
|
||||
playlist->setRevision( newrev(),
|
||||
rawPl->setRevision( newrev(),
|
||||
true, // this *is* the newest revision so far
|
||||
m_type,
|
||||
m_controls,
|
||||
m_applied );
|
||||
else
|
||||
playlist->setRevision( newrev(),
|
||||
rawPl->setRevision( newrev(),
|
||||
orderedentriesguids,
|
||||
m_previous_rev_orderedguids,
|
||||
m_type,
|
||||
@ -251,3 +260,9 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
|
||||
query2.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::setPlaylist( DynamicPlaylist* pl )
|
||||
{
|
||||
m_playlist = pl;
|
||||
}
|
||||
|
@ -78,11 +78,16 @@ public:
|
||||
void setType( const QString& type ) { m_type = type; }
|
||||
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:
|
||||
QString m_type;
|
||||
GeneratorMode m_mode;
|
||||
QList< dyncontrol_ptr > m_controls;
|
||||
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
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
|
||||
int e = t.elapsed();
|
||||
if ( e >= TOMAHAWK_QUERY_THRESHOLD )
|
||||
qDebug() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms";
|
||||
tLog() << "TomahawkSqlQuery (" << lastQuery() << ") finished in" << t.elapsed() << "ms";
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -67,11 +67,10 @@ public:
|
||||
private:
|
||||
void showError()
|
||||
{
|
||||
qDebug()
|
||||
<< endl << "*** DATABASE ERROR ***" << endl
|
||||
<< this->lastQuery() << endl
|
||||
<< "boundValues:" << this->boundValues() << endl
|
||||
<< this->lastError().text() << endl
|
||||
tLog() << "\n" << "*** DATABASE ERROR ***" << "\n"
|
||||
<< this->lastQuery() << "\n"
|
||||
<< "boundValues:" << this->boundValues() << "\n"
|
||||
<< this->lastError().text() << "\n"
|
||||
;
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
|
||||
int lastmod,
|
||||
const QString& guid )
|
||||
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
|
||||
, m_autoLoad( false )
|
||||
{
|
||||
// qDebug() << "Creating Dynamic Playlist 1";
|
||||
// TODO instantiate generator
|
||||
@ -75,8 +76,10 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
|
||||
const QString& creator,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
bool shared )
|
||||
bool shared,
|
||||
bool autoLoad )
|
||||
: Playlist ( author, guid, title, info, creator, shared )
|
||||
, m_autoLoad( autoLoad )
|
||||
{
|
||||
// qDebug() << "Creating Dynamic Playlist 2";
|
||||
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
||||
@ -127,14 +130,17 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author,
|
||||
const QString& creator,
|
||||
GeneratorMode mode,
|
||||
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()) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
dynplaylist->reportCreated( dynplaylist );
|
||||
if( autoLoad )
|
||||
dynplaylist->reportCreated( dynplaylist );
|
||||
return dynplaylist;
|
||||
}
|
||||
|
||||
@ -187,6 +193,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||
type,
|
||||
Static,
|
||||
controls );
|
||||
if( !m_autoLoad )
|
||||
cmd->setPlaylist( this );
|
||||
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
|
||||
@ -211,6 +220,9 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||
type,
|
||||
OnDemand,
|
||||
controls );
|
||||
if( !m_autoLoad )
|
||||
cmd->setPlaylist( this );
|
||||
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@ class DLLEXPORT DynamicPlaylist : public Playlist
|
||||
// :-( int becuase qjson chokes on my enums
|
||||
Q_PROPERTY( int mode WRITE setMode READ mode )
|
||||
Q_PROPERTY( QString type WRITE setType READ type )
|
||||
Q_PROPERTY( bool autoLoad READ autoLoad )
|
||||
|
||||
friend class ::DatabaseCommand_SetDynamicPlaylistRevision;
|
||||
friend class ::DatabaseCommand_CreateDynamicPlaylist;
|
||||
@ -86,7 +87,9 @@ public:
|
||||
const QString& creator,
|
||||
GeneratorMode mode,
|
||||
bool shared,
|
||||
const QString& type = QString() );
|
||||
const QString& type = QString(),
|
||||
bool autoLoad = true
|
||||
);
|
||||
|
||||
static bool remove( const dynplaylist_ptr& playlist );
|
||||
virtual void loadRevision( const QString& rev = "" );
|
||||
@ -95,6 +98,7 @@ public:
|
||||
int mode() const;
|
||||
QString type() 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
|
||||
// mode of a playlist and want to save it to db/others.
|
||||
@ -186,10 +190,13 @@ private:
|
||||
const QString& creator,
|
||||
const QString& type,
|
||||
GeneratorMode mode,
|
||||
bool shared );
|
||||
bool shared,
|
||||
bool autoLoad = true );
|
||||
|
||||
QList< dyncontrol_ptr > variantsToControl( const QList< QVariantMap >& controlsV );
|
||||
|
||||
geninterface_ptr m_generator;
|
||||
bool m_autoLoad;
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
@ -36,7 +36,7 @@ DatabaseControl::DatabaseControl( const QString& selectedType, const QStringList
|
||||
}
|
||||
|
||||
DatabaseControl::DatabaseControl( const QString& sql, const QString& summary, const QStringList& typeSelectors, QObject* parent )
|
||||
: DynamicControl ( typeSelectors )
|
||||
: DynamicControl ( "SQL", typeSelectors )
|
||||
, m_sql( sql )
|
||||
, m_sqlSummary( summary )
|
||||
{
|
||||
|
@ -53,7 +53,11 @@ DatabaseFactory::typeSelectors() const
|
||||
|
||||
DatabaseGenerator::DatabaseGenerator ( QObject* parent )
|
||||
: GeneratorInterface ( parent )
|
||||
, m_curCountRequested( 0 )
|
||||
{
|
||||
// defaults
|
||||
m_type = "database";
|
||||
m_mode = Static;
|
||||
// m_logo.load( RESPATH "images )
|
||||
}
|
||||
|
||||
@ -85,41 +89,62 @@ void
|
||||
DatabaseGenerator::generate( int number )
|
||||
{
|
||||
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 )
|
||||
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.
|
||||
bool isSql = false;
|
||||
bool hasSql = false;
|
||||
bool hasOther = false;
|
||||
foreach ( const dyncontrol_ptr& ctrl, m_controls )
|
||||
{
|
||||
if( ctrl->selectedType() == "SQL" )
|
||||
isSql = true;
|
||||
else if( !isSql )
|
||||
{
|
||||
qWarning() << "Cannot mix sql and non-sql controls!";
|
||||
emit error( "Failed to generate tracks", "Cannot mix sql and non-sql controls" );
|
||||
}
|
||||
if ( ctrl->selectedType() == "SQL" )
|
||||
hasSql = true;
|
||||
else
|
||||
hasOther = true;
|
||||
}
|
||||
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
|
||||
if ( isSql )
|
||||
if ( hasSql )
|
||||
{
|
||||
dyncontrol_ptr control = m_controls.first();
|
||||
|
||||
DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( control.dynamicCast< DatabaseControl >()->sql(), this );
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SIGNAL( tracksGenerated( QList<Tomahawk::query_ptr> ) ) );
|
||||
tDebug() << "Generated sql query:" << control.dynamicCast< DatabaseControl >()->sql();
|
||||
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 ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,6 +73,7 @@ namespace Tomahawk
|
||||
|
||||
private:
|
||||
QPixmap m_logo;
|
||||
int m_curCountRequested;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "database/databasecommand_loaddynamicplaylist.h"
|
||||
#include "database/database.h"
|
||||
#include "sourcelist.h"
|
||||
#include "dynamic/GeneratorInterface.h"
|
||||
#include "dynamic/database/DatabaseGenerator.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define COOLPLAYLIST_GUID "TOMAHAWK_COOLPLAYLISTOHAI_GUID"
|
||||
|
||||
@ -68,6 +71,9 @@ SocialPlaylistWidget::dynamicPlaylistLoaded ( const dynplaylist_ptr& ptr )
|
||||
m_coolQuery1 = ptr;
|
||||
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->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() );
|
||||
}
|
||||
|
||||
@ -75,6 +81,11 @@ void
|
||||
SocialPlaylistWidget::playlistRevisionLoaded( Tomahawk::DynamicPlaylistRevision )
|
||||
{
|
||||
m_coolQuery1Model->loadPlaylist( m_coolQuery1 );
|
||||
m_coolQuery1->resolve();
|
||||
|
||||
if ( m_coolQuery1->entries().isEmpty() ) // Generate some
|
||||
m_coolQuery1->generator()->generate( 30 );
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -90,5 +101,38 @@ SocialPlaylistWidget::dynamicPlaylistLoadDone()
|
||||
void
|
||||
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() );
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,11 @@ signals:
|
||||
private slots:
|
||||
void dynamicPlaylistLoaded( const Tomahawk::dynplaylist_ptr& ptr );
|
||||
void playlistRevisionLoaded ( Tomahawk::DynamicPlaylistRevision );
|
||||
void tracksGenerated ( QList<Tomahawk::query_ptr> );
|
||||
void dynamicPlaylistLoadDone();
|
||||
|
||||
void playlist1Created();
|
||||
|
||||
private:
|
||||
void load();
|
||||
void createPlaylist();
|
||||
|
@ -72,9 +72,6 @@ public:
|
||||
virtual QIcon icon() const;
|
||||
virtual QWidget* configWidget();
|
||||
|
||||
signals:
|
||||
void avatarReceived( QString, QPixmap );
|
||||
|
||||
public slots:
|
||||
virtual bool connectPlugin( bool startup );
|
||||
void disconnectPlugin();
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "sip/SipHandler.h"
|
||||
#include "playlist/dynamic/GeneratorFactory.h"
|
||||
#include "playlist/dynamic/echonest/EchonestGenerator.h"
|
||||
#include "playlist/dynamic/database/DatabaseGenerator.h"
|
||||
#include "web/api_v1.h"
|
||||
#include "resolvers/scriptresolver.h"
|
||||
#include "resolvers/qtscriptresolver.h"
|
||||
@ -175,6 +176,8 @@ TomahawkApp::init()
|
||||
|
||||
tDebug() << "Init Echonest Factory.";
|
||||
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
|
||||
tDebug() << "Init Database Factory.";
|
||||
GeneratorFactory::registerFactory( "database", new DatabaseFactory );
|
||||
|
||||
// Register shortcut handler for this platform
|
||||
#ifdef Q_WS_MAC
|
||||
|
Loading…
x
Reference in New Issue
Block a user