1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-09 07:36:48 +02:00

Fixes for spotify and lastfm custom accounts, and fix some misc older bugs

This commit is contained in:
Leo Franchi
2012-05-22 22:03:18 -04:00
parent af50be9ef8
commit 92ec403f7c
6 changed files with 140 additions and 43 deletions

View File

@@ -438,7 +438,20 @@ AtticaManager::syncServerData()
void 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() ); Q_ASSERT( !resolver.id().isNull() );
@@ -454,7 +467,8 @@ AtticaManager::installResolver( const Content& resolver, bool autoCreateAccount
ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() ); ItemJob< DownloadItem >* job = m_resolverProvider.downloadLink( resolver.id() );
connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolverDownloadFinished( Attica::BaseJob* ) ) ); connect( job, SIGNAL( finished( Attica::BaseJob* ) ), this, SLOT( resolverDownloadFinished( Attica::BaseJob* ) ) );
job->setProperty( "resolverId", resolver.id() ); 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->setProperty( "binarySignature", resolver.attribute("signature"));
job->start(); job->start();
@@ -492,6 +506,7 @@ AtticaManager::resolverDownloadFinished ( BaseJob* j )
connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) ); connect( reply, SIGNAL( finished() ), this, SLOT( payloadFetched() ) );
reply->setProperty( "resolverId", job->property( "resolverId" ) ); reply->setProperty( "resolverId", job->property( "resolverId" ) );
reply->setProperty( "createAccount", job->property( "createAccount" ) ); reply->setProperty( "createAccount", job->property( "createAccount" ) );
reply->setProperty( "handler", job->property( "handler" ) );
reply->setProperty( "binarySignature", job->property( "binarySignature" ) ); reply->setProperty( "binarySignature", job->property( "binarySignature" ) );
} }
else else
@@ -551,7 +566,14 @@ AtticaManager::payloadFetched()
// update with absolute, not relative, path // update with absolute, not relative, path
m_resolverStates[ resolverId ].scriptPath = resolverPath; 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 // Do the install / add to tomahawk
Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, "resolveraccount", true ); Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, "resolveraccount", true );

View File

@@ -32,6 +32,12 @@
#include <attica/providermanager.h> #include <attica/providermanager.h>
#include <attica/content.h> #include <attica/content.h>
namespace Tomahawk {
namespace Accounts {
class AtticaResolverAccount;
}
}
class BinaryInstallerHelper; class BinaryInstallerHelper;
class DLLEXPORT AtticaManager : public QObject class DLLEXPORT AtticaManager : public QObject
@@ -105,6 +111,8 @@ public:
public slots: public slots:
void installResolver( const Attica::Content& resolver, bool autoCreateAccount = true ); 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 ); void upgradeResolver( const Attica::Content& resolver );
signals: signals:
@@ -133,6 +141,7 @@ private slots:
private: private:
QString extractPayload( const QString& filename, const QString& resolverId ) const; QString extractPayload( const QString& filename, const QString& resolverId ) const;
void doResolverRemove( const QString& id ) const; void doResolverRemove( const QString& id ) const;
void doInstallResolver( const Attica::Content& resolver, bool autoCreate, Tomahawk::Accounts::AtticaResolverAccount* handler );
Attica::ProviderManager m_manager; Attica::ProviderManager m_manager;

View File

@@ -109,10 +109,14 @@ AccountModel::loadData()
foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) ) 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 ) ) 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() ) if ( resolver->atticaId() == content.id() )
{ {
allAccounts.removeAll( acct ); allAccounts.removeAll( acct );
@@ -345,12 +349,15 @@ AccountModel::data( const QModelIndex& index, int role ) const
Q_ASSERT( node->customAccount ); Q_ASSERT( node->customAccount );
Q_ASSERT( node->factory ); Q_ASSERT( node->factory );
Account* account = node->customAccount; Attica::Content content = node->atticaContent;
// This is sort of ugly. CustomAccounts are pure Account*, but we know that // 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 // 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 // they have a Attica::Content set on the node, so we use that to display some
// extra metadata and rating // 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 ) switch ( role )
{ {
@@ -362,15 +369,15 @@ AccountModel::data( const QModelIndex& index, int role ) const
return ShippedWithTomahawk; return ShippedWithTomahawk;
case Qt::ToolTipRole: case Qt::ToolTipRole:
case DescriptionRole: case DescriptionRole:
return hasAttica ? node->atticaContent.description() : node->factory->description(); return hasAttica ? content.description() : node->factory->description();
case CanRateRole: case CanRateRole:
return hasAttica; return hasAttica;
case AuthorRole: case AuthorRole:
return hasAttica ? node->atticaContent.author() : QString(); return hasAttica ? content.author() : QString();
case RatingRole: 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: case DownloadCounterRole:
return hasAttica ? node->atticaContent.downloads() : QVariant(); return hasAttica ? content.downloads() : QVariant();
case RowTypeRole: case RowTypeRole:
return CustomAccount; return CustomAccount;
case AccountData: case AccountData:
@@ -383,6 +390,8 @@ AccountModel::data( const QModelIndex& index, int role ) const
return account->enabled() ? Qt::Checked : Qt::Unchecked; return account->enabled() ? Qt::Checked : Qt::Unchecked;
case ConnectionStateRole: case ConnectionStateRole:
return account->connectionState(); return account->connectionState();
case UserHasRatedRole:
return hasAttica ? AtticaManager::instance()->userHasRated( content ) : false;
default: default:
return QVariant(); return QVariant();
} }
@@ -459,7 +468,11 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
qDebug() << "Kicked off fetch+install, now waiting"; qDebug() << "Kicked off fetch+install, now waiting";
m_waitingForAtticaInstall.insert( resolver.id() ); 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; return true;
} }
@@ -542,16 +555,25 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
if ( role == RatingRole ) if ( role == RatingRole )
{ {
// We only support rating Attica resolvers for the moment. // 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! // For now only allow rating if a resolver is installed!
if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade ) if ( state != AtticaManager::Installed && state != AtticaManager::NeedsUpgrade )
return false; return false;
if ( AtticaManager::instance()->userHasRated( node->atticaContent ) ) if ( AtticaManager::instance()->userHasRated( content ) )
return false; return false;
node->atticaContent.setRating( value.toInt() * 20 ); content.setRating( value.toInt() * 20 );
AtticaManager::instance()->uploadRating( node->atticaContent ); AtticaManager::instance()->uploadRating( content );
if ( node->type == AccountModelNode::AtticaType )
node->atticaContent = content;
emit dataChanged( index, index ); emit dataChanged( index, index );

View File

@@ -139,9 +139,6 @@ struct AccountModelNode {
init(); init();
customAccount = account; customAccount = account;
factory = AccountManager::instance()->factoryForAccount( account ); factory = AccountManager::instance()->factoryForAccount( account );
if ( CustomAtticaAccount* customAtticaAccount = qobject_cast< CustomAtticaAccount* >( account ) )
atticaContent = customAtticaAccount->atticaContent();
} }
void init() void init()

View File

@@ -74,18 +74,12 @@ ResolverAccount::ResolverAccount( const QString& accountId )
{ {
const QString path = configuration()[ "path" ].toString(); const QString path = configuration()[ "path" ].toString();
setTypes( AccountType( ResolverType ) );
// We should have a valid saved path // We should have a valid saved path
Q_ASSERT( !path.isEmpty() ); Q_ASSERT( !path.isEmpty() );
m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, enabled() ) ) ); init( path );
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 ) );
} }
@@ -95,16 +89,8 @@ ResolverAccount::ResolverAccount( const QString& accountId, const QString& path
QVariantHash configuration; QVariantHash configuration;
configuration[ "path" ] = path; configuration[ "path" ] = path;
setConfiguration( configuration ); setConfiguration( configuration );
setEnabled( true );
m_resolver = QWeakPointer< ExternalResolverGui >( qobject_cast< ExternalResolverGui* >( Pipeline::instance()->addScriptResolver( path, true ) ) ); init( path );
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 ) );
sync(); 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 void
ResolverAccount::authenticate() ResolverAccount::authenticate()
{ {
Q_ASSERT( !m_resolver.isNull() ); if ( m_resolver.isNull() )
return;
qDebug() << Q_FUNC_INFO << "Authenticating/starting resolver, exists?" << m_resolver; qDebug() << Q_FUNC_INFO << "Authenticating/starting resolver, exists?" << m_resolver;
if ( !m_resolver.data()->running() ) if ( !m_resolver.data()->running() )
@@ -137,14 +153,14 @@ ResolverAccount::authenticate()
bool bool
ResolverAccount::isAuthenticated() const ResolverAccount::isAuthenticated() const
{ {
return m_resolver.data()->running(); return !m_resolver.isNull() && m_resolver.data()->running();
} }
void void
ResolverAccount::deauthenticate() ResolverAccount::deauthenticate()
{ {
if ( m_resolver.data()->running() ) if ( !m_resolver.isNull() && m_resolver.data()->running() )
m_resolver.data()->stop(); m_resolver.data()->stop();
emit connectionStateChanged( connectionState() ); emit connectionStateChanged( connectionState() );
@@ -155,7 +171,7 @@ ResolverAccount::deauthenticate()
Account::ConnectionState Account::ConnectionState
ResolverAccount::connectionState() const ResolverAccount::connectionState() const
{ {
if ( m_resolver.data()->running() ) if ( !m_resolver.isNull() && m_resolver.data()->running() )
return Connected; return Connected;
else else
return Disconnected; return Disconnected;
@@ -165,6 +181,9 @@ ResolverAccount::connectionState() const
QWidget* QWidget*
ResolverAccount::configurationWidget() ResolverAccount::configurationWidget()
{ {
if ( m_resolver.isNull() )
return 0;
return m_resolver.data()->configUI(); return m_resolver.data()->configUI();
} }
@@ -189,6 +208,7 @@ ResolverAccount::removeFromConfig()
void ResolverAccount::saveConfig() void ResolverAccount::saveConfig()
{ {
Account::saveConfig(); Account::saveConfig();
if ( !m_resolver.isNull() )
m_resolver.data()->saveConfig(); m_resolver.data()->saveConfig();
} }
@@ -196,6 +216,9 @@ void ResolverAccount::saveConfig()
QString QString
ResolverAccount::path() const ResolverAccount::path() const
{ {
if ( m_resolver.isNull() )
return QString();
return m_resolver.data()->filePath(); return m_resolver.data()->filePath();
} }
@@ -242,6 +265,9 @@ AtticaResolverAccount::~AtticaResolverAccount()
void void
AtticaResolverAccount::loadIcon() AtticaResolverAccount::loadIcon()
{ {
if ( m_resolver.isNull() )
return;
const QFileInfo fi( m_resolver.data()->filePath() ); const QFileInfo fi( m_resolver.data()->filePath() );
QDir codeDir = fi.absoluteDir(); QDir codeDir = fi.absoluteDir();
codeDir.cd( "../images" ); 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 QPixmap
AtticaResolverAccount::icon() const AtticaResolverAccount::icon() const
{ {

View File

@@ -89,8 +89,14 @@ private slots:
protected: protected:
// Created by factory, when user installs a new resolver // Created by factory, when user installs a new resolver
ResolverAccount( const QString& accountId, const QString& path ); ResolverAccount( const QString& accountId, const QString& path );
void hookupResolver();
QWeakPointer<ExternalResolverGui> m_resolver; QWeakPointer<ExternalResolverGui> m_resolver;
private:
void init( const QString& path );
friend class ResolverAccountFactory; friend class ResolverAccountFactory;
}; };
@@ -110,6 +116,8 @@ public:
virtual QPixmap icon() const; virtual QPixmap icon() const;
QString atticaId() const { return m_atticaId; } QString atticaId() const { return m_atticaId; }
void setPath( const QString& path );
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 );