diff --git a/data/js/es6-promise-2.0.0.min.js b/data/js/es6-promise-2.0.0.min.js new file mode 100644 index 000000000..59bc74560 --- /dev/null +++ b/data/js/es6-promise-2.0.0.min.js @@ -0,0 +1,18 @@ +/*! + * @overview es6-promise - a tiny implementation of Promises/A+. + * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) + * @license Licensed under MIT license + * See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE + * @version 2.0.0 + */ + +(function(){function r(a,b){n[l]=a;n[l+1]=b;l+=2;2===l&&A()}function s(a){return"function"===typeof a}function F(){return function(){process.nextTick(t)}}function G(){var a=0,b=new B(t),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function H(){var a=new MessageChannel;a.port1.onmessage=t;return function(){a.port2.postMessage(0)}}function I(){return function(){setTimeout(t,1)}}function t(){for(var a=0;adata/sql/dbmigrate-27_to_28.sql data/sql/dbmigrate-28_to_29.sql data/js/tomahawk.js + data/js/tomahawk-infosystem.js + data/js/es6-promise-2.0.0.min.js data/images/drop-all-songs.svg data/images/drop-local-songs.svg data/images/drop-top-songs.svg diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 4c31e08e9..84fc5b202 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -84,6 +84,8 @@ set( libGuiSources resolvers/ExternalResolverGui.cpp resolvers/ScriptResolver.cpp + resolvers/JSInfoPlugin.cpp + resolvers/JSInfoSystemHelper.cpp resolvers/JSResolver.cpp resolvers/JSResolverHelper.cpp resolvers/ScriptEngine.cpp diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp new file mode 100644 index 000000000..488f074a2 --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -0,0 +1,236 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2014, Dominik Schmidt + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "JSInfoPlugin_p.h" + +#include "JSResolver.h" +#include "Typedefs.h" + +#include "../utils/Logger.h" +#include "../utils/Json.h" + +JSInfoPlugin::JSInfoPlugin( int id, JSResolver *resolver ) + : d_ptr( new JSInfoPluginPrivate( this, id, resolver ) ) +{ + Q_ASSERT( resolver ); + + // read in supported GetTypes and PushTypes + m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedGetTypes" ) ); + m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedPushTypes" ) ); + + setFriendlyName( QString( "JSInfoPlugin: %1" ).arg( resolver->name() ) ); +} + + +JSInfoPlugin::~JSInfoPlugin() +{ +} + + +void +JSInfoPlugin::init() +{ +} + + +void +JSInfoPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + Q_D( JSInfoPlugin ); + + d->requestDataCache[ requestData.requestId ] = requestData; + + QString eval = QString("_getInfo(%1, %2, %3, %4)") + .arg( d->id ) // infoPluginId + .arg( requestData.requestId ) // requestId + .arg( requestData.type ) // type + .arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( requestData.input.value() ) ) ); // infoHash + + callMethodOnInfoPlugin( eval ); +} + + +void +JSInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) +{ + Q_D( JSInfoPlugin ); + + QString eval = QString( "pushInfo({ type: %1, pushFlags: %2, input: %3, additionalInput: %4})" ) + .arg( pushData.type ) + .arg( pushData.pushFlags ) + .arg( serializeQVariantMap ( pushData.infoPair.second.toMap() ) ) + .arg( serializeQVariantMap( pushData.infoPair.first ) ); + + callMethodOnInfoPlugin( eval ); +} + + +void +JSInfoPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) +{ + Q_D( JSInfoPlugin ); + + d->requestDataCache[ requestData.requestId ] = requestData; + d->criteriaCache[ requestData.requestId ] = criteria; + + + QString eval = QString( "_notInCache(%1, %2, %3, %4)" ) + .arg( d->id ) + .arg( requestData.requestId ) + .arg( requestData.type ) + .arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( criteria ) ) ); + + callMethodOnInfoPlugin( eval ); +} + + +void +JSInfoPlugin::addInfoRequestResult ( int requestId, qint64 maxAge, const QVariantMap& returnedData ) +{ + Q_D( JSInfoPlugin ); + + // retrieve requestData from cache and delete it + Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ]; + d->requestDataCache.remove( requestId ); + + emit info( requestData, returnedData ); + + // retrieve criteria from cache and delete it + Tomahawk::InfoSystem::InfoStringHash criteria = d->criteriaCache[ requestId ]; + d->criteriaCache.remove( requestId ); + + emit updateCache( criteria, maxAge, requestData.type, returnedData ); +} + + +void +JSInfoPlugin::emitGetCachedInfo ( int requestId, const QVariantMap& criteria, int newMaxAge ) +{ + Q_D( JSInfoPlugin ); + + emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]); +} + + +void +JSInfoPlugin::emitInfo ( int requestId, const QVariantMap& output ) +{ + Q_D( JSInfoPlugin ); + + emit info( d->requestDataCache[ requestId ], output ); +} + + +QString +JSInfoPlugin::serviceGetter() const +{ + Q_D( const JSInfoPlugin ); + + return QString("Tomahawk.InfoSystem.getInfoPlugin(%1)").arg( d->id ); +} + + +QVariant +JSInfoPlugin::callMethodOnInfoPlugin ( const QString& scriptSource ) +{ + Q_D( JSInfoPlugin ); + + QString eval = QString( "%1.%2" ).arg( serviceGetter() ).arg( scriptSource ); + + tLog() << Q_FUNC_INFO << eval; + + return d->resolver->evaluateJavaScript( eval ); +} + +QSet< Tomahawk::InfoSystem::InfoType > +JSInfoPlugin::parseSupportedTypes ( const QVariant& variant ) +{ + QVariantList list = variant.toList(); + + QSet < Tomahawk::InfoSystem::InfoType > results; + foreach( const QVariant& type, list ) + { + bool ok; + int intType = type.toInt( &ok ); + if ( ok ) + { + results.insert( static_cast< Tomahawk::InfoSystem::InfoType >( intType ) ); + } + tLog() << type << intType; + } + + return results; +} + + +QString +JSInfoPlugin::serializeQVariantMap ( const QVariantMap& map ) +{ + QVariantMap localMap = map; + + foreach( const QString& key, localMap.keys() ) + { + QVariant currentVariant = localMap[ key ]; + + // strip unserializable types - at least QJson needs this, check with QtJson + if( currentVariant.canConvert() ) + { + localMap.remove( key ); + } + + // convert InfoStringHash to QVariantMap + if( currentVariant.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { + Tomahawk::InfoSystem::InfoStringHash currentHash = currentVariant.value< Tomahawk::InfoSystem::InfoStringHash >(); + localMap[ key ] = convertInfoStringHashToQVariantMap( currentHash ); + } + } + + QByteArray serialized = TomahawkUtils::toJson( localMap ); + + return QString("JSON.parse('%1')").arg( QString::fromUtf8( serialized ) ); +} + + +QVariantMap +JSInfoPlugin::convertInfoStringHashToQVariantMap ( const Tomahawk::InfoSystem::InfoStringHash& hash ) +{ + QVariantMap map; + + foreach( const QString& key, hash.keys() ) + { + map[key] = QVariant::fromValue< QString >( hash.value( key ) ); + } + + return map; +} + + +Tomahawk::InfoSystem::InfoStringHash +JSInfoPlugin::convertQVariantMapToInfoStringHash ( const QVariantMap& map ) +{ + Tomahawk::InfoSystem::InfoStringHash hash; + + foreach( const QString& key, map.keys() ) + { + hash.insert( key, map[ key ].toString() ); + } + + return hash; +} + diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.h b/src/libtomahawk/resolvers/JSInfoPlugin.h new file mode 100644 index 000000000..5087993ad --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoPlugin.h @@ -0,0 +1,69 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2014, Dominik Schmidt + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TOMAHAWK_JSINFOPLUGIN_H +#define TOMAHAWK_JSINFOPLUGIN_H + +#include "../infosystem/InfoSystem.h" + +#include "DllMacro.h" + + +class JSResolver; +class JSInfoPluginPrivate; + + +class DLLEXPORT JSInfoPlugin : public Tomahawk::InfoSystem::InfoPlugin +{ +Q_OBJECT + +public: + /** + * @param id unique identifier to identify an infoplugin in its scope + */ + JSInfoPlugin( int id, JSResolver* resolver ); + virtual ~JSInfoPlugin(); + + + void addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData ); + void emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge ); + void emitInfo( int requestId, const QVariantMap& output ); + +protected slots: + void init() override; + + void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) override; + void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) override; + void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) override; + +protected: + // TODO: create JSPlugin base class and move these methods there + QString serviceGetter() const; // = 0 + QVariant callMethodOnInfoPlugin( const QString& scriptSource ); + +private: + static QSet< Tomahawk::InfoSystem::InfoType > parseSupportedTypes(const QVariant& variant); + static QString serializeQVariantMap(const QVariantMap& map); + static QVariantMap convertInfoStringHashToQVariantMap(const Tomahawk::InfoSystem::InfoStringHash& hash); + static Tomahawk::InfoSystem::InfoStringHash convertQVariantMapToInfoStringHash( const QVariantMap& map ); + + Q_DECLARE_PRIVATE( JSInfoPlugin ) + QScopedPointer d_ptr; +}; + +#endif // TOMAHAWK_JSINFOPLUGIN_H diff --git a/src/libtomahawk/resolvers/JSInfoPlugin_p.h b/src/libtomahawk/resolvers/JSInfoPlugin_p.h new file mode 100644 index 000000000..8d2769cc5 --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoPlugin_p.h @@ -0,0 +1,46 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2014, Dominik Schmidt + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TOMAHAWK_JSINFOPLUGIN_P_H +#define TOMAHAWK_JSINFOPLUGIN_P_H + +#include "JSInfoPlugin.h" + +class JSInfoPluginPrivate +{ + friend class ::JSInfoPlugin; +public: + JSInfoPluginPrivate( JSInfoPlugin* q, int id, JSResolver* resolver ) + : q_ptr ( q ) + , id( id ) + , resolver( resolver ) + { + } + JSInfoPlugin* q_ptr; + Q_DECLARE_PUBLIC ( JSInfoPlugin ) + +private: + int id; + JSResolver* resolver; + + QMap< int, Tomahawk::InfoSystem::InfoRequestData > requestDataCache; + QMap< int, Tomahawk::InfoSystem::InfoStringHash > criteriaCache; +}; + + +#endif // TOMAHAWK_JSINFOPLUGIN_P_H diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp new file mode 100644 index 000000000..fb556566a --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp @@ -0,0 +1,118 @@ +/* === This file is part of Tomahawk Player - === +* +* Copyright 2014, Dominik Schmidt +* +* Tomahawk is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Tomahawk is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Tomahawk. If not, see . +*/ + +#include "JSInfoSystemHelper_p.h" +#include "JSInfoPlugin.h" + +#include "../utils/Logger.h" + +#include + + +JSInfoSystemHelper::JSInfoSystemHelper( JSResolver* parent ) + : QObject( parent ) + , d_ptr( new JSInfoSystemHelperPrivate( this, parent ) ) +{ +} + + +JSInfoSystemHelper::~JSInfoSystemHelper() +{ +} + + +QStringList JSInfoSystemHelper::requiredScriptPaths() const +{ + return QStringList() + << RESPATH "js/es6-promise-2.0.0.min.js" + << RESPATH "js/tomahawk-infosystem.js"; +} + + +void +JSInfoSystemHelper::nativeAddInfoPlugin ( int id ) +{ + Q_D( JSInfoSystemHelper ); + + // create infoplugin instance + JSInfoPlugin* jsInfoPlugin = new JSInfoPlugin( id, d->resolver ); + Tomahawk::InfoSystem::InfoPluginPtr infoPlugin( jsInfoPlugin ); + + // move it to infosystem thread + infoPlugin->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() ); + + // add it to local list of infoplugins + d->infoPlugins[id] = jsInfoPlugin; + + // add it to infosystem + Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin ); +} + + +void +JSInfoSystemHelper::nativeRemoveInfoPlugin ( int id ) +{ + Q_UNUSED( id ); + tLog() << "Removing Info plugins from JS is not implemented yet"; + Q_ASSERT( false ); +} + + +void +JSInfoSystemHelper::nativeAddInfoRequestResult ( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData ) +{ + Q_D( JSInfoSystemHelper ); + + if ( !d->infoPlugins[ infoPluginId ] ) + { + Q_ASSERT( d->infoPlugins[ infoPluginId ] ); + return; + } + + d->infoPlugins[ infoPluginId ]->addInfoRequestResult( requestId, maxAge, returnedData ); +} + + +void +JSInfoSystemHelper::nativeGetCachedInfo ( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria ) +{ + Q_D( JSInfoSystemHelper ); + + if ( !d->infoPlugins[ infoPluginId ] ) + { + Q_ASSERT( d->infoPlugins[ infoPluginId ] ); + return; + } + + d->infoPlugins[ infoPluginId ]->emitGetCachedInfo( requestId, criteria, newMaxAge ); + +} + +void JSInfoSystemHelper::nativeDataError ( int infoPluginId, int requestId ) +{ + Q_D( JSInfoSystemHelper ); + + if ( !d->infoPlugins[ infoPluginId ] ) + { + Q_ASSERT( d->infoPlugins[ infoPluginId ] ); + return; + } + + d->infoPlugins[ infoPluginId ]->emitInfo( requestId, QVariantMap() ); +} + diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.h b/src/libtomahawk/resolvers/JSInfoSystemHelper.h new file mode 100644 index 000000000..01f2e7798 --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.h @@ -0,0 +1,50 @@ +/* === This file is part of Tomahawk Player - === +* +* Copyright 2014, Dominik Schmidt +* +* Tomahawk is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Tomahawk is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Tomahawk. If not, see . +*/ + +#ifndef TOMAHAWK_JSINFOSYSTEMHELPER_H +#define TOMAHAWK_JSINFOSYSTEMHELPER_H + +#include + +class JSResolver; +class JSInfoSystemHelperPrivate; + +class JSInfoSystemHelper : public QObject +{ + Q_OBJECT + +public: + JSInfoSystemHelper( JSResolver* parent ); + ~JSInfoSystemHelper(); + + QStringList requiredScriptPaths() const; + + Q_INVOKABLE void nativeAddInfoPlugin( int id ); + Q_INVOKABLE void nativeRemoveInfoPlugin( int id ); + + Q_INVOKABLE void nativeAddInfoRequestResult( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData ); + Q_INVOKABLE void nativeGetCachedInfo( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria); + Q_INVOKABLE void nativeDataError( int infoPluginId, int requestId ); + + +private: + Q_DECLARE_PRIVATE( JSInfoSystemHelper ) + QScopedPointer d_ptr; +}; + +#endif // TOMAHAWK_JSINFOSYSTEMHELPER_H diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h b/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h new file mode 100644 index 000000000..121a84ca5 --- /dev/null +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h @@ -0,0 +1,45 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2014, Dominik Schmidt + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef TOMAHAWK_JSINFOSYSTEMHELPER_P_H +#define TOMAHAWK_JSINFOSYSTEMHELPER_P_H + +#include "JSResolver.h" +#include "JSInfoSystemHelper.h" + +class JSInfoSystemHelperPrivate +{ + friend class ::JSInfoSystemHelper; +public: + JSInfoSystemHelperPrivate( JSInfoSystemHelper* q, JSResolver* resolver ) + : q_ptr ( q ) + , resolver ( resolver ) + { + } + + JSInfoSystemHelper* q_ptr; + Q_DECLARE_PUBLIC ( JSInfoSystemHelper ) + +private: + JSResolver* resolver; + QMap infoPlugins; + +}; + + +#endif // TOMAHAWK_JSINFOSYSTEMHELPER_P_H diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 6f8d8be38..ee52c4391 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -42,6 +42,7 @@ #include "TomahawkSettings.h" #include "TomahawkVersion.h" #include "Track.h" +#include "JSInfoPlugin.h" #include #include @@ -204,57 +205,44 @@ JSResolver::init() d->engine->mainFrame()->setHtml( "", QUrl( "file:///invalid/file/for/security/policy" ) ); - // add c++ part of tomahawk javascript library - d->engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", d->resolverHelper ); - // Load CrytoJS - { - d->engine->setScriptPath( "cryptojs-core.js" ); - QFile jslib( RESPATH "js/cryptojs-core.js" ); - jslib.open( QIODevice::ReadOnly ); - d->engine->mainFrame()->evaluateJavaScript( jslib.readAll() ); - jslib.close(); - } + // tomahawk.js { + // add c++ part of tomahawk javascript library + d->engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", d->resolverHelper ); + + // Load CrytoJS core + loadScript( RESPATH "js/cryptojs-core.js" ); + + // Load CryptoJS modules QStringList jsfiles; jsfiles << "*.js"; QDir cryptojs( RESPATH "js/cryptojs" ); foreach ( QString jsfile, cryptojs.entryList( jsfiles ) ) { - d->engine->setScriptPath( RESPATH "js/cryptojs/" + jsfile ); - QFile jslib( RESPATH "js/cryptojs/" + jsfile ); - jslib.open( QIODevice::ReadOnly ); - d->engine->mainFrame()->evaluateJavaScript( jslib.readAll() ); - jslib.close(); + loadScript( RESPATH "js/cryptojs/" + jsfile ); } + + // Load tomahawk.js + loadScript( RESPATH "js/tomahawk.js" ); } + + // tomahawk-infosystem.js { - // Load the tomahawk javascript utilities - d->engine->setScriptPath( "tomahawk.js" ); - QFile jslib( RESPATH "js/tomahawk.js" ); - jslib.open( QIODevice::ReadOnly ); - d->engine->mainFrame()->evaluateJavaScript( jslib.readAll() ); - jslib.close(); + // add c++ part of tomahawk infosystem bindings as Tomahawk.InfoSystem + d->engine->mainFrame()->addToJavaScriptWindowObject( "_TomahawkInfoSystem", d->infoSystemHelper ); + d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.InfoSystem = _TomahawkInfoSystem;" ); + + // add deps + loadScripts( d->infoSystemHelper->requiredScriptPaths() ); } // add resolver dependencies, if any - foreach ( const QString& s, d->requiredScriptPaths ) - { - QFile reqFile( s ); - if ( !reqFile.open( QIODevice::ReadOnly ) ) - { - qWarning() << "Failed to read contents of file:" << s << reqFile.errorString(); - return; - } - const QByteArray reqContents = reqFile.readAll(); + loadScripts( d->requiredScriptPaths ); - d->engine->setScriptPath( s ); - d->engine->mainFrame()->evaluateJavaScript( reqContents ); - } // add resolver - d->engine->setScriptPath( filePath() ); - d->engine->mainFrame()->evaluateJavaScript( scriptContents ); + loadScript( filePath() ); // init resolver resolverInit(); @@ -485,6 +473,16 @@ JSResolver::lookupUrl( const QString& url ) } +QVariant +JSResolver::evaluateJavaScript ( const QString& scriptSource ) +{ + Q_D( JSResolver ); + + return d->engine->mainFrame()->evaluateJavaScript( scriptSource ); +} + + + Tomahawk::ExternalResolver::ErrorState JSResolver::error() const { @@ -943,3 +941,36 @@ JSResolver::resolverCollections() // Then when there's callbacks from a resolver, it sends source name, collection id // + data. } + + +void +JSResolver::loadScript ( const QString& path ) +{ + Q_D( JSResolver ); + + QFile file( path ); + + if ( !file.open( QIODevice::ReadOnly ) ) + { + qWarning() << "Failed to read contents of file:" << path << file.errorString(); + Q_ASSERT(false); + return; + } + + const QByteArray contents = file.readAll(); + + d->engine->setScriptPath( path ); + d->engine->mainFrame()->evaluateJavaScript( contents ); + + file.close(); +} + + +void +JSResolver::loadScripts ( const QStringList& paths ) +{ + foreach ( const QString& path, paths ) + { + loadScript( path ); + } +} diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index 65402950e..b89df2c5a 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -27,6 +27,7 @@ #include "ExternalResolverGui.h" #include "Typedefs.h" +class JSInfoPlugin; class JSResolverHelper; class JSResolverPrivate; class ScriptEngine; @@ -60,6 +61,8 @@ public: bool canParseUrl( const QString& url, UrlType type ) override; + QVariant evaluateJavaScript( const QString& scriptSource ); + public slots: void resolve( const Tomahawk::query_ptr& query ) override; void stop() override; @@ -88,6 +91,8 @@ private: void fillDataInWidgets( const QVariantMap& data ); void onCapabilitiesChanged( Capabilities capabilities ); void loadCollections(); + void loadScript( const QString& path ); + void loadScripts( const QStringList& paths ); // encapsulate javascript calls QVariantMap resolverSettings(); diff --git a/src/libtomahawk/resolvers/JSResolverHelper.cpp b/src/libtomahawk/resolvers/JSResolverHelper.cpp index 75e533e09..945ee6e11 100644 --- a/src/libtomahawk/resolvers/JSResolverHelper.cpp +++ b/src/libtomahawk/resolvers/JSResolverHelper.cpp @@ -125,7 +125,7 @@ JSResolverHelper::resolverData() void JSResolverHelper::log( const QString& message ) { - tLog() << m_scriptPath << ":" << message; + tLog() << "JAVASCRIPT:" << m_scriptPath << ":" << message; } diff --git a/src/libtomahawk/resolvers/JSResolver_p.h b/src/libtomahawk/resolvers/JSResolver_p.h index 0850ac59d..33729722f 100644 --- a/src/libtomahawk/resolvers/JSResolver_p.h +++ b/src/libtomahawk/resolvers/JSResolver_p.h @@ -25,6 +25,7 @@ #include "JSResolver.h" #include "JSResolverHelper.h" +#include "JSInfoSystemHelper.h" #include "database/fuzzyindex/FuzzyIndex.h" class JSResolverPrivate @@ -38,6 +39,8 @@ public: , stopped( true ) , error( Tomahawk::ExternalResolver::NoError ) , resolverHelper( new JSResolverHelper( scriptPath, q ) ) + // TODO: be smarter about this, only instantiate this if the resolver supports infoplugins + , infoSystemHelper( new JSInfoSystemHelper( q ) ) , requiredScriptPaths( additionalScriptPaths ) { } @@ -58,6 +61,7 @@ private: Tomahawk::ExternalResolver::ErrorState error; JSResolverHelper* resolverHelper; + JSInfoSystemHelper* infoSystemHelper; QScopedPointer fuzzyIndex; QPointer< AccountConfigWidget > configWidget; QList< QVariant > dataWidgets;