From 92ec403f7c3cd96f6ad832547facfd933172712b Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Tue, 22 May 2012 22:03:18 -0400 Subject: [PATCH] Fixes for spotify and lastfm custom accounts, and fix some misc older bugs --- src/libtomahawk/AtticaManager.cpp | 28 ++++++- src/libtomahawk/AtticaManager.h | 9 +++ src/libtomahawk/accounts/AccountModel.cpp | 52 ++++++++---- src/libtomahawk/accounts/AccountModelNode.h | 3 - src/libtomahawk/accounts/ResolverAccount.cpp | 83 ++++++++++++++------ src/libtomahawk/accounts/ResolverAccount.h | 8 ++ 6 files changed, 140 insertions(+), 43 deletions(-) diff --git a/src/libtomahawk/AtticaManager.cpp b/src/libtomahawk/AtticaManager.cpp index bd604b37a..c6f2d95f4 100644 --- a/src/libtomahawk/AtticaManager.cpp +++ b/src/libtomahawk/AtticaManager.cpp @@ -438,7 +438,20 @@ AtticaManager::syncServerData() void -AtticaManager::installResolver( const Content& resolver, bool autoCreateAccount ) +AtticaManager::installResolver( const Content& resolver, bool autoCreate ) +{ + doInstallResolver( resolver, autoCreate, 0 ); +} + + +void +AtticaManager::installResolverWithHandler( const Content& resolver, Tomahawk::Accounts::AtticaResolverAccount* handler ) +{ + doInstallResolver( resolver, false, handler ); +} + + +void AtticaManager::doInstallResolver( const Content& resolver, bool autoCreate, Tomahawk::Accounts::AtticaResolverAccount* handler ) { Q_ASSERT( !resolver.id().isNull() ); @@ -454,7 +467,8 @@ AtticaManager::installResolver( const Content& resolver, bool autoCreateAccount ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() ); connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolverDownloadFinished( Attica::BaseJob* ) ) ); job->setProperty( "resolverId", resolver.id() ); - job->setProperty( "createAccount", autoCreateAccount ); + job->setProperty( "createAccount", autoCreate ); + job->setProperty( "handler", QVariant::fromValue< QObject* >( handler ) ); job->setProperty( "binarySignature", resolver.attribute("signature")); job->start(); @@ -492,6 +506,7 @@ AtticaManager::resolverDownloadFinished ( BaseJob* j ) connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) ); reply->setProperty( "resolverId", job->property( "resolverId" ) ); reply->setProperty( "createAccount", job->property( "createAccount" ) ); + reply->setProperty( "handler", job->property( "handler" ) ); reply->setProperty( "binarySignature", job->property( "binarySignature" ) ); } else @@ -551,7 +566,14 @@ AtticaManager::payloadFetched() // update with absolute, not relative, path m_resolverStates[ resolverId ].scriptPath = resolverPath; - if ( reply->property( "createAccount" ).toBool() ) + Tomahawk::Accounts::AtticaResolverAccount* handlerAccount = qobject_cast< Tomahawk::Accounts::AtticaResolverAccount* >( reply->property( "handler" ).value< QObject* >() ); + const bool createAccount = reply->property( "createAccount" ).toBool(); + if ( handlerAccount ) + { + handlerAccount->setPath( resolverPath ); + Tomahawk::Accounts::AccountManager::instance()->enableAccount( handlerAccount ); + } + else if ( createAccount ) { // Do the install / add to tomahawk Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, "resolveraccount", true ); diff --git a/src/libtomahawk/AtticaManager.h b/src/libtomahawk/AtticaManager.h index 079672529..b6b206069 100644 --- a/src/libtomahawk/AtticaManager.h +++ b/src/libtomahawk/AtticaManager.h @@ -32,6 +32,12 @@ #include #include +namespace Tomahawk { +namespace Accounts { +class AtticaResolverAccount; +} +} + class BinaryInstallerHelper; class DLLEXPORT AtticaManager : public QObject @@ -105,6 +111,8 @@ public: public slots: void installResolver( const Attica::Content& resolver, bool autoCreateAccount = true ); + void installResolverWithHandler( const Attica::Content& resolver, Tomahawk::Accounts::AtticaResolverAccount* handler ); + void upgradeResolver( const Attica::Content& resolver ); signals: @@ -133,6 +141,7 @@ private slots: private: QString extractPayload( const QString& filename, const QString& resolverId ) const; void doResolverRemove( const QString& id ) const; + void doInstallResolver( const Attica::Content& resolver, bool autoCreate, Tomahawk::Accounts::AtticaResolverAccount* handler ); Attica::ProviderManager m_manager; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 822acd6e7..9b1a6809e 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -109,10 +109,14 @@ AccountModel::loadData() foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) { -// qDebug() << "Found ResolverAccount" << acct->accountFriendlyName(); +#if ACCOUNTMODEL_DEBUG + qDebug() << "Found ResolverAccount" << acct->accountFriendlyName(); +#endif if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) ) { -// qDebug() << "Which is an attica resolver with id:" << resolver->atticaId(); +#if ACCOUNTMODEL_DEBUG + qDebug() << "Which is an attica resolver with id:" << resolver->atticaId(); +#endif if ( resolver->atticaId() == content.id() ) { allAccounts.removeAll( acct ); @@ -345,12 +349,15 @@ AccountModel::data( const QModelIndex& index, int role ) const Q_ASSERT( node->customAccount ); Q_ASSERT( node->factory ); - Account* account = node->customAccount; - // This is sort of ugly. CustomAccounts are pure Account*, but we know that + Attica::Content content = node->atticaContent; + // This is ugly. CustomAccounts are pure Account*, but we know that // some might also be linked to attica resolvers (not always). If that is the case // they have a Attica::Content set on the node, so we use that to display some // extra metadata and rating - const bool hasAttica = !node->atticaContent.id().isEmpty(); + Account* account = node->customAccount; + if ( node->type == AccountModelNode::CustomAccountType && qobject_cast< CustomAtticaAccount* >( account ) ) + content = qobject_cast< CustomAtticaAccount* >( node->customAccount )->atticaContent(); + const bool hasAttica = !content.id().isNull(); switch ( role ) { @@ -362,15 +369,15 @@ AccountModel::data( const QModelIndex& index, int role ) const return ShippedWithTomahawk; case Qt::ToolTipRole: case DescriptionRole: - return hasAttica ? node->atticaContent.description() : node->factory->description(); + return hasAttica ? content.description() : node->factory->description(); case CanRateRole: return hasAttica; case AuthorRole: - return hasAttica ? node->atticaContent.author() : QString(); + return hasAttica ? content.author() : QString(); case RatingRole: - return hasAttica ? node->atticaContent.rating() / 20 : 0; // rating is out of 100 + return hasAttica ? content.rating() / 20 : 0; // rating is out of 100 case DownloadCounterRole: - return hasAttica ? node->atticaContent.downloads() : QVariant(); + return hasAttica ? content.downloads() : QVariant(); case RowTypeRole: return CustomAccount; case AccountData: @@ -383,6 +390,8 @@ AccountModel::data( const QModelIndex& index, int role ) const return account->enabled() ? Qt::Checked : Qt::Unchecked; case ConnectionStateRole: return account->connectionState(); + case UserHasRatedRole: + return hasAttica ? AtticaManager::instance()->userHasRated( content ) : false; default: return QVariant(); } @@ -459,7 +468,11 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role qDebug() << "Kicked off fetch+install, now waiting"; m_waitingForAtticaInstall.insert( resolver.id() ); - AtticaManager::instance()->installResolver( resolver ); + if ( node->atticaAccount ) + AtticaManager::instance()->installResolverWithHandler( resolver, node->atticaAccount ); + else + AtticaManager::instance()->installResolver( resolver, true ); + return true; } @@ -542,16 +555,25 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role if ( role == RatingRole ) { // We only support rating Attica resolvers for the moment. - Q_ASSERT( node->type == AccountModelNode::AtticaType ); + Attica::Content content; + if ( node->type == AccountModelNode::AtticaType ) + content = node->atticaContent; + else if ( node->type == AccountModelNode::CustomAccountType && qobject_cast< CustomAtticaAccount* >( node->customAccount ) ) + content = qobject_cast< CustomAtticaAccount* >( node->customAccount )->atticaContent(); - AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( node->atticaContent ); + Q_ASSERT( !content.id().isNull() ); + + AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( content ); // For now only allow rating if a resolver is installed! if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) return false; - if ( AtticaManager::instance()->userHasRated( node->atticaContent ) ) + if ( AtticaManager::instance()->userHasRated( content ) ) return false; - node->atticaContent.setRating( value.toInt() * 20 ); - AtticaManager::instance()->uploadRating( node->atticaContent ); + content.setRating( value.toInt() * 20 ); + AtticaManager::instance()->uploadRating( content ); + + if ( node->type == AccountModelNode::AtticaType ) + node->atticaContent = content; emit dataChanged( index, index ); diff --git a/src/libtomahawk/accounts/AccountModelNode.h b/src/libtomahawk/accounts/AccountModelNode.h index 857d57402..18486ef8b 100644 --- a/src/libtomahawk/accounts/AccountModelNode.h +++ b/src/libtomahawk/accounts/AccountModelNode.h @@ -139,9 +139,6 @@ struct AccountModelNode { init(); customAccount = account; factory = AccountManager::instance()->factoryForAccount( account ); - - if ( CustomAtticaAccount* customAtticaAccount = qobject_cast< CustomAtticaAccount* >( account ) ) - atticaContent = customAtticaAccount->atticaContent(); } void init() diff --git a/src/libtomahawk/accounts/ResolverAccount.cpp b/src/libtomahawk/accounts/ResolverAccount.cpp index 799279df8..4e7921702 100644 --- a/src/libtomahawk/accounts/ResolverAccount.cpp +++ b/src/libtomahawk/accounts/ResolverAccount.cpp @@ -74,18 +74,12 @@ ResolverAccount::ResolverAccount( const QString& accountId ) { const QString path = configuration()[ "path" ].toString(); + setTypes( AccountType( ResolverType ) ); // We should have a valid saved path Q_ASSERT( !path.isEmpty() ); - m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ) ); - connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); - - // What resolver do we have here? Should only be types that are 'real' resolvers - Q_ASSERT ( !m_resolver.isNull() ); - - setAccountFriendlyName( m_resolver.data()->name() ); - setTypes( AccountType( ResolverType ) ); + init( path ); } @@ -95,16 +89,8 @@ ResolverAccount::ResolverAccount( const QString& accountId, const QString& path QVariantHash configuration; configuration[ "path" ] = path; setConfiguration( configuration ); - setEnabled( true ); - m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, true ) ) ); - connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); - - // What resolver do we have here? Should only be types that are 'real' resolvers - Q_ASSERT ( m_resolver.data() ); - - setAccountFriendlyName( m_resolver.data()->name() ); - setTypes( AccountType( ResolverType ) ); + init( path ); sync(); } @@ -120,11 +106,41 @@ ResolverAccount::~ResolverAccount() } +void +ResolverAccount::init( const QString& path ) +{ + setTypes( AccountType( ResolverType ) ); + + if ( !QFile::exists( path ) ) + { + AccountManager::instance()->disableAccount( this ); + } + else + { + hookupResolver(); + } +} + + +void +ResolverAccount::hookupResolver() +{ + m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( configuration().value( "path" ).toString(), true ) ) ); + connect( m_resolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) ); + + // What resolver do we have here? Should only be types that are 'real' resolvers + Q_ASSERT ( m_resolver.data() ); + + setAccountFriendlyName( m_resolver.data()->name() ); +} + void ResolverAccount::authenticate() { - Q_ASSERT( !m_resolver.isNull() ); + if ( m_resolver.isNull() ) + return; + qDebug() << Q_FUNC_INFO << "Authenticating/starting resolver, exists?" << m_resolver; if ( !m_resolver.data()->running() ) @@ -137,14 +153,14 @@ ResolverAccount::authenticate() bool ResolverAccount::isAuthenticated() const { - return m_resolver.data()->running(); + return !m_resolver.isNull() && m_resolver.data()->running(); } void ResolverAccount::deauthenticate() { - if ( m_resolver.data()->running() ) + if ( !m_resolver.isNull() && m_resolver.data()->running() ) m_resolver.data()->stop(); emit connectionStateChanged( connectionState() ); @@ -155,7 +171,7 @@ ResolverAccount::deauthenticate() Account::ConnectionState ResolverAccount::connectionState() const { - if ( m_resolver.data()->running() ) + if ( !m_resolver.isNull() && m_resolver.data()->running() ) return Connected; else return Disconnected; @@ -165,6 +181,9 @@ ResolverAccount::connectionState() const QWidget* ResolverAccount::configurationWidget() { + if ( m_resolver.isNull() ) + return 0; + return m_resolver.data()->configUI(); } @@ -189,13 +208,17 @@ ResolverAccount::removeFromConfig() void ResolverAccount::saveConfig() { Account::saveConfig(); - m_resolver.data()->saveConfig(); + if ( !m_resolver.isNull() ) + m_resolver.data()->saveConfig(); } QString ResolverAccount::path() const { + if ( m_resolver.isNull() ) + return QString(); + return m_resolver.data()->filePath(); } @@ -242,6 +265,9 @@ AtticaResolverAccount::~AtticaResolverAccount() void AtticaResolverAccount::loadIcon() { + if ( m_resolver.isNull() ) + return; + const QFileInfo fi( m_resolver.data()->filePath() ); QDir codeDir = fi.absoluteDir(); codeDir.cd( "../images" ); @@ -252,6 +278,19 @@ AtticaResolverAccount::loadIcon() } +void +AtticaResolverAccount::setPath( const QString& path ) +{ + QVariantHash config = configuration(); + config[ "path" ] = path; + setConfiguration( config ); + + hookupResolver(); + + sync(); +} + + QPixmap AtticaResolverAccount::icon() const { diff --git a/src/libtomahawk/accounts/ResolverAccount.h b/src/libtomahawk/accounts/ResolverAccount.h index bcf167640..fb3f5487e 100644 --- a/src/libtomahawk/accounts/ResolverAccount.h +++ b/src/libtomahawk/accounts/ResolverAccount.h @@ -89,8 +89,14 @@ private slots: protected: // Created by factory, when user installs a new resolver ResolverAccount( const QString& accountId, const QString& path ); + + void hookupResolver(); + QWeakPointer m_resolver; +private: + void init( const QString& path ); + friend class ResolverAccountFactory; }; @@ -110,6 +116,8 @@ public: virtual QPixmap icon() const; QString atticaId() const { return m_atticaId; } + + void setPath( const QString& path ); private: // Created by factory, when user installs a new resolver AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId );