From d5fab408849259b06d9833779204e39b09e3a780 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 10 Nov 2014 16:40:28 +0100 Subject: [PATCH 01/16] Add JavaScript InfoPlugins --- data/js/es6-promise-2.0.0.min.js | 18 ++ data/js/tomahawk-infosystem.js | 160 ++++++++++++ resources.qrc | 2 + src/libtomahawk/CMakeLists.txt | 2 + src/libtomahawk/resolvers/JSInfoPlugin.cpp | 236 ++++++++++++++++++ src/libtomahawk/resolvers/JSInfoPlugin.h | 69 +++++ src/libtomahawk/resolvers/JSInfoPlugin_p.h | 46 ++++ .../resolvers/JSInfoSystemHelper.cpp | 118 +++++++++ .../resolvers/JSInfoSystemHelper.h | 50 ++++ .../resolvers/JSInfoSystemHelper_p.h | 45 ++++ src/libtomahawk/resolvers/JSResolver.cpp | 101 +++++--- src/libtomahawk/resolvers/JSResolver.h | 5 + .../resolvers/JSResolverHelper.cpp | 2 +- src/libtomahawk/resolvers/JSResolver_p.h | 4 + 14 files changed, 822 insertions(+), 36 deletions(-) create mode 100644 data/js/es6-promise-2.0.0.min.js create mode 100644 data/js/tomahawk-infosystem.js create mode 100644 src/libtomahawk/resolvers/JSInfoPlugin.cpp create mode 100644 src/libtomahawk/resolvers/JSInfoPlugin.h create mode 100644 src/libtomahawk/resolvers/JSInfoPlugin_p.h create mode 100644 src/libtomahawk/resolvers/JSInfoSystemHelper.cpp create mode 100644 src/libtomahawk/resolvers/JSInfoSystemHelper.h create mode 100644 src/libtomahawk/resolvers/JSInfoSystemHelper_p.h 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; From f075259b8d3a1cdd8247b96e735badd95e415232 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 11 Nov 2014 19:13:36 +0100 Subject: [PATCH 02/16] Make promises available to resolvers as well --- src/libtomahawk/resolvers/JSInfoSystemHelper.cpp | 1 - src/libtomahawk/resolvers/JSResolver.cpp | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp index fb556566a..6ceccdc64 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp @@ -39,7 +39,6 @@ JSInfoSystemHelper::~JSInfoSystemHelper() QStringList JSInfoSystemHelper::requiredScriptPaths() const { return QStringList() - << RESPATH "js/es6-promise-2.0.0.min.js" << RESPATH "js/tomahawk-infosystem.js"; } diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index ee52c4391..7b3fc8d55 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -211,6 +211,10 @@ JSResolver::init() // add c++ part of tomahawk javascript library d->engine->mainFrame()->addToJavaScriptWindowObject( "Tomahawk", d->resolverHelper ); + // load es6-promises shim + loadScript( RESPATH "js/es6-promise-2.0.0.min.js" ); + + // Load CrytoJS core loadScript( RESPATH "js/cryptojs-core.js" ); From 5ae9275a5a7078c81981ea470d2a2984467f0b83 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 11 Nov 2014 21:49:59 +0100 Subject: [PATCH 03/16] Add helper method to call properties/functions on resolver js object --- src/libtomahawk/resolvers/JSResolver.cpp | 47 ++++++++++++++---------- src/libtomahawk/resolvers/JSResolver.h | 3 ++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 7b3fc8d55..4a367e806 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -324,10 +324,10 @@ JSResolver::artists( const Tomahawk::collection_ptr& collection ) return; } - QString eval = QString( "Tomahawk.resolver.instance.artists( '%1' );" ) + QString eval = QString( "artists( '%1' )" ) .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) { // if the resolver doesn't return anything, async api is used @@ -360,11 +360,11 @@ JSResolver::albums( const Tomahawk::collection_ptr& collection, const Tomahawk:: return; } - QString eval = QString( "Tomahawk.resolver.instance.albums( '%1', '%2' );" ) + QString eval = QString( "albums( '%1', '%2' )" ) .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( artist->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) { // if the resolver doesn't return anything, async api is used @@ -397,12 +397,12 @@ JSResolver::tracks( const Tomahawk::collection_ptr& collection, const Tomahawk:: return; } - QString eval = QString( "Tomahawk.resolver.instance.tracks( '%1', '%2', '%3' );" ) + QString eval = QString( "tracks( '%1', '%2', '%3' )" ) .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( album->artist()->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( album->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) { // if the resolver doesn't return anything, async api is used @@ -430,10 +430,10 @@ JSResolver::canParseUrl( const QString& url, UrlType type ) if ( d->capabilities.testFlag( UrlLookup ) ) { - QString eval = QString( "Tomahawk.resolver.instance.canParseUrl( '%1', %2 );" ) + QString eval = QString( "canParseUrl( '%1', %2 )" ) .arg( QString( url ).replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( (int) type ); - return d->engine->mainFrame()->evaluateJavaScript( eval ).toBool(); + return callOnResolver( eval ).toBool(); } else { @@ -461,10 +461,10 @@ JSResolver::lookupUrl( const QString& url ) return; } - QString eval = QString( "Tomahawk.resolver.instance.lookupUrl( '%1' );" ) + QString eval = QString( "lookupUrl( '%1' )" ) .arg( QString( url ).replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) { // if the resolver doesn't return anything, async api is used @@ -510,7 +510,7 @@ JSResolver::resolve( const Tomahawk::query_ptr& query ) QString eval; if ( !query->isFullTextQuery() ) { - eval = QString( "Tomahawk.resolver.instance.resolve( '%1', '%2', '%3', '%4' );" ) + eval = QString( "resolve( '%1', '%2', '%3', '%4' )" ) .arg( query->id().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( query->queryTrack()->artist().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( query->queryTrack()->album().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) @@ -518,12 +518,12 @@ JSResolver::resolve( const Tomahawk::query_ptr& query ) } else { - eval = QString( "Tomahawk.resolver.instance.search( '%1', '%2' );" ) + eval = QString( "search( '%1', '%2' )" ) .arg( query->id().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) .arg( query->fullTextQuery().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); } - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( eval ).toMap(); + QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) { // if the resolver doesn't return anything, async api is used @@ -669,7 +669,7 @@ JSResolver::loadUi() { Q_D( JSResolver ); - QVariantMap m = d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getConfigUi();" ).toMap(); + QVariantMap m = callOnResolver( "getConfigUi()" ).toMap(); d->dataWidgets = m["fields"].toList(); bool compressed = m.value( "compressed", "false" ).toBool(); @@ -718,7 +718,7 @@ JSResolver::saveConfig() // qDebug() << Q_FUNC_INFO << saveData; d->resolverHelper->setResolverConfig( saveData.toMap() ); - d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.saveUserConfig();" ); + callOnResolver( "saveUserConfig()" ); } @@ -817,7 +817,7 @@ JSResolver::loadCollections() if ( d->capabilities.testFlag( Browsable ) ) { - const QVariantMap collectionInfo = d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.collection();" ).toMap(); + const QVariantMap collectionInfo = callOnResolver( "collection()" ).toMap(); if ( collectionInfo.isEmpty() || !collectionInfo.contains( "prettyname" ) || !collectionInfo.contains( "description" ) ) @@ -914,7 +914,7 @@ JSResolver::resolverSettings() { Q_D( JSResolver ); - return d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.settings;" ).toMap(); + return callOnResolver( "settings" ).toMap(); } @@ -923,7 +923,7 @@ JSResolver::resolverUserConfig() { Q_D( JSResolver ); - return d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.getUserConfig();" ).toMap(); + return callOnResolver( "getUserConfig()" ).toMap(); } @@ -932,7 +932,7 @@ JSResolver::resolverInit() { Q_D( JSResolver ); - return d->engine->mainFrame()->evaluateJavaScript( "Tomahawk.resolver.instance.init();" ).toMap(); + return callOnResolver( "init()" ).toMap(); } @@ -978,3 +978,12 @@ JSResolver::loadScripts ( const QStringList& paths ) loadScript( path ); } } + + +QVariant +JSResolver::callOnResolver ( const QString& scriptSource ) +{ + Q_D( JSResolver ); + + return d->engine->mainFrame()->evaluateJavaScript( scriptSource + ";" ); +} diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index b89df2c5a..0105bba24 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -78,6 +78,9 @@ public slots: signals: void stopped(); +protected: + QVariant callOnResolver( const QString& scriptSource ); + private slots: void onCollectionIconFetched(); From b77d4dc73eb322f5c62cf4705eccc214645eaf2b Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 11 Nov 2014 21:51:26 +0100 Subject: [PATCH 04/16] Call _adapter_$propertyName on resolver object if available to allow a nice promise based API without breaking legacy resolvers --- src/libtomahawk/resolvers/JSResolver.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 4a367e806..02b68f59d 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -985,5 +985,13 @@ JSResolver::callOnResolver ( const QString& scriptSource ) { Q_D( JSResolver ); - return d->engine->mainFrame()->evaluateJavaScript( scriptSource + ";" ); + QString propertyName = scriptSource.split('(').first(); + + return d->engine->mainFrame()->evaluateJavaScript( QString( + "if(Tomahawk.resolver.instance['_adapter_%1']) {" + " Tomahawk.resolver.instance._adapter_%2;" + "} else {" + " Tomahawk.resolver.instance.%2" + "}" + ).arg( propertyName ).arg( scriptSource ) ); } From 0d51bfb786800dd9ef30abf6bcf49497930c8194 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 13 Nov 2014 18:01:26 +0100 Subject: [PATCH 05/16] Fix code style --- src/libtomahawk/resolvers/JSInfoPlugin.cpp | 23 ++++++++++--------- .../resolvers/JSInfoSystemHelper.cpp | 13 +++++------ src/libtomahawk/resolvers/JSResolver.cpp | 6 ++--- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp index 488f074a2..0aeaf9340 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.cpp +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -55,7 +55,7 @@ JSInfoPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) d->requestDataCache[ requestData.requestId ] = requestData; - QString eval = QString("_getInfo(%1, %2, %3, %4)") + QString eval = QString( "_getInfo(%1, %2, %3, %4)" ) .arg( d->id ) // infoPluginId .arg( requestData.requestId ) // requestId .arg( requestData.type ) // type @@ -100,7 +100,7 @@ JSInfoPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tom void -JSInfoPlugin::addInfoRequestResult ( int requestId, qint64 maxAge, const QVariantMap& returnedData ) +JSInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData ) { Q_D( JSInfoPlugin ); @@ -119,7 +119,7 @@ JSInfoPlugin::addInfoRequestResult ( int requestId, qint64 maxAge, const QVarian void -JSInfoPlugin::emitGetCachedInfo ( int requestId, const QVariantMap& criteria, int newMaxAge ) +JSInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge ) { Q_D( JSInfoPlugin ); @@ -128,7 +128,7 @@ JSInfoPlugin::emitGetCachedInfo ( int requestId, const QVariantMap& criteria, in void -JSInfoPlugin::emitInfo ( int requestId, const QVariantMap& output ) +JSInfoPlugin::emitInfo( int requestId, const QVariantMap& output ) { Q_D( JSInfoPlugin ); @@ -141,12 +141,12 @@ JSInfoPlugin::serviceGetter() const { Q_D( const JSInfoPlugin ); - return QString("Tomahawk.InfoSystem.getInfoPlugin(%1)").arg( d->id ); + return QString( "Tomahawk.InfoSystem.getInfoPlugin(%1)" ).arg( d->id ); } QVariant -JSInfoPlugin::callMethodOnInfoPlugin ( const QString& scriptSource ) +JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource ) { Q_D( JSInfoPlugin ); @@ -157,8 +157,9 @@ JSInfoPlugin::callMethodOnInfoPlugin ( const QString& scriptSource ) return d->resolver->evaluateJavaScript( eval ); } + QSet< Tomahawk::InfoSystem::InfoType > -JSInfoPlugin::parseSupportedTypes ( const QVariant& variant ) +JSInfoPlugin::parseSupportedTypes( const QVariant& variant ) { QVariantList list = variant.toList(); @@ -179,7 +180,7 @@ JSInfoPlugin::parseSupportedTypes ( const QVariant& variant ) QString -JSInfoPlugin::serializeQVariantMap ( const QVariantMap& map ) +JSInfoPlugin::serializeQVariantMap( const QVariantMap& map ) { QVariantMap localMap = map; @@ -203,12 +204,12 @@ JSInfoPlugin::serializeQVariantMap ( const QVariantMap& map ) QByteArray serialized = TomahawkUtils::toJson( localMap ); - return QString("JSON.parse('%1')").arg( QString::fromUtf8( serialized ) ); + return QString( "JSON.parse('%1')" ).arg( QString::fromUtf8( serialized ) ); } QVariantMap -JSInfoPlugin::convertInfoStringHashToQVariantMap ( const Tomahawk::InfoSystem::InfoStringHash& hash ) +JSInfoPlugin::convertInfoStringHashToQVariantMap( const Tomahawk::InfoSystem::InfoStringHash& hash ) { QVariantMap map; @@ -222,7 +223,7 @@ JSInfoPlugin::convertInfoStringHashToQVariantMap ( const Tomahawk::InfoSystem::I Tomahawk::InfoSystem::InfoStringHash -JSInfoPlugin::convertQVariantMapToInfoStringHash ( const QVariantMap& map ) +JSInfoPlugin::convertQVariantMapToInfoStringHash( const QVariantMap& map ) { Tomahawk::InfoSystem::InfoStringHash hash; diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp index 6ceccdc64..cbee2433e 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp @@ -44,7 +44,7 @@ QStringList JSInfoSystemHelper::requiredScriptPaths() const void -JSInfoSystemHelper::nativeAddInfoPlugin ( int id ) +JSInfoSystemHelper::nativeAddInfoPlugin( int id ) { Q_D( JSInfoSystemHelper ); @@ -64,7 +64,7 @@ JSInfoSystemHelper::nativeAddInfoPlugin ( int id ) void -JSInfoSystemHelper::nativeRemoveInfoPlugin ( int id ) +JSInfoSystemHelper::nativeRemoveInfoPlugin( int id ) { Q_UNUSED( id ); tLog() << "Removing Info plugins from JS is not implemented yet"; @@ -73,7 +73,7 @@ JSInfoSystemHelper::nativeRemoveInfoPlugin ( int id ) void -JSInfoSystemHelper::nativeAddInfoRequestResult ( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData ) +JSInfoSystemHelper::nativeAddInfoRequestResult( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData ) { Q_D( JSInfoSystemHelper ); @@ -88,7 +88,7 @@ JSInfoSystemHelper::nativeAddInfoRequestResult ( int infoPluginId, int requestId void -JSInfoSystemHelper::nativeGetCachedInfo ( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria ) +JSInfoSystemHelper::nativeGetCachedInfo( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria ) { Q_D( JSInfoSystemHelper ); @@ -99,10 +99,10 @@ JSInfoSystemHelper::nativeGetCachedInfo ( int infoPluginId, int requestId, int n } d->infoPlugins[ infoPluginId ]->emitGetCachedInfo( requestId, criteria, newMaxAge ); - } -void JSInfoSystemHelper::nativeDataError ( int infoPluginId, int requestId ) + +void JSInfoSystemHelper::nativeDataError( int infoPluginId, int requestId ) { Q_D( JSInfoSystemHelper ); @@ -114,4 +114,3 @@ void JSInfoSystemHelper::nativeDataError ( int infoPluginId, int requestId ) d->infoPlugins[ infoPluginId ]->emitInfo( requestId, QVariantMap() ); } - diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 02b68f59d..431be5aa0 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -948,7 +948,7 @@ JSResolver::resolverCollections() void -JSResolver::loadScript ( const QString& path ) +JSResolver::loadScript( const QString& path ) { Q_D( JSResolver ); @@ -971,7 +971,7 @@ JSResolver::loadScript ( const QString& path ) void -JSResolver::loadScripts ( const QStringList& paths ) +JSResolver::loadScripts( const QStringList& paths ) { foreach ( const QString& path, paths ) { @@ -981,7 +981,7 @@ JSResolver::loadScripts ( const QStringList& paths ) QVariant -JSResolver::callOnResolver ( const QString& scriptSource ) +JSResolver::callOnResolver( const QString& scriptSource ) { Q_D( JSResolver ); From b88faf3bdfa8caec795ad870f6e72a2c4468818d Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 13 Nov 2014 18:26:37 +0100 Subject: [PATCH 06/16] Remove unused include --- src/libtomahawk/resolvers/JSInfoSystemHelper.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp index cbee2433e..a997e6f08 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp @@ -21,8 +21,6 @@ #include "../utils/Logger.h" -#include - JSInfoSystemHelper::JSInfoSystemHelper( JSResolver* parent ) : QObject( parent ) From 0c265332611edce810bc825ea893c0ad959f2de5 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 13 Nov 2014 19:56:49 +0100 Subject: [PATCH 07/16] Make sure JSInfo* methods are called in the right threads --- src/libtomahawk/resolvers/JSInfoPlugin.cpp | 44 +++++++++++++++++++--- src/libtomahawk/resolvers/JSInfoPlugin.h | 9 +++-- src/libtomahawk/resolvers/JSResolver.cpp | 26 ++++++++++++- src/libtomahawk/resolvers/JSResolver.h | 16 +++++++- 4 files changed, 83 insertions(+), 12 deletions(-) diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp index 0aeaf9340..672b4637f 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.cpp +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -29,9 +29,9 @@ JSInfoPlugin::JSInfoPlugin( int id, JSResolver *resolver ) { Q_ASSERT( resolver ); - // read in supported GetTypes and PushTypes - m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedGetTypes" ) ); - m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPlugin( "supportedPushTypes" ) ); + // read in supported GetTypes and PushTypes - we can do this safely because we are still in WebKit thread here + m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedGetTypes" ) ); + m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedPushTypes" ) ); setFriendlyName( QString( "JSInfoPlugin: %1" ).arg( resolver->name() ) ); } @@ -104,6 +104,12 @@ JSInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariant { Q_D( JSInfoPlugin ); + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "addInfoRequestResult", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( qint64, maxAge ), Q_ARG( QVariantMap, returnedData ) ); + return; + } + // retrieve requestData from cache and delete it Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ]; d->requestDataCache.remove( requestId ); @@ -123,6 +129,12 @@ JSInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int { Q_D( JSInfoPlugin ); + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "emitGetCachedInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, criteria ), Q_ARG( int, newMaxAge ) ); + return; + } + emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]); } @@ -132,6 +144,12 @@ JSInfoPlugin::emitInfo( int requestId, const QVariantMap& output ) { Q_D( JSInfoPlugin ); + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "emitInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, output ) ); + return; + } + emit info( d->requestDataCache[ requestId ], output ); } @@ -144,8 +162,8 @@ JSInfoPlugin::serviceGetter() const return QString( "Tomahawk.InfoSystem.getInfoPlugin(%1)" ).arg( d->id ); } - -QVariant +// TODO: DRY, really move things into base class +void JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource ) { Q_D( JSInfoPlugin ); @@ -154,10 +172,24 @@ JSInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource ) tLog() << Q_FUNC_INFO << eval; - return d->resolver->evaluateJavaScript( eval ); + d->resolver->evaluateJavaScript( eval ); } +QVariant +JSInfoPlugin::callMethodOnInfoPluginWithResult(const QString& scriptSource) +{ + Q_D( JSInfoPlugin ); + + QString eval = QString( "%1.%2" ).arg( serviceGetter() ).arg( scriptSource ); + + tLog() << Q_FUNC_INFO << eval; + + return d->resolver->evaluateJavaScriptWithResult( eval ); +} + + + QSet< Tomahawk::InfoSystem::InfoType > JSInfoPlugin::parseSupportedTypes( const QVariant& variant ) { diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.h b/src/libtomahawk/resolvers/JSInfoPlugin.h index 5087993ad..bb399d288 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.h +++ b/src/libtomahawk/resolvers/JSInfoPlugin.h @@ -40,9 +40,9 @@ public: 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 ); + Q_INVOKABLE void addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData ); + Q_INVOKABLE void emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge ); + Q_INVOKABLE void emitInfo( int requestId, const QVariantMap& output ); protected slots: void init() override; @@ -54,7 +54,8 @@ protected slots: protected: // TODO: create JSPlugin base class and move these methods there QString serviceGetter() const; // = 0 - QVariant callMethodOnInfoPlugin( const QString& scriptSource ); + void callMethodOnInfoPlugin( const QString& scriptSource ); + QVariant callMethodOnInfoPluginWithResult( const QString& scriptSource ); private: static QSet< Tomahawk::InfoSystem::InfoType > parseSupportedTypes(const QVariant& variant); diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 431be5aa0..1c40aa84e 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -478,7 +478,7 @@ JSResolver::lookupUrl( const QString& url ) QVariant -JSResolver::evaluateJavaScript ( const QString& scriptSource ) +JSResolver::evaluateJavaScriptInternal(const QString& scriptSource) { Q_D( JSResolver ); @@ -486,6 +486,30 @@ JSResolver::evaluateJavaScript ( const QString& scriptSource ) } +void +JSResolver::evaluateJavaScript( const QString& scriptSource ) +{ + Q_D( JSResolver ); + + if ( QThread::currentThread() != thread() ) + { + QMetaObject::invokeMethod( this, "evaluateJavaScript", Qt::QueuedConnection, Q_ARG( QString, scriptSource ) ); + return; + } + + evaluateJavaScriptInternal( scriptSource ); +} + + +QVariant +JSResolver::evaluateJavaScriptWithResult( const QString& scriptSource ) +{ + Q_ASSERT( QThread::currentThread() == thread() ); + + return evaluateJavaScriptInternal( scriptSource ); +} + + Tomahawk::ExternalResolver::ErrorState JSResolver::error() const diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index 0105bba24..f2163e3d7 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -61,7 +61,16 @@ public: bool canParseUrl( const QString& url, UrlType type ) override; - QVariant evaluateJavaScript( const QString& scriptSource ); + /** + * Evaluate JavaScript on the WebKit thread + */ + Q_INVOKABLE void evaluateJavaScript( const QString& scriptSource ); + + /** + * This method must be called from the WebKit thread + */ + QVariant evaluateJavaScriptWithResult( const QString& scriptSource ); + public slots: void resolve( const Tomahawk::query_ptr& query ) override; @@ -97,6 +106,11 @@ private: void loadScript( const QString& path ); void loadScripts( const QStringList& paths ); + /** + * Wrap the pure evaluateJavaScript call in here, while the threadings guards are in public methods + */ + QVariant evaluateJavaScriptInternal( const QString& scriptSource ); + // encapsulate javascript calls QVariantMap resolverSettings(); QVariantMap resolverUserConfig(); From 84b30f0f5e55a8c9104f8b10510c9cd481100bc7 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 13 Nov 2014 20:10:20 +0100 Subject: [PATCH 08/16] Move Q_D underneath any thread guards --- src/libtomahawk/resolvers/JSInfoPlugin.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp index 672b4637f..4109ae213 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.cpp +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -102,14 +102,14 @@ JSInfoPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tom void JSInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData ) { - Q_D( JSInfoPlugin ); - if ( QThread::currentThread() != thread() ) { QMetaObject::invokeMethod( this, "addInfoRequestResult", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( qint64, maxAge ), Q_ARG( QVariantMap, returnedData ) ); return; } + Q_D( JSInfoPlugin ); + // retrieve requestData from cache and delete it Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ]; d->requestDataCache.remove( requestId ); @@ -127,14 +127,15 @@ JSInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariant void JSInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge ) { - Q_D( JSInfoPlugin ); - if ( QThread::currentThread() != thread() ) { QMetaObject::invokeMethod( this, "emitGetCachedInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, criteria ), Q_ARG( int, newMaxAge ) ); return; } + Q_D( JSInfoPlugin ); + + emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]); } @@ -142,14 +143,14 @@ JSInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int void JSInfoPlugin::emitInfo( int requestId, const QVariantMap& output ) { - Q_D( JSInfoPlugin ); - if ( QThread::currentThread() != thread() ) { QMetaObject::invokeMethod( this, "emitInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, output ) ); return; } + Q_D( JSInfoPlugin ); + emit info( d->requestDataCache[ requestId ], output ); } From 2cd4b0442e3a5aa8c798b5867ecde6e5c216d34a Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Thu, 13 Nov 2014 20:14:30 +0100 Subject: [PATCH 09/16] Remove spurious newline --- src/libtomahawk/resolvers/JSResolver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 1c40aa84e..5fd752133 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -510,7 +510,6 @@ JSResolver::evaluateJavaScriptWithResult( const QString& scriptSource ) } - Tomahawk::ExternalResolver::ErrorState JSResolver::error() const { From 470cd7e0c5e08ada89fa38c9b41818d2a8b7b635 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 15:15:32 +0100 Subject: [PATCH 10/16] Don't use QVariantHash instead of QVariantMap for artist biographies --- src/infoplugins/generic/echonest/EchonestPlugin.cpp | 2 +- src/libtomahawk/Artist.cpp | 2 +- src/libtomahawk/accounts/lastfm/LastFmInfoPlugin.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/infoplugins/generic/echonest/EchonestPlugin.cpp b/src/infoplugins/generic/echonest/EchonestPlugin.cpp index c0135a0b5..762b601d6 100644 --- a/src/infoplugins/generic/echonest/EchonestPlugin.cpp +++ b/src/infoplugins/generic/echonest/EchonestPlugin.cpp @@ -182,7 +182,7 @@ EchonestPlugin::getArtistBiographySlot() QVariantMap biographyMap; Q_FOREACH( const Echonest::Biography& biography, biographies ) { - QVariantHash siteData; + QVariantMap siteData; siteData[ "site" ] = biography.site(); siteData[ "url" ] = biography.url().toString(); siteData[ "text" ] = biography.text(); diff --git a/src/libtomahawk/Artist.cpp b/src/libtomahawk/Artist.cpp index f5c5c94d3..1f930c60e 100644 --- a/src/libtomahawk/Artist.cpp +++ b/src/libtomahawk/Artist.cpp @@ -547,7 +547,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari foreach ( const QString& source, bmap.keys() ) { if ( source == "last.fm" ) - m_biography = bmap[ source ].toHash()[ "text" ].toString(); + m_biography = bmap[ source ].toMap()[ "text" ].toString(); } m_biographyLoaded = true; diff --git a/src/libtomahawk/accounts/lastfm/LastFmInfoPlugin.cpp b/src/libtomahawk/accounts/lastfm/LastFmInfoPlugin.cpp index 59cd85e32..acc96fd0d 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmInfoPlugin.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmInfoPlugin.cpp @@ -736,7 +736,7 @@ LastFmInfoPlugin::artistInfoReturned() .replace( trackRegExp, "" ) .replace( "&album=_", "" ); - QVariantHash siteData; + QVariantMap siteData; siteData[ "site" ] = "last.fm"; siteData[ "text" ] = biography.replace( "\r", "\n" ).replace( "\n\n", "\n" ); siteData[ "summary" ] = lfm["artist"]["bio"]["summary"].text().trimmed().replace( "\r", "\n" ).replace( "\n\n", "\n" ); From e8b8f95a25c6a204f9fba661b42c48f65f0561a9 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 15:17:27 +0100 Subject: [PATCH 11/16] Get rid of QVariantHash in EchonestPlugin completely --- src/infoplugins/generic/echonest/EchonestPlugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/infoplugins/generic/echonest/EchonestPlugin.cpp b/src/infoplugins/generic/echonest/EchonestPlugin.cpp index 762b601d6..92e8c110b 100644 --- a/src/infoplugins/generic/echonest/EchonestPlugin.cpp +++ b/src/infoplugins/generic/echonest/EchonestPlugin.cpp @@ -228,7 +228,7 @@ EchonestPlugin::getArtistTermsSlot() Echonest::TermList terms = artist.terms(); QVariantMap termsMap; Q_FOREACH( const Echonest::Term& term, terms ) { - QVariantHash termHash; + QVariantMap termHash; termHash[ "weight" ] = QString::number( term.weight() ); termHash[ "frequency" ] = QString::number( term.frequency() ); termsMap[ term.name() ] = termHash; @@ -246,7 +246,7 @@ EchonestPlugin::getMiscTopSlot() Echonest::TermList terms = Echonest::Artist::parseTopTerms( reply ); QVariantMap termsMap; Q_FOREACH( const Echonest::Term& term, terms ) { - QVariantHash termHash; + QVariantMap termHash; termHash[ "weight" ] = QString::number( term.weight() ); termHash[ "frequency" ] = QString::number( term.frequency() ); termsMap[ term.name() ] = termHash; From f8ce2c910868fdcc81b3b30153e9441acaea23d9 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 15:47:56 +0100 Subject: [PATCH 12/16] Add Tomahawk.assert to JS bindings --- data/js/tomahawk.js | 4 ++++ src/libtomahawk/resolvers/JSResolverHelper.cpp | 11 +++++++++++ src/libtomahawk/resolvers/JSResolverHelper.h | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/data/js/tomahawk.js b/data/js/tomahawk.js index ff419bd1a..f14caaffa 100644 --- a/data/js/tomahawk.js +++ b/data/js/tomahawk.js @@ -409,6 +409,10 @@ Tomahawk.asyncRequest = function (url, callback, extraHeaders, options) { } }; +Tomahawk.assert = function (assertion, message) { + Tomahawk.nativeAssert(assertion, message); +} + Tomahawk.sha256 = Tomahawk.sha256 || CryptoJS.SHA256; Tomahawk.md5 = Tomahawk.md5 || CryptoJS.MD5; // Return a HMAC (md5) signature of the input text with the desired key diff --git a/src/libtomahawk/resolvers/JSResolverHelper.cpp b/src/libtomahawk/resolvers/JSResolverHelper.cpp index 945ee6e11..ae371c482 100644 --- a/src/libtomahawk/resolvers/JSResolverHelper.cpp +++ b/src/libtomahawk/resolvers/JSResolverHelper.cpp @@ -460,6 +460,17 @@ JSResolverHelper::reportStreamUrl( const QString& qid, const QString& streamUrl } +void JSResolverHelper::nativeAssert(bool assertion, const QString& message) +{ + if ( !assertion ) + { + tLog() << "Assertion failed" << message; + Q_ASSERT( assertion ); + } +} + + + void JSResolverHelper::customIODeviceFactory( const Tomahawk::result_ptr&, const QString& url, std::function< void( const QString&, QSharedPointer< QIODevice >& ) > callback ) diff --git a/src/libtomahawk/resolvers/JSResolverHelper.h b/src/libtomahawk/resolvers/JSResolverHelper.h index f94ec1d4a..fb91847a7 100644 --- a/src/libtomahawk/resolvers/JSResolverHelper.h +++ b/src/libtomahawk/resolvers/JSResolverHelper.h @@ -60,6 +60,11 @@ public: Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl ); Q_INVOKABLE void reportStreamUrl( const QString& qid, const QString& streamUrl, const QVariantMap& headers ); + /** + * Make Tomahawk assert the assertion is true, probably not to be used by resolvers directly + */ + Q_INVOKABLE void nativeAssert( bool assertion, const QString& message = QString() ); + /** * Retrieve metadata for a media stream. * From de0fcab5f91b99aef1fabacf2596f79972e15172 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 15:56:51 +0100 Subject: [PATCH 13/16] Add escape helper method to JSResolver --- src/libtomahawk/resolvers/JSResolver.cpp | 34 ++++++++++++++---------- src/libtomahawk/resolvers/JSResolver.h | 5 ++++ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 5fd752133..e5f1c980e 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -325,7 +325,7 @@ JSResolver::artists( const Tomahawk::collection_ptr& collection ) } QString eval = QString( "artists( '%1' )" ) - .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( collection->name() ) ); QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) @@ -361,8 +361,8 @@ JSResolver::albums( const Tomahawk::collection_ptr& collection, const Tomahawk:: } QString eval = QString( "albums( '%1', '%2' )" ) - .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( artist->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( collection->name() ) ) + .arg( escape( artist->name() ) ); QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) @@ -398,9 +398,9 @@ JSResolver::tracks( const Tomahawk::collection_ptr& collection, const Tomahawk:: } QString eval = QString( "tracks( '%1', '%2', '%3' )" ) - .arg( collection->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( album->artist()->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( album->name().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( collection->name() ) ) + .arg( escape( album->artist()->name() ) ) + .arg( escape( album->name() ) ); QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) @@ -431,7 +431,7 @@ JSResolver::canParseUrl( const QString& url, UrlType type ) if ( d->capabilities.testFlag( UrlLookup ) ) { QString eval = QString( "canParseUrl( '%1', %2 )" ) - .arg( QString( url ).replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) + .arg( escape( QString( url ) ) ) .arg( (int) type ); return callOnResolver( eval ).toBool(); } @@ -462,7 +462,7 @@ JSResolver::lookupUrl( const QString& url ) } QString eval = QString( "lookupUrl( '%1' )" ) - .arg( QString( url ).replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( QString( url ) ) ); QVariantMap m = callOnResolver( eval ).toMap(); if ( m.isEmpty() ) @@ -534,16 +534,16 @@ JSResolver::resolve( const Tomahawk::query_ptr& query ) if ( !query->isFullTextQuery() ) { eval = QString( "resolve( '%1', '%2', '%3', '%4' )" ) - .arg( query->id().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( query->queryTrack()->artist().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( query->queryTrack()->album().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( query->queryTrack()->track().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( query->id() ) ) + .arg( escape( query->queryTrack()->artist() ) ) + .arg( escape( query->queryTrack()->album() ) ) + .arg( escape( query->queryTrack()->track() ) ); } else { eval = QString( "search( '%1', '%2' )" ) - .arg( query->id().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ) - .arg( query->fullTextQuery().replace( "\\", "\\\\" ).replace( "'", "\\'" ) ); + .arg( escape( query->id() ) ) + .arg( escape( query->fullTextQuery() ) ); } QVariantMap m = callOnResolver( eval ).toMap(); @@ -1018,3 +1018,9 @@ JSResolver::callOnResolver( const QString& scriptSource ) "}" ).arg( propertyName ).arg( scriptSource ) ); } + + +QString JSResolver::escape( const QString& source ) +{ + return source.replace( "\\", "\\\\" ).replace( "'", "\\'" ); +} diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index f2163e3d7..3ba555bcf 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -111,6 +111,11 @@ private: */ QVariant evaluateJavaScriptInternal( const QString& scriptSource ); + /** + * Escape \ and ' in strings so they are safe to use in JavaScript + */ + static QString escape( const QString& source ); + // encapsulate javascript calls QVariantMap resolverSettings(); QVariantMap resolverUserConfig(); From b3ace2f05a2bbfd9e7f620b41737dc75b517618b Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 16:12:53 +0100 Subject: [PATCH 14/16] Make JSResolver::escape public and use it from JSInfoPlugin --- src/libtomahawk/resolvers/JSInfoPlugin.cpp | 8 ++++---- src/libtomahawk/resolvers/JSResolver.cpp | 3 ++- src/libtomahawk/resolvers/JSResolver.h | 9 ++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp index 4109ae213..b8669ec99 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.cpp +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -59,7 +59,7 @@ JSInfoPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) .arg( d->id ) // infoPluginId .arg( requestData.requestId ) // requestId .arg( requestData.type ) // type - .arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( requestData.input.value() ) ) ); // infoHash + .arg( JSResolver::escape( serializeQVariantMap( convertInfoStringHashToQVariantMap( requestData.input.value() ) ) ) ); // infoHash callMethodOnInfoPlugin( eval ); } @@ -73,8 +73,8 @@ JSInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) 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 ) ); + .arg( JSResolver::escape( serializeQVariantMap ( pushData.infoPair.second.toMap() ) ) ) + .arg( JSResolver::escape( serializeQVariantMap( pushData.infoPair.first ) ) ); callMethodOnInfoPlugin( eval ); } @@ -93,7 +93,7 @@ JSInfoPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tom .arg( d->id ) .arg( requestData.requestId ) .arg( requestData.type ) - .arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( criteria ) ) ); + .arg( JSResolver::escape( serializeQVariantMap( convertInfoStringHashToQVariantMap( criteria ) ) ) ); callMethodOnInfoPlugin( eval ); } diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index e5f1c980e..11fc81cf0 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -1022,5 +1022,6 @@ JSResolver::callOnResolver( const QString& scriptSource ) QString JSResolver::escape( const QString& source ) { - return source.replace( "\\", "\\\\" ).replace( "'", "\\'" ); + QString copy = source; + return copy.replace( "\\", "\\\\" ).replace( "'", "\\'" ); } diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index 3ba555bcf..9ff8df559 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -71,6 +71,10 @@ public: */ QVariant evaluateJavaScriptWithResult( const QString& scriptSource ); + /** + * Escape \ and ' in strings so they are safe to use in JavaScript + */ + static QString escape( const QString& source ); public slots: void resolve( const Tomahawk::query_ptr& query ) override; @@ -111,11 +115,6 @@ private: */ QVariant evaluateJavaScriptInternal( const QString& scriptSource ); - /** - * Escape \ and ' in strings so they are safe to use in JavaScript - */ - static QString escape( const QString& source ); - // encapsulate javascript calls QVariantMap resolverSettings(); QVariantMap resolverUserConfig(); From 91af16fc1858dabf581e496c0b956b7e2ff1c166 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 16:13:08 +0100 Subject: [PATCH 15/16] Style and debug spam cleanup --- data/js/tomahawk-infosystem.js | 11 ++--------- src/libtomahawk/resolvers/JSResolver.cpp | 3 ++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/data/js/tomahawk-infosystem.js b/data/js/tomahawk-infosystem.js index 73f67c697..6fde5f1e1 100644 --- a/data/js/tomahawk-infosystem.js +++ b/data/js/tomahawk-infosystem.js @@ -96,10 +96,9 @@ Tomahawk.InfoSystem.PushInfoFlags.PushShortUrlFlag = 2; Tomahawk.InfoSystem._infoPluginIdCounter = 0; Tomahawk.InfoSystem._infoPluginHash = Object.create(null); -Tomahawk.InfoSystem.addInfoPlugin = function(infoPlugin) { +Tomahawk.InfoSystem.addInfoPlugin = function (infoPlugin) { var infoPluginId = Tomahawk.InfoSystem._infoPluginIdCounter++; Tomahawk.InfoSystem._infoPluginHash[infoPluginId] = infoPlugin; - Tomahawk.log("Call nativeAddInfoPlugin"); Tomahawk.InfoSystem.nativeAddInfoPlugin(infoPluginId); }; @@ -113,7 +112,7 @@ Tomahawk.InfoSystem.removeInfoPlugin = function (infoPluginId) { }; Tomahawk.InfoSystem.InfoPlugin = { - infoTypeString: function(infoType) { + infoTypeString: function (infoType) { for (var currentInfoTypeString in Tomahawk.InfoSystem.InfoType) { if (Tomahawk.InfoSystem.InfoType[currentInfoTypeString] === infoType) { return currentInfoTypeString; @@ -123,7 +122,6 @@ Tomahawk.InfoSystem.InfoPlugin = { // we can get around infoPluginId here probably ... but internal either way _notInCache: function (infoPluginId, requestId, requestType, criteria) { this.notInCache(requestType, criteria).then(function(result) { - Tomahawk.log("Call nativeAddInfoRequestResult"); Tomahawk.InfoSystem.nativeAddInfoRequestResult(infoPluginId, requestId, result.maxAge, result.data); }).catch(function() { // TODO: how to handle errors here?! @@ -131,7 +129,6 @@ Tomahawk.InfoSystem.InfoPlugin = { }, notInCache: function (infoType, criteria) { var requestMethod = 'request' + this.infoTypeString(infoType); - Tomahawk.log('Calling requestMethod: ' + requestMethod); return Promise.resolve(this[requestMethod](criteria)); }, @@ -141,10 +138,7 @@ Tomahawk.InfoSystem.InfoPlugin = { }, // we can get around infoPluginId here probably ... but internal either way _getInfo: function (infoPluginId, requestId, type, infoHash) { - Tomahawk.log("currentInfoPlugin._getInfo"); - window.getInfo = arguments; this.getInfo(type, infoHash).then(function(result) { - Tomahawk.log("Call nativeGetCachedInfo"); Tomahawk.InfoSystem.nativeGetCachedInfo(infoPluginId, requestId, result.newMaxAge, result.criteria) }, function() { Tomahawk.log("Call nativeDataError"); @@ -152,7 +146,6 @@ Tomahawk.InfoSystem.InfoPlugin = { }); }, getInfo: function (type, infoHash) { - Tomahawk.log("currentInfoPlugin.getInfo"); var getInfoMethod = 'get' + this.infoTypeString(type); return Promise.resolve(this[getInfoMethod](infoHash)); diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 11fc81cf0..765ae3425 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -1020,7 +1020,8 @@ JSResolver::callOnResolver( const QString& scriptSource ) } -QString JSResolver::escape( const QString& source ) +QString +JSResolver::escape( const QString& source ) { QString copy = source; return copy.replace( "\\", "\\\\" ).replace( "'", "\\'" ); From e1dbeb4cd6cc5ba7bb57ef0019fef9cee64f5cbe Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 17 Nov 2014 17:03:35 +0100 Subject: [PATCH 16/16] Move all classes in libtomahawk/resolvers to Tomahawk namespace --- src/libtomahawk/accounts/spotify/SpotifyAccount.h | 3 +-- src/libtomahawk/resolvers/ExternalResolver.h | 10 +++++----- src/libtomahawk/resolvers/JSInfoPlugin.cpp | 2 ++ src/libtomahawk/resolvers/JSInfoPlugin.h | 5 +++++ src/libtomahawk/resolvers/JSInfoPlugin_p.h | 6 +++++- src/libtomahawk/resolvers/JSInfoSystemHelper.cpp | 1 + src/libtomahawk/resolvers/JSInfoSystemHelper.h | 5 +++++ src/libtomahawk/resolvers/JSInfoSystemHelper_p.h | 6 +++++- src/libtomahawk/resolvers/JSResolver.cpp | 2 ++ src/libtomahawk/resolvers/JSResolver.h | 6 +++++- src/libtomahawk/resolvers/JSResolverHelper.h | 10 +++++++++- src/libtomahawk/resolvers/JSResolver_p.h | 6 +++++- src/libtomahawk/resolvers/ScriptCommand.h | 5 +++++ src/libtomahawk/resolvers/ScriptCommandQueue.cpp | 2 ++ src/libtomahawk/resolvers/ScriptCommandQueue.h | 7 ++++++- src/libtomahawk/resolvers/ScriptCommand_AllAlbums.cpp | 2 ++ src/libtomahawk/resolvers/ScriptCommand_AllAlbums.h | 5 +++++ src/libtomahawk/resolvers/ScriptCommand_AllArtists.cpp | 2 ++ src/libtomahawk/resolvers/ScriptCommand_AllArtists.h | 5 +++++ src/libtomahawk/resolvers/ScriptCommand_AllTracks.cpp | 2 ++ src/libtomahawk/resolvers/ScriptCommand_AllTracks.h | 5 +++++ src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp | 2 ++ src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h | 7 +++---- src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h | 5 +++++ src/libtomahawk/resolvers/ScriptEngine.cpp | 2 ++ src/libtomahawk/resolvers/ScriptEngine.h | 8 +++++++- src/libtomahawk/resolvers/ScriptResolver.cpp | 2 ++ src/libtomahawk/resolvers/ScriptResolver.h | 5 +++++ 28 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccount.h b/src/libtomahawk/accounts/spotify/SpotifyAccount.h index 1443e3ee4..10da048b9 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyAccount.h +++ b/src/libtomahawk/accounts/spotify/SpotifyAccount.h @@ -33,11 +33,10 @@ //class SpotifyPlaylistUpdater; class QTimer; -class ScriptResolver; - namespace Tomahawk { class SpotifyParser; +class ScriptResolver; namespace InfoSystem { diff --git a/src/libtomahawk/resolvers/ExternalResolver.h b/src/libtomahawk/resolvers/ExternalResolver.h index 10f165369..6c8ff4199 100644 --- a/src/libtomahawk/resolvers/ExternalResolver.h +++ b/src/libtomahawk/resolvers/ExternalResolver.h @@ -48,11 +48,11 @@ 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; + friend class ScriptCommandQueue; + friend class ScriptCommand_AllArtists; + friend class ScriptCommand_AllAlbums; + friend class ScriptCommand_AllTracks; + friend class ScriptCommand_LookupUrl; public: enum ErrorState { diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.cpp b/src/libtomahawk/resolvers/JSInfoPlugin.cpp index b8669ec99..507d403d9 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.cpp +++ b/src/libtomahawk/resolvers/JSInfoPlugin.cpp @@ -24,6 +24,8 @@ #include "../utils/Logger.h" #include "../utils/Json.h" +using namespace Tomahawk; + JSInfoPlugin::JSInfoPlugin( int id, JSResolver *resolver ) : d_ptr( new JSInfoPluginPrivate( this, id, resolver ) ) { diff --git a/src/libtomahawk/resolvers/JSInfoPlugin.h b/src/libtomahawk/resolvers/JSInfoPlugin.h index bb399d288..faf20e146 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin.h +++ b/src/libtomahawk/resolvers/JSInfoPlugin.h @@ -24,6 +24,9 @@ #include "DllMacro.h" +namespace Tomahawk +{ + class JSResolver; class JSInfoPluginPrivate; @@ -67,4 +70,6 @@ private: QScopedPointer d_ptr; }; +}; // ns: Tomahawk + #endif // TOMAHAWK_JSINFOPLUGIN_H diff --git a/src/libtomahawk/resolvers/JSInfoPlugin_p.h b/src/libtomahawk/resolvers/JSInfoPlugin_p.h index 8d2769cc5..6f9743848 100644 --- a/src/libtomahawk/resolvers/JSInfoPlugin_p.h +++ b/src/libtomahawk/resolvers/JSInfoPlugin_p.h @@ -21,9 +21,12 @@ #include "JSInfoPlugin.h" +namespace Tomahawk +{ + class JSInfoPluginPrivate { - friend class ::JSInfoPlugin; + friend class JSInfoPlugin; public: JSInfoPluginPrivate( JSInfoPlugin* q, int id, JSResolver* resolver ) : q_ptr ( q ) @@ -42,5 +45,6 @@ private: QMap< int, Tomahawk::InfoSystem::InfoStringHash > criteriaCache; }; +} // ns: Tomahawk #endif // TOMAHAWK_JSINFOPLUGIN_P_H diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp index a997e6f08..5cfd053f9 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.cpp @@ -21,6 +21,7 @@ #include "../utils/Logger.h" +using namespace Tomahawk; JSInfoSystemHelper::JSInfoSystemHelper( JSResolver* parent ) : QObject( parent ) diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper.h b/src/libtomahawk/resolvers/JSInfoSystemHelper.h index 01f2e7798..78ca758e6 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper.h +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper.h @@ -21,6 +21,9 @@ #include +namespace Tomahawk +{ + class JSResolver; class JSInfoSystemHelperPrivate; @@ -47,4 +50,6 @@ private: QScopedPointer d_ptr; }; +} // ns: Tomahawk + #endif // TOMAHAWK_JSINFOSYSTEMHELPER_H diff --git a/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h b/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h index 121a84ca5..644d53170 100644 --- a/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h +++ b/src/libtomahawk/resolvers/JSInfoSystemHelper_p.h @@ -22,9 +22,12 @@ #include "JSResolver.h" #include "JSInfoSystemHelper.h" +namespace Tomahawk +{ + class JSInfoSystemHelperPrivate { - friend class ::JSInfoSystemHelper; + friend class JSInfoSystemHelper; public: JSInfoSystemHelperPrivate( JSInfoSystemHelper* q, JSResolver* resolver ) : q_ptr ( q ) @@ -41,5 +44,6 @@ private: }; +} // ns: Tomahawk #endif // TOMAHAWK_JSINFOSYSTEMHELPER_P_H diff --git a/src/libtomahawk/resolvers/JSResolver.cpp b/src/libtomahawk/resolvers/JSResolver.cpp index 765ae3425..82a560a28 100644 --- a/src/libtomahawk/resolvers/JSResolver.cpp +++ b/src/libtomahawk/resolvers/JSResolver.cpp @@ -54,6 +54,8 @@ #include #include +using namespace Tomahawk; + JSResolver::JSResolver( const QString& accountId, const QString& scriptPath, const QStringList& additionalScriptPaths ) : Tomahawk::ExternalResolverGui( scriptPath ) , d_ptr( new JSResolverPrivate( this, accountId, scriptPath, additionalScriptPaths ) ) diff --git a/src/libtomahawk/resolvers/JSResolver.h b/src/libtomahawk/resolvers/JSResolver.h index 9ff8df559..916457ac5 100644 --- a/src/libtomahawk/resolvers/JSResolver.h +++ b/src/libtomahawk/resolvers/JSResolver.h @@ -27,6 +27,9 @@ #include "ExternalResolverGui.h" #include "Typedefs.h" +namespace Tomahawk +{ + class JSInfoPlugin; class JSResolverHelper; class JSResolverPrivate; @@ -36,7 +39,7 @@ class DLLEXPORT JSResolver : public Tomahawk::ExternalResolverGui { Q_OBJECT -friend class ::JSResolverHelper; +friend class JSResolverHelper; public: explicit JSResolver( const QString& accountId, const QString& scriptPath, const QStringList& additionalScriptPaths = QStringList() ); @@ -130,4 +133,5 @@ private: QScopedPointer d_ptr; }; +} // ns: Tomahawk #endif // JSRESOLVER_H diff --git a/src/libtomahawk/resolvers/JSResolverHelper.h b/src/libtomahawk/resolvers/JSResolverHelper.h index fb91847a7..d1439f423 100644 --- a/src/libtomahawk/resolvers/JSResolverHelper.h +++ b/src/libtomahawk/resolvers/JSResolverHelper.h @@ -34,9 +34,14 @@ #include -class JSResolver; + Q_DECLARE_METATYPE( std::function< void( QSharedPointer< QIODevice >& ) > ) +namespace Tomahawk +{ + +class JSResolver; + class DLLEXPORT JSResolverHelper : public QObject { Q_OBJECT @@ -161,4 +166,7 @@ private: QString m_pendingUrl; Tomahawk::album_ptr m_pendingAlbum; }; + +} // ns: Tomahawk + #endif // JSRESOLVERHELPER_H diff --git a/src/libtomahawk/resolvers/JSResolver_p.h b/src/libtomahawk/resolvers/JSResolver_p.h index 33729722f..9cf837673 100644 --- a/src/libtomahawk/resolvers/JSResolver_p.h +++ b/src/libtomahawk/resolvers/JSResolver_p.h @@ -28,9 +28,12 @@ #include "JSInfoSystemHelper.h" #include "database/fuzzyindex/FuzzyIndex.h" +namespace Tomahawk +{ + class JSResolverPrivate { - friend class ::JSResolverHelper; + friend class JSResolverHelper; public: JSResolverPrivate( JSResolver* q, const QString& pAccountId, const QString& scriptPath, const QStringList& additionalScriptPaths ) : q_ptr ( q ) @@ -68,5 +71,6 @@ private: QStringList requiredScriptPaths; }; +} // ns: Tomahawk #endif // JSRESOLVER_P_H diff --git a/src/libtomahawk/resolvers/ScriptCommand.h b/src/libtomahawk/resolvers/ScriptCommand.h index 60ae4db7c..0c3df3a51 100644 --- a/src/libtomahawk/resolvers/ScriptCommand.h +++ b/src/libtomahawk/resolvers/ScriptCommand.h @@ -21,6 +21,9 @@ #include +namespace Tomahawk +{ + class ScriptCommand : public QObject { public: @@ -36,4 +39,6 @@ protected: virtual void reportFailure() = 0; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_H diff --git a/src/libtomahawk/resolvers/ScriptCommandQueue.cpp b/src/libtomahawk/resolvers/ScriptCommandQueue.cpp index a0e17e87d..98e11227c 100644 --- a/src/libtomahawk/resolvers/ScriptCommandQueue.cpp +++ b/src/libtomahawk/resolvers/ScriptCommandQueue.cpp @@ -21,6 +21,8 @@ #include #include +using namespace Tomahawk; + ScriptCommandQueue::ScriptCommandQueue( QObject* parent ) : QObject( parent ) , m_timer( new QTimer( this ) ) diff --git a/src/libtomahawk/resolvers/ScriptCommandQueue.h b/src/libtomahawk/resolvers/ScriptCommandQueue.h index aa137ab82..8795ff7aa 100644 --- a/src/libtomahawk/resolvers/ScriptCommandQueue.h +++ b/src/libtomahawk/resolvers/ScriptCommandQueue.h @@ -27,6 +27,9 @@ #include #include +namespace Tomahawk +{ + class ScriptCommandQueue : public QObject { Q_OBJECT @@ -47,6 +50,8 @@ private: QMutex m_mutex; }; -Q_DECLARE_METATYPE( QSharedPointer< ScriptCommand > ) +} // ns: Tomahawk + +Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::ScriptCommand > ) #endif // SCRIPTCOMMANDQUEUE_H diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.cpp b/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.cpp index 06764e5fc..20c2f98f4 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.cpp +++ b/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.cpp @@ -26,6 +26,8 @@ #include "PlaylistEntry.h" #include "ScriptCollection.h" +using namespace Tomahawk; + ScriptCommand_AllAlbums::ScriptCommand_AllAlbums( const Tomahawk::collection_ptr& collection, const Tomahawk::artist_ptr& artist, QObject* parent ) diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.h b/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.h index 13712e7cd..a3c2ff137 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.h +++ b/src/libtomahawk/resolvers/ScriptCommand_AllAlbums.h @@ -24,6 +24,9 @@ #include "collection/Collection.h" #include "resolvers/ScriptCommand.h" +namespace Tomahawk +{ + class ScriptCommand_AllAlbums : public ScriptCommand, public Tomahawk::AlbumsRequest { Q_OBJECT @@ -54,4 +57,6 @@ private: QString m_filter; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_ALLALBUMS_H diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllArtists.cpp b/src/libtomahawk/resolvers/ScriptCommand_AllArtists.cpp index c7cdce6f2..2f31e5462 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllArtists.cpp +++ b/src/libtomahawk/resolvers/ScriptCommand_AllArtists.cpp @@ -24,6 +24,8 @@ #include "utils/Logger.h" +using namespace Tomahawk; + ScriptCommand_AllArtists::ScriptCommand_AllArtists( const Tomahawk::collection_ptr& collection, QObject* parent ) : ScriptCommand( parent ) diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllArtists.h b/src/libtomahawk/resolvers/ScriptCommand_AllArtists.h index 3020d355f..03643956d 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllArtists.h +++ b/src/libtomahawk/resolvers/ScriptCommand_AllArtists.h @@ -24,6 +24,9 @@ #include "collection/Collection.h" #include "resolvers/ScriptCommand.h" +namespace Tomahawk +{ + class ScriptCommand_AllArtists : public ScriptCommand, public Tomahawk::ArtistsRequest { Q_OBJECT @@ -52,4 +55,6 @@ private: QString m_filter; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_ALLARTISTS_H diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllTracks.cpp b/src/libtomahawk/resolvers/ScriptCommand_AllTracks.cpp index aadba4637..81aafdaae 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllTracks.cpp +++ b/src/libtomahawk/resolvers/ScriptCommand_AllTracks.cpp @@ -24,6 +24,8 @@ #include "utils/Logger.h" +using namespace Tomahawk; + ScriptCommand_AllTracks::ScriptCommand_AllTracks( const Tomahawk::collection_ptr& collection, const Tomahawk::album_ptr& album, QObject* parent ) diff --git a/src/libtomahawk/resolvers/ScriptCommand_AllTracks.h b/src/libtomahawk/resolvers/ScriptCommand_AllTracks.h index f7f9f5c9c..845fc75f0 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_AllTracks.h +++ b/src/libtomahawk/resolvers/ScriptCommand_AllTracks.h @@ -24,6 +24,9 @@ #include "collection/Collection.h" #include "resolvers/ScriptCommand.h" +namespace Tomahawk +{ + class ScriptCommand_AllTracks : public ScriptCommand, public Tomahawk::TracksRequest { Q_OBJECT @@ -51,4 +54,6 @@ private: Tomahawk::album_ptr m_album; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_ALLTRACKS_H diff --git a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp index 6ebcf4964..5e91cbe73 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp +++ b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.cpp @@ -20,6 +20,8 @@ #include "PlaylistEntry.h" +using namespace Tomahawk; + ScriptCommand_LookupUrl::ScriptCommand_LookupUrl( Tomahawk::ExternalResolver* resolver, const QString& url, QObject* parent ) : ScriptCommand( parent ) , d_ptr( new ScriptCommand_LookupUrlPrivate( this, resolver, url ) ) diff --git a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h index 04cc0513a..7f68e37a1 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h +++ b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl.h @@ -26,15 +26,12 @@ #include -class ScriptCommand_LookupUrlPrivate; - namespace Tomahawk { +class ScriptCommand_LookupUrlPrivate; class ExternalResolver; -} - class DLLEXPORT ScriptCommand_LookupUrl : public ScriptCommand { Q_OBJECT @@ -62,4 +59,6 @@ private: ScriptCommand_LookupUrlPrivate* d_ptr; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_LOOKUPURL_H diff --git a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h index a63f6f5ee..a47f1f5d1 100644 --- a/src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h +++ b/src/libtomahawk/resolvers/ScriptCommand_LookupUrl_p.h @@ -23,6 +23,9 @@ #include "ExternalResolver.h" +namespace Tomahawk +{ + class ScriptCommand_LookupUrlPrivate { public: @@ -40,4 +43,6 @@ private: Tomahawk::ExternalResolver* resolver; }; +} // ns: Tomahawk + #endif // SCRIPTCOMMAND_LOOKUPURL_P_H diff --git a/src/libtomahawk/resolvers/ScriptEngine.cpp b/src/libtomahawk/resolvers/ScriptEngine.cpp index a347cd729..28d9af9d2 100644 --- a/src/libtomahawk/resolvers/ScriptEngine.cpp +++ b/src/libtomahawk/resolvers/ScriptEngine.cpp @@ -33,6 +33,8 @@ #include #include +using namespace Tomahawk; + ScriptEngine::ScriptEngine( JSResolver* parent ) : QWebPage( (QObject*) parent ) , m_parent( parent ) diff --git a/src/libtomahawk/resolvers/ScriptEngine.h b/src/libtomahawk/resolvers/ScriptEngine.h index c90377527..33efecec7 100644 --- a/src/libtomahawk/resolvers/ScriptEngine.h +++ b/src/libtomahawk/resolvers/ScriptEngine.h @@ -27,9 +27,13 @@ #include #include -class JSResolver; class QNetworkReply; +namespace Tomahawk +{ + +class JSResolver; + class DLLEXPORT ScriptEngine : public QWebPage { Q_OBJECT @@ -55,4 +59,6 @@ private: QString m_header; }; +} // ns: Tomahawk + #endif // SCRIPTENGINE_H diff --git a/src/libtomahawk/resolvers/ScriptResolver.cpp b/src/libtomahawk/resolvers/ScriptResolver.cpp index 99e4c62b1..090ecbbab 100644 --- a/src/libtomahawk/resolvers/ScriptResolver.cpp +++ b/src/libtomahawk/resolvers/ScriptResolver.cpp @@ -44,6 +44,8 @@ #include #endif +using namespace Tomahawk; + ScriptResolver::ScriptResolver( const QString& exe ) : Tomahawk::ExternalResolverGui( exe ) , m_num_restarts( 0 ) diff --git a/src/libtomahawk/resolvers/ScriptResolver.h b/src/libtomahawk/resolvers/ScriptResolver.h index 090a914a0..403cbcf89 100644 --- a/src/libtomahawk/resolvers/ScriptResolver.h +++ b/src/libtomahawk/resolvers/ScriptResolver.h @@ -32,6 +32,9 @@ class QWidget; +namespace Tomahawk +{ + class DLLEXPORT ScriptResolver : public Tomahawk::ExternalResolverGui { Q_OBJECT @@ -107,4 +110,6 @@ private: ExternalResolver::ErrorState m_error; }; +} + #endif // SCRIPTRESOLVER_H