mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-12 09:04:33 +02:00
Added required scripts loading support to QtScriptResolver.
The good: * you can now add multiple scripts to be loaded for a single resolver before the main script, specified in metadata.json in a bundle. The bad: * it adds some complexity, and it's not tested at all. The ugly: * passing configuration from ResolverAccountFactory as QVariantHash, but that's not new, * changing ResolverFactoryFunc, * an added optional QStringList parameter to Pipeline::addScriptResolver, * the inevitable uselessness of this parameter in ScriptResolver.
This commit is contained in:
@@ -201,8 +201,8 @@ TomahawkApp::init()
|
|||||||
m_scanManager = QPointer<ScanManager>( new ScanManager( this ) );
|
m_scanManager = QPointer<ScanManager>( new ScanManager( this ) );
|
||||||
|
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
Pipeline::instance()->addExternalResolverFactory( boost::bind( &QtScriptResolver::factory, _1 ) );
|
Pipeline::instance()->addExternalResolverFactory( boost::bind( &QtScriptResolver::factory, _1, _2 ) );
|
||||||
Pipeline::instance()->addExternalResolverFactory( boost::bind( &ScriptResolver::factory, _1 ) );
|
Pipeline::instance()->addExternalResolverFactory( boost::bind( &ScriptResolver::factory, _1, _2 ) );
|
||||||
|
|
||||||
new ActionCollection( this );
|
new ActionCollection( this );
|
||||||
connect( ActionCollection::instance()->getAction( "quit" ), SIGNAL( triggered() ), SLOT( quit() ), Qt::UniqueConnection );
|
connect( ActionCollection::instance()->getAction( "quit" ), SIGNAL( triggered() ), SLOT( quit() ), Qt::UniqueConnection );
|
||||||
|
@@ -137,13 +137,13 @@ Pipeline::addExternalResolverFactory( ResolverFactoryFunc resolverFactory )
|
|||||||
|
|
||||||
|
|
||||||
Tomahawk::ExternalResolver*
|
Tomahawk::ExternalResolver*
|
||||||
Pipeline::addScriptResolver( const QString& path )
|
Pipeline::addScriptResolver( const QString& path, const QStringList& additionalScriptPaths )
|
||||||
{
|
{
|
||||||
ExternalResolver* res = 0;
|
ExternalResolver* res = 0;
|
||||||
|
|
||||||
foreach ( ResolverFactoryFunc factory, m_resolverFactories )
|
foreach ( ResolverFactoryFunc factory, m_resolverFactories )
|
||||||
{
|
{
|
||||||
res = factory( path );
|
res = factory( path, additionalScriptPaths );
|
||||||
if ( !res )
|
if ( !res )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@ namespace Tomahawk
|
|||||||
{
|
{
|
||||||
class Resolver;
|
class Resolver;
|
||||||
class ExternalResolver;
|
class ExternalResolver;
|
||||||
typedef boost::function<Tomahawk::ExternalResolver*(QString)> ResolverFactoryFunc;
|
typedef boost::function<Tomahawk::ExternalResolver*( QString, QStringList )> ResolverFactoryFunc;
|
||||||
|
|
||||||
class DLLEXPORT Pipeline : public QObject
|
class DLLEXPORT Pipeline : public QObject
|
||||||
{
|
{
|
||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
void reportArtists( QID qid, const QList< artist_ptr >& artists );
|
void reportArtists( QID qid, const QList< artist_ptr >& artists );
|
||||||
|
|
||||||
void addExternalResolverFactory( ResolverFactoryFunc resolverFactory );
|
void addExternalResolverFactory( ResolverFactoryFunc resolverFactory );
|
||||||
Tomahawk::ExternalResolver* addScriptResolver( const QString& scriptPath );
|
Tomahawk::ExternalResolver* addScriptResolver( const QString& scriptPath, const QStringList& additionalScriptPaths = QStringList() );
|
||||||
void stopScriptResolver( const QString& scriptPath );
|
void stopScriptResolver( const QString& scriptPath );
|
||||||
void removeScriptResolver( const QString& scriptPath );
|
void removeScriptResolver( const QString& scriptPath );
|
||||||
QList< QPointer< ExternalResolver > > scriptResolvers() const { return m_scriptResolvers; }
|
QList< QPointer< ExternalResolver > > scriptResolvers() const { return m_scriptResolvers; }
|
||||||
|
@@ -89,7 +89,7 @@ namespace Tomahawk
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ExternalResolver;
|
class ExternalResolver;
|
||||||
typedef boost::function<Tomahawk::ExternalResolver*(QString)> ResolverFactoryFunc;
|
typedef boost::function<Tomahawk::ExternalResolver*( QString, QStringList )> ResolverFactoryFunc;
|
||||||
|
|
||||||
namespace PlaylistModes {
|
namespace PlaylistModes {
|
||||||
enum RepeatMode { NoRepeat, RepeatOne, RepeatAll };
|
enum RepeatMode { NoRepeat, RepeatOne, RepeatAll };
|
||||||
|
@@ -63,15 +63,23 @@ Account*
|
|||||||
ResolverAccountFactory::createFromPath( const QString& path, const QString& factory, bool isAttica )
|
ResolverAccountFactory::createFromPath( const QString& path, const QString& factory, bool isAttica )
|
||||||
{
|
{
|
||||||
qDebug() << "Creating ResolverAccount from path:" << path << "is attica" << isAttica;
|
qDebug() << "Creating ResolverAccount from path:" << path << "is attica" << isAttica;
|
||||||
|
|
||||||
|
const QFileInfo pathInfo( path );
|
||||||
|
|
||||||
if ( isAttica )
|
if ( isAttica )
|
||||||
{
|
{
|
||||||
QFileInfo info( path );
|
QVariantHash configuration;
|
||||||
return new AtticaResolverAccount( generateId( factory ), path, info.baseName() );
|
QDir dir = pathInfo.absoluteDir();//assume we are in the code directory of a bundle
|
||||||
|
if ( dir.cdUp() && dir.cdUp() ) //go up twice to the content dir, if any
|
||||||
|
{
|
||||||
|
QString metadataFilePath = dir.absoluteFilePath( "metadata.json" );
|
||||||
|
configuration = metadataFromJsonFile( metadataFilePath );
|
||||||
|
}
|
||||||
|
return new AtticaResolverAccount( generateId( factory ), path, pathInfo.baseName(), configuration );
|
||||||
}
|
}
|
||||||
else //on filesystem, but it could be a bundle or a legacy resolver file
|
else //on filesystem, but it could be a bundle or a legacy resolver file
|
||||||
{
|
{
|
||||||
QString realPath( path );
|
QString realPath( path );
|
||||||
const QFileInfo pathInfo( path );
|
|
||||||
|
|
||||||
QVariantHash configuration;
|
QVariantHash configuration;
|
||||||
|
|
||||||
@@ -135,6 +143,16 @@ ResolverAccountFactory::metadataFromJsonFile( const QString& path )
|
|||||||
QFileInfo fi( path );
|
QFileInfo fi( path );
|
||||||
result[ "path" ] = fi.absoluteDir().absoluteFilePath( manifest[ "main" ].toString() ); //this is our path to the JS
|
result[ "path" ] = fi.absoluteDir().absoluteFilePath( manifest[ "main" ].toString() ); //this is our path to the JS
|
||||||
}
|
}
|
||||||
|
if ( !manifest[ "scripts" ].isNull() )
|
||||||
|
{
|
||||||
|
QStringList scripts;
|
||||||
|
foreach ( QString s, manifest[ "scripts" ].toStringList() )
|
||||||
|
{
|
||||||
|
QFileInfo fi( path );
|
||||||
|
scripts << fi.absoluteDir().absoluteFilePath( s );
|
||||||
|
}
|
||||||
|
result[ "scripts" ] = scripts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: correct baseName and rename directory maybe?
|
//TODO: correct baseName and rename directory maybe?
|
||||||
@@ -161,6 +179,7 @@ ResolverAccount::ResolverAccount( const QString& accountId, const QString& path,
|
|||||||
{
|
{
|
||||||
QVariantHash configuration( initialConfiguration );
|
QVariantHash configuration( initialConfiguration );
|
||||||
configuration[ "path" ] = path;
|
configuration[ "path" ] = path;
|
||||||
|
|
||||||
setConfiguration( configuration );
|
setConfiguration( configuration );
|
||||||
|
|
||||||
init( path );
|
init( path );
|
||||||
@@ -200,7 +219,13 @@ ResolverAccount::hookupResolver()
|
|||||||
{
|
{
|
||||||
tDebug() << "Hooking up resolver:" << configuration().value( "path" ).toString() << enabled();
|
tDebug() << "Hooking up resolver:" << configuration().value( "path" ).toString() << enabled();
|
||||||
|
|
||||||
m_resolver = QPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( configuration().value( "path" ).toString() ) ) );
|
QString mainScriptPath = configuration().value( "path" ).toString();
|
||||||
|
QStringList additionalPaths;
|
||||||
|
if ( configuration().contains( "scripts" ) )
|
||||||
|
additionalPaths = configuration().value( "scripts" ).toStringList();
|
||||||
|
|
||||||
|
Tomahawk::ExternalResolver* er = Pipeline::instance()->addScriptResolver( mainScriptPath, additionalPaths );
|
||||||
|
m_resolver = QPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( er ) );
|
||||||
connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
|
connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
|
||||||
|
|
||||||
// What resolver do we have here? Should only be types that are 'real' resolvers
|
// What resolver do we have here? Should only be types that are 'real' resolvers
|
||||||
@@ -341,8 +366,8 @@ AtticaResolverAccount::AtticaResolverAccount( const QString& accountId )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId )
|
AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId, const QVariantHash& initialConfiguration )
|
||||||
: ResolverAccount( accountId, path )
|
: ResolverAccount( accountId, path, initialConfiguration )
|
||||||
, m_atticaId( atticaId )
|
, m_atticaId( atticaId )
|
||||||
{
|
{
|
||||||
QVariantHash conf = configuration();
|
QVariantHash conf = configuration();
|
||||||
|
@@ -133,7 +133,7 @@ private slots:
|
|||||||
void loadIcon();
|
void loadIcon();
|
||||||
private:
|
private:
|
||||||
// Created by factory, when user installs a new resolver
|
// Created by factory, when user installs a new resolver
|
||||||
AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId );
|
AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId, const QVariantHash& initialConfiguration = QVariantHash() );
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
@@ -343,12 +343,13 @@ ScriptEngine::javaScriptConsoleMessage( const QString& message, int lineNumber,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QtScriptResolver::QtScriptResolver( const QString& scriptPath )
|
QtScriptResolver::QtScriptResolver( const QString& scriptPath, const QStringList& additionalScriptPaths )
|
||||||
: Tomahawk::ExternalResolverGui( scriptPath )
|
: Tomahawk::ExternalResolverGui( scriptPath )
|
||||||
, m_ready( false )
|
, m_ready( false )
|
||||||
, m_stopped( true )
|
, m_stopped( true )
|
||||||
, m_error( Tomahawk::ExternalResolver::NoError )
|
, m_error( Tomahawk::ExternalResolver::NoError )
|
||||||
, m_resolverHelper( new QtScriptResolverHelper( scriptPath, this ) )
|
, m_resolverHelper( new QtScriptResolverHelper( scriptPath, this ) )
|
||||||
|
, m_requiredScriptPaths( additionalScriptPaths )
|
||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO << "Loading JS resolver:" << scriptPath;
|
tLog() << Q_FUNC_INFO << "Loading JS resolver:" << scriptPath;
|
||||||
|
|
||||||
@@ -379,14 +380,14 @@ QtScriptResolver::~QtScriptResolver()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Tomahawk::ExternalResolver* QtScriptResolver::factory( const QString& scriptPath )
|
Tomahawk::ExternalResolver* QtScriptResolver::factory( const QString& scriptPath, const QStringList& additionalScriptPaths )
|
||||||
{
|
{
|
||||||
ExternalResolver* res = 0;
|
ExternalResolver* res = 0;
|
||||||
|
|
||||||
const QFileInfo fi( scriptPath );
|
const QFileInfo fi( scriptPath );
|
||||||
if ( fi.suffix() == "js" || fi.suffix() == "script" )
|
if ( fi.suffix() == "js" || fi.suffix() == "script" )
|
||||||
{
|
{
|
||||||
res = new QtScriptResolver( scriptPath );
|
res = new QtScriptResolver( scriptPath, additionalScriptPaths );
|
||||||
tLog() << Q_FUNC_INFO << scriptPath << "Loaded.";
|
tLog() << Q_FUNC_INFO << scriptPath << "Loaded.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,6 +439,21 @@ QtScriptResolver::init()
|
|||||||
m_engine->mainFrame()->evaluateJavaScript( jslib.readAll() );
|
m_engine->mainFrame()->evaluateJavaScript( jslib.readAll() );
|
||||||
jslib.close();
|
jslib.close();
|
||||||
|
|
||||||
|
// add resolver dependencies, if any
|
||||||
|
foreach ( QString s, m_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();
|
||||||
|
|
||||||
|
m_engine->setScriptPath( s );
|
||||||
|
m_engine->mainFrame()->evaluateJavaScript( reqContents );
|
||||||
|
}
|
||||||
|
|
||||||
// add resolver
|
// add resolver
|
||||||
m_engine->setScriptPath( filePath() );
|
m_engine->setScriptPath( filePath() );
|
||||||
m_engine->mainFrame()->evaluateJavaScript( scriptContents );
|
m_engine->mainFrame()->evaluateJavaScript( scriptContents );
|
||||||
|
@@ -148,9 +148,9 @@ Q_OBJECT
|
|||||||
friend class ::QtScriptResolverHelper;
|
friend class ::QtScriptResolverHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QtScriptResolver( const QString& scriptPath );
|
explicit QtScriptResolver( const QString& scriptPath, const QStringList& additionalScriptPaths = QStringList() );
|
||||||
virtual ~QtScriptResolver();
|
virtual ~QtScriptResolver();
|
||||||
static ExternalResolver* factory( const QString& scriptPath );
|
static ExternalResolver* factory( const QString& scriptPath, const QStringList& additionalScriptPaths = QStringList() );
|
||||||
|
|
||||||
virtual Capabilities capabilities() const { return m_capabilities; }
|
virtual Capabilities capabilities() const { return m_capabilities; }
|
||||||
|
|
||||||
@@ -219,6 +219,7 @@ private:
|
|||||||
QtScriptResolverHelper* m_resolverHelper;
|
QtScriptResolverHelper* m_resolverHelper;
|
||||||
QPointer< AccountConfigWidget > m_configWidget;
|
QPointer< AccountConfigWidget > m_configWidget;
|
||||||
QList< QVariant > m_dataWidgets;
|
QList< QVariant > m_dataWidgets;
|
||||||
|
QStringList m_requiredScriptPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTSCRIPTRESOLVER_H
|
#endif // QTSCRIPTRESOLVER_H
|
||||||
|
@@ -96,8 +96,10 @@ ScriptResolver::~ScriptResolver()
|
|||||||
|
|
||||||
|
|
||||||
Tomahawk::ExternalResolver*
|
Tomahawk::ExternalResolver*
|
||||||
ScriptResolver::factory( const QString& exe )
|
ScriptResolver::factory( const QString& exe, const QStringList& unused )
|
||||||
{
|
{
|
||||||
|
Q_UNUSED( unused )
|
||||||
|
|
||||||
ExternalResolver* res = 0;
|
ExternalResolver* res = 0;
|
||||||
|
|
||||||
const QFileInfo fi( exe );
|
const QFileInfo fi( exe );
|
||||||
|
@@ -40,7 +40,7 @@ Q_OBJECT
|
|||||||
public:
|
public:
|
||||||
explicit ScriptResolver( const QString& exe );
|
explicit ScriptResolver( const QString& exe );
|
||||||
virtual ~ScriptResolver();
|
virtual ~ScriptResolver();
|
||||||
static ExternalResolver* factory( const QString& exe );
|
static ExternalResolver* factory( const QString& exe, const QStringList& );
|
||||||
|
|
||||||
virtual QString name() const { return m_name; }
|
virtual QString name() const { return m_name; }
|
||||||
virtual QPixmap icon() const { return m_icon; }
|
virtual QPixmap icon() const { return m_icon; }
|
||||||
|
Reference in New Issue
Block a user