diff --git a/src/libtomahawk/Query.cpp b/src/libtomahawk/Query.cpp index 58c6ffa0f..6e9c284a3 100644 --- a/src/libtomahawk/Query.cpp +++ b/src/libtomahawk/Query.cpp @@ -24,10 +24,10 @@ #include "database/Database.h" #include "database/DatabaseImpl.h" #include "database/DatabaseCommand_LogPlayback.h" -#include "database/DatabaseCommand_PlaybackHistory.h" #include "database/DatabaseCommand_LoadPlaylistEntries.h" #include "database/DatabaseCommand_LoadSocialActions.h" #include "database/DatabaseCommand_SocialAction.h" +#include "database/DatabaseCommand_TrackStats.h" #include "Album.h" #include "Collection.h" #include "Pipeline.h" @@ -74,6 +74,8 @@ Query::Query( const QString& artist, const QString& track, const QString& album, , m_album( album ) , m_track( track ) , m_socialActionsLoaded( false ) + , m_simTracksLoaded( false ) + , m_infoJobs( 0 ) { init(); @@ -505,6 +507,55 @@ Query::playedBy() const } +void +Query::loadStats() +{ + query_ptr q = m_ownRef.toStrongRef(); + + DatabaseCommand_TrackStats* cmd = new DatabaseCommand_TrackStats( q ); + Database::instance()->enqueue( QSharedPointer(cmd) ); +} + + +QList< Tomahawk::PlaybackLog > +Query::playbackHistory( const Tomahawk::source_ptr& source ) const +{ + QList< Tomahawk::PlaybackLog > history; + + foreach ( const PlaybackLog& log, m_playbackHistory ) + { + if ( source.isNull() || log.source == source ) + { + history << log; + } + } + + return history; +} + + +void +Query::setPlaybackHistory( const QList< Tomahawk::PlaybackLog >& playbackData ) +{ + m_playbackHistory = playbackData; + emit statsLoaded(); +} + + +unsigned int +Query::playbackCount( const source_ptr& source ) +{ + unsigned int count = 0; + foreach ( const PlaybackLog& log, m_playbackHistory ) + { + if ( source.isNull() || log.source == source ) + count++; + } + + return count; +} + + void Query::loadSocialActions() { @@ -512,24 +563,17 @@ Query::loadSocialActions() query_ptr q = m_ownRef.toStrongRef(); DatabaseCommand_LoadSocialActions* cmd = new DatabaseCommand_LoadSocialActions( q ); - connect( cmd, SIGNAL( finished() ), SLOT( onSocialActionsLoaded() ) ); Database::instance()->enqueue( QSharedPointer(cmd) ); } -void -Query::onSocialActionsLoaded() -{ - parseSocialActions(); - - emit socialActionsLoaded(); -} - - void Query::setAllSocialActions( const QList< SocialAction >& socialActions ) { m_allSocialActions = socialActions; + parseSocialActions(); + + emit socialActionsLoaded(); } @@ -690,7 +734,7 @@ Query::cover( const QSize& size, bool forceLoad ) const if ( !m_albumPtr->cover( size ).isNull() ) return m_albumPtr->cover( size ); - return m_artistPtr->cover( size ); + return m_artistPtr->cover( size, forceLoad ); } return QPixmap(); @@ -698,6 +742,92 @@ Query::cover( const QSize& size, bool forceLoad ) const #endif +QList +Query::similarTracks() const +{ + if ( !m_simTracksLoaded ) + { + Tomahawk::InfoSystem::InfoStringHash trackInfo; + trackInfo["artist"] = artist(); + trackInfo["track"] = track(); + + Tomahawk::InfoSystem::InfoRequestData requestData; + requestData.caller = id(); + requestData.customData = QVariantMap(); + + requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ); + requestData.type = Tomahawk::InfoSystem::InfoTrackSimilars; + requestData.requestId = TomahawkUtils::infosystemRequestId(); + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), + SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection ); + + connect( Tomahawk::InfoSystem::InfoSystem::instance(), + SIGNAL( finished( QString ) ), + SLOT( infoSystemFinished( QString ) ), Qt::UniqueConnection ); + + m_infoJobs++; + Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); + } + + return m_similarTracks; +} + + +void +Query::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) +{ + if ( requestData.caller != id() ) + return; + + QVariantMap returnedData = output.value< QVariantMap >(); + switch ( requestData.type ) + { + case InfoSystem::InfoTrackSimilars: + { + const QStringList artists = returnedData["artists"].toStringList(); + const QStringList tracks = returnedData["tracks"].toStringList(); + + for ( int i = 0; i < tracks.count() && i < 50; i++ ) + { + m_similarTracks << Query::get( artists.at( i ), tracks.at( i ), QString(), uuid(), true ); + } + + m_simTracksLoaded = true; + emit similarTracksLoaded(); + + break; + } + + default: + Q_ASSERT( false ); + } +} + + +void +Query::infoSystemFinished( QString target ) +{ + tDebug() << Q_FUNC_INFO; + Q_UNUSED( target ); + + if ( target != id() ) + return; + + if ( --m_infoJobs == 0 ) + { + disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), + this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) ); + + disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), + this, SLOT( infoSystemFinished( QString ) ) ); + } + + emit updated(); +} + + int Query::levenshtein( const QString& source, const QString& target ) { diff --git a/src/libtomahawk/Query.h b/src/libtomahawk/Query.h index 6565c2e55..a2656684e 100644 --- a/src/libtomahawk/Query.h +++ b/src/libtomahawk/Query.h @@ -27,6 +27,7 @@ #include "Typedefs.h" #include "Result.h" +#include "infosystem/InfoSystem.h" #include "DllMacro.h" @@ -39,6 +40,22 @@ namespace Tomahawk class Resolver; +struct SocialAction +{ + QVariant action; + QVariant value; + QVariant timestamp; + Tomahawk::source_ptr source; +}; + +struct PlaybackLog +{ + Tomahawk::source_ptr source; + unsigned int timestamp; + unsigned int secsPlayed; +}; + + class DLLEXPORT Query : public QObject { Q_OBJECT @@ -119,11 +136,18 @@ public: void setLoved( bool loved ); bool loved(); + void loadStats(); + QList< Tomahawk::PlaybackLog > playbackHistory( const Tomahawk::source_ptr& source = Tomahawk::source_ptr() ) const; + void setPlaybackHistory( const QList< Tomahawk::PlaybackLog >& playbackData ); + unsigned int playbackCount( const Tomahawk::source_ptr& source = Tomahawk::source_ptr() ); + void loadSocialActions(); QList< Tomahawk::SocialAction > allSocialActions() const; void setAllSocialActions( const QList< Tomahawk::SocialAction >& socialActions ); QString socialActionDescription( const QString& action, DescriptionMode mode ) const; + QList similarTracks() const; + QWeakPointer< Tomahawk::Query > weakRef() { return m_ownRef; } void setWeakRef( QWeakPointer< Tomahawk::Query > weakRef ) { m_ownRef = weakRef; } @@ -141,8 +165,9 @@ signals: void coverChanged(); - // emitted when social actions are loaded void socialActionsLoaded(); + void statsLoaded(); + void similarTracksLoaded(); void updated(); public slots: @@ -160,9 +185,11 @@ public slots: void onResolverRemoved(); private slots: + void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); + void infoSystemFinished( QString target ); + void onResultStatusChanged(); void refreshResults(); - void onSocialActionsLoaded(); private: Query(); @@ -211,12 +238,19 @@ private: QList< QWeakPointer< Tomahawk::Resolver > > m_resolvers; mutable QMutex m_mutex; - QWeakPointer< Tomahawk::Query > m_ownRef; + bool m_playbackHistoryLoaded; + QList< PlaybackLog > m_playbackHistory; + bool m_socialActionsLoaded; QHash< QString, QVariant > m_currentSocialActions; QList< SocialAction > m_allSocialActions; + + bool m_simTracksLoaded; + QList m_similarTracks; + + mutable int m_infoJobs; }; }; //ns