mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-20 07:49:42 +01:00
Merge branch 'spotifyAccount'
This commit is contained in:
commit
5c0507323c
@ -456,7 +456,7 @@ AtticaManager::payloadFetched()
|
||||
if ( reply->property( "createAccount" ).toBool() )
|
||||
{
|
||||
// Do the install / add to tomahawk
|
||||
Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, true );
|
||||
Tomahawk::Accounts::Account* resolver = Tomahawk::Accounts::ResolverAccountFactory::createFromPath( resolverPath, "resolveraccount", true );
|
||||
Tomahawk::Accounts::AccountManager::instance()->addAccount( resolver );
|
||||
TomahawkSettings::instance()->addAccount( resolver->accountId() );
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ set( libSources
|
||||
accounts/ResolverAccount.cpp
|
||||
accounts/LastFmAccount.cpp
|
||||
accounts/LastFmConfig.cpp
|
||||
accounts/SpotifyAccount.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
|
@ -58,7 +58,6 @@ Account::Account( const QString& accountId )
|
||||
|
||||
Account::~Account()
|
||||
{
|
||||
sync();
|
||||
}
|
||||
|
||||
|
||||
|
@ -180,6 +180,10 @@ public:
|
||||
virtual AccountTypes types() const = 0;
|
||||
|
||||
virtual Account* createAccount( const QString& accountId = QString() ) = 0;
|
||||
|
||||
/// If this resolver type accepts this path on disk (For general and special resolver accounts)
|
||||
virtual bool acceptsPath( const QString& ) const { return false; }
|
||||
virtual Account* createFromPath( const QString& ) { return 0; }
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "sourcelist.h"
|
||||
#include "ResolverAccount.h"
|
||||
#include "LastFmAccount.h"
|
||||
#include "SpotifyAccount.h"
|
||||
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QtCore/QDir>
|
||||
@ -59,9 +60,14 @@ AccountManager::AccountManager( QObject *parent )
|
||||
// We include the resolver factory manually, not in a plugin
|
||||
ResolverAccountFactory* f = new ResolverAccountFactory();
|
||||
m_accountFactories[ f->factoryId() ] = f;
|
||||
registerAccountFactoryForFilesystem( f );
|
||||
|
||||
LastFmAccountFactory* l = new LastFmAccountFactory();
|
||||
m_accountFactories[ l->factoryId() ] = l;
|
||||
|
||||
SpotifyAccountFactory* s = new SpotifyAccountFactory;
|
||||
m_accountFactories[ s->factoryId() ] = s;
|
||||
registerAccountFactoryForFilesystem( s );
|
||||
}
|
||||
|
||||
|
||||
@ -331,6 +337,30 @@ AccountManager::removeAccount( Account* account )
|
||||
}
|
||||
|
||||
|
||||
Account*
|
||||
AccountManager::accountFromPath( const QString& accountPath )
|
||||
{
|
||||
foreach ( AccountFactory* factory, m_factoriesForFilesytem )
|
||||
{
|
||||
if ( factory->acceptsPath( accountPath ) )
|
||||
{
|
||||
return factory->createFromPath( accountPath );
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT_X( false, "Shouldn't have had no account factory accepting a path.. at least ResolverAccount!!", "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AccountManager::registerAccountFactoryForFilesystem( AccountFactory* factory )
|
||||
{
|
||||
m_factoriesForFilesytem.prepend( factory );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
AccountManager::hookupAccount( Account* account ) const
|
||||
{
|
||||
|
@ -61,6 +61,21 @@ public:
|
||||
QList< Account* > accounts() const { return m_accounts; };
|
||||
QList< Account* > accounts( Tomahawk::Accounts::AccountType type ) const { return m_accountsByAccountType[ type ]; }
|
||||
|
||||
/**
|
||||
* Returns a new Account for a certain path on disk. This will go through all on-disk resolver account providers
|
||||
* to find the most specific account that matches this.
|
||||
*
|
||||
* The fallback is ResolverAccount, which handles our generic external script resolvers.
|
||||
*/
|
||||
Account* accountFromPath( const QString& path );
|
||||
|
||||
/**
|
||||
* Registers an account factory as being able to "handle" resolvers on disk. When accountFromPath is called
|
||||
* AccountManager will go through all registered account factories in order until it finds one that can handle the path.
|
||||
* This is searched in LIFO order.
|
||||
*/
|
||||
void registerAccountFactoryForFilesystem( AccountFactory* factory );
|
||||
|
||||
public slots:
|
||||
void connectAll();
|
||||
void disconnectAll();
|
||||
@ -97,6 +112,7 @@ private:
|
||||
|
||||
QHash< AccountType, QList< Account* > > m_accountsByAccountType;
|
||||
QHash< QString, AccountFactory* > m_accountFactories;
|
||||
QList< AccountFactory* > m_factoriesForFilesytem;
|
||||
|
||||
static AccountManager* s_instance;
|
||||
};
|
||||
|
@ -311,7 +311,7 @@ AccountModel::data( const QModelIndex& index, int role ) const
|
||||
case Qt::DecorationRole:
|
||||
return acct->icon();
|
||||
case DescriptionRole:
|
||||
return node->type == AccountModelNode::ManualResolverType ? QString() : node->factory->description();
|
||||
return node->factory ? node->factory->description() : QString();
|
||||
case Qt::CheckStateRole:
|
||||
return acct->enabled() ? Qt::Checked : Qt::Unchecked;
|
||||
case AccountData:
|
||||
@ -597,7 +597,6 @@ void
|
||||
AccountModel::accountStateChanged( Account* account , Account::ConnectionState )
|
||||
{
|
||||
// Find the factory this belongs up, and update
|
||||
AccountFactory* factory = AccountManager::instance()->factoryForAccount( account );
|
||||
for ( int i = 0; i < m_accounts.size(); i++ )
|
||||
{
|
||||
AccountModelNode* n = m_accounts.at( i );
|
||||
|
@ -118,6 +118,7 @@ struct AccountModelNode {
|
||||
{
|
||||
init();
|
||||
resolverAccount = ra;
|
||||
factory = AccountManager::instance()->factoryForAccount( ra );
|
||||
}
|
||||
|
||||
explicit AccountModelNode( Account* account ) : type( CustomAccountType )
|
||||
|
@ -83,6 +83,13 @@ LastFmAccount::~LastFmAccount()
|
||||
void
|
||||
LastFmAccount::authenticate()
|
||||
{
|
||||
if ( !AtticaManager::instance()->resolversLoaded() )
|
||||
{
|
||||
// If we're still waiting to load, wait for the attica resolvers to come down the pipe
|
||||
connect( AtticaManager::instance(), SIGNAL(resolversLoaded(Attica::Content::List)), this, SLOT( atticaLoaded( Attica::Content::List ) ), Qt::UniqueConnection );
|
||||
return;
|
||||
}
|
||||
|
||||
const Attica::Content res = AtticaManager::instance()->resolverForId( "lastfm" );
|
||||
const AtticaManager::ResolverState state = AtticaManager::instance()->resolverState( res );
|
||||
|
||||
@ -106,6 +113,14 @@ LastFmAccount::authenticate()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmAccount::atticaLoaded( Attica::Content::List )
|
||||
{
|
||||
disconnect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( atticaLoaded( Attica::Content::List ) ) );
|
||||
authenticate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmAccount::deauthenticate()
|
||||
{
|
||||
|
@ -94,6 +94,8 @@ public:
|
||||
Attica::Content atticaContent() const;
|
||||
|
||||
private slots:
|
||||
void atticaLoaded( Attica::Content::List );
|
||||
|
||||
void resolverInstalled( const QString& resolverId );
|
||||
|
||||
void resolverChanged();
|
||||
|
@ -46,16 +46,23 @@ ResolverAccountFactory::createAccount( const QString& accountId )
|
||||
|
||||
|
||||
Account*
|
||||
ResolverAccountFactory::createFromPath( const QString& path, bool isAttica )
|
||||
ResolverAccountFactory::createFromPath( const QString& path )
|
||||
{
|
||||
return createFromPath( path, factoryId(), false );
|
||||
}
|
||||
|
||||
|
||||
Account*
|
||||
ResolverAccountFactory::createFromPath( const QString& path, const QString& factory, bool isAttica )
|
||||
{
|
||||
qDebug() << "Creating ResolverAccount from path:" << path << "is attica" << isAttica;
|
||||
if ( isAttica )
|
||||
{
|
||||
QFileInfo info( path );
|
||||
return new AtticaResolverAccount( generateId( "resolveraccount" ), path, info.baseName() );
|
||||
return new AtticaResolverAccount( generateId( factory ), path, info.baseName() );
|
||||
}
|
||||
else
|
||||
return new ResolverAccount( generateId( "resolveraccount" ), path );
|
||||
return new ResolverAccount( generateId( factory ), path );
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
ResolverAccountFactory() {}
|
||||
virtual ~ResolverAccountFactory() {}
|
||||
|
||||
virtual Account* createAccount(const QString& accountId = QString());
|
||||
virtual Account* createAccount( const QString& accountId = QString() );
|
||||
virtual QString factoryId() const { return "resolveraccount"; }
|
||||
virtual QString description() const { return QString(); }
|
||||
virtual QString prettyName() const { return QString(); } // Internal, not displayed
|
||||
@ -44,7 +44,11 @@ public:
|
||||
|
||||
// Used to create a new resolver from a script on disk, either chosen by
|
||||
// the user, or installed from synchrotron
|
||||
static Account* createFromPath( const QString& path, bool isAttica );
|
||||
virtual bool acceptsPath( const QString& path ) const { return true; } // This is the catch-all filesystem account
|
||||
virtual Account* createFromPath( const QString& path );
|
||||
|
||||
// Internal use
|
||||
static Account* createFromPath( const QString& path, const QString& factoryId, bool isAttica );
|
||||
};
|
||||
|
||||
/**
|
||||
|
148
src/libtomahawk/accounts/SpotifyAccount.cpp
Normal file
148
src/libtomahawk/accounts/SpotifyAccount.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SpotifyAccount.h"
|
||||
#include "playlist.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "PlaylistUpdaterInterface.h"
|
||||
#include "sourcelist.h"
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
using namespace Tomahawk;
|
||||
using namespace Accounts;
|
||||
|
||||
static QPixmap* s_icon = 0;
|
||||
|
||||
Account*
|
||||
SpotifyAccountFactory::createAccount( const QString& accountId )
|
||||
{
|
||||
return new SpotifyAccount( accountId );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SpotifyAccountFactory::acceptsPath( const QString& path ) const
|
||||
{
|
||||
QFileInfo info( path );
|
||||
return info.baseName().startsWith( "spotify_" );
|
||||
}
|
||||
|
||||
|
||||
Account*
|
||||
SpotifyAccountFactory::createFromPath( const QString& path )
|
||||
{
|
||||
return new SpotifyAccount( generateId( factoryId() ), path );
|
||||
}
|
||||
|
||||
|
||||
QPixmap
|
||||
SpotifyAccountFactory::icon() const
|
||||
{
|
||||
if ( !s_icon )
|
||||
s_icon = new QPixmap( RESPATH "images/spotify-logo.png" );
|
||||
|
||||
return *s_icon;
|
||||
}
|
||||
|
||||
|
||||
SpotifyAccount::SpotifyAccount( const QString& accountId )
|
||||
: ResolverAccount( accountId )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
SpotifyAccount::SpotifyAccount( const QString& accountId, const QString& path )
|
||||
: ResolverAccount( accountId, path )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
QPixmap
|
||||
SpotifyAccount::icon() const
|
||||
{
|
||||
if ( !s_icon )
|
||||
s_icon = new QPixmap( RESPATH "images/spotify-logo.png" );
|
||||
|
||||
return *s_icon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SpotifyAccount::addPlaylist( const QString &qid, const QString& title, QList< Tomahawk::query_ptr > tracks )
|
||||
{
|
||||
Sync sync;
|
||||
sync.id_ = qid;
|
||||
int index = m_syncPlaylists.indexOf( sync );
|
||||
|
||||
if( !m_syncPlaylists.contains( sync ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Adding playlist to sync" << qid;
|
||||
playlist_ptr pl;
|
||||
pl = Tomahawk::Playlist::create( SourceList::instance()->getLocal(),
|
||||
uuid(),
|
||||
title,
|
||||
QString(),
|
||||
QString(),
|
||||
false,
|
||||
tracks );
|
||||
sync.playlist = pl;
|
||||
sync.uuid = pl->guid();
|
||||
m_syncPlaylists.append( sync );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Found playlist";
|
||||
|
||||
if ( index != -1 && !tracks.isEmpty())
|
||||
{
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Got pl" << m_syncPlaylists[ index ].playlist->guid();
|
||||
|
||||
QList< query_ptr > currTracks;
|
||||
foreach ( const plentry_ptr ple, m_syncPlaylists[ index ].playlist->entries() )
|
||||
currTracks << ple->query();
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "tracks" << currTracks;
|
||||
|
||||
bool changed = false;
|
||||
QList< query_ptr > mergedTracks = TomahawkUtils::mergePlaylistChanges( currTracks, tracks, changed );
|
||||
|
||||
if ( changed )
|
||||
{
|
||||
QList<Tomahawk::plentry_ptr> el = m_syncPlaylists[ index ].playlist->entriesFromQueries( mergedTracks, true );
|
||||
m_syncPlaylists[ index ].playlist->createNewRevision( uuid(), m_syncPlaylists[ index ].playlist->currentrevision(), el );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool operator==( SpotifyAccount::Sync one, SpotifyAccount::Sync two )
|
||||
{
|
||||
if( one.id_ == two.id_ )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
88
src/libtomahawk/accounts/SpotifyAccount.h
Normal file
88
src/libtomahawk/accounts/SpotifyAccount.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SpotifyAccount_H
|
||||
#define SpotifyAccount_H
|
||||
|
||||
#include "playlist.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "sourcelist.h"
|
||||
#include "ResolverAccount.h"
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
class ExternalResolverGui;
|
||||
|
||||
namespace Accounts {
|
||||
|
||||
|
||||
class SpotifyAccountFactory : public AccountFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpotifyAccountFactory() {}
|
||||
|
||||
virtual Account* createAccount( const QString& accountId = QString() );
|
||||
virtual QString description() const { return tr( "Play music from and sync your playlists with Spotify" ); }
|
||||
virtual QString factoryId() const { return "spotifyaccount"; }
|
||||
virtual QString prettyName() const { return "Spotify"; }
|
||||
|
||||
virtual bool acceptsPath( const QString& path ) const;
|
||||
virtual Account* createFromPath( const QString& path );
|
||||
|
||||
virtual AccountTypes types() const { return AccountTypes( ResolverType ); }
|
||||
virtual bool allowUserCreation() const { return false; }
|
||||
virtual QPixmap icon() const;
|
||||
virtual bool isUnique() const { return true; }
|
||||
|
||||
};
|
||||
|
||||
class SpotifyAccount : public ResolverAccount
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SpotifyAccount( const QString& accountId );
|
||||
SpotifyAccount( const QString& accountId, const QString& path );
|
||||
virtual ~SpotifyAccount() {}
|
||||
|
||||
virtual QPixmap icon() const;
|
||||
|
||||
virtual QWidget* aclWidget() { return 0; }
|
||||
virtual InfoSystem::InfoPlugin* infoPlugin() { return 0; }
|
||||
virtual SipPlugin* sipPlugin() { return 0; }
|
||||
|
||||
void addPlaylist( const QString &qid, const QString& title, QList< Tomahawk::query_ptr > tracks );
|
||||
|
||||
struct Sync {
|
||||
QString id_;
|
||||
QString uuid;
|
||||
Tomahawk::playlist_ptr playlist;
|
||||
};
|
||||
|
||||
private:
|
||||
QList<Sync> m_syncPlaylists;
|
||||
int m_sCount;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // SpotifyAccount_H
|
@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -228,7 +229,7 @@ ScriptResolver::handleMsg( const QByteArray& msg )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( msgtype == "results" )
|
||||
else if ( msgtype == "results" )
|
||||
{
|
||||
const QString qid = m.value( "qid" ).toString();
|
||||
QList< Tomahawk::result_ptr > results;
|
||||
@ -265,6 +266,25 @@ ScriptResolver::handleMsg( const QByteArray& msg )
|
||||
|
||||
Tomahawk::Pipeline::instance()->reportResults( qid, results );
|
||||
}
|
||||
else if ( msgtype == "playlist" )
|
||||
{
|
||||
|
||||
QList< Tomahawk::query_ptr > tracks;
|
||||
const QString qid = m.value( "qid" ).toString();
|
||||
const QString title = m.value( "identifier" ).toString();
|
||||
const QVariantList reslist = m.value( "playlist" ).toList();
|
||||
|
||||
if( !reslist.isEmpty() )
|
||||
{
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
QVariantMap m = rv.toMap();
|
||||
qDebug() << "Found playlist result:" << m;
|
||||
Tomahawk::query_ptr q = Tomahawk::Query::get( m.value( "artist" ).toString() , m.value( "track" ).toString() , QString(), uuid(), false );
|
||||
tracks << q;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -27,7 +28,6 @@
|
||||
|
||||
#include "query.h"
|
||||
#include "ExternalResolverGui.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
class QWidget;
|
||||
|
@ -396,7 +396,8 @@ SettingsDialog::installFromFile()
|
||||
|
||||
if( !resolver.isEmpty() )
|
||||
{
|
||||
Account* acct = ResolverAccountFactory::createFromPath( resolver, false );
|
||||
Account* acct = AccountManager::instance()->accountFromPath( resolver );
|
||||
|
||||
AccountManager::instance()->addAccount( acct );
|
||||
TomahawkSettings::instance()->addAccount( acct->accountId() );
|
||||
AccountManager::instance()->enableAccount( acct );
|
||||
|
Loading…
x
Reference in New Issue
Block a user