From ad1e057078dbc238dd81858c92cf1d0f4575f5c8 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 25 Jan 2013 22:58:18 +0100 Subject: [PATCH] Artists fetching support in scriptcollection. --- src/libtomahawk/ExternalResolver.h | 10 +- .../resolvers/QtScriptResolver.cpp | 102 +++++++++++++++++- src/libtomahawk/resolvers/QtScriptResolver.h | 9 ++ .../resolvers/ScriptCollection.cpp | 26 ++++- src/libtomahawk/resolvers/ScriptCollection.h | 6 +- src/libtomahawk/resolvers/ScriptResolver.cpp | 2 +- src/libtomahawk/resolvers/ScriptResolver.h | 6 ++ 7 files changed, 152 insertions(+), 9 deletions(-) diff --git a/src/libtomahawk/ExternalResolver.h b/src/libtomahawk/ExternalResolver.h index a99a2eb43..dc87f5c90 100644 --- a/src/libtomahawk/ExternalResolver.h +++ b/src/libtomahawk/ExternalResolver.h @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Leo Franchi + * Copyright 2013, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,12 +72,17 @@ public: virtual ErrorState error() const; virtual bool running() const = 0; virtual Capabilities capabilities() const = 0; - virtual QList< Tomahawk::collection_ptr > collections() { return m_collections; } + virtual QMap< QString, Tomahawk::collection_ptr > collections() { return m_collections; } public slots: virtual void start() = 0; virtual void stop() = 0; + // For 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; + signals: void changed(); // if config widget was added/removed, name changed, etc void collectionAdded( const Tomahawk::collection_ptr& collection ); @@ -84,7 +90,7 @@ signals: protected: void setFilePath( const QString& path ) { m_filePath = path; } - QList< Tomahawk::collection_ptr > m_collections; + QMap< QString, Tomahawk::collection_ptr > m_collections; private: QString m_filePath; diff --git a/src/libtomahawk/resolvers/QtScriptResolver.cpp b/src/libtomahawk/resolvers/QtScriptResolver.cpp index 7b66798aa..3a2d8c051 100644 --- a/src/libtomahawk/resolvers/QtScriptResolver.cpp +++ b/src/libtomahawk/resolvers/QtScriptResolver.cpp @@ -134,6 +134,37 @@ QtScriptResolverHelper::addTrackResults( const QVariantMap& results ) } +void +QtScriptResolverHelper::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(); + foreach ( const Tomahawk::collection_ptr& coll, m_resolver->collections() ) + { + if ( coll->name() == qid ) + { + collection = coll; + } + } + if ( collection.isNull() ) + return; + + tDebug() << Q_FUNC_INFO << "about to push" << artists.count() << "artists"; + foreach( const Tomahawk::artist_ptr& artist, artists) + tDebug() << artist->name(); + QMetaObject::invokeMethod( collection.data(), "onArtistsFetched", Qt::QueuedConnection, + Q_ARG( QList< Tomahawk::artist_ptr >, artists ) ); +} + +void QtScriptResolverHelper::addAlbumResults(const QVariantMap &results) +{ +} + + void QtScriptResolverHelper::setResolverConfig( const QVariantMap& config ) { @@ -389,6 +420,57 @@ QtScriptResolver::start() } +void +QtScriptResolver::artists( const Tomahawk::collection_ptr& collection ) +{ + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "artists", Qt::QueuedConnection, Q_ARG( Tomahawk::collection_ptr, collection ) ); + return; + } + + if ( !m_collections.contains( collection->name() ) || //if the collection doesn't belong to this resolver + !capabilities().testFlag( Browsable ) ) //or this resolver doesn't even support collections + { + QMetaObject::invokeMethod( collection.data(), "onArtistsFetched", Qt::QueuedConnection, + Q_ARG( QList< Tomahawk::artist_ptr >, QList< Tomahawk::artist_ptr >() ) ); + return; + } + + QString eval = QString( "resolver.artists( '%1' );" ) + .arg( collection->name().replace( "'", "\\'" ) ); + + QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + if ( m.isEmpty() ) + { + // if the resolver doesn't return anything, async api is used + return; + } + + qDebug() << "Artists JavaScript Result:" << m; + + const QString qid = collection->name(); + const QVariantList reslist = m.value( "artists" ).toList(); + + QList< Tomahawk::artist_ptr > artists = parseArtistVariantList( reslist ); + + QMetaObject::invokeMethod( collection.data(), "onArtistsFetched", Qt::QueuedConnection, + Q_ARG( QList< Tomahawk::artist_ptr >, artists ) ); +} + + +void +QtScriptResolver::albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ) +{ +} + + +void +QtScriptResolver::tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ) +{ +} + + Tomahawk::ExternalResolver::ErrorState QtScriptResolver::error() const { @@ -503,6 +585,24 @@ QtScriptResolver::parseResultVariantList( const QVariantList& reslist ) return results; } +QList< Tomahawk::artist_ptr > +QtScriptResolver::parseArtistVariantList( const QVariantList& reslist ) +{ + QList< Tomahawk::artist_ptr > results; + + foreach( const QVariant& rv, reslist ) + { + if ( rv.toString().trimmed().isEmpty() ) + continue; + + Tomahawk::artist_ptr ap = Tomahawk::Artist::get( rv.toString(), false ); + + results << ap; + } + + return results; +} + void QtScriptResolver::stop() @@ -652,7 +752,7 @@ QtScriptResolver::loadCollections() m_collections.clear(); // at this point we assume that all the tracks browsable through a resolver belong to the local source Tomahawk::collection_ptr collection( new Tomahawk::ScriptCollection( SourceList::instance()->getLocal(), this ) ); - m_collections.append( collection ); + m_collections.insert( collection->name(), collection ); emit collectionAdded( collection ); //TODO: implement multiple collections from a resolver diff --git a/src/libtomahawk/resolvers/QtScriptResolver.h b/src/libtomahawk/resolvers/QtScriptResolver.h index a57795099..02030635d 100644 --- a/src/libtomahawk/resolvers/QtScriptResolver.h +++ b/src/libtomahawk/resolvers/QtScriptResolver.h @@ -72,6 +72,9 @@ public slots: void addTrackResults( const QVariantMap& results ); + void addArtistResults( const QVariantMap& results ); + void addAlbumResults( const QVariantMap& results ); + private: QString m_scriptPath, m_urlCallback; QVariantMap m_resolverConfig; @@ -151,6 +154,11 @@ public slots: virtual void stop(); virtual void start(); + // For ScriptCollection + virtual void artists( const Tomahawk::collection_ptr& collection ); + virtual void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ); + virtual void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ); + signals: void stopped(); @@ -171,6 +179,7 @@ private: QVariantMap resolverCollections(); QList< Tomahawk::result_ptr > parseResultVariantList( const QVariantList& reslist ); + QList< Tomahawk::artist_ptr > parseArtistVariantList( const QVariantList& reslist ); ScriptEngine* m_engine; diff --git a/src/libtomahawk/resolvers/ScriptCollection.cpp b/src/libtomahawk/resolvers/ScriptCollection.cpp index c57f5b9c7..89200d722 100644 --- a/src/libtomahawk/resolvers/ScriptCollection.cpp +++ b/src/libtomahawk/resolvers/ScriptCollection.cpp @@ -30,10 +30,10 @@ using namespace Tomahawk; ScriptCollection::ScriptCollection( const source_ptr& source, ExternalResolver* resolver, QObject* parent ) - : Collection( source, resolver->name(), parent ) + : Collection( source, QString( "scriptcollection:" + resolver->name() + ":" + uuid() ), parent ) { Q_ASSERT( resolver != 0 ); - qDebug() << Q_FUNC_INFO << resolver->name() << source->friendlyName(); + qDebug() << Q_FUNC_INFO << resolver->name() << name(); m_resolver = resolver; } @@ -83,8 +83,7 @@ ScriptCollection::icon() const void ScriptCollection::artists() { - //TODO: implement! - emit artistsResult( QList< Tomahawk::artist_ptr >() ); + m_resolver->artists( m_resolver->collections().value( name() ) ); } @@ -100,3 +99,22 @@ ScriptCollection::tracks( const Tomahawk::album_ptr& album ) { emit tracksResult( QList< Tomahawk::query_ptr >() ); } + + +void +ScriptCollection::onArtistsFetched( const QList& artists ) +{ + emit artistsResult( artists ); +} + + +void +ScriptCollection::onAlbumsFetched( const QList& albums ) +{ +} + + +void +ScriptCollection::onTracksFetched( const QList& tracks ) +{ +} diff --git a/src/libtomahawk/resolvers/ScriptCollection.h b/src/libtomahawk/resolvers/ScriptCollection.h index 53b9a6ca2..7c4c60ccd 100644 --- a/src/libtomahawk/resolvers/ScriptCollection.h +++ b/src/libtomahawk/resolvers/ScriptCollection.h @@ -51,9 +51,13 @@ public: virtual void albums( const Tomahawk::artist_ptr& artist ); virtual void tracks( const Tomahawk::album_ptr& album ); +private slots: + void onArtistsFetched( const QList< Tomahawk::artist_ptr >& artists ); + void onAlbumsFetched( const QList< Tomahawk::album_ptr >& albums ); + void onTracksFetched( const QList< Tomahawk::query_ptr >& tracks ); + private: ExternalResolver* m_resolver; - }; } //ns diff --git a/src/libtomahawk/resolvers/ScriptResolver.cpp b/src/libtomahawk/resolvers/ScriptResolver.cpp index dfc1de05f..7d805a273 100644 --- a/src/libtomahawk/resolvers/ScriptResolver.cpp +++ b/src/libtomahawk/resolvers/ScriptResolver.cpp @@ -454,7 +454,7 @@ ScriptResolver::loadCollections() m_collections.clear(); // at this point we assume that all the tracks browsable through a resolver belong to the local source Tomahawk::collection_ptr collection( new Tomahawk::ScriptCollection( SourceList::instance()->getLocal(), this ) ); - m_collections.append( collection ); + m_collections.insert( collection->name(), collection ); emit collectionAdded( collection ); //TODO: implement multiple collections from a resolver diff --git a/src/libtomahawk/resolvers/ScriptResolver.h b/src/libtomahawk/resolvers/ScriptResolver.h index 36e02d3f5..3ce59d81b 100644 --- a/src/libtomahawk/resolvers/ScriptResolver.h +++ b/src/libtomahawk/resolvers/ScriptResolver.h @@ -70,6 +70,12 @@ public slots: virtual void resolve( const Tomahawk::query_ptr& query ); virtual void start(); + // TODO: implement. Or not. Not really an issue while Spotify doesn't do browsable personal cloud storage. + virtual void artists( const Tomahawk::collection_ptr& collection ){} + virtual void albums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist ) {} + virtual void tracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album ) {} + + private slots: void readStderr(); void readStdout();