From ff431b11832c4c8d2b1db77a4034276c95b5f11c Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Wed, 16 May 2012 18:07:56 -0400 Subject: [PATCH] More work on handling binary resolver install --- src/AccountDelegate.cpp | 1 + src/accounts/spotify/SpotifyAccount.cpp | 38 ++++++++++++--- src/accounts/spotify/SpotifyAccount.h | 2 + src/libtomahawk/AtticaManager.cpp | 46 ++++++++++++------- src/libtomahawk/TomahawkSettings.cpp | 29 ++++++++++++ src/libtomahawk/TomahawkSettings.h | 2 +- .../accounts/AccountModelFilterProxy.cpp | 2 +- src/libtomahawk/utils/TomahawkUtils.cpp | 4 +- src/libtomahawk/utils/TomahawkUtils_Mac.mm | 10 ++-- 9 files changed, 104 insertions(+), 30 deletions(-) diff --git a/src/AccountDelegate.cpp b/src/AccountDelegate.cpp index 505257a89..6f6185708 100644 --- a/src/AccountDelegate.cpp +++ b/src/AccountDelegate.cpp @@ -738,6 +738,7 @@ void AccountDelegate::errorInstalling( const QPersistentModelIndex& idx ) { // Just hide the loading spinner as we do after a successful install + qDebug() << "ERROR INSTALLING index:" << idx; doneInstalling( idx ); } diff --git a/src/accounts/spotify/SpotifyAccount.cpp b/src/accounts/spotify/SpotifyAccount.cpp index 2d8278bf0..902c5695e 100644 --- a/src/accounts/spotify/SpotifyAccount.cpp +++ b/src/accounts/spotify/SpotifyAccount.cpp @@ -45,6 +45,14 @@ using namespace Accounts; static QPixmap* s_icon = 0; +#ifdef Q_OS_MAC +static QString s_resolverId = "spotify-osx"; +#elif defined(Q_OS_WIN) +static QString s_resolverId = "spotify-win"; +#else +static QString s_resolverId = "spotify-linux" +#endif + Account* SpotifyAccountFactory::createAccount( const QString& accountId ) { @@ -80,14 +88,21 @@ SpotifyAccount::init() { qRegisterMetaType< Tomahawk::Accounts::SpotifyPlaylistInfo* >( "Tomahawk::Accounts::SpotifyPlaylist*" ); - AtticaManager::instance()->registerCustomAccount( "spotify", this ); + setAccountFriendlyName( "Spotify" ); + + AtticaManager::instance()->registerCustomAccount( s_resolverId, this ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( resolverInstalled( QString ) ) ); - const Attica::Content res = AtticaManager::instance()->resolverForId( "spotify" ); + const Attica::Content res = AtticaManager::instance()->resolverForId( s_resolverId ); const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); - if ( state == AtticaManager::Installed ) + 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 ) { hookupResolver(); } @@ -100,7 +115,7 @@ 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( "spotify" ); + 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 ); @@ -124,6 +139,17 @@ SpotifyAccount::hookupResolver() } +bool SpotifyAccount::checkForResolver() +{ +#ifdef Q_OS_MAC + const QDir path = QCoreApplication::applicationDirPath(); + QFile file( path.absoluteFilePath( "spotify_tomahawkresolver" ) ); + return file.exists(); +#endif + + return false; +} + void SpotifyAccount::resolverChanged() { @@ -135,7 +161,7 @@ SpotifyAccount::resolverChanged() Attica::Content SpotifyAccount::atticaContent() const { - return AtticaManager::instance()->resolverForId( "spotify" ); + return AtticaManager::instance()->resolverForId( s_resolverId ); } @@ -149,7 +175,7 @@ SpotifyAccount::authenticate() return; } - const Attica::Content res = AtticaManager::instance()->resolverForId( "spotify" ); + const Attica::Content res = AtticaManager::instance()->resolverForId( s_resolverId ); const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res ); qDebug() << "Spotify account authenticating..."; diff --git a/src/accounts/spotify/SpotifyAccount.h b/src/accounts/spotify/SpotifyAccount.h index daf339e50..44930cb5e 100644 --- a/src/accounts/spotify/SpotifyAccount.h +++ b/src/accounts/spotify/SpotifyAccount.h @@ -118,6 +118,8 @@ private slots: private: void init(); void hookupResolver(); + bool checkForResolver(); + void loadPlaylists(); void clearUser( bool permanentlyDelete = false ); diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index 2652a3b55..857ed434f 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -43,10 +43,11 @@ class BinaryInstallerHelper : public QObject { Q_OBJECT public: - explicit BinaryInstallerHelper( const QString& resolverId, AtticaManager* manager) + explicit BinaryInstallerHelper( const QString& resolverId, bool createAccount, AtticaManager* manager) : QObject( manager ) , m_manager( QWeakPointer< AtticaManager >( manager ) ) , m_resolverId( resolverId ) + , m_createAccount( createAccount ) { Q_ASSERT( !m_resolverId.isEmpty() ); Q_ASSERT( !m_manager.isNull() ); @@ -55,17 +56,21 @@ public: virtual ~BinaryInstallerHelper() {} public slots: - void extractSucceeded( const QString& path ) + void installSucceeded( const QString& path ) { + qDebug() << Q_FUNC_INFO << "install of binary resolver succeeded, enabling"; + if ( m_manager.isNull() ) return; - Tomahawk::Accounts::Account* acct = Tomahawk::Accounts::AccountManager::instance()->accountFromPath( path ); - - Tomahawk::Accounts::AccountManager::instance()->addAccount( acct ); - TomahawkSettings::instance()->addAccount( acct->accountId() ); - Tomahawk::Accounts::AccountManager::instance()->enableAccount( acct ); + if ( m_createAccount ) + { + Tomahawk::Accounts::Account* acct = Tomahawk::Accounts::AccountManager::instance()->accountFromPath( path ); + Tomahawk::Accounts::AccountManager::instance()->addAccount( acct ); + TomahawkSettings::instance()->addAccount( acct->accountId() ); + Tomahawk::Accounts::AccountManager::instance()->enableAccount( acct ); + } m_manager.data()->m_resolverStates[ m_resolverId ].state = AtticaManager::Installed; TomahawkSettingsGui::instanceGui()->setAtticaResolverStates( m_manager.data()->m_resolverStates ); @@ -74,8 +79,10 @@ public slots: deleteLater(); } - void extractFailed() + void installFailed() { + qDebug() << Q_FUNC_INFO << "install failed"; + if ( m_manager.isNull() ) return; @@ -86,6 +93,7 @@ public slots: private: QString m_resolverId; + bool m_createAccount; QWeakPointer m_manager; }; @@ -267,11 +275,8 @@ AtticaManager::userHasRated( const Content& c ) const bool AtticaManager::hasCustomAccountForAttica( const QString &id ) const { - // Only last.fm at the moment contains a custom account - if ( id == "lastfm" ) - return true; - - return false; + qDebug() << "Got custom account for?" << id << m_customAccounts.keys(); + return m_customAccounts.keys().contains( id ); } @@ -417,6 +422,10 @@ AtticaManager::binaryResolversList( BaseJob* j ) r.binary = true; m_resolverStates.insert( c.id(), r ); } + else if ( m_resolverStates[ c.id() ].binary != true ) + { // HACK workaround... why is this not set in the first place sometimes? Migration issue? + m_resolverStates[ c.id() ].binary = true; + } } @@ -580,10 +589,13 @@ AtticaManager::payloadFetched() if ( !TomahawkUtils::verifyFile( f.fileName(), signature ) ) { qWarning() << "FILE SIGNATURE FAILED FOR BINARY RESOLVER! WARNING! :" << f.fileName() << signature; - return; } - - TomahawkUtils::extractBinaryResolver( f.fileName(), new BinaryInstallerHelper( resolverId, this ) ); + else + { + TomahawkUtils::extractBinaryResolver( f.fileName(), new BinaryInstallerHelper( resolverId, reply->property( "createAccount" ).toBool(), this ) ); + // Don't emit failed yet + installedSuccessfully = true; + } } else { @@ -702,4 +714,4 @@ AtticaManager::doResolverRemove( const QString& id ) const TomahawkUtils::removeDirectory( resolverDir.absolutePath() ); } -#include "AtticaManager.moc" \ No newline at end of file +#include "AtticaManager.moc" diff --git a/src/libtomahawk/TomahawkSettings.cpp b/src/libtomahawk/TomahawkSettings.cpp index 3f68f5f99..002de3865 100644 --- a/src/libtomahawk/TomahawkSettings.cpp +++ b/src/libtomahawk/TomahawkSettings.cpp @@ -516,6 +516,35 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion ) remove( "playlistupdaters" ); } + else if ( oldVersion == 11 ) + { + // If the user doesn't have a spotify account, create one, since now it + // is like the last.fm account and always exists + QStringList allAccounts = value( "accounts/allaccounts" ).toStringList(); + bool found = false; + foreach ( const QString& account, allAccounts ) + { + if ( account.startsWith( "spotifyaccount_" ) ) + { + found = true; + break; + } + } + + if ( !found ) + { + const QString accountKey = QString( "spotifyaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) ); + beginGroup( "accounts/" + accountKey ); + setValue( "enabled", false ); + setValue( "types", QStringList() << "ResolverType" ); + setValue( "credentials", QVariantHash() ); + setValue( "configuration", QVariantHash() ); + endGroup(); + + allAccounts << accountKey; + setValue( "accounts/allaccounts", allAccounts ); + } + } } diff --git a/src/libtomahawk/TomahawkSettings.h b/src/libtomahawk/TomahawkSettings.h index b998c46d6..421a6480c 100644 --- a/src/libtomahawk/TomahawkSettings.h +++ b/src/libtomahawk/TomahawkSettings.h @@ -30,7 +30,7 @@ #include "DllMacro.h" -#define TOMAHAWK_SETTINGS_VERSION 11 +#define TOMAHAWK_SETTINGS_VERSION 12 /** * Convenience wrapper around QSettings for tomahawk-specific config diff --git a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp index 2e3b9bc8d..fee5516f3 100644 --- a/src/libtomahawk/accounts/AccountModelFilterProxy.cpp +++ b/src/libtomahawk/accounts/AccountModelFilterProxy.cpp @@ -38,7 +38,7 @@ AccountModelFilterProxy::setSourceModel( QAbstractItemModel* sourceModel ) connect( sourceModel, SIGNAL( scrollTo( QModelIndex ) ), this, SLOT( onScrollTo( QModelIndex ) ) ); connect( sourceModel, SIGNAL( startInstalling( QPersistentModelIndex ) ), this, SLOT( onStartInstalling( QPersistentModelIndex ) ) ); connect( sourceModel, SIGNAL( doneInstalling( QPersistentModelIndex ) ), this, SLOT( onDoneInstalling( QPersistentModelIndex ) ) ); - connect( sourceModel, SIGNAL( doneInstalling( QPersistentModelIndex ) ), this, SLOT( errorInstalling( QPersistentModelIndex ) ) ); + connect( sourceModel, SIGNAL( errorInstalling( QPersistentModelIndex ) ), this, SLOT( onErrorInstalling( QPersistentModelIndex ) ) ); QSortFilterProxyModel::setSourceModel( sourceModel ); } diff --git a/src/libtomahawk/utils/TomahawkUtils.cpp b/src/libtomahawk/utils/TomahawkUtils.cpp index c5533d599..e2b220e10 100644 --- a/src/libtomahawk/utils/TomahawkUtils.cpp +++ b/src/libtomahawk/utils/TomahawkUtils.cpp @@ -845,7 +845,7 @@ unzipFileInFolder( const QString &zipFileName, const QDir &folder ) void -extractBinaryResolver( const QString& zipFilename, QObject* ) +extractBinaryResolver( const QString& zipFilename, QObject* receiver ) { #if !defined(Q_OS_MAC) && !defined (Q_OS_WIN) Q_ASSERT( false ); @@ -877,7 +877,7 @@ extractBinaryResolver( const QString& zipFilename, QObject* ) const QString src = toList.absoluteFilePath( files.first() ); qDebug() << "OS X: Copying binary resolver from to:" << src << dest; - copyWithAuthentication( src, dest, 0 ); + copyWithAuthentication( src, dest, receiver ); #elif defined(Q_OS_WIN) #endif diff --git a/src/libtomahawk/utils/TomahawkUtils_Mac.mm b/src/libtomahawk/utils/TomahawkUtils_Mac.mm index 07ab5da2c..fc5c3d08c 100644 --- a/src/libtomahawk/utils/TomahawkUtils_Mac.mm +++ b/src/libtomahawk/utils/TomahawkUtils_Mac.mm @@ -42,12 +42,11 @@ - (void)moveFinished { - if ( receiver ) - QMetaObject::invokeMethod(receiver, "installSucceeded", Qt::DirectConnection, Q_ARG(QString, path)); - // HACK since I can't figure out how to get QuaZip to maintain executable permissions after unzip (nor find the info) // we set the binary to executable here + NSLog(@"Move succeeded!, handling result"); + NSFileManager *manager = [[[NSFileManager alloc] init] autorelease]; NSError* error; NSDictionary* attrs = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0755], NSFilePosixPermissions, nil]; @@ -58,10 +57,15 @@ if (!success) { NSLog( @"Failed to do chmod +x of moved resolver! %@", [[error userInfo] objectForKey: NSLocalizedDescriptionKey] ); } + + if ( receiver ) + QMetaObject::invokeMethod(receiver, "installSucceeded", Qt::DirectConnection, Q_ARG(QString, path)); + } - (void)moveFailedWithError:(NSError *)error { + NSLog(@"Move failed, handling result"); if ( receiver ) QMetaObject::invokeMethod(receiver, "installFailed", Qt::DirectConnection); }