1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 16:29:43 +01: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
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 );

View File

@ -32,6 +32,12 @@
#include <attica/providermanager.h>
#include <attica/content.h>
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;

View File

@ -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 );

View File

@ -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()

View File

@ -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
{

View File

@ -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<ExternalResolverGui> 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 );