1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-16 19:14:06 +02:00

Merge branch 'master' into decltest

This commit is contained in:
Christian Muehlhaeuser
2012-07-06 06:21:02 +02:00
15 changed files with 549 additions and 77 deletions

View File

@@ -83,7 +83,7 @@ ACLRegistryImpl::isAuthorizedUser( const QString& dbid, const QString &username,
}
}
#endif
bool found = false;
QMutableListIterator< ACLRegistry::User > i( m_cache );
while ( i.hasNext() )
@@ -187,8 +187,8 @@ ACLRegistryImpl::queueNextJob()
QMetaObject::invokeMethod( this, "queueNextJob", Qt::QueuedConnection );
return;
}
tLog() << Q_FUNC_INFO << "jobCount = " << m_jobCount;
tLog() << Q_FUNC_INFO << "jobQueue size = " << m_jobQueue.length();
tLog() << Q_FUNC_INFO << "jobCount =" << m_jobCount;
tLog() << Q_FUNC_INFO << "jobQueue size =" << m_jobQueue.length();
if ( m_jobCount != 0 )
return;
@@ -202,14 +202,14 @@ ACLRegistryImpl::queueNextJob()
ACLRegistry::ACL acl = isAuthorizedUser( dbid, job->username(), ACLRegistry::NotFound, true );
if ( acl != ACLRegistry::NotFound )
{
tLog() << Q_FUNC_INFO << "Found existing acl entry for = " << user.knownAccountIds.first();
tLog() << Q_FUNC_INFO << "Found existing acl entry for =" << user.knownAccountIds.first();
found = true;
break;
}
}
if ( found )
{
tLog() << Q_FUNC_INFO << "deleting job, already have ACL for " << user.knownAccountIds.first();
tLog() << Q_FUNC_INFO << "deleting job, already have ACL for" << user.knownAccountIds.first();
delete job;
QTimer::singleShot( 0, this, SLOT( queueNextJob() ) );
return;
@@ -225,6 +225,7 @@ ACLRegistryImpl::queueNextJob()
}
#endif
void
ACLRegistryImpl::wipeEntries()
{
@@ -232,6 +233,7 @@ ACLRegistryImpl::wipeEntries()
save();
}
void
ACLRegistryImpl::load()
{
@@ -244,7 +246,6 @@ ACLRegistryImpl::load()
tLog() << Q_FUNC_INFO << "entry is invalid";
continue;
}
tLog() << Q_FUNC_INFO << "loading entry";
ACLRegistry::User entryUser = entry.value< ACLRegistry::User >();
if ( entryUser.knownAccountIds.empty() || entryUser.knownDbids.empty() )
{
@@ -263,7 +264,7 @@ ACLRegistryImpl::save()
QVariantList entryList;
foreach ( ACLRegistry::User user, m_cache )
{
tLog() << Q_FUNC_INFO << "user is " << user.uuid << " with known name " << user.knownAccountIds.first();
tLog() << Q_FUNC_INFO << "user is" << user.uuid << "with known name" << user.knownAccountIds.first();
QVariant val = QVariant::fromValue< ACLRegistry::User >( user );
if ( val.isValid() )
entryList.append( val );

View File

@@ -194,6 +194,7 @@ set( libSources
accounts/spotify/SpotifyAccount.cpp
accounts/spotify/SpotifyAccountConfig.cpp
accounts/spotify/SpotifyPlaylistUpdater.cpp
accounts/spotify/SpotifyInfoPlugin.cpp
accounts/lastfm/LastFmAccount.cpp
accounts/lastfm/LastFmConfig.cpp

View File

@@ -111,20 +111,21 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
if ( m_supportedActions & ActionPage && itemCount() == 1 )
m_sigmap->setMapping( addAction( tr( "&Show Track Page" ) ), ActionPage );
if ( m_supportedActions & ActionEditMetadata && itemCount() == 1 ) {
addSeparator();
if ( m_supportedActions & ActionEditMetadata && itemCount() == 1 )
{
if ( m_queries.first()->results().isEmpty() )
return;
Tomahawk::result_ptr result = m_queries.first()->results().first();
if ( result->collection() && result->collection()->source() &&
result->collection()->source()->isLocal() ) {
m_sigmap->setMapping( addAction( tr( "Properties") ), ActionEditMetadata );
result->collection()->source()->isLocal() )
{
m_sigmap->setMapping( addAction( tr( "Properties..." ) ), ActionEditMetadata );
}
}
addSeparator();
if ( m_supportedActions & ActionDelete )
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete );

View File

@@ -228,6 +228,7 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults )
checkResults();
emit resultsAdded( newresults );
emit resultsChanged();
}
@@ -292,6 +293,7 @@ Query::removeResult( const Tomahawk::result_ptr& result )
emit resultsRemoved( result );
checkResults();
emit resultsChanged();
}

View File

@@ -207,6 +207,10 @@ Result::toQuery()
if ( m_query.isNull() )
{
m_query = Tomahawk::Query::get( artist()->name(), track(), album()->name() );
if ( m_query.isNull() )
return query_ptr();
m_query->setAlbumPos( albumpos() );
m_query->setDiscNumber( discnumber() );
m_query->setDuration( duration() );

View File

@@ -29,6 +29,8 @@
#include "Pipeline.h"
#include "accounts/AccountManager.h"
#include "utils/Closure.h"
#include "SpotifyInfoPlugin.h"
#include "infosystem/InfoSystem.h"
#ifndef ENABLE_HEADLESS
#include "jobview/JobStatusView.h"
@@ -80,6 +82,7 @@ SpotifyAccountFactory::icon() const
SpotifyAccount::SpotifyAccount( const QString& accountId )
: CustomAtticaAccount( accountId )
, m_preventEnabling( false )
, m_loggedIn( false )
{
init();
}
@@ -106,6 +109,12 @@ SpotifyAccount::init()
AtticaManager::instance()->registerCustomAccount( s_resolverId, this );
qRegisterMetaType< Tomahawk::Accounts::SpotifyPlaylistInfo* >( "Tomahawk::Accounts::SpotifyPlaylist*" );
if ( infoPlugin() && Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() )
{
infoPlugin().data()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin() );
}
if ( !AtticaManager::instance()->resolversLoaded() )
{
// If we're still waiting to load, wait for the attica resolvers to come down the pipe
@@ -195,15 +204,10 @@ SpotifyAccount::hookupResolver()
connect( m_spotifyResolver.data(), SIGNAL( changed() ), this, SLOT( resolverChanged() ) );
connect( m_spotifyResolver.data(), SIGNAL( customMessage( QString,QVariantMap ) ), this, SLOT( resolverMessage( QString, QVariantMap ) ) );
const bool hasMigrated = configuration().value( "hasMigrated" ).toBool();
if ( !hasMigrated )
{
qDebug() << "Getting credentials from spotify resolver to migrate to in-app config";
QVariantMap msg;
msg[ "_msgtype" ] = "getCredentials";
m_spotifyResolver.data()->sendMessage( msg );
}
// Always get logged in status
QVariantMap msg;
msg[ "_msgtype" ] = "getCredentials";
m_spotifyResolver.data()->sendMessage( msg );
}
@@ -328,6 +332,18 @@ SpotifyAccount::connectionState() const
}
InfoSystem::InfoPluginPtr
SpotifyAccount::infoPlugin()
{
if ( m_infoPlugin.isNull() )
{
m_infoPlugin = QWeakPointer< InfoSystem::SpotifyInfoPlugin >( new InfoSystem::SpotifyInfoPlugin( this ) );
}
return InfoSystem::InfoPluginPtr( m_infoPlugin.data() );
}
void
SpotifyAccount::resolverInstalled(const QString& resolverId)
{
@@ -384,6 +400,13 @@ SpotifyAccount::setManualResolverPath( const QString &resolverPath )
}
bool
SpotifyAccount::loggedIn() const
{
return m_loggedIn;
}
void
SpotifyAccount::hookupAfterDeletion( bool autoEnable )
{
@@ -515,6 +538,15 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
creds[ "highQuality" ] = msg.value( "highQuality" );
setCredentials( creds );
m_loggedIn = msg.value( "loggedIn", false ).toBool();
if ( m_loggedIn )
{
configurationWidget();
if ( !m_configWidget.isNull() )
m_configWidget.data()->loginResponse( true, QString(), creds[ "username" ].toString() );
}
qDebug() << "Set creds:" << creds.value( "username" ) << creds.value( "password" ) << msg.value( "username" ) << msg.value( "password" );
QVariantHash config = configuration();
@@ -675,6 +707,8 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
const bool success = msg.value( "success" ).toBool();
m_loggedIn = success;
if ( success )
createActions();
@@ -682,7 +716,7 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
if ( m_configWidget.data() )
{
const QString message = msg.value( "message" ).toString();
m_configWidget.data()->loginResponse( success, message );
m_configWidget.data()->loginResponse( success, message, creds[ "username" ].toString() );
}
}
else if ( msgType == "playlistDeleted" )
@@ -695,6 +729,23 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
SpotifyPlaylistUpdater* updater = m_updaters.take( plid );
updater->remove( false );
}
else if ( msgType == "status" )
{
const bool loggedIn = msg.value( "loggedIn" ).toBool();
const QString username = msg.value( "username" ).toString();
qDebug() << "Got status message with login info:" << loggedIn << username;
if ( !loggedIn || username.isEmpty() || credentials().value( "username").toString() != username )
m_loggedIn = false;
QVariantMap msg;
msg[ "_msgtype" ] = "status";
msg[ "_status" ] = 1;
sendMessage( msg );
return;
}
}
@@ -734,16 +785,17 @@ SpotifyAccount::icon() const
QWidget*
SpotifyAccount::configurationWidget()
{
if ( m_spotifyResolver.isNull() || !m_spotifyResolver.data()->running() )
return 0;
if ( m_configWidget.isNull() )
{
m_configWidget = QWeakPointer< SpotifyAccountConfig >( new SpotifyAccountConfig( this ) );
connect( m_configWidget.data(), SIGNAL( login( QString,QString ) ), this, SLOT( login( QString,QString ) ) );
connect( m_configWidget.data(), SIGNAL( logout() ), this, SLOT( logout() ) );
m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists );
}
if ( m_spotifyResolver.isNull() || !m_spotifyResolver.data()->running() )
return 0;
return static_cast< QWidget* >( m_configWidget.data() );
}
@@ -823,7 +875,6 @@ SpotifyAccount::saveConfig()
void
SpotifyAccount::login( const QString& username, const QString& password )
{
// Send the result to the resolver
QVariantMap msg;
msg[ "_msgtype" ] = "login";
msg[ "username" ] = username;
@@ -835,6 +886,15 @@ SpotifyAccount::login( const QString& username, const QString& password )
}
void
SpotifyAccount::logout()
{
QVariantMap msg;
msg[ "_msgtype" ] = "logout";
m_spotifyResolver.data()->sendMessage( msg );
}
void
SpotifyAccount::startPlaylistSync( SpotifyPlaylistInfo* playlist )
{

View File

@@ -35,6 +35,12 @@ class QTimer;
class ScriptResolver;
namespace Tomahawk {
namespace InfoSystem
{
class SpotifyInfoPlugin;
}
namespace Accounts {
class SpotifyAccountConfig;
@@ -89,7 +95,7 @@ public:
virtual void deauthenticate();
virtual QWidget* aclWidget() { return 0; }
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin() { return Tomahawk::InfoSystem::InfoPluginPtr(); }
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin();
virtual SipPlugin* sipPlugin() { return 0; }
virtual bool preventEnabling() const { return m_preventEnabling; }
@@ -102,6 +108,8 @@ public:
void setManualResolverPath( const QString& resolverPath );
bool loggedIn() const;
public slots:
void aboutToShow( QAction* action, const Tomahawk::playlist_ptr& playlist );
void syncActionTriggered( bool );
@@ -114,6 +122,8 @@ private slots:
void resolverMessage( const QString& msgType, const QVariantMap& msg );
void login( const QString& username, const QString& password );
void logout();
// SpotifyResolver message handlers, all take msgtype, msg as argument
// void <here>( const QString& msgType, const QVariantMap& msg );
void startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg );
@@ -143,6 +153,7 @@ private:
QWeakPointer<SpotifyAccountConfig> m_configWidget;
QWeakPointer<QWidget> m_aboutWidget;
QWeakPointer<ScriptResolver> m_spotifyResolver;
QWeakPointer< InfoSystem::SpotifyInfoPlugin > m_infoPlugin;
QMap<QString, QPair<QObject*, QString> > m_qidToSlotMap;
@@ -152,7 +163,7 @@ private:
QHash< QString, playlist_ptr > m_waitingForCreateReply;
bool m_preventEnabling;
bool m_preventEnabling, m_loggedIn;
SmartPointerList< QAction > m_customActions;
friend class ::SpotifyPlaylistUpdater;

View File

@@ -25,6 +25,7 @@
#include <QListWidget>
#include <QListWidgetItem>
#include <QShowEvent>
#include <QLabel>
using namespace Tomahawk;
using namespace Accounts;
@@ -32,16 +33,18 @@ using namespace Accounts;
SpotifyAccountConfig::SpotifyAccountConfig( SpotifyAccount *account )
: QWidget( 0 )
, m_ui( new Ui::SpotifyConfig )
, m_loggedInUser( 0 )
, m_account( account )
, m_playlistsLoading( 0 )
, m_loggedInManually( false )
, m_isLoggedIn( false )
{
m_ui->setupUi( this );
connect( m_ui->loginButton, SIGNAL( clicked( bool ) ), this, SLOT( doLogin() ) );
connect( m_ui->usernameEdit, SIGNAL( textChanged( QString ) ), this, SLOT( resetLoginButton() ) );
connect( m_ui->passwordEdit, SIGNAL( textChanged( QString ) ), this, SLOT( resetLoginButton() ) );
connect( m_ui->usernameEdit, SIGNAL( textEdited( QString ) ), this, SLOT( resetLoginButton() ) );
connect( m_ui->passwordEdit, SIGNAL( textEdited( QString ) ), this, SLOT( resetLoginButton() ) );
loadFromConfig();
m_playlistsLoading = new AnimatedSpinner( m_ui->playlistList );
@@ -61,10 +64,21 @@ SpotifyAccountConfig::showEvent( QShowEvent *event )
void
SpotifyAccountConfig::loadFromConfig()
{
m_ui->usernameEdit->setText( m_account->credentials().value( "username" ).toString() );
const QString username = m_account->credentials().value( "username" ).toString();
m_ui->usernameEdit->setText( username );
m_ui->passwordEdit->setText( m_account->credentials().value( "password" ).toString() );
m_ui->streamingCheckbox->setChecked( m_account->credentials().value( "highQuality" ).toBool() );
m_ui->deleteOnUnsync->setChecked( m_account->deleteOnUnsync() );
if ( m_account->loggedIn() )
{
qDebug() << "Loading spotify config widget with logged in username:" << username;
if ( !username.isEmpty() )
m_verifiedUsername = username;
showLoggedIn();
}
else
showLoggedOut();
}
void
@@ -132,28 +146,44 @@ SpotifyAccountConfig::setPlaylists( const QList<SpotifyPlaylistInfo *>& playlist
void
SpotifyAccountConfig::doLogin()
{
m_ui->loginButton->setText( tr( "Logging in..." ) );
m_ui->loginButton->setEnabled( false );
if ( !m_isLoggedIn )
{
m_ui->loginButton->setText( tr( "Logging in..." ) );
m_ui->loginButton->setEnabled( false );
m_playlistsLoading->fadeIn();
m_loggedInManually = true;
m_playlistsLoading->fadeIn();
m_loggedInManually = true;
emit login( username(), password() );
emit login( username(), password() );
}
else
{
// Log out
m_isLoggedIn = false;
m_loggedInManually = true;
m_verifiedUsername.clear();
m_ui->playlistList->clear();
emit logout();
showLoggedOut();
}
}
void
SpotifyAccountConfig::loginResponse( bool success, const QString& msg )
SpotifyAccountConfig::loginResponse( bool success, const QString& msg, const QString& username )
{
if ( success )
{
m_ui->loginButton->setText( tr( "Logged in!" ) );
m_ui->loginButton->setEnabled( false );
qDebug() << Q_FUNC_INFO << "Login response with username:" << username;
m_verifiedUsername = username;
m_isLoggedIn = true;
showLoggedIn();
}
else
{
setPlaylists( QList< SpotifyPlaylistInfo* >() );
m_playlistsLoading->fadeOut();
m_ui->loginButton->setText( tr( "Failed: %1" ).arg( msg ) );
m_ui->loginButton->setEnabled( true );
}
@@ -162,9 +192,51 @@ SpotifyAccountConfig::loginResponse( bool success, const QString& msg )
void
SpotifyAccountConfig::resetLoginButton()
SpotifyAccountConfig::showLoggedIn()
{
m_ui->passwordEdit->hide();
m_ui->passwordLabel->hide();
m_ui->usernameEdit->hide();
m_ui->usernameLabel->hide();
if ( !m_loggedInUser )
{
m_loggedInUser = new QLabel( this );
m_ui->verticalLayout->insertWidget( 1, m_loggedInUser, 0, Qt::AlignCenter );
}
qDebug() << "Showing logged in withuserame:" << m_verifiedUsername;
m_loggedInUser->show();
m_loggedInUser->setText( tr( "Logged in as %1" ).arg( m_verifiedUsername ) );
m_ui->loginButton->setText( tr( "Log Out" ) );
m_ui->loginButton->setEnabled( true );
}
void
SpotifyAccountConfig::showLoggedOut()
{
m_ui->passwordEdit->show();
m_ui->passwordLabel->show();
m_ui->usernameEdit->show();
m_ui->usernameLabel->show();
if ( m_loggedInUser )
m_loggedInUser->hide();
m_ui->loginButton->setText( tr( "Log In" ) );
m_ui->loginButton->setEnabled( true );
}
void
SpotifyAccountConfig::resetLoginButton()
{
if ( !m_isLoggedIn )
{
m_ui->loginButton->setText( tr( "Log In" ) );
m_ui->loginButton->setEnabled( true );
}
}

View File

@@ -23,6 +23,7 @@
#include <QVariantMap>
#include <QTimer>
class QLabel;
class AnimatedSpinner;
class QShowEvent;
@@ -55,14 +56,13 @@ public:
void loadFromConfig();
void saveSettings();
void loginResponse( bool success, const QString& msg );
void loginResponse( bool success, const QString& msg, const QString& username );
bool loggedInManually() const { return m_loggedInManually; }
signals:
void login( const QString& username, const QString& pw );
public slots:
// void verifyResult( const QString& msgType, const QVariantMap& msg );
void logout();
protected:
void showEvent( QShowEvent* event );
@@ -72,10 +72,15 @@ private slots:
void resetLoginButton();
private:
void showLoggedIn();
void showLoggedOut();
Ui::SpotifyConfig* m_ui;
QLabel* m_loggedInUser;
QString m_verifiedUsername;
SpotifyAccount* m_account;
AnimatedSpinner* m_playlistsLoading;
bool m_loggedInManually;
bool m_loggedInManually, m_isLoggedIn;
};
}

View File

@@ -0,0 +1,263 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 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 "SpotifyInfoPlugin.h"
#include "SpotifyAccount.h"
#include "utils/Closure.h"
using namespace Tomahawk;
using namespace Tomahawk::InfoSystem;
SpotifyInfoPlugin::SpotifyInfoPlugin( Accounts::SpotifyAccount* account )
: InfoPlugin()
, m_account( QWeakPointer< Accounts::SpotifyAccount >( account ) )
{
if ( !m_account.isNull() )
m_supportedGetTypes << InfoAlbumSongs;
}
SpotifyInfoPlugin::~SpotifyInfoPlugin()
{
}
void
SpotifyInfoPlugin::getInfo( InfoRequestData requestData )
{
switch ( requestData.type )
{
case InfoAlbumSongs:
{
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
{
dataError( requestData );
return;
}
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
if ( !hash.contains( "album" ) )
{
dataError( requestData );
return;
}
Tomahawk::InfoSystem::InfoStringHash criteria;
criteria[ "album" ] = hash[ "album" ];
if ( hash.contains( "artist" ) )
criteria["artist"] = hash["artist"];
emit getCachedInfo( criteria, 2419200000, requestData );
return;
}
default:
dataError( requestData );
}
}
void
SpotifyInfoPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData )
{
switch ( requestData.type )
{
case InfoAlbumSongs:
{
const QString album = criteria[ "album" ];
const QString artist = criteria[ "artist" ];
if ( m_account.isNull() || !m_account.data()->loggedIn() )
{
// No running spotify account, use our webservice
QUrl lookupUrl( "http://ws.spotify.com/search/1/album.json" );
lookupUrl.addQueryItem( "q", QString( "%1 %2" ).arg( album ).arg( album ) );
QNetworkReply * reply = TomahawkUtils::nam()->get( QNetworkRequest( lookupUrl ) );
NewClosure( reply, SIGNAL( finished() ), this, SLOT( albumIdLookupFinished( QNetworkReply*, Tomahawk::InfoSystem::InfoRequestData ) ), reply, requestData );
}
else
{
// Running resolver, so do the lookup through that
qDebug() << Q_FUNC_INFO << "Doing album lookup through spotify:" << album << artist;
QVariantMap message;
message[ "_msgtype" ] = "albumListing";
message[ "artist" ] = artist;
message[ "album" ] = album;
const QString qid = m_account.data()->sendMessage( message, this, "albumListingResult" );
m_waitingForResults[ qid ] = requestData;
}
break;
}
default:
{
Q_ASSERT( false );
break;
}
}
}
void
SpotifyInfoPlugin::albumListingResult( const QString& msgType, const QVariantMap& msg )
{
Q_ASSERT( msg.contains( "qid" ) );
Q_ASSERT( m_waitingForResults.contains( msg.value( "qid" ).toString() ) );
if ( !msg.contains( "qid" ) || !m_waitingForResults.contains( msg.value( "qid" ).toString() ) )
return;
const InfoRequestData requestData = m_waitingForResults.take( msg.value( "qid" ).toString() );
QVariantList tracks = msg.value( "tracks" ).toList();
QStringList trackNameList;
foreach ( const QVariant track, tracks )
{
const QVariantMap trackData = track.toMap();
if ( trackData.contains( "track" ) && !trackData[ "track" ].toString().isEmpty() )
trackNameList << trackData[ "track" ].toString();
}
qDebug() << Q_FUNC_INFO << "Successfully got album listing from spotify resolver";
trackListResult( trackNameList, requestData );
}
void
SpotifyInfoPlugin::albumIdLookupFinished( QNetworkReply* reply, const InfoRequestData& requestData )
{
Q_ASSERT( reply );
reply->deleteLater();
if ( reply->error() == QNetworkReply::NoError )
{
QJson::Parser p;
const QVariantMap response = p.parse( reply ).toMap();
if ( !response.contains( "albums" ) )
{
dataError( requestData );
return;
}
const QVariantList albums = response.value( "albums" ).toList();
if ( albums.isEmpty() )
{
dataError( requestData );
return;
}
const QVariantMap album = albums.first().toMap();
const QString id = album.value( "href" ).toString();
if ( id.isEmpty() || !id.contains( "spotify:album" ) )
{
qDebug() << "Empty or malformed spotify album ID from json:" << id << response;
dataError( requestData );
return;
}
qDebug() << "Doing spotify album lookup via webservice with ID:" << id;
QUrl lookupUrl( QString( "http://spotikea.tomahawk-player.org/browse/%1" ).arg( id ) );
QNetworkReply * reply = TomahawkUtils::nam()->get( QNetworkRequest( lookupUrl ) );
NewClosure( reply, SIGNAL( finished() ), this, SLOT( albumContentsLookupFinished( QNetworkReply*, Tomahawk::InfoSystem::InfoRequestData ) ), reply, requestData );
}
else
{
qDebug() << "Network Error retrieving ID from spotify metadata service:" << reply->error() << reply->errorString() << reply->url();
}
}
void
SpotifyInfoPlugin::albumContentsLookupFinished( QNetworkReply* reply, const InfoRequestData& requestData )
{
Q_ASSERT( reply );
reply->deleteLater();
if ( reply->error() == QNetworkReply::NoError )
{
QJson::Parser p;
const QVariantMap response = p.parse( reply ).toMap();
if ( !response.contains( "album" ) )
{
dataError( requestData );
return;
}
const QVariantMap album = response.value( "album" ).toMap();
if ( !album.contains( "result" ) || album.value( "result" ).toList().isEmpty() )
{
dataError( requestData );
return;
}
const QVariantList albumTracks = album.value( "result" ).toList();
QStringList trackNameList;
foreach ( const QVariant& track, albumTracks )
{
const QVariantMap trackMap = track.toMap();
if ( trackMap.contains( "title" ) )
trackNameList << trackMap.value( "title" ).toString();
}
qDebug() << Q_FUNC_INFO << "Successfully got album listing from spotikea service!";
if ( trackNameList.isEmpty() )
dataError( requestData );
else
trackListResult( trackNameList, requestData );
}
else
{
qDebug() << "Network Error retrieving ID from spotify metadata service:" << reply->error() << reply->errorString() << reply->url();
}
}
void
SpotifyInfoPlugin::dataError( InfoRequestData requestData )
{
emit info( requestData, QVariant() );
}
void
SpotifyInfoPlugin::trackListResult( const QStringList& trackNameList, const InfoRequestData& requestData )
{
QVariantMap returnedData;
returnedData["tracks"] = trackNameList;
emit info( requestData, returnedData );
Tomahawk::InfoSystem::InfoStringHash criteria;
criteria["artist"] = requestData.input.value< InfoStringHash>()["artist"];
criteria["album"] = requestData.input.value< InfoStringHash>()["album"];
emit updateCache( criteria, 0, requestData.type, returnedData );
}

View File

@@ -0,0 +1,74 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012 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 SPOTIFYINFOPLUGIN_H
#define SPOTIFYINFOPLUGIN_H
#include "infosystem/InfoSystem.h"
#include "DllMacro.h"
#include <QWeakPointer>
class QNetworkReply;
namespace Tomahawk
{
namespace Accounts
{
class SpotifyAccount;
}
namespace InfoSystem
{
class DLLEXPORT SpotifyInfoPlugin : public InfoPlugin
{
Q_OBJECT
public:
explicit SpotifyInfoPlugin( Accounts::SpotifyAccount* account );
virtual ~SpotifyInfoPlugin();
public slots:
void albumListingResult( const QString& msgType, const QVariantMap& msg );
protected slots:
virtual void init() {}
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData ) {}
private slots:
void albumIdLookupFinished( QNetworkReply* reply, const Tomahawk::InfoSystem::InfoRequestData& requestData );
void albumContentsLookupFinished( QNetworkReply* reply, const Tomahawk::InfoSystem::InfoRequestData& requestData );
private:
void dataError( InfoRequestData );
void trackListResult( const QStringList& trackNameList, const Tomahawk::InfoSystem::InfoRequestData& requestData );
QHash< QString, InfoRequestData > m_waitingForResults;
QWeakPointer< Tomahawk::Accounts::SpotifyAccount > m_account;
};
}
}
#endif // SPOTIFYINFOPLUGIN_H

View File

@@ -91,12 +91,6 @@ PlayableItem::PlayableItem( const Tomahawk::query_ptr& query, PlayableItem* pare
connect( query.data(), SIGNAL( updated() ),
SIGNAL( dataChanged() ) );
connect( query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
SLOT( onResultsChanged() ) );
connect( query.data(), SIGNAL( resultsRemoved( Tomahawk::result_ptr ) ),
SLOT( onResultsChanged() ) );
connect( query.data(), SIGNAL( resultsChanged() ),
SLOT( onResultsChanged() ) );
@@ -118,12 +112,6 @@ PlayableItem::PlayableItem( const Tomahawk::plentry_ptr& entry, PlayableItem* pa
connect( m_query.data(), SIGNAL( updated() ),
SIGNAL( dataChanged() ) );
connect( m_query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ),
SLOT( onResultsChanged() ) );
connect( m_query.data(), SIGNAL( resultsRemoved( Tomahawk::result_ptr ) ),
SLOT( onResultsChanged() ) );
connect( m_query.data(), SIGNAL( resultsChanged() ),
SLOT( onResultsChanged() ) );

View File

@@ -255,11 +255,6 @@ ScriptResolver::handleMsg( const QByteArray& msg )
setupConfWidget( m );
return;
}
else if ( msgtype == "status" )
{
sendStatus();
return;
}
else if ( msgtype == "results" )
{
const QString qid = m.value( "qid" ).toString();
@@ -365,16 +360,6 @@ ScriptResolver::resolve( const Tomahawk::query_ptr& query )
}
void
ScriptResolver::sendStatus()
{
QVariantMap msg;
msg[ "_msgtype" ] = "status";
msg[ "_status" ] = 1;
sendMessage( msg );
}
void
ScriptResolver::doSetup( const QVariantMap& m )
{
@@ -387,6 +372,7 @@ ScriptResolver::doSetup( const QVariantMap& m )
m_ready = true;
m_configSent = false;
m_num_restarts = 0;
if ( !m_stopped )
Tomahawk::Pipeline::instance()->addResolver( this );

View File

@@ -77,7 +77,6 @@ private:
void sendMsg( const QByteArray& msg );
void doSetup( const QVariantMap& m );
void setupConfWidget( const QVariantMap& m );
void sendStatus();
void startProcess();

View File

@@ -51,6 +51,7 @@ PixmapDelegateFader::PixmapDelegateFader( const artist_ptr& artist, const QSize&
{
connect( m_artist.data(), SIGNAL( updated() ), SLOT( artistChanged() ) );
connect( m_artist.data(), SIGNAL( coverChanged() ), SLOT( artistChanged() ) );
m_currentReference = m_artist->cover( size, forceLoad );
}
@@ -67,6 +68,7 @@ PixmapDelegateFader::PixmapDelegateFader( const album_ptr& album, const QSize& s
{
connect( m_album.data(), SIGNAL( updated() ), SLOT( albumChanged() ) );
connect( m_album.data(), SIGNAL( coverChanged() ), SLOT( albumChanged() ) );
m_currentReference = m_album->cover( size, forceLoad );
}
@@ -82,8 +84,10 @@ PixmapDelegateFader::PixmapDelegateFader( const query_ptr& track, const QSize& s
if ( !m_track.isNull() )
{
connect( m_track.data(), SIGNAL( updated() ), SLOT( trackChanged() ) );
connect( m_track.data(), SIGNAL( coverChanged() ), SLOT( trackChanged() ) );
m_currentReference = m_track->cover( size, forceLoad );
connect( m_track.data(), SIGNAL( resultsChanged() ), SLOT( trackChanged() ) );
connect( m_track->displayQuery().data(), SIGNAL( coverChanged() ), SLOT( trackChanged() ) );
m_currentReference = m_track->displayQuery()->cover( size, forceLoad );
}
init();
@@ -144,7 +148,7 @@ PixmapDelegateFader::setSize( const QSize& size )
else if ( !m_artist.isNull() )
m_currentReference = m_artist->cover( m_size );
else if ( !m_track.isNull() )
m_currentReference = m_track->cover( m_size );
m_currentReference = m_track->displayQuery()->cover( m_size );
}
emit repaintRequest();
@@ -177,7 +181,8 @@ PixmapDelegateFader::trackChanged()
if ( m_track.isNull() )
return;
QMetaObject::invokeMethod( this, "setPixmap", Qt::QueuedConnection, Q_ARG( QPixmap, m_track->cover( m_size ) ) );
connect( m_track->displayQuery().data(), SIGNAL( coverChanged() ), SLOT( trackChanged() ) );
QMetaObject::invokeMethod( this, "setPixmap", Qt::QueuedConnection, Q_ARG( QPixmap, m_track->displayQuery()->cover( m_size ) ) );
}