mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 19:30:21 +02:00
Port script collections to new script system
This commit is contained in:
@@ -615,6 +615,12 @@ Tomahawk.PluginManager = {
|
||||
Tomahawk.registerScriptPlugin(type, object.id);
|
||||
},
|
||||
|
||||
unregisterPlugin: function(type, object) {
|
||||
this.objects[this.identifyObject(object)] = object;
|
||||
|
||||
Tomahawk.log("unregisterPlugin: " + type + " id: " + object.id);
|
||||
Tomahawk.unregisterScriptPlugin(type, object.id);
|
||||
},
|
||||
|
||||
invokeSync: function (objectId, methodName, params) {
|
||||
if (!this.objects[objectId]) {
|
||||
|
@@ -303,6 +303,8 @@ Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection , bo
|
||||
m_collection = collection;
|
||||
if ( emitOnlineEvents )
|
||||
{
|
||||
Q_ASSERT( !collection.isNull() );
|
||||
connect( collection.data(), SIGNAL( destroyed( QObject * ) ), SLOT( onOffline() ), Qt::QueuedConnection );
|
||||
connect( collection->source().data(), SIGNAL( online() ), SLOT( onOnline() ), Qt::QueuedConnection );
|
||||
connect( collection->source().data(), SIGNAL( offline() ), SLOT( onOffline() ), Qt::QueuedConnection );
|
||||
}
|
||||
|
@@ -52,6 +52,8 @@ public:
|
||||
QList<Tomahawk::source_ptr> sources( bool onlyOnline = false ) const;
|
||||
unsigned int count() const;
|
||||
|
||||
void addScriptCollection( const Tomahawk::collection_ptr& collection );
|
||||
void removeScriptCollection( const Tomahawk::collection_ptr& collection );
|
||||
QList<Tomahawk::collection_ptr> scriptCollections() const;
|
||||
|
||||
Tomahawk::source_ptr get( const QString& username, const QString& friendlyName = QString(), bool autoCreate = false );
|
||||
@@ -81,9 +83,6 @@ private slots:
|
||||
void latchedOn( const Tomahawk::source_ptr& );
|
||||
void latchedOff( const Tomahawk::source_ptr& );
|
||||
|
||||
void addScriptCollection( const Tomahawk::collection_ptr& collection );
|
||||
void removeScriptCollection( const Tomahawk::collection_ptr& collection );
|
||||
|
||||
private:
|
||||
void add( const Tomahawk::source_ptr& source );
|
||||
|
||||
|
@@ -25,9 +25,6 @@
|
||||
#include "DllMacro.h"
|
||||
#include "Resolver.h"
|
||||
#include "ScriptCommandQueue.h"
|
||||
#include "ScriptCommand_AllArtists.h"
|
||||
#include "ScriptCommand_AllAlbums.h"
|
||||
#include "ScriptCommand_AllTracks.h"
|
||||
#include "ScriptCommand_LookupUrl.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
@@ -49,9 +46,6 @@ class DLLEXPORT ExternalResolver : public Resolver
|
||||
Q_OBJECT
|
||||
|
||||
friend class ScriptCommandQueue;
|
||||
friend class ScriptCommand_AllArtists;
|
||||
friend class ScriptCommand_AllAlbums;
|
||||
friend class ScriptCommand_AllTracks;
|
||||
friend class ScriptCommand_LookupUrl;
|
||||
|
||||
public:
|
||||
@@ -120,10 +114,6 @@ protected:
|
||||
ScriptCommandQueue* m_commandQueue;
|
||||
|
||||
// Should only be called by ScriptCommands
|
||||
// ScriptCollection
|
||||
virtual void artists( const Tomahawk::collection_ptr& collection ) = 0;
|
||||
virtual void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ) = 0;
|
||||
virtual void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ) = 0;
|
||||
// UrlLookup
|
||||
virtual void lookupUrl( const QString& url ) = 0;
|
||||
|
||||
|
@@ -48,11 +48,9 @@
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QImageReader>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
#include <QMetaProperty>
|
||||
#include <QTime>
|
||||
#include <QWebFrame>
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -68,6 +66,8 @@ JSResolver::JSResolver( const QString& accountId, const QString& scriptPath, con
|
||||
d->name = QFileInfo( filePath() ).baseName();
|
||||
d->scriptAccount.reset( new JSAccount( d->name ) );
|
||||
d->scriptAccount->setResolver( this );
|
||||
d->scriptAccount->setFilePath( filePath() );
|
||||
d->scriptAccount->setIcon( icon( QSize( 0, 0 ) ) );
|
||||
|
||||
// set the icon, if we launch properly we'll get the icon the resolver reports
|
||||
d->icon = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultResolver, TomahawkUtils::Original, QSize( 128, 128 ) );
|
||||
@@ -312,115 +312,6 @@ JSResolver::start()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::artists( const Tomahawk::collection_ptr& collection )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "artists", Qt::QueuedConnection, Q_ARG( Tomahawk::collection_ptr, collection ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( const JSResolver );
|
||||
|
||||
if ( /* !m_collections.contains( collection->name() ) || */ //if the collection doesn't belong to this resolver
|
||||
!d->capabilities.testFlag( Browsable ) ) //or this resolver doesn't even support collections
|
||||
{
|
||||
emit artistsFound( QList< Tomahawk::artist_ptr >() );
|
||||
return;
|
||||
}
|
||||
|
||||
QString eval = QString( "artists( '%1' )" )
|
||||
.arg( JSAccount::escape( collection->name() ) );
|
||||
|
||||
QVariantMap m = callOnResolver( eval ).toMap();
|
||||
if ( m.isEmpty() )
|
||||
{
|
||||
// if the resolver doesn't return anything, async api is used
|
||||
return;
|
||||
}
|
||||
|
||||
QString errorMessage = tr( "Script Resolver Warning: API call %1 returned data synchronously." ).arg( eval );
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMessage ) );
|
||||
tDebug() << errorMessage << m;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "albums", Qt::QueuedConnection,
|
||||
Q_ARG( Tomahawk::collection_ptr, collection ),
|
||||
Q_ARG( Tomahawk::artist_ptr, artist ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( const JSResolver );
|
||||
|
||||
if ( /* !m_collections.contains( collection->name() ) || */ //if the collection doesn't belong to this resolver
|
||||
!d->capabilities.testFlag( Browsable ) ) //or this resolver doesn't even support collections
|
||||
{
|
||||
emit albumsFound( QList< Tomahawk::album_ptr >() );
|
||||
return;
|
||||
}
|
||||
|
||||
QString eval = QString( "albums( '%1', '%2' )" )
|
||||
.arg( JSAccount::escape( collection->name() ) )
|
||||
.arg( JSAccount::escape( artist->name() ) );
|
||||
|
||||
QVariantMap m = callOnResolver( eval ).toMap();
|
||||
if ( m.isEmpty() )
|
||||
{
|
||||
// if the resolver doesn't return anything, async api is used
|
||||
return;
|
||||
}
|
||||
|
||||
QString errorMessage = tr( "Script Resolver Warning: API call %1 returned data synchronously." ).arg( eval );
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMessage ) );
|
||||
tDebug() << errorMessage << m;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "tracks", Qt::QueuedConnection,
|
||||
Q_ARG( Tomahawk::collection_ptr, collection ),
|
||||
Q_ARG( Tomahawk::album_ptr, album ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( const JSResolver );
|
||||
|
||||
if ( /* !m_collections.contains( collection->name() ) || */ //if the collection doesn't belong to this resolver
|
||||
!d->capabilities.testFlag( Browsable ) ) //or this resolver doesn't even support collections
|
||||
{
|
||||
emit tracksFound( QList< Tomahawk::query_ptr >() );
|
||||
return;
|
||||
}
|
||||
|
||||
QString eval = QString( "tracks( '%1', '%2', '%3' )" )
|
||||
.arg( JSAccount::escape( collection->name() ) )
|
||||
.arg( JSAccount::escape( album->artist()->name() ) )
|
||||
.arg( JSAccount::escape( album->name() ) );
|
||||
|
||||
QVariantMap m = callOnResolver( eval ).toMap();
|
||||
if ( m.isEmpty() )
|
||||
{
|
||||
// if the resolver doesn't return anything, async api is used
|
||||
return;
|
||||
}
|
||||
|
||||
QString errorMessage = tr( "Script Resolver Warning: API call %1 returned data synchronously." ).arg( eval );
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( errorMessage ) );
|
||||
tDebug() << errorMessage << m;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JSResolver::canParseUrl( const QString& url, UrlType type )
|
||||
{
|
||||
@@ -518,140 +409,6 @@ JSResolver::resolve( const Tomahawk::query_ptr& query )
|
||||
}
|
||||
|
||||
QVariantMap m = callOnResolver( eval ).toMap();
|
||||
if ( m.isEmpty() )
|
||||
{
|
||||
// if the resolver doesn't return anything, async api is used
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "JavaScript Result:" << m;
|
||||
|
||||
const QString qid = query->id();
|
||||
const QVariantList reslist = m.value( "results" ).toList();
|
||||
|
||||
QList< Tomahawk::result_ptr > results = parseResultVariantList( reslist );
|
||||
|
||||
Tomahawk::Pipeline::instance()->reportResults( qid, results );
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::result_ptr >
|
||||
JSResolver::parseResultVariantList( const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::result_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
QVariantMap m = rv.toMap();
|
||||
// TODO we need to handle preview urls separately. they should never trump a real url, and we need to display
|
||||
// the purchaseUrl for the user to upgrade to a full stream.
|
||||
if ( m.value( "preview" ).toBool() == true )
|
||||
continue;
|
||||
|
||||
int duration = m.value( "duration", 0 ).toInt();
|
||||
if ( duration <= 0 && m.contains( "durationString" ) )
|
||||
{
|
||||
QTime time = QTime::fromString( m.value( "durationString" ).toString(), "hh:mm:ss" );
|
||||
duration = time.secsTo( QTime( 0, 0 ) ) * -1;
|
||||
}
|
||||
|
||||
Tomahawk::track_ptr track = Tomahawk::Track::get( m.value( "artist" ).toString(),
|
||||
m.value( "track" ).toString(),
|
||||
m.value( "album" ).toString(),
|
||||
m.value( "albumArtist" ).toString(),
|
||||
duration,
|
||||
QString(),
|
||||
m.value( "albumpos" ).toUInt(),
|
||||
m.value( "discnumber" ).toUInt() );
|
||||
if ( !track )
|
||||
continue;
|
||||
|
||||
Tomahawk::result_ptr rp = Tomahawk::Result::get( m.value( "url" ).toString(), track );
|
||||
if ( !rp )
|
||||
continue;
|
||||
|
||||
rp->setBitrate( m.value( "bitrate" ).toUInt() );
|
||||
rp->setSize( m.value( "size" ).toUInt() );
|
||||
rp->setRID( uuid() );
|
||||
rp->setFriendlySource( name() );
|
||||
rp->setPurchaseUrl( m.value( "purchaseUrl" ).toString() );
|
||||
rp->setLinkUrl( m.value( "linkUrl" ).toString() );
|
||||
rp->setScore( m.value( "score" ).toFloat() );
|
||||
rp->setChecked( m.value( "checked" ).toBool() );
|
||||
|
||||
//FIXME
|
||||
if ( m.contains( "year" ) )
|
||||
{
|
||||
QVariantMap attr;
|
||||
attr[ "releaseyear" ] = m.value( "year" );
|
||||
// rp->track()->setAttributes( attr );
|
||||
}
|
||||
|
||||
rp->setMimetype( m.value( "mimetype" ).toString() );
|
||||
if ( rp->mimetype().isEmpty() )
|
||||
{
|
||||
rp->setMimetype( TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() ) );
|
||||
Q_ASSERT( !rp->mimetype().isEmpty() );
|
||||
}
|
||||
|
||||
rp->setResolvedByResolver( this );
|
||||
|
||||
|
||||
// find collection
|
||||
const QString collectionId = m.value( "collectionId" ).toString();
|
||||
if ( !collectionId.isEmpty() )
|
||||
{
|
||||
Tomahawk::collection_ptr collection = Tomahawk::collection_ptr();
|
||||
if ( !collection.isNull() )
|
||||
{
|
||||
rp->setResolvedByCollection( collection );
|
||||
}
|
||||
}
|
||||
|
||||
results << rp;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::artist_ptr >
|
||||
JSResolver::parseArtistVariantList( const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::artist_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
const QString val = rv.toString();
|
||||
if ( val.trimmed().isEmpty() )
|
||||
continue;
|
||||
|
||||
Tomahawk::artist_ptr ap = Tomahawk::Artist::get( val, false );
|
||||
|
||||
results << ap;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::album_ptr >
|
||||
JSResolver::parseAlbumVariantList( const Tomahawk::artist_ptr& artist, const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::album_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
const QString val = rv.toString();
|
||||
if ( val.trimmed().isEmpty() )
|
||||
continue;
|
||||
|
||||
Tomahawk::album_ptr ap = Tomahawk::Album::get( artist, val, false );
|
||||
|
||||
results << ap;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
@@ -662,6 +419,7 @@ JSResolver::stop()
|
||||
|
||||
d->stopped = true;
|
||||
|
||||
scriptAccount()->stop();
|
||||
|
||||
Tomahawk::Pipeline::instance()->removeResolver( this );
|
||||
emit stopped();
|
||||
@@ -738,6 +496,15 @@ JSResolver::loadDataFromWidgets()
|
||||
}
|
||||
|
||||
|
||||
ScriptAccount*
|
||||
JSResolver::scriptAccount() const
|
||||
{
|
||||
Q_D( const JSResolver );
|
||||
|
||||
return d->scriptAccount.get();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::onCapabilitiesChanged( Tomahawk::ExternalResolver::Capabilities capabilities )
|
||||
{
|
||||
@@ -747,30 +514,6 @@ JSResolver::onCapabilitiesChanged( Tomahawk::ExternalResolver::Capabilities capa
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::onCollectionIconFetched()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( reply != 0 )
|
||||
{
|
||||
Tomahawk::collection_ptr collection;
|
||||
/* collection = m_collections.value( reply->property( "collectionName" ).toString() ); */
|
||||
if ( !collection.isNull() )
|
||||
{
|
||||
if ( reply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QImageReader imageReader( reply );
|
||||
QPixmap collectionIcon = QPixmap::fromImageReader( &imageReader );
|
||||
|
||||
if ( !collectionIcon.isNull() )
|
||||
qobject_cast< Tomahawk::ScriptCollection* >( collection.data() )->setIcon( collectionIcon );
|
||||
}
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVariantMap
|
||||
JSResolver::resolverSettings()
|
||||
{
|
||||
|
@@ -73,15 +73,13 @@ public:
|
||||
|
||||
QVariantMap loadDataFromWidgets();
|
||||
|
||||
ScriptAccount* scriptAccount() const;
|
||||
|
||||
public slots:
|
||||
void resolve( const Tomahawk::query_ptr& query ) override;
|
||||
void stop() override;
|
||||
void start() override;
|
||||
|
||||
// For ScriptCollection
|
||||
void artists( const Tomahawk::collection_ptr& collection ) override;
|
||||
void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ) override;
|
||||
void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ) override;
|
||||
// For UrlLookup
|
||||
void lookupUrl( const QString& url ) override;
|
||||
|
||||
@@ -91,9 +89,6 @@ signals:
|
||||
protected:
|
||||
QVariant callOnResolver( const QString& scriptSource );
|
||||
|
||||
private slots:
|
||||
void onCollectionIconFetched();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
@@ -105,11 +100,6 @@ private:
|
||||
QVariantMap resolverUserConfig();
|
||||
QVariantMap resolverInit();
|
||||
|
||||
QList< Tomahawk::result_ptr > parseResultVariantList( const QVariantList& reslist );
|
||||
QList< Tomahawk::artist_ptr > parseArtistVariantList( const QVariantList& reslist );
|
||||
QList< Tomahawk::album_ptr > parseAlbumVariantList( const Tomahawk::artist_ptr& artist,
|
||||
const QVariantList& reslist );
|
||||
|
||||
Q_DECLARE_PRIVATE( JSResolver )
|
||||
QScopedPointer<JSResolverPrivate> d_ptr;
|
||||
};
|
||||
|
@@ -41,6 +41,10 @@
|
||||
#include "SourceList.h"
|
||||
#include "UrlHandler.h"
|
||||
#include "JSAccount.h"
|
||||
#include "../Album.h"
|
||||
#include "../Artist.h"
|
||||
#include "../Result.h"
|
||||
#include "../Track.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
@@ -133,8 +137,18 @@ JSResolverHelper::log( const QString& message )
|
||||
void
|
||||
JSResolverHelper::addTrackResults( const QVariantMap& results )
|
||||
{
|
||||
qDebug() << "Resolver reporting results:" << results;
|
||||
QList< Tomahawk::result_ptr > tracks = m_resolver->parseResultVariantList( results.value("results").toList() );
|
||||
tLog() << "Resolver reporting results:" << m_resolver->name() << results;
|
||||
|
||||
Q_ASSERT( results["results"].toMap().isEmpty() );
|
||||
|
||||
QList< Tomahawk::result_ptr > tracks = m_resolver->scriptAccount()->parseResultVariantList( results.value("results").toList() );
|
||||
|
||||
foreach( const result_ptr& track, tracks )
|
||||
{
|
||||
tLog() << "Found result: " << track->track()->track() << "by" << track->track()->artist();
|
||||
track->setResolvedByResolver( m_resolver );
|
||||
track->setFriendlySource( "FOOBAR" );
|
||||
}
|
||||
|
||||
QString qid = results.value("qid").toString();
|
||||
|
||||
@@ -142,86 +156,6 @@ JSResolverHelper::addTrackResults( const QVariantMap& results )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::addArtistResults( const QVariantMap& results )
|
||||
{
|
||||
qDebug() << "Resolver reporting artists:" << results;
|
||||
QList< Tomahawk::artist_ptr > artists = m_resolver->parseArtistVariantList( results.value( "artists" ).toList() );
|
||||
|
||||
QString qid = results.value("qid").toString();
|
||||
|
||||
Tomahawk::collection_ptr collection = Tomahawk::collection_ptr();
|
||||
if ( collection.isNull() )
|
||||
return;
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << artists.count() << "artists";
|
||||
foreach( const Tomahawk::artist_ptr& artist, artists)
|
||||
tDebug() << artist->name();
|
||||
|
||||
emit m_resolver->artistsFound( artists );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::addAlbumResults( const QVariantMap& results )
|
||||
{
|
||||
qDebug() << "Resolver reporting albums:" << results;
|
||||
QString artistName = results.value( "artist" ).toString();
|
||||
if ( artistName.trimmed().isEmpty() )
|
||||
return;
|
||||
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( artistName, false );
|
||||
QList< Tomahawk::album_ptr > albums = m_resolver->parseAlbumVariantList( artist, results.value( "albums" ).toList() );
|
||||
|
||||
QString qid = results.value("qid").toString();
|
||||
|
||||
Tomahawk::collection_ptr collection = Tomahawk::collection_ptr();
|
||||
if ( collection.isNull() )
|
||||
return;
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << albums.count() << "albums";
|
||||
foreach( const Tomahawk::album_ptr& album, albums)
|
||||
tDebug() << album->name();
|
||||
|
||||
emit m_resolver->albumsFound( albums );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::addAlbumTrackResults( const QVariantMap& results )
|
||||
{
|
||||
qDebug() << "Resolver reporting album tracks:" << results;
|
||||
QString artistName = results.value( "artist" ).toString();
|
||||
if ( artistName.trimmed().isEmpty() )
|
||||
return;
|
||||
QString albumName = results.value( "album" ).toString();
|
||||
if ( albumName.trimmed().isEmpty() )
|
||||
return;
|
||||
|
||||
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( artistName, false );
|
||||
Tomahawk::album_ptr album = Tomahawk::Album::get( artist, albumName, false );
|
||||
|
||||
QList< Tomahawk::result_ptr > tracks = m_resolver->parseResultVariantList( results.value("results").toList() );
|
||||
|
||||
QString qid = results.value("qid").toString();
|
||||
|
||||
Tomahawk::collection_ptr collection = Tomahawk::collection_ptr();
|
||||
if ( collection.isNull() )
|
||||
return;
|
||||
|
||||
QList< Tomahawk::query_ptr > queries;
|
||||
foreach ( const Tomahawk::result_ptr& result, tracks )
|
||||
{
|
||||
result->setScore( 1.0 );
|
||||
result->setResolvedByCollection( collection );
|
||||
queries.append( result->toQuery() );
|
||||
}
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << tracks.count() << "tracks";
|
||||
|
||||
emit m_resolver->tracksFound( queries );
|
||||
}
|
||||
|
||||
|
||||
query_ptr
|
||||
JSResolverHelper::parseTrack( const QVariantMap& track )
|
||||
{
|
||||
@@ -396,12 +330,19 @@ JSResolverHelper::reportScriptJobResults( const QVariantMap& result )
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::registerScriptPlugin(const QString& type, const QString& objectId)
|
||||
JSResolverHelper::registerScriptPlugin( const QString& type, const QString& objectId )
|
||||
{
|
||||
m_resolver->d_func()->scriptAccount->registerScriptPlugin( type, objectId );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::unregisterScriptPlugin( const QString& type, const QString& objectId )
|
||||
{
|
||||
m_resolver->d_func()->scriptAccount->unregisterScriptPlugin( type, objectId );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolverHelper::tracksAdded( const QList<query_ptr>&, const ModelMode, const collection_ptr&)
|
||||
{
|
||||
|
@@ -143,10 +143,6 @@ public slots:
|
||||
|
||||
void addTrackResults( const QVariantMap& results );
|
||||
|
||||
void addArtistResults( const QVariantMap& results );
|
||||
void addAlbumResults( const QVariantMap& results );
|
||||
void addAlbumTrackResults( const QVariantMap& results );
|
||||
|
||||
void addUrlResult( const QString& url, const QVariantMap& result );
|
||||
|
||||
void reportCapabilities( const QVariant& capabilities );
|
||||
@@ -154,6 +150,7 @@ public slots:
|
||||
void reportScriptJobResults( const QVariantMap& result );
|
||||
|
||||
void registerScriptPlugin( const QString& type, const QString& objectId );
|
||||
void unregisterScriptPlugin( const QString& type, const QString& objectId );
|
||||
|
||||
private slots:
|
||||
void gotStreamUrl( IODeviceCallback callback, NetworkReply* reply );
|
||||
|
@@ -26,6 +26,15 @@
|
||||
#include "../utils/LinkGenerator.h"
|
||||
#include "ScriptLinkGeneratorPlugin.h"
|
||||
#include "ScriptInfoPlugin.h"
|
||||
#include "SourceList.h"
|
||||
#include "ScriptCollection.h"
|
||||
|
||||
// TODO:
|
||||
#include "../Result.h"
|
||||
#include "../Track.h"
|
||||
#include <QTime>
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -37,6 +46,51 @@ ScriptAccount::ScriptAccount( const QString& name )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::stop()
|
||||
{
|
||||
foreach( const QWeakPointer< ScriptCollection >& collection, m_collections.hash().values() )
|
||||
{
|
||||
unregisterScriptPlugin( "collection", collection.data()->scriptObject()->id() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
ScriptAccount::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::setIcon(const QPixmap& icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
}
|
||||
|
||||
|
||||
const QPixmap
|
||||
ScriptAccount::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::setFilePath( const QString& filePath )
|
||||
{
|
||||
m_filePath = filePath;
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
ScriptAccount::filePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
|
||||
static QString
|
||||
requestIdGenerator()
|
||||
{
|
||||
@@ -102,6 +156,33 @@ ScriptAccount::registerScriptPlugin( const QString& type, const QString& objectI
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::unregisterScriptPlugin( const QString& type, const QString& objectId )
|
||||
{
|
||||
scriptobject_ptr object = m_objects.value( objectId );
|
||||
if( !object )
|
||||
{
|
||||
tLog() << "ScriptAccount" << name() << "tried to unregister plugin that was not registered";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == "collection" )
|
||||
{
|
||||
collection_ptr collection = scriptCollection( objectId );
|
||||
if ( !collection.isNull() )
|
||||
{
|
||||
SourceList::instance()->removeScriptCollection( collection );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "This plugin type is not handled by Tomahawk or simply cannot be removed yet";
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::onScriptObjectDeleted()
|
||||
{
|
||||
@@ -137,6 +218,54 @@ ScriptAccount::scriptPluginFactory( const QString& type, const scriptobject_ptr&
|
||||
// add it to infosystem
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin );
|
||||
}
|
||||
else if( type == "collection" )
|
||||
{
|
||||
if ( !scriptCollection( object->id() ).isNull() )
|
||||
return;
|
||||
|
||||
const QVariantMap collectionInfo = object->syncInvoke( "collection" ).toMap();
|
||||
|
||||
if ( collectionInfo.isEmpty() ||
|
||||
!collectionInfo.contains( "prettyname" ) ||
|
||||
!collectionInfo.contains( "description" ) )
|
||||
return;
|
||||
|
||||
const QString prettyname = collectionInfo.value( "prettyname" ).toString();
|
||||
const QString desc = collectionInfo.value( "description" ).toString();
|
||||
|
||||
// at this point we assume that all the tracks browsable through a resolver belong to the local source
|
||||
Tomahawk::ScriptCollection* sc = new Tomahawk::ScriptCollection( object, SourceList::instance()->getLocal(), this );
|
||||
QSharedPointer<ScriptCollection> collection( sc );
|
||||
collection->setWeakRef( collection.toWeakRef() );
|
||||
|
||||
sc->setServiceName( prettyname );
|
||||
sc->setDescription( desc );
|
||||
|
||||
if ( collectionInfo.contains( "trackcount" ) ) //a resolver might not expose this
|
||||
{
|
||||
bool ok = false;
|
||||
int trackCount = collectionInfo.value( "trackcount" ).toInt( &ok );
|
||||
if ( ok )
|
||||
sc->setTrackCount( trackCount );
|
||||
}
|
||||
|
||||
if ( collectionInfo.contains( "iconfile" ) )
|
||||
{
|
||||
QString iconPath = QFileInfo( filePath() ).path() + "/"
|
||||
+ collectionInfo.value( "iconfile" ).toString();
|
||||
|
||||
QPixmap iconPixmap;
|
||||
bool ok = iconPixmap.load( iconPath );
|
||||
if ( ok && !iconPixmap.isNull() )
|
||||
sc->setIcon( iconPixmap );
|
||||
}
|
||||
|
||||
SourceList::instance()->addScriptCollection( collection );
|
||||
|
||||
sc->fetchIcon( collectionInfo.value( "iconurl" ).toString() );
|
||||
|
||||
m_collections.insert( object->id(), collection );
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "This plugin type is not handled by Tomahawk";
|
||||
@@ -150,3 +279,92 @@ ScriptAccount::onJobDeleted( const QString& jobId )
|
||||
{
|
||||
m_jobs.remove( jobId );
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::result_ptr >
|
||||
ScriptAccount::parseResultVariantList( const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::result_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
QVariantMap m = rv.toMap();
|
||||
// TODO we need to handle preview urls separately. they should never trump a real url, and we need to display
|
||||
// the purchaseUrl for the user to upgrade to a full stream.
|
||||
if ( m.value( "preview" ).toBool() == true )
|
||||
continue;
|
||||
|
||||
int duration = m.value( "duration", 0 ).toInt();
|
||||
if ( duration <= 0 && m.contains( "durationString" ) )
|
||||
{
|
||||
QTime time = QTime::fromString( m.value( "durationString" ).toString(), "hh:mm:ss" );
|
||||
duration = time.secsTo( QTime( 0, 0 ) ) * -1;
|
||||
}
|
||||
|
||||
Tomahawk::track_ptr track = Tomahawk::Track::get( m.value( "artist" ).toString(),
|
||||
m.value( "track" ).toString(),
|
||||
m.value( "album" ).toString(),
|
||||
m.value( "albumArtist" ).toString(),
|
||||
duration,
|
||||
QString(),
|
||||
m.value( "albumpos" ).toUInt(),
|
||||
m.value( "discnumber" ).toUInt() );
|
||||
if ( !track )
|
||||
continue;
|
||||
|
||||
Tomahawk::result_ptr rp = Tomahawk::Result::get( m.value( "url" ).toString(), track );
|
||||
if ( !rp )
|
||||
continue;
|
||||
|
||||
rp->setBitrate( m.value( "bitrate" ).toUInt() );
|
||||
rp->setSize( m.value( "size" ).toUInt() );
|
||||
rp->setRID( uuid() );
|
||||
rp->setPurchaseUrl( m.value( "purchaseUrl" ).toString() );
|
||||
rp->setLinkUrl( m.value( "linkUrl" ).toString() );
|
||||
rp->setScore( m.value( "score" ).toFloat() );
|
||||
rp->setChecked( m.value( "checked" ).toBool() );
|
||||
|
||||
//FIXME
|
||||
if ( m.contains( "year" ) )
|
||||
{
|
||||
QVariantMap attr;
|
||||
attr[ "releaseyear" ] = m.value( "year" );
|
||||
// rp->track()->setAttributes( attr );
|
||||
}
|
||||
|
||||
rp->setMimetype( m.value( "mimetype" ).toString() );
|
||||
if ( rp->mimetype().isEmpty() )
|
||||
{
|
||||
rp->setMimetype( TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() ) );
|
||||
Q_ASSERT( !rp->mimetype().isEmpty() );
|
||||
}
|
||||
|
||||
rp->setFriendlySource( name() );
|
||||
|
||||
// find collection
|
||||
const QString collectionId = m.value( "collectionId" ).toString();
|
||||
if ( !collectionId.isEmpty() )
|
||||
{
|
||||
if ( scriptCollection( collectionId ).isNull() )
|
||||
{
|
||||
tLog() << "Resolver returned invalid collection id";
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
rp->setResolvedByCollection( scriptCollection( collectionId ) );
|
||||
}
|
||||
}
|
||||
|
||||
results << rp;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
const QSharedPointer< ScriptCollection >
|
||||
ScriptAccount::scriptCollection( const QString& id ) const
|
||||
{
|
||||
return m_collections.hash().value( id );
|
||||
}
|
||||
|
@@ -27,7 +27,11 @@
|
||||
#include <QVariantMap>
|
||||
|
||||
//TODO: pimple
|
||||
#include "../utils/WeakObjectHash.h"
|
||||
#include "ScriptCollection.h"
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
|
||||
|
||||
#include "../DllMacro.h"
|
||||
|
||||
@@ -44,6 +48,16 @@ public:
|
||||
ScriptAccount( const QString& name );
|
||||
virtual ~ScriptAccount() {}
|
||||
|
||||
void stop();
|
||||
|
||||
const QString name() const;
|
||||
|
||||
void setIcon( const QPixmap& icon );
|
||||
const QPixmap icon() const;
|
||||
|
||||
void setFilePath( const QString& filePath );
|
||||
const QString filePath() const;
|
||||
|
||||
ScriptJob* invoke( const scriptobject_ptr& scriptObject, const QString& methodName, const QVariantMap& arguments );
|
||||
virtual const QVariant syncInvoke( const scriptobject_ptr& scriptObject, const QString& methodName, const QVariantMap& arguments ) = 0;
|
||||
|
||||
@@ -51,9 +65,14 @@ public:
|
||||
|
||||
void reportScriptJobResult( const QVariantMap& result );
|
||||
void registerScriptPlugin( const QString& type, const QString& objectId );
|
||||
void unregisterScriptPlugin( const QString& type, const QString& objectId );
|
||||
|
||||
virtual void scriptPluginFactory( const QString& type, const scriptobject_ptr& object );
|
||||
|
||||
QList< Tomahawk::result_ptr > parseResultVariantList( const QVariantList& reslist );
|
||||
|
||||
const QSharedPointer< ScriptCollection > scriptCollection( const QString& id ) const;
|
||||
|
||||
private slots:
|
||||
void onJobDeleted( const QString& jobId );
|
||||
|
||||
@@ -61,8 +80,11 @@ private slots:
|
||||
|
||||
private: // TODO: pimple, might be renamed before tho
|
||||
QString m_name;
|
||||
QPixmap m_icon;
|
||||
QString m_filePath;
|
||||
QHash< QString, ScriptJob* > m_jobs;
|
||||
QHash< QString, scriptobject_ptr > m_objects;
|
||||
Utils::WeakObjectHash< ScriptCollection > m_collections;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
@@ -20,45 +20,45 @@
|
||||
#include "ScriptCollection.h"
|
||||
|
||||
#include "Source.h"
|
||||
#include "ExternalResolverGui.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/NetworkAccessManager.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "resolvers/ScriptCommand_AllArtists.h"
|
||||
#include "resolvers/ScriptCommand_AllAlbums.h"
|
||||
#include "resolvers/ScriptCommand_AllTracks.h"
|
||||
#include "ScriptAccount.h"
|
||||
|
||||
#include <QImageReader>
|
||||
#include <QPainter>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
ScriptCollection::ScriptCollection( const QString& id,
|
||||
ScriptCollection::ScriptCollection( const scriptobject_ptr& scriptObject,
|
||||
const source_ptr& source,
|
||||
ExternalResolver* resolver,
|
||||
ScriptAccount* scriptAccount,
|
||||
QObject* parent )
|
||||
: Collection( source, QString( "scriptcollection:" + resolver->name() + ":" + uuid() ), parent )
|
||||
, m_id( id )
|
||||
: Collection( source, QString( "scriptcollection:" + scriptAccount->name() + ":" + uuid() ), parent )
|
||||
, ScriptPlugin( scriptObject )
|
||||
, m_scriptAccount( scriptAccount )
|
||||
, m_trackCount( -1 ) //null value
|
||||
{
|
||||
Q_ASSERT( resolver );
|
||||
qDebug() << Q_FUNC_INFO << resolver->name() << Collection::name();
|
||||
Q_ASSERT( scriptAccount );
|
||||
qDebug() << Q_FUNC_INFO << scriptAccount->name() << Collection::name();
|
||||
|
||||
m_resolver = resolver;
|
||||
|
||||
m_servicePrettyName = m_resolver->name();
|
||||
m_servicePrettyName = scriptAccount->name();
|
||||
}
|
||||
|
||||
|
||||
ScriptCollection::~ScriptCollection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
ScriptCollection::id() const
|
||||
ScriptAccount*
|
||||
ScriptCollection::scriptAccount() const
|
||||
{
|
||||
return m_id;
|
||||
return m_scriptAccount;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ QString
|
||||
ScriptCollection::prettyName() const
|
||||
{
|
||||
return tr( "%1 Collection",
|
||||
"Name of a collection based on a resolver, e.g. Subsonic Collection" )
|
||||
"Name of a collection based on a script pluginsc, e.g. Subsonic Collection" )
|
||||
.arg( m_servicePrettyName );
|
||||
}
|
||||
|
||||
@@ -181,3 +181,39 @@ ScriptCollection::trackCount() const
|
||||
{
|
||||
return m_trackCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCollection::fetchIcon( const QString& iconUrlString )
|
||||
{
|
||||
if ( !iconUrlString.isEmpty() )
|
||||
{
|
||||
QUrl iconUrl = QUrl::fromEncoded( iconUrlString.toLatin1() );
|
||||
if ( iconUrl.isValid() )
|
||||
{
|
||||
QNetworkRequest req( iconUrl );
|
||||
tDebug() << "Creating a QNetworkReply with url:" << req.url().toString();
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( req );
|
||||
|
||||
connect( reply, SIGNAL( finished() ),
|
||||
this, SLOT( onIconFetched() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCollection::onIconFetched()
|
||||
{
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( reply != 0 )
|
||||
{
|
||||
if( reply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QImageReader imageReader( reply );
|
||||
setIcon( QPixmap::fromImageReader( &imageReader ) );
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#ifndef SCRIPTCOLLECTION_H
|
||||
#define SCRIPTCOLLECTION_H
|
||||
|
||||
#include "ExternalResolver.h"
|
||||
#include "ScriptPlugin.h"
|
||||
#include "collection/Collection.h"
|
||||
#include "collection/ArtistsRequest.h"
|
||||
#include "collection/AlbumsRequest.h"
|
||||
@@ -34,19 +34,27 @@
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
class ScriptAccount;
|
||||
|
||||
class DLLEXPORT ScriptCollection : public Collection
|
||||
class DLLEXPORT ScriptCollection : public Collection, public ScriptPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
// access to ScriptObject
|
||||
friend class ScriptCommand_AllArtists;
|
||||
friend class ScriptCommand_AllAlbums;
|
||||
friend class ScriptCommand_AllTracks;
|
||||
friend class JSResolver;
|
||||
|
||||
|
||||
public:
|
||||
explicit ScriptCollection( const QString& id,
|
||||
explicit ScriptCollection( const scriptobject_ptr& scriptObject,
|
||||
const source_ptr& source,
|
||||
ExternalResolver* resolver,
|
||||
ScriptAccount* scriptAccount,
|
||||
QObject* parent = nullptr );
|
||||
virtual ~ScriptCollection();
|
||||
|
||||
const QString id() const;
|
||||
ScriptAccount* scriptAccount() const;
|
||||
|
||||
/**
|
||||
* @brief setServiceName sets the name of the service that provides the ScriptCollection.
|
||||
@@ -62,6 +70,7 @@ public:
|
||||
QString itemName() const override;
|
||||
BackendType backendType() const override { return ScriptCollectionType; }
|
||||
|
||||
void fetchIcon( const QString& iconUrl );
|
||||
void setIcon( const QPixmap& icon );
|
||||
const QPixmap icon( const QSize& size ) const override;
|
||||
QPixmap bigIcon() const override;
|
||||
@@ -69,8 +78,6 @@ public:
|
||||
void setDescription( const QString& text );
|
||||
QString description() const override;
|
||||
|
||||
virtual ExternalResolver* resolver() { return m_resolver; }
|
||||
|
||||
Tomahawk::ArtistsRequest* requestArtists() override;
|
||||
Tomahawk::AlbumsRequest* requestAlbums( const Tomahawk::artist_ptr& artist ) override;
|
||||
Tomahawk::TracksRequest* requestTracks( const Tomahawk::album_ptr& album ) override;
|
||||
@@ -78,9 +85,11 @@ public:
|
||||
void setTrackCount( int count );
|
||||
int trackCount() const override;
|
||||
|
||||
private slots:
|
||||
void onIconFetched();
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
ExternalResolver* m_resolver;
|
||||
ScriptAccount* m_scriptAccount;
|
||||
QString m_servicePrettyName;
|
||||
QString m_description;
|
||||
int m_trackCount;
|
||||
|
@@ -22,9 +22,10 @@
|
||||
|
||||
#include "Album.h"
|
||||
#include "Artist.h"
|
||||
#include "ExternalResolver.h"
|
||||
#include "ScriptAccount.h"
|
||||
#include "PlaylistEntry.h"
|
||||
#include "ScriptCollection.h"
|
||||
#include "ScriptJob.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -75,10 +76,12 @@ ScriptCommand_AllAlbums::exec()
|
||||
return;
|
||||
}
|
||||
|
||||
connect( collection->resolver(), SIGNAL( albumsFound( QList< Tomahawk::album_ptr > ) ),
|
||||
this, SLOT( onResolverDone( QList< Tomahawk::album_ptr > ) ) );
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_artist->name();
|
||||
|
||||
collection->resolver()->albums( m_collection, m_artist );
|
||||
ScriptJob* job = collection->scriptObject()->invoke( "albums", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onAlbumsJobDone( QVariantMap ) ), Qt::QueuedConnection );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -94,8 +97,19 @@ ScriptCommand_AllAlbums::reportFailure()
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_AllAlbums::onResolverDone( const QList< Tomahawk::album_ptr >& a )
|
||||
ScriptCommand_AllAlbums::onAlbumsJobDone(const QVariantMap& result)
|
||||
{
|
||||
ScriptJob* job = qobject_cast< ScriptJob* >( sender() );
|
||||
Q_ASSERT( job );
|
||||
|
||||
if ( job->error() )
|
||||
{
|
||||
reportFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
QList< Tomahawk::album_ptr > a = parseAlbumVariantList( m_artist, result[ "albums" ].toList() );
|
||||
|
||||
if ( m_filter.isEmpty() )
|
||||
emit albums( a );
|
||||
else
|
||||
@@ -110,4 +124,26 @@ ScriptCommand_AllAlbums::onResolverDone( const QList< Tomahawk::album_ptr >& a )
|
||||
emit albums( filtered );
|
||||
}
|
||||
emit done();
|
||||
|
||||
job->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::album_ptr >
|
||||
ScriptCommand_AllAlbums::parseAlbumVariantList( const Tomahawk::artist_ptr& artist, const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::album_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
const QString val = rv.toString();
|
||||
if ( val.trimmed().isEmpty() )
|
||||
continue;
|
||||
|
||||
Tomahawk::album_ptr ap = Tomahawk::Album::get( artist, val, false );
|
||||
|
||||
results << ap;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
@@ -49,9 +49,11 @@ protected:
|
||||
virtual void reportFailure();
|
||||
|
||||
private slots:
|
||||
void onResolverDone( const QList< Tomahawk::album_ptr >& );
|
||||
void onAlbumsJobDone( const QVariantMap& result );
|
||||
|
||||
private:
|
||||
static QList< Tomahawk::album_ptr > parseAlbumVariantList( const Tomahawk::artist_ptr& artist,
|
||||
const QVariantList& reslist );
|
||||
Tomahawk::collection_ptr m_collection;
|
||||
Tomahawk::artist_ptr m_artist;
|
||||
QString m_filter;
|
||||
|
@@ -19,10 +19,13 @@
|
||||
#include "ScriptCommand_AllArtists.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "ExternalResolver.h"
|
||||
#include "ScriptAccount.h"
|
||||
#include "ScriptCollection.h"
|
||||
#include "ScriptObject.h"
|
||||
#include "ScriptJob.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "../Typedefs.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -59,16 +62,11 @@ void
|
||||
ScriptCommand_AllArtists::exec()
|
||||
{
|
||||
Tomahawk::ScriptCollection* collection = qobject_cast< Tomahawk::ScriptCollection* >( m_collection.data() );
|
||||
if ( collection == 0 )
|
||||
{
|
||||
emit artists( QList< Tomahawk::artist_ptr >() );
|
||||
return;
|
||||
}
|
||||
Q_ASSERT( collection );
|
||||
|
||||
connect( collection->resolver(), SIGNAL( artistsFound( QList< Tomahawk::artist_ptr > ) ),
|
||||
this, SLOT( onResolverDone( QList< Tomahawk::artist_ptr > ) ) );
|
||||
|
||||
collection->resolver()->artists( m_collection );
|
||||
ScriptJob* job = collection->scriptObject()->invoke( "artists" );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onArtistsJobDone( QVariantMap ) ), Qt::QueuedConnection );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -81,10 +79,24 @@ ScriptCommand_AllArtists::reportFailure()
|
||||
}
|
||||
|
||||
|
||||
void ScriptCommand_AllArtists::onResolverDone( const QList< Tomahawk::artist_ptr >& a )
|
||||
void
|
||||
ScriptCommand_AllArtists::onArtistsJobDone( const QVariantMap& result )
|
||||
{
|
||||
ScriptJob* job = qobject_cast< ScriptJob* >( sender() );
|
||||
Q_ASSERT( job );
|
||||
|
||||
if ( job->error() )
|
||||
{
|
||||
reportFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
QList< Tomahawk::artist_ptr > a = parseArtistVariantList( result[ "artists" ].toList() );
|
||||
|
||||
if ( m_filter.isEmpty() )
|
||||
{
|
||||
emit artists( a );
|
||||
}
|
||||
else
|
||||
{
|
||||
QList< Tomahawk::artist_ptr > filtered;
|
||||
@@ -93,7 +105,30 @@ void ScriptCommand_AllArtists::onResolverDone( const QList< Tomahawk::artist_ptr
|
||||
if ( artist->name().contains( m_filter ) )
|
||||
filtered.append( artist );
|
||||
}
|
||||
emit artists( filtered );
|
||||
emit artists( a );
|
||||
}
|
||||
|
||||
emit done();
|
||||
|
||||
job->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::artist_ptr >
|
||||
ScriptCommand_AllArtists::parseArtistVariantList( const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::artist_ptr > results;
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
const QString val = rv.toString();
|
||||
if ( val.trimmed().isEmpty() )
|
||||
continue;
|
||||
|
||||
Tomahawk::artist_ptr ap = Tomahawk::Artist::get( val, false );
|
||||
|
||||
results << ap;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
@@ -48,9 +48,11 @@ protected:
|
||||
void reportFailure() override;
|
||||
|
||||
private slots:
|
||||
void onResolverDone( const QList< Tomahawk::artist_ptr >& );
|
||||
void onArtistsJobDone( const QVariantMap& result );
|
||||
|
||||
private:
|
||||
static QList< Tomahawk::artist_ptr > parseArtistVariantList( const QVariantList& reslist );
|
||||
|
||||
Tomahawk::collection_ptr m_collection;
|
||||
QString m_filter;
|
||||
};
|
||||
|
@@ -18,11 +18,15 @@
|
||||
|
||||
#include "ScriptCommand_AllTracks.h"
|
||||
|
||||
#include "ExternalResolver.h"
|
||||
|
||||
#include "ScriptAccount.h"
|
||||
#include "PlaylistEntry.h"
|
||||
#include "ScriptCollection.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Album.h"
|
||||
#include "ScriptJob.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "../Result.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -66,10 +70,13 @@ ScriptCommand_AllTracks::exec()
|
||||
return;
|
||||
}
|
||||
|
||||
connect( collection->resolver(), SIGNAL( tracksFound( QList< Tomahawk::query_ptr > ) ),
|
||||
this, SLOT( onResolverDone( QList< Tomahawk::query_ptr > ) ) );
|
||||
QVariantMap arguments;
|
||||
arguments[ "artist" ] = m_album->artist()->name();
|
||||
arguments[ "album" ] = m_album->name();
|
||||
|
||||
collection->resolver()->tracks( m_collection, m_album );
|
||||
ScriptJob* job = collection->scriptObject()->invoke( "tracks", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onTracksJobDone( QVariantMap ) ), Qt::QueuedConnection );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +96,37 @@ ScriptCommand_AllTracks::reportFailure()
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_AllTracks::onResolverDone( const QList< Tomahawk::query_ptr >& q )
|
||||
ScriptCommand_AllTracks::onTracksJobDone( const QVariantMap& result )
|
||||
{
|
||||
emit tracks( q );
|
||||
ScriptJob* job = qobject_cast< ScriptJob* >( sender() );
|
||||
Q_ASSERT( job );
|
||||
|
||||
qDebug() << "Resolver reporting album tracks:" << result;
|
||||
|
||||
if ( job->error() )
|
||||
{
|
||||
reportFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
QSharedPointer< ScriptCollection > collection = m_collection.objectCast< ScriptCollection >();
|
||||
Q_ASSERT( !collection.isNull() );
|
||||
|
||||
QList< Tomahawk::result_ptr > t = collection->scriptAccount()->parseResultVariantList( result[ "tracks"].toList() );
|
||||
|
||||
|
||||
QList< Tomahawk::query_ptr > queries;
|
||||
foreach ( const Tomahawk::result_ptr& result, t )
|
||||
{
|
||||
result->setScore( 1.0 );
|
||||
result->setResolvedByCollection( m_collection );
|
||||
queries.append( result->toQuery() );
|
||||
}
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << queries.count() << "tracks";
|
||||
|
||||
emit tracks( queries );
|
||||
emit done();
|
||||
|
||||
job->deleteLater();
|
||||
}
|
||||
|
@@ -43,11 +43,11 @@ signals:
|
||||
void done();
|
||||
|
||||
protected:
|
||||
void exec() override;
|
||||
Q_INVOKABLE void exec() override;
|
||||
void reportFailure() override;
|
||||
|
||||
private slots:
|
||||
void onResolverDone( const QList< Tomahawk::query_ptr >& );
|
||||
void onTracksJobDone( const QVariantMap& result );
|
||||
|
||||
private:
|
||||
Tomahawk::collection_ptr m_collection;
|
||||
|
@@ -42,6 +42,8 @@ public:
|
||||
ScriptObject( const QString& id, ScriptAccount* parent );
|
||||
virtual ~ScriptObject();
|
||||
|
||||
QString id() const;
|
||||
|
||||
void setWeakRef( const scriptobject_wptr& weakRef );
|
||||
const scriptobject_wptr weakRef() const;
|
||||
|
||||
@@ -53,8 +55,6 @@ public:
|
||||
const QVariant syncInvoke( const QString& methodName, const QVariantMap& arguments = QVariantMap() );
|
||||
|
||||
protected:
|
||||
QString id() const;
|
||||
|
||||
void startJob( ScriptJob* scriptJob );
|
||||
|
||||
private:
|
||||
|
@@ -72,7 +72,7 @@ public:
|
||||
m_hash.insert( key, value.toWeakRef() );
|
||||
}
|
||||
|
||||
const QHash< QString, QWeakPointer<T> >& hash() { return m_hash; }
|
||||
const QHash< QString, QWeakPointer<T> >& hash() const { return m_hash; }
|
||||
virtual void remove( const QString& key ) { m_hash.remove( key ); }
|
||||
|
||||
private:
|
||||
|
Reference in New Issue
Block a user