From 48ab96a1f6d9cffa2c30fa43e78fbea84a7a1fff Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Thu, 17 May 2012 19:03:18 -0400 Subject: [PATCH] Add hack/workaround for manually adding spotify resolver --- src/SettingsDialog.cpp | 34 ++++++++++++-- src/accounts/spotify/SpotifyAccount.cpp | 62 ++++++++++++++++++++----- src/accounts/spotify/SpotifyAccount.h | 6 ++- src/libtomahawk/AtticaManager.h | 2 +- 4 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index a03e36262..c9cc2546c 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -52,6 +52,7 @@ #include #include "utils/Logger.h" #include "AccountFactoryWrapper.h" +#include "accounts/spotify/SpotifyAccount.h" #include "ui_ProxyDialog.h" #include "ui_StackedSettingsDialog.h" @@ -458,15 +459,40 @@ SettingsDialog::installFromFile() if( !resolver.isEmpty() ) { + const QFileInfo resolverAbsoluteFilePath( resolver ); + TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); + + if ( resolverAbsoluteFilePath.baseName() == "spotify_tomahawkresolver" ) + { + // HACK if this is a spotify resolver, we treat is specially. + // usually we expect the user to just download the spotify resolver from attica, + // however developers, those who build their own tomahawk, can't do that, or linux + // users can't do that. However, we have an already-existing SpotifyAccount that we + // know exists that we need to use this resolver path. + // + // Hence, we special-case the spotify resolver and directly set the path on it here. + SpotifyAccount* acct = 0; + foreach ( Account* account, AccountManager::instance()->accounts() ) + { + if ( SpotifyAccount* spotify = qobject_cast< SpotifyAccount* >( account ) ) + { + acct = spotify; + break; + } + } + + if ( acct ) + { + acct->setManualResolverPath( resolver ); + return; + } + } + Account* acct = AccountManager::instance()->accountFromPath( resolver ); AccountManager::instance()->addAccount( acct ); TomahawkSettings::instance()->addAccount( acct->accountId() ); AccountManager::instance()->enableAccount( acct ); - - - QFileInfo resolverAbsoluteFilePath( resolver ); - TomahawkSettings::instance()->setScriptDefaultPath( resolverAbsoluteFilePath.absolutePath() ); } } diff --git a/src/accounts/spotify/SpotifyAccount.cpp b/src/accounts/spotify/SpotifyAccount.cpp index 866cbc309..e8dbafca4 100644 --- a/src/accounts/spotify/SpotifyAccount.cpp +++ b/src/accounts/spotify/SpotifyAccount.cpp @@ -28,6 +28,7 @@ #include "ActionCollection.h" #include "Pipeline.h" #include "accounts/AccountManager.h" +#include "utils/Closure.h" #ifndef ENABLE_HEADLESS #include "jobview/JobStatusView.h" @@ -105,12 +106,13 @@ SpotifyAccount::init() const Attica::Content res = AtticaManager::instance()->resolverForId( s_resolverId ); const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); + const QString path = configuration().value( "resolverPath" ).toString(); // Manual path override if ( !checkForResolver() && state != AtticaManager::Uninstalled ) { // If the user manually deleted the resolver, mark it as uninstalled, so we re-fetch for the user AtticaManager::instance()->uninstallResolver( res ); } - else if ( state == AtticaManager::Installed ) + else if ( state == AtticaManager::Installed || !path.isEmpty() ) { hookupResolver(); } @@ -122,16 +124,21 @@ SpotifyAccount::hookupResolver() { // initialize the resolver itself. this is called if the account actually has an installed spotify resolver, // as it might not. - // If there is a last.fm resolver from attica installed, create the corresponding ExternalResolver* and hook up to it - const Attica::Content res = AtticaManager::instance()->resolverForId( s_resolverId ); - const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); - Q_ASSERT( state == AtticaManager::Installed ); - Q_UNUSED( state ); + // If there is a spotify resolver from attica installed, create the corresponding ExternalResolver* and hook up to it + QString path = configuration().value( "resolverPath" ).toString(); + if ( path.isEmpty() ) + { + const Attica::Content res = AtticaManager::instance()->resolverForId( s_resolverId ); + const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); + Q_ASSERT( state == AtticaManager::Installed ); + Q_UNUSED( state ); - const AtticaManager::Resolver data = AtticaManager::instance()->resolverData( res.id() ); + const AtticaManager::Resolver data = AtticaManager::instance()->resolverData( res.id() ); + path = data.scriptPath; + } - qDebug() << "Starting spotify resolver with path:" << data.scriptPath; - m_spotifyResolver = QWeakPointer< ScriptResolver >( qobject_cast< ScriptResolver* >( Pipeline::instance()->addScriptResolver( data.scriptPath, enabled() ) ) ); + qDebug() << "Starting spotify resolver with path:" << path; + m_spotifyResolver = QWeakPointer< ScriptResolver >( qobject_cast< ScriptResolver* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ) ); connect( m_spotifyResolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); connect( m_spotifyResolver.data(), SIGNAL( customMessage( QString,QVariantMap ) ), this, SLOT( resolverMessage( QString, QVariantMap ) ) ); @@ -162,7 +169,6 @@ bool SpotifyAccount::checkForResolver() void SpotifyAccount::resolverChanged() { - setAccountFriendlyName( m_spotifyResolver.data()->name() ); emit connectionStateChanged( connectionState() ); } @@ -199,7 +205,7 @@ SpotifyAccount::authenticate() if ( res.isValid() && !res.id().isEmpty() ) AtticaManager::instance()->installResolver( res, false ); } - else + else if ( !m_spotifyResolver.data()->running() ) { m_spotifyResolver.data()->start(); } @@ -252,6 +258,40 @@ SpotifyAccount::atticaLoaded( Attica::Content::List ) } +void +SpotifyAccount::setManualResolverPath( const QString &resolverPath ) +{ + Q_ASSERT( !resolverPath.isEmpty() ); + + QVariantHash configuration; + configuration[ "resolverPath" ] = resolverPath; + setConfiguration( configuration ); + sync(); + + if ( !m_spotifyResolver.isNull() ) + { + // replace + //connect( m_spotifyResolver.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( hookupResolver() ) ); + NewClosure( m_spotifyResolver.data(), SIGNAL( destroyed() ), this, SLOT( hookupAfterDeletion( bool ) ), true ); + m_spotifyResolver.data()->deleteLater(); + } + else + { + hookupResolver(); + authenticate(); + } +} + + +void +SpotifyAccount::hookupAfterDeletion( bool autostart ) +{ + hookupResolver(); + if ( autostart ) + authenticate(); +} + + void SpotifyAccount::aboutToShow( QAction* action, const playlist_ptr& playlist ) { diff --git a/src/accounts/spotify/SpotifyAccount.h b/src/accounts/spotify/SpotifyAccount.h index 7d23dddde..b8a9884cb 100644 --- a/src/accounts/spotify/SpotifyAccount.h +++ b/src/accounts/spotify/SpotifyAccount.h @@ -98,6 +98,8 @@ public: bool deleteOnUnsync() const; + void setManualResolverPath( const QString& resolverPath ); + public slots: void aboutToShow( QAction* action, const Tomahawk::playlist_ptr& playlist ); void syncActionTriggered( bool ); @@ -116,9 +118,11 @@ private slots: void playlistCreated( const QString& msgType, const QVariantMap& msg ); void init(); + void hookupAfterDeletion( bool autostart ); + private: - void hookupResolver(); bool checkForResolver(); + void hookupResolver(); void loadPlaylists(); void clearUser( bool permanentlyDelete = false ); diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 7add543d9..fecb2d27f 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -92,7 +92,7 @@ public: /** If the resolver coming from libattica has a native custom c++ account - as well. For example the last.fm account. + as well. For example the last.fm & spotify accounts. */ bool hasCustomAccountForAttica( const QString& id ) const; Tomahawk::Accounts::Account* customAccountForAttica( const QString& id ) const;