mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-12 09:04:33 +02:00
Add a last.fm account w. resolver and infotype. Needs merging w/ attica still
This commit is contained in:
BIN
data/images/lastfm-icon.png
Normal file
BIN
data/images/lastfm-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
@@ -133,6 +133,7 @@
|
|||||||
<file>data/images/headphones-bigger.png</file>
|
<file>data/images/headphones-bigger.png</file>
|
||||||
<file>data/images/no-album-no-case.png</file>
|
<file>data/images/no-album-no-case.png</file>
|
||||||
<file>data/images/rdio.png</file>
|
<file>data/images/rdio.png</file>
|
||||||
|
<file>data/images/lastfm-icon.png</file>
|
||||||
<file>data/sql/dbmigrate-27_to_28.sql</file>
|
<file>data/sql/dbmigrate-27_to_28.sql</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@@ -75,10 +75,10 @@ AccountDelegate::AccountDelegate( QObject* parent )
|
|||||||
|
|
||||||
|
|
||||||
QSize
|
QSize
|
||||||
AccountDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
AccountDelegate::sizeHint( const QStyleOptionViewItem&, const QModelIndex& index ) const
|
||||||
{
|
{
|
||||||
AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||||
if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory )
|
if ( rowType == AccountModel::TopLevelAccount || rowType == AccountModel::UniqueFactory || rowType == AccountModel::CustomAccount )
|
||||||
return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT );
|
return QSize( 200, TOPLEVEL_ACCOUNT_HEIGHT );
|
||||||
else if ( rowType == AccountModel::TopLevelFactory )
|
else if ( rowType == AccountModel::TopLevelFactory )
|
||||||
{
|
{
|
||||||
@@ -204,7 +204,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
|
|||||||
rightEdge = drawAccountList( painter, opt, accts, rightEdge );
|
rightEdge = drawAccountList( painter, opt, accts, rightEdge );
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
|
||||||
int centeredUnderAccounts = oldRightEdge - (oldRightEdge - rightEdge)/2 - (btnWidth/2);
|
|
||||||
btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING );
|
btnRect = QRect( opt.rect.right() - PADDING - btnWidth, opt.rect.bottom() - installMetrics.height() - 3*PADDING, btnWidth, installMetrics.height() + 2*PADDING );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +302,6 @@ AccountDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option,
|
|||||||
{
|
{
|
||||||
// rating stars
|
// rating stars
|
||||||
const int rating = index.data( AccountModel::RatingRole ).toInt();
|
const int rating = index.data( AccountModel::RatingRole ).toInt();
|
||||||
const int ratingWidth = 5 * ( m_ratingStarPositive.width() + PADDING_BETWEEN_STARS );
|
|
||||||
|
|
||||||
// int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth;
|
// int runningEdge = opt.rect.right() - 2*PADDING - ratingWidth;
|
||||||
int runningEdge = textRect.left();
|
int runningEdge = textRect.left();
|
||||||
@@ -414,7 +412,8 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
|
|||||||
m_configPressed = index;
|
m_configPressed = index;
|
||||||
|
|
||||||
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
const AccountModel::RowType rowType = static_cast< AccountModel::RowType >( index.data( AccountModel::RowTypeRole ).toInt() );
|
||||||
if ( rowType == AccountModel::TopLevelAccount )
|
if ( rowType == AccountModel::TopLevelAccount ||
|
||||||
|
rowType == AccountModel::CustomAccount )
|
||||||
{
|
{
|
||||||
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
Account* acct = qobject_cast< Account* >( index.data( AccountModel::AccountData ).value< QObject* >() );
|
||||||
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
|
Q_ASSERT( acct ); // Should not be showing a config wrench if there is no account!
|
||||||
@@ -445,8 +444,6 @@ AccountDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QS
|
|||||||
|
|
||||||
m_configPressed = QModelIndex();
|
m_configPressed = QModelIndex();
|
||||||
|
|
||||||
const AccountModel::ItemState state = static_cast< AccountModel::ItemState >( index.data( AccountModel::StateRole ).toInt() );
|
|
||||||
|
|
||||||
if ( checkRectForIndex( option, index ).contains( me->pos() ) )
|
if ( checkRectForIndex( option, index ).contains( me->pos() ) )
|
||||||
{
|
{
|
||||||
// Check box for this row
|
// Check box for this row
|
||||||
|
@@ -308,6 +308,8 @@ set( libSources
|
|||||||
accounts/AccountModel.cpp
|
accounts/AccountModel.cpp
|
||||||
accounts/AccountModelFilterProxy.cpp
|
accounts/AccountModelFilterProxy.cpp
|
||||||
accounts/ResolverAccount.cpp
|
accounts/ResolverAccount.cpp
|
||||||
|
accounts/LastFmAccount.cpp
|
||||||
|
accounts/LastFmConfig.cpp
|
||||||
|
|
||||||
sip/SipPlugin.cpp
|
sip/SipPlugin.cpp
|
||||||
sip/SipHandler.cpp
|
sip/SipHandler.cpp
|
||||||
@@ -450,6 +452,8 @@ set( libHeaders
|
|||||||
accounts/AccountModel.h
|
accounts/AccountModel.h
|
||||||
accounts/AccountModelFilterProxy.h
|
accounts/AccountModelFilterProxy.h
|
||||||
accounts/ResolverAccount.h
|
accounts/ResolverAccount.h
|
||||||
|
accounts/LastFmAccount.h
|
||||||
|
accounts/LastFmConfig.h
|
||||||
|
|
||||||
EchonestCatalogSynchronizer.h
|
EchonestCatalogSynchronizer.h
|
||||||
|
|
||||||
@@ -582,6 +586,7 @@ set( libUI ${libUI}
|
|||||||
playlist/queueview.ui
|
playlist/queueview.ui
|
||||||
context/ContextWidget.ui
|
context/ContextWidget.ui
|
||||||
infobar/infobar.ui
|
infobar/infobar.ui
|
||||||
|
accounts/LastFmConfig.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.. ..
|
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.. ..
|
||||||
|
@@ -35,6 +35,7 @@ accountTypeToString( AccountType type )
|
|||||||
case ResolverType:
|
case ResolverType:
|
||||||
return QObject::tr( "Music Finders" );
|
return QObject::tr( "Music Finders" );
|
||||||
case InfoType:
|
case InfoType:
|
||||||
|
case StatusPushType:
|
||||||
return QObject::tr( "Status Updaters" );
|
return QObject::tr( "Status Updaters" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +175,8 @@ Account::setTypes( AccountTypes types )
|
|||||||
m_types << "SipType";
|
m_types << "SipType";
|
||||||
if ( types & ResolverType )
|
if ( types & ResolverType )
|
||||||
m_types << "ResolverType";
|
m_types << "ResolverType";
|
||||||
|
if ( types & StatusPushType )
|
||||||
|
m_types << "StatusPushType";
|
||||||
syncConfig();
|
syncConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +192,8 @@ Account::types() const
|
|||||||
types |= SipType;
|
types |= SipType;
|
||||||
if ( m_types.contains( "ResolverType" ) )
|
if ( m_types.contains( "ResolverType" ) )
|
||||||
types |= ResolverType;
|
types |= ResolverType;
|
||||||
|
if ( m_types.contains( "StatusPushTypeType" ) )
|
||||||
|
types |= StatusPushType;
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
@@ -50,7 +50,8 @@ enum AccountType
|
|||||||
|
|
||||||
InfoType = 0x01,
|
InfoType = 0x01,
|
||||||
SipType = 0x02,
|
SipType = 0x02,
|
||||||
ResolverType = 0x04
|
ResolverType = 0x04,
|
||||||
|
StatusPushType = 0x08
|
||||||
};
|
};
|
||||||
|
|
||||||
DLLEXPORT QString accountTypeToString( AccountType type );
|
DLLEXPORT QString accountTypeToString( AccountType type );
|
||||||
@@ -88,7 +89,7 @@ public:
|
|||||||
virtual QWidget* configurationWidget() = 0;
|
virtual QWidget* configurationWidget() = 0;
|
||||||
virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings
|
virtual void saveConfig() {} // called when the widget has been edited. save values from config widget, call sync() to write to disk account generic settings
|
||||||
|
|
||||||
QVariantHash credentials() { QMutexLocker locker( &m_mutex ); return m_credentials; }
|
QVariantHash credentials() const { QMutexLocker locker( &m_mutex ); return m_credentials; }
|
||||||
|
|
||||||
QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; }
|
QVariantMap acl() const { QMutexLocker locker( &m_mutex ); return m_acl; }
|
||||||
virtual QWidget* aclWidget() = 0;
|
virtual QWidget* aclWidget() = 0;
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "sourcelist.h"
|
#include "sourcelist.h"
|
||||||
#include "ResolverAccount.h"
|
#include "ResolverAccount.h"
|
||||||
|
#include "LastFmAccount.h"
|
||||||
|
|
||||||
#include <QtCore/QLibrary>
|
#include <QtCore/QLibrary>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
@@ -58,6 +59,9 @@ AccountManager::AccountManager( QObject *parent )
|
|||||||
// We include the resolver factory manually, not in a plugin
|
// We include the resolver factory manually, not in a plugin
|
||||||
ResolverAccountFactory* f = new ResolverAccountFactory();
|
ResolverAccountFactory* f = new ResolverAccountFactory();
|
||||||
m_accountFactories[ f->factoryId() ] = f;
|
m_accountFactories[ f->factoryId() ] = f;
|
||||||
|
|
||||||
|
LastFmAccountFactory* l = new LastFmAccountFactory();
|
||||||
|
m_accountFactories[ l->factoryId() ] = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -291,16 +295,14 @@ AccountManager::addAccount( Account* account )
|
|||||||
if ( account->types() & Accounts::SipType )
|
if ( account->types() & Accounts::SipType )
|
||||||
m_accountsByAccountType[ Accounts::SipType ].append( account );
|
m_accountsByAccountType[ Accounts::SipType ].append( account );
|
||||||
if ( account->types() & Accounts::InfoType )
|
if ( account->types() & Accounts::InfoType )
|
||||||
{
|
|
||||||
m_accountsByAccountType[ Accounts::InfoType ].append( account );
|
m_accountsByAccountType[ Accounts::InfoType ].append( account );
|
||||||
|
|
||||||
if ( account->infoPlugin() )
|
|
||||||
{
|
|
||||||
InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( account->types() & Accounts::ResolverType )
|
if ( account->types() & Accounts::ResolverType )
|
||||||
m_accountsByAccountType[ Accounts::ResolverType ].append( account );
|
m_accountsByAccountType[ Accounts::ResolverType ].append( account );
|
||||||
|
if ( account->types() & Accounts::StatusPushType )
|
||||||
|
m_accountsByAccountType[ Accounts::StatusPushType ].append( account );
|
||||||
|
|
||||||
|
if ( account->infoPlugin() )
|
||||||
|
InfoSystem::InfoSystem::instance()->addInfoPlugin( account->infoPlugin() );
|
||||||
|
|
||||||
emit added( account );
|
emit added( account );
|
||||||
}
|
}
|
||||||
|
@@ -59,6 +59,13 @@ AccountModel::loadData()
|
|||||||
|
|
||||||
qDebug() << "Creating factory node:" << fac->prettyName();
|
qDebug() << "Creating factory node:" << fac->prettyName();
|
||||||
m_accounts << new AccountModelNode( fac );
|
m_accounts << new AccountModelNode( fac );
|
||||||
|
|
||||||
|
// remove the accounts we are dealing with
|
||||||
|
foreach ( Account* acct, allAccounts )
|
||||||
|
{
|
||||||
|
if ( AccountManager::instance()->factoryForAccount( acct ) == fac )
|
||||||
|
allAccounts.removeAll( acct );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all attica resolvers (installed or uninstalled)
|
// add all attica resolvers (installed or uninstalled)
|
||||||
@@ -67,15 +74,26 @@ AccountModel::loadData()
|
|||||||
{
|
{
|
||||||
qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name();
|
qDebug() << "Loading ATTICA ACCOUNT with content:" << content.id() << content.name();
|
||||||
m_accounts << new AccountModelNode( content );
|
m_accounts << new AccountModelNode( content );
|
||||||
|
|
||||||
|
foreach ( Account* acct, AccountManager::instance()->accounts( Accounts::ResolverType ) )
|
||||||
|
{
|
||||||
|
if ( AtticaResolverAccount* resolver = qobject_cast< AtticaResolverAccount* >( acct ) )
|
||||||
|
{
|
||||||
|
if ( resolver->atticaId() == content.id() )
|
||||||
|
{
|
||||||
|
allAccounts.removeAll( acct );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all non-attica manually installed resolvers
|
// All other accounts we haven't dealt with yet
|
||||||
foreach ( Account* acct, allAccounts )
|
foreach ( Account* acct, allAccounts )
|
||||||
{
|
{
|
||||||
if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) )
|
if ( qobject_cast< ResolverAccount* >( acct ) && !qobject_cast< AtticaResolverAccount* >( acct ) )
|
||||||
{
|
|
||||||
m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) );
|
m_accounts << new AccountModelNode( qobject_cast< ResolverAccount* >( acct ) );
|
||||||
}
|
else
|
||||||
|
m_accounts << new AccountModelNode( acct );
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@@ -280,6 +298,41 @@ AccountModel::data( const QModelIndex& index, int role ) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case AccountModelNode::CustomAccountType:
|
||||||
|
{
|
||||||
|
Q_ASSERT( node->customAccount );
|
||||||
|
Q_ASSERT( node->factory );
|
||||||
|
|
||||||
|
Account* account = node->customAccount;
|
||||||
|
switch ( role )
|
||||||
|
{
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return account->accountFriendlyName();
|
||||||
|
case Qt::DecorationRole:
|
||||||
|
return account->icon();
|
||||||
|
case StateRole:
|
||||||
|
return ShippedWithTomahawk;
|
||||||
|
case Qt::ToolTipRole:
|
||||||
|
case DescriptionRole:
|
||||||
|
return node->factory->description();
|
||||||
|
case CanRateRole:
|
||||||
|
return false;
|
||||||
|
case RowTypeRole:
|
||||||
|
return CustomAccount;
|
||||||
|
case AccountData:
|
||||||
|
return QVariant::fromValue< QObject* >( account );
|
||||||
|
case HasConfig:
|
||||||
|
return account->configurationWidget() != 0;
|
||||||
|
case AccountTypeRole:
|
||||||
|
return QVariant::fromValue< AccountTypes >( account->types() );
|
||||||
|
case Qt::CheckStateRole:
|
||||||
|
return account->enabled();
|
||||||
|
case ConnectionStateRole:
|
||||||
|
return account->connectionState();
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@@ -345,6 +398,9 @@ AccountModel::setData( const QModelIndex& index, const QVariant& value, int role
|
|||||||
case AccountModelNode::ManualResolverType:
|
case AccountModelNode::ManualResolverType:
|
||||||
acct = node->resolverAccount;
|
acct = node->resolverAccount;
|
||||||
break;
|
break;
|
||||||
|
case AccountModelNode::CustomAccountType:
|
||||||
|
acct = node->customAccount;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
@@ -70,7 +70,8 @@ public:
|
|||||||
enum RowType {
|
enum RowType {
|
||||||
TopLevelFactory,
|
TopLevelFactory,
|
||||||
TopLevelAccount,
|
TopLevelAccount,
|
||||||
UniqueFactory
|
UniqueFactory,
|
||||||
|
CustomAccount
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ItemState {
|
enum ItemState {
|
||||||
|
@@ -36,13 +36,14 @@ namespace Accounts {
|
|||||||
* 1) AccountFactory* for all factories that have child accounts. Also a list of children
|
* 1) AccountFactory* for all factories that have child accounts. Also a list of children
|
||||||
* 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers)
|
* 2) Attica::Content for AtticaResolverAccounts (with associated AtticaResolverAccount*) (all synchrotron resolvers)
|
||||||
* 3) ResolverAccount* for manually added resolvers (from file).
|
* 3) ResolverAccount* for manually added resolvers (from file).
|
||||||
|
* 4) Account* for custom accounts. These may be hybrid infosystem/resolver/sip plugins or other special accounts
|
||||||
*
|
*
|
||||||
* These are the top-level items in tree.
|
* These are the top-level items in tree.
|
||||||
*
|
*
|
||||||
* Top level nodes all look the same to the user. The only difference is that services that have login (and thus
|
* Top level nodes all look the same to the user. The only difference is that services that have login (and thus
|
||||||
* can have multiple logins at once) allow a user to create multiple children with specific login information.
|
* can have multiple logins at once) allow a user to create multiple children with specific login information.
|
||||||
* All other top level accounts (Account*, Attica::Content, ResolverAccount*) behave the same to the user, they can
|
* All other top level accounts (Account*, Attica::Content, ResolverAccount*) behave the same to the user, they can
|
||||||
* simply click "Install" or toggle on/off.
|
* simply toggle on/off.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -51,7 +52,8 @@ struct AccountModelNode {
|
|||||||
FactoryType,
|
FactoryType,
|
||||||
UniqueFactoryType,
|
UniqueFactoryType,
|
||||||
AtticaType,
|
AtticaType,
|
||||||
ManualResolverType
|
ManualResolverType,
|
||||||
|
CustomAccountType
|
||||||
};
|
};
|
||||||
AccountModelNode* parent;
|
AccountModelNode* parent;
|
||||||
NodeType type;
|
NodeType type;
|
||||||
@@ -67,6 +69,9 @@ struct AccountModelNode {
|
|||||||
/// 3.
|
/// 3.
|
||||||
ResolverAccount* resolverAccount;
|
ResolverAccount* resolverAccount;
|
||||||
|
|
||||||
|
/// 4.
|
||||||
|
Account* customAccount;
|
||||||
|
|
||||||
// Construct in one of four ways. Then access the corresponding members
|
// Construct in one of four ways. Then access the corresponding members
|
||||||
explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType )
|
explicit AccountModelNode( AccountFactory* fac ) : type( FactoryType )
|
||||||
{
|
{
|
||||||
@@ -114,11 +119,19 @@ struct AccountModelNode {
|
|||||||
resolverAccount = ra;
|
resolverAccount = ra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit AccountModelNode( Account* account ) : type( CustomAccountType )
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
customAccount = account;
|
||||||
|
factory = AccountManager::instance()->factoryForAccount( account );
|
||||||
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
factory = 0;
|
factory = 0;
|
||||||
atticaAccount = 0;
|
atticaAccount = 0;
|
||||||
resolverAccount = 0;
|
resolverAccount = 0;
|
||||||
|
customAccount = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
194
src/libtomahawk/accounts/LastFmAccount.cpp
Normal file
194
src/libtomahawk/accounts/LastFmAccount.cpp
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-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 "LastFmAccount.h"
|
||||||
|
#include "LastFmConfig.h"
|
||||||
|
|
||||||
|
#include "infosystem/infosystem.h"
|
||||||
|
#include "infosystem/infoplugins/generic/lastfmplugin.h"
|
||||||
|
#include "utils/tomahawkutils.h"
|
||||||
|
#include "resolvers/qtscriptresolver.h"
|
||||||
|
|
||||||
|
using namespace Tomahawk;
|
||||||
|
using namespace InfoSystem;
|
||||||
|
using namespace Accounts;
|
||||||
|
|
||||||
|
LastFmAccountFactory::LastFmAccountFactory()
|
||||||
|
{
|
||||||
|
m_icon.load( RESPATH "images/lastfm-icon.png" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Account*
|
||||||
|
LastFmAccountFactory::createAccount( const QString& accountId )
|
||||||
|
{
|
||||||
|
return new LastFmAccount( accountId.isEmpty() ? generateId( factoryId() ) : accountId );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QPixmap
|
||||||
|
LastFmAccountFactory::icon() const
|
||||||
|
{
|
||||||
|
return m_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LastFmAccount::LastFmAccount( const QString& accountId )
|
||||||
|
: Account( accountId )
|
||||||
|
{
|
||||||
|
m_infoPlugin = new LastFmPlugin( this );
|
||||||
|
|
||||||
|
setAccountFriendlyName( "Last.Fm" );
|
||||||
|
m_icon.load( RESPATH "images/lastfm-icon.png" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LastFmAccount::~LastFmAccount()
|
||||||
|
{
|
||||||
|
delete m_infoPlugin;
|
||||||
|
delete m_resolver.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::authenticate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::deauthenticate()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget*
|
||||||
|
LastFmAccount::configurationWidget()
|
||||||
|
{
|
||||||
|
if ( m_configWidget.isNull() )
|
||||||
|
m_configWidget = QWeakPointer<LastFmConfig>( new LastFmConfig( this ) );
|
||||||
|
|
||||||
|
return m_configWidget.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Account::ConnectionState
|
||||||
|
LastFmAccount::connectionState() const
|
||||||
|
{
|
||||||
|
return m_authenticated ? Account::Connected : Account::Disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QPixmap
|
||||||
|
LastFmAccount::icon() const
|
||||||
|
{
|
||||||
|
return m_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InfoPlugin*
|
||||||
|
LastFmAccount::infoPlugin()
|
||||||
|
{
|
||||||
|
return m_infoPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
LastFmAccount::isAuthenticated() const
|
||||||
|
{
|
||||||
|
return m_authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::saveConfig()
|
||||||
|
{
|
||||||
|
if ( !m_configWidget.isNull() )
|
||||||
|
{
|
||||||
|
setUsername( m_configWidget.data()->username() );
|
||||||
|
setPassword( m_configWidget.data()->password() );
|
||||||
|
setScrobble( m_configWidget.data()->scrobble() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_infoPlugin->settingsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
LastFmAccount::password() const
|
||||||
|
{
|
||||||
|
return credentials().value( "password" ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::setPassword( const QString& password )
|
||||||
|
{
|
||||||
|
QVariantHash creds;
|
||||||
|
creds[ "password" ] = password;
|
||||||
|
setCredentials( creds );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LastFmAccount::sessionKey() const
|
||||||
|
{
|
||||||
|
return credentials().value( "sessionkey" ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::setSessionKey( const QString& sessionkey )
|
||||||
|
{
|
||||||
|
QVariantHash creds;
|
||||||
|
creds[ "sessionkey" ] = sessionkey;
|
||||||
|
setCredentials( creds );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
LastFmAccount::username() const
|
||||||
|
{
|
||||||
|
return credentials().value( "username" ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::setUsername( const QString& username )
|
||||||
|
{
|
||||||
|
QVariantHash creds;
|
||||||
|
creds[ "username" ] = username;
|
||||||
|
setCredentials( creds );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LastFmAccount::scrobble() const
|
||||||
|
{
|
||||||
|
return configuration().value( "scrobble" ).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmAccount::setScrobble( bool scrobble )
|
||||||
|
{
|
||||||
|
QVariantHash conf;
|
||||||
|
conf[ "scrobble" ] = scrobble;
|
||||||
|
setConfiguration( conf );
|
||||||
|
}
|
||||||
|
|
103
src/libtomahawk/accounts/LastFmAccount.h
Normal file
103
src/libtomahawk/accounts/LastFmAccount.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-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 LASTFMACCOUNT_H
|
||||||
|
#define LASTFMACCOUNT_H
|
||||||
|
|
||||||
|
#include "accounts/Account.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QtScriptResolver;
|
||||||
|
|
||||||
|
namespace Tomahawk {
|
||||||
|
namespace InfoSystem {
|
||||||
|
class LastFmPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Accounts {
|
||||||
|
|
||||||
|
class LastFmConfig;
|
||||||
|
|
||||||
|
class LastFmAccountFactory : public AccountFactory
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
LastFmAccountFactory();
|
||||||
|
|
||||||
|
virtual Account* createAccount(const QString& accountId = QString());
|
||||||
|
virtual QString description() const { return tr( "Scrobble your tracks to last.fm, and find freely downloadable tracks to play" ); }
|
||||||
|
virtual QString factoryId() const { return "lastfmaccount"; }
|
||||||
|
virtual QString prettyName() const { return "Last.fm"; }
|
||||||
|
virtual AccountTypes types() const { return AccountTypes( InfoType | StatusPushType ); }
|
||||||
|
virtual bool allowUserCreation() const { return false; }
|
||||||
|
virtual QPixmap icon() const;
|
||||||
|
virtual bool isUnique() const { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPixmap m_icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3.Last.Fm account is special. It is both an attica resolver *and* a InfoPlugin. We always want the infoplugin,
|
||||||
|
* but the user can install the attica resolver on-demand. So we take care of both there.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class LastFmAccount : public Account
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LastFmAccount( const QString& accountId );
|
||||||
|
~LastFmAccount();
|
||||||
|
|
||||||
|
virtual void deauthenticate();
|
||||||
|
virtual void authenticate();
|
||||||
|
|
||||||
|
virtual SipPlugin* sipPlugin() { return 0; }
|
||||||
|
virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin();
|
||||||
|
|
||||||
|
virtual bool isAuthenticated() const;
|
||||||
|
|
||||||
|
virtual ConnectionState connectionState() const;
|
||||||
|
virtual QPixmap icon() const;
|
||||||
|
virtual QWidget* aclWidget() { return 0; }
|
||||||
|
virtual QWidget* configurationWidget();
|
||||||
|
virtual void saveConfig();
|
||||||
|
|
||||||
|
QString username() const;
|
||||||
|
void setUsername( const QString& );
|
||||||
|
QString password() const;
|
||||||
|
void setPassword( const QString& );
|
||||||
|
QString sessionKey() const;
|
||||||
|
void setSessionKey( const QString& );
|
||||||
|
bool scrobble() const;
|
||||||
|
void setScrobble( bool scrobble );
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_authenticated;
|
||||||
|
QWeakPointer<QtScriptResolver> m_resolver;
|
||||||
|
Tomahawk::InfoSystem::LastFmPlugin* m_infoPlugin;
|
||||||
|
QWeakPointer<LastFmConfig> m_configWidget;
|
||||||
|
QPixmap m_icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LASTFMACCOUNT_H
|
134
src/libtomahawk/accounts/LastFmConfig.cpp
Normal file
134
src/libtomahawk/accounts/LastFmConfig.cpp
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/* === 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 "LastFmConfig.h"
|
||||||
|
|
||||||
|
#include "LastFmAccount.h"
|
||||||
|
#include <utils/tomahawkutils.h>
|
||||||
|
#include "ui_LastFmConfig.h"
|
||||||
|
#include "lastfm/ws.h"
|
||||||
|
#include "lastfm/XmlQuery"
|
||||||
|
|
||||||
|
using namespace Tomahawk::Accounts;
|
||||||
|
|
||||||
|
LastFmConfig::LastFmConfig( LastFmAccount* account )
|
||||||
|
: QWidget( 0 )
|
||||||
|
, m_account( account )
|
||||||
|
{
|
||||||
|
m_ui = new Ui_LastFmConfig;
|
||||||
|
m_ui->setupUi( this );
|
||||||
|
|
||||||
|
m_ui->username->setText( m_account->username() );
|
||||||
|
m_ui->password->setText( m_account->password() );
|
||||||
|
m_ui->enable->setChecked( m_account->scrobble() );
|
||||||
|
|
||||||
|
connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), this, SLOT( testLogin( bool ) ) );
|
||||||
|
|
||||||
|
// #ifdef Q_WS_MAC // FIXME
|
||||||
|
// m_ui->testLogin->setVisible( false );
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
LastFmConfig::password() const
|
||||||
|
{
|
||||||
|
return m_ui->password->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LastFmConfig::scrobble() const
|
||||||
|
{
|
||||||
|
return m_ui->enable->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
LastFmConfig::username() const
|
||||||
|
{
|
||||||
|
return m_ui->username->text().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmConfig::testLogin(bool )
|
||||||
|
{
|
||||||
|
m_ui->testLogin->setEnabled( false );
|
||||||
|
m_ui->testLogin->setText( "Testing..." );
|
||||||
|
|
||||||
|
QString authToken = TomahawkUtils::md5( ( m_ui->username->text().toLower() + TomahawkUtils::md5( m_ui->password->text().toUtf8() ) ).toUtf8() );
|
||||||
|
|
||||||
|
// now authenticate w/ last.fm and get our session key
|
||||||
|
QMap<QString, QString> query;
|
||||||
|
query[ "method" ] = "auth.getMobileSession";
|
||||||
|
query[ "username" ] = m_ui->username->text().toLower();
|
||||||
|
query[ "authToken" ] = authToken;
|
||||||
|
|
||||||
|
// ensure they have up-to-date settings
|
||||||
|
lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
|
||||||
|
|
||||||
|
QNetworkReply* authJob = lastfm::ws::post( query );
|
||||||
|
|
||||||
|
connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmConfig::onLastFmFinished()
|
||||||
|
{
|
||||||
|
QNetworkReply* authJob = dynamic_cast<QNetworkReply*>( sender() );
|
||||||
|
if( !authJob )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << "No auth job returned!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if( authJob->error() == QNetworkReply::NoError )
|
||||||
|
{
|
||||||
|
lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() );
|
||||||
|
|
||||||
|
if( lfm.children( "error" ).size() > 0 )
|
||||||
|
{
|
||||||
|
qDebug() << "ERROR from last.fm:" << lfm.text();
|
||||||
|
m_ui->testLogin->setText( tr( "Failed" ) );
|
||||||
|
m_ui->testLogin->setEnabled( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->testLogin->setText( tr( "Success" ) );
|
||||||
|
m_ui->testLogin->setEnabled( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch( authJob->error() )
|
||||||
|
{
|
||||||
|
case QNetworkReply::ContentOperationNotPermittedError:
|
||||||
|
case QNetworkReply::AuthenticationRequiredError:
|
||||||
|
m_ui->testLogin->setText( tr( "Failed" ) );
|
||||||
|
m_ui->testLogin->setEnabled( true );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qDebug() << "Couldn't get last.fm auth result";
|
||||||
|
m_ui->testLogin->setText( tr( "Could not contact server" ) );
|
||||||
|
m_ui->testLogin->setEnabled( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/libtomahawk/accounts/LastFmConfig.h
Normal file
53
src/libtomahawk/accounts/LastFmConfig.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* === 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 LASTFMCONFIG_H
|
||||||
|
#define LASTFMCONFIG_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class Ui_LastFmConfig;
|
||||||
|
|
||||||
|
namespace Tomahawk {
|
||||||
|
namespace Accounts {
|
||||||
|
|
||||||
|
class LastFmAccount;
|
||||||
|
|
||||||
|
class LastFmConfig : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LastFmConfig( LastFmAccount* account );
|
||||||
|
|
||||||
|
QString username() const;
|
||||||
|
QString password() const;
|
||||||
|
bool scrobble() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void testLogin( bool );
|
||||||
|
void onLastFmFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LastFmAccount* m_account;
|
||||||
|
Ui_LastFmConfig* m_ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // LASTFMCONFIG_H
|
85
src/libtomahawk/accounts/LastFmConfig.ui
Normal file
85
src/libtomahawk/accounts/LastFmConfig.ui
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>LastFmConfig</class>
|
||||||
|
<widget class="QWidget" name="LastFmConfig">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>178</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="../../../resources.qrc">:/data/images/lastfm-icon.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="enable">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Scrobble tracks to Last.fm</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Username:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="username"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Password:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="password">
|
||||||
|
<property name="echoMode">
|
||||||
|
<enum>QLineEdit::Password</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="testLogin">
|
||||||
|
<property name="text">
|
||||||
|
<string>Test Login</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../../resources.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -26,34 +26,37 @@
|
|||||||
#include "album.h"
|
#include "album.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include "audio/audioengine.h"
|
#include "audio/audioengine.h"
|
||||||
#include "tomahawksettings.h"
|
|
||||||
#include "utils/tomahawkutils.h"
|
#include "utils/tomahawkutils.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
#include "accounts/LastFmAccount.h"
|
||||||
|
|
||||||
#include <lastfm/ws.h>
|
#include <lastfm/ws.h>
|
||||||
#include <lastfm/XmlQuery>
|
#include <lastfm/XmlQuery>
|
||||||
|
|
||||||
#include <qjson/parser.h>
|
#include <qjson/parser.h>
|
||||||
|
|
||||||
|
using namespace Tomahawk::Accounts;
|
||||||
using namespace Tomahawk::InfoSystem;
|
using namespace Tomahawk::InfoSystem;
|
||||||
|
|
||||||
|
|
||||||
LastFmPlugin::LastFmPlugin()
|
LastFmPlugin::LastFmPlugin( LastFmAccount* account )
|
||||||
: InfoPlugin()
|
: InfoPlugin()
|
||||||
|
, m_account( account )
|
||||||
, m_scrobbler( 0 )
|
, m_scrobbler( 0 )
|
||||||
{
|
{
|
||||||
m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs << InfoChart << InfoChartCapabilities;
|
m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs << InfoChart << InfoChartCapabilities;
|
||||||
m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove;
|
m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove;
|
||||||
|
|
||||||
// Flush session key cache
|
// Flush session key cache
|
||||||
TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() );
|
// TODO WHY FLUSH
|
||||||
|
// m_account->setSessionKey( QByteArray() );
|
||||||
|
|
||||||
lastfm::ws::ApiKey = "7194b85b6d1f424fe1668173a78c0c4a";
|
lastfm::ws::ApiKey = "7194b85b6d1f424fe1668173a78c0c4a";
|
||||||
lastfm::ws::SharedSecret = "ba80f1df6d27ae63e9cb1d33ccf2052f";
|
lastfm::ws::SharedSecret = "ba80f1df6d27ae63e9cb1d33ccf2052f";
|
||||||
lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername();
|
lastfm::ws::Username = m_account->username();
|
||||||
lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
|
lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
|
||||||
|
|
||||||
m_pw = TomahawkSettings::instance()->lastFmPassword();
|
m_pw = m_account->password();
|
||||||
|
|
||||||
//HACK work around a bug in liblastfm---it doesn't create its config dir, so when it
|
//HACK work around a bug in liblastfm---it doesn't create its config dir, so when it
|
||||||
// tries to write the track cache, it fails silently. until we have a fixed version, do this
|
// tries to write the track cache, it fails silently. until we have a fixed version, do this
|
||||||
@@ -69,9 +72,6 @@ LastFmPlugin::LastFmPlugin()
|
|||||||
|
|
||||||
m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" );
|
m_badUrls << QUrl( "http://cdn.last.fm/flatness/catalogue/noimage" );
|
||||||
|
|
||||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ),
|
|
||||||
SLOT( settingsChanged() ), Qt::QueuedConnection );
|
|
||||||
|
|
||||||
QTimer::singleShot( 0, this, SLOT( settingsChanged() ) );
|
QTimer::singleShot( 0, this, SLOT( settingsChanged() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,23 +693,23 @@ LastFmPlugin::artistImagesReturned()
|
|||||||
void
|
void
|
||||||
LastFmPlugin::settingsChanged()
|
LastFmPlugin::settingsChanged()
|
||||||
{
|
{
|
||||||
if ( !m_scrobbler && TomahawkSettings::instance()->scrobblingEnabled() )
|
if ( !m_scrobbler && m_account->enabled() )
|
||||||
{ // can simply create the scrobbler
|
{ // can simply create the scrobbler
|
||||||
lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername();
|
lastfm::ws::Username = m_account->username();
|
||||||
m_pw = TomahawkSettings::instance()->lastFmPassword();
|
m_pw = m_account->password();
|
||||||
|
|
||||||
createScrobbler();
|
createScrobbler();
|
||||||
}
|
}
|
||||||
else if ( m_scrobbler && !TomahawkSettings::instance()->scrobblingEnabled() )
|
else if ( m_scrobbler && !m_account->enabled() )
|
||||||
{
|
{
|
||||||
delete m_scrobbler;
|
delete m_scrobbler;
|
||||||
m_scrobbler = 0;
|
m_scrobbler = 0;
|
||||||
}
|
}
|
||||||
else if ( TomahawkSettings::instance()->lastFmUsername() != lastfm::ws::Username ||
|
else if ( m_account->username() != lastfm::ws::Username ||
|
||||||
TomahawkSettings::instance()->lastFmPassword() != m_pw )
|
m_account->password() != m_pw )
|
||||||
{
|
{
|
||||||
lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername();
|
lastfm::ws::Username = m_account->username();
|
||||||
m_pw = TomahawkSettings::instance()->lastFmPassword();
|
m_pw = m_account->password();
|
||||||
// credentials have changed, have to re-create scrobbler for them to take effect
|
// credentials have changed, have to re-create scrobbler for them to take effect
|
||||||
if ( m_scrobbler )
|
if ( m_scrobbler )
|
||||||
{
|
{
|
||||||
@@ -739,16 +739,16 @@ LastFmPlugin::onAuthenticated()
|
|||||||
if ( lfm.children( "error" ).size() > 0 )
|
if ( lfm.children( "error" ).size() > 0 )
|
||||||
{
|
{
|
||||||
tLog() << "Error from authenticating with Last.fm service:" << lfm.text();
|
tLog() << "Error from authenticating with Last.fm service:" << lfm.text();
|
||||||
TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() );
|
m_account->setSessionKey( QByteArray() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lastfm::ws::SessionKey = lfm[ "session" ][ "key" ].text();
|
lastfm::ws::SessionKey = lfm[ "session" ][ "key" ].text();
|
||||||
|
|
||||||
TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() );
|
m_account->setSessionKey( lastfm::ws::SessionKey.toLatin1() );
|
||||||
|
|
||||||
// qDebug() << "Got session key from last.fm";
|
// qDebug() << "Got session key from last.fm";
|
||||||
if ( TomahawkSettings::instance()->scrobblingEnabled() )
|
if ( m_account->enabled() )
|
||||||
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
|
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -764,7 +764,7 @@ LastFmPlugin::onAuthenticated()
|
|||||||
void
|
void
|
||||||
LastFmPlugin::createScrobbler()
|
LastFmPlugin::createScrobbler()
|
||||||
{
|
{
|
||||||
if ( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one
|
if ( m_account->sessionKey().isEmpty() ) // no session key, so get one
|
||||||
{
|
{
|
||||||
qDebug() << "LastFmPlugin::createScrobbler Session key is empty";
|
qDebug() << "LastFmPlugin::createScrobbler Session key is empty";
|
||||||
QString authToken = TomahawkUtils::md5( ( lastfm::ws::Username.toLower() + TomahawkUtils::md5( m_pw.toUtf8() ) ).toUtf8() );
|
QString authToken = TomahawkUtils::md5( ( lastfm::ws::Username.toLower() + TomahawkUtils::md5( m_pw.toUtf8() ) ).toUtf8() );
|
||||||
@@ -780,7 +780,7 @@ LastFmPlugin::createScrobbler()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "LastFmPlugin::createScrobbler Already have session key";
|
qDebug() << "LastFmPlugin::createScrobbler Already have session key";
|
||||||
lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey();
|
lastfm::ws::SessionKey = m_account->sessionKey();
|
||||||
|
|
||||||
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
|
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,11 @@ class QNetworkReply;
|
|||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace Accounts
|
||||||
|
{
|
||||||
|
class LastFmAccount;
|
||||||
|
}
|
||||||
|
|
||||||
namespace InfoSystem
|
namespace InfoSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -40,7 +45,7 @@ class LastFmPlugin : public InfoPlugin
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LastFmPlugin();
|
LastFmPlugin( Accounts::LastFmAccount* account );
|
||||||
virtual ~LastFmPlugin();
|
virtual ~LastFmPlugin();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -74,6 +79,7 @@ private:
|
|||||||
|
|
||||||
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||||
|
|
||||||
|
Accounts::LastFmAccount* m_account;
|
||||||
QList<lastfm::Track> parseTrackList( QNetworkReply * reply );
|
QList<lastfm::Track> parseTrackList( QNetworkReply * reply );
|
||||||
|
|
||||||
lastfm::MutableTrack m_track;
|
lastfm::MutableTrack m_track;
|
||||||
@@ -88,3 +94,5 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif // LASTFMPLUGIN_H
|
#endif // LASTFMPLUGIN_H
|
||||||
|
|
||||||
|
class A;
|
||||||
|
@@ -46,6 +46,9 @@ InfoSystem* InfoSystem::s_instance = 0;
|
|||||||
InfoSystem*
|
InfoSystem*
|
||||||
InfoSystem::instance()
|
InfoSystem::instance()
|
||||||
{
|
{
|
||||||
|
if ( !s_instance )
|
||||||
|
s_instance = new InfoSystem( 0 );
|
||||||
|
|
||||||
return s_instance;
|
return s_instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,6 +104,9 @@ void
|
|||||||
InfoSystem::init()
|
InfoSystem::init()
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO;
|
tDebug() << Q_FUNC_INFO;
|
||||||
|
if ( m_inited )
|
||||||
|
return;
|
||||||
|
|
||||||
if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() )
|
if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() )
|
||||||
{
|
{
|
||||||
QTimer::singleShot( 0, this, SLOT( init() ) );
|
QTimer::singleShot( 0, this, SLOT( init() ) );
|
||||||
@@ -199,6 +205,12 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input )
|
|||||||
void
|
void
|
||||||
InfoSystem::addInfoPlugin( InfoPlugin* plugin )
|
InfoSystem::addInfoPlugin( InfoPlugin* plugin )
|
||||||
{
|
{
|
||||||
|
// Init is not complete (waiting for worker th read to start and create worker object) so keep trying till then
|
||||||
|
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod( this, "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) );
|
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPlugin*, plugin ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -242,8 +242,9 @@ public:
|
|||||||
bool pushInfo( const QString &caller, const InfoType type, const QVariant &input );
|
bool pushInfo( const QString &caller, const InfoType type, const QVariant &input );
|
||||||
bool pushInfo( const QString &caller, const InfoTypeMap &input );
|
bool pushInfo( const QString &caller, const InfoTypeMap &input );
|
||||||
|
|
||||||
|
public slots:
|
||||||
// InfoSystem takes ownership of InfoPlugins
|
// InfoSystem takes ownership of InfoPlugins
|
||||||
void addInfoPlugin( InfoPlugin* plugin );
|
void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||||
|
@@ -62,7 +62,8 @@ public slots:
|
|||||||
|
|
||||||
void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||||
|
|
||||||
void addInfoPlugin( InfoPlugin* plugin );
|
void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void checkTimeoutsTimerFired();
|
void checkTimeoutsTimerFired();
|
||||||
|
|
||||||
|
@@ -164,6 +164,9 @@ Pipeline::removeScriptResolver( const QString& scriptPath )
|
|||||||
QWeakPointer< ExternalResolver > r;
|
QWeakPointer< ExternalResolver > r;
|
||||||
foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers )
|
foreach ( QWeakPointer< ExternalResolver > res, m_scriptResolvers )
|
||||||
{
|
{
|
||||||
|
if ( res.isNull() )
|
||||||
|
continue;
|
||||||
|
|
||||||
if ( res.data()->filePath() == scriptPath )
|
if ( res.data()->filePath() == scriptPath )
|
||||||
r = res;
|
r = res;
|
||||||
}
|
}
|
||||||
|
@@ -296,6 +296,28 @@ TomahawkSettings::doUpgrade( int oldVersion, int newVersion )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a Last.Fm account since we now moved the infoplugin into the account
|
||||||
|
const QString accountKey = QString( "lastfmaccount_%1" ).arg( QUuid::createUuid().toString().mid( 1, 8 ) );
|
||||||
|
accounts << accountKey;
|
||||||
|
const QString lfmUsername = value( "lastfm/username" ).toString();
|
||||||
|
const QString lfmPassword = value( "lastfm/password" ).toString();
|
||||||
|
const bool scrobble = value( "lastfm/enablescrobbling", false ).toBool();
|
||||||
|
beginGroup( "accounts/" + accountKey );
|
||||||
|
// setValue( "enabled", false );
|
||||||
|
setValue( "autoconnect", true );
|
||||||
|
setValue( "types", QStringList() << "ResolverType" << "StatusPushType" );
|
||||||
|
QVariantHash credentials;
|
||||||
|
credentials[ "username" ] = lfmUsername;
|
||||||
|
credentials[ "password" ] = lfmPassword;
|
||||||
|
credentials[ "session" ] = value( "lastfm/session" ).toString();
|
||||||
|
setValue( "credentials", credentials );
|
||||||
|
QVariantHash configuration;
|
||||||
|
configuration[ "scrobble" ] = scrobble;
|
||||||
|
setValue( "configuration", configuration );
|
||||||
|
endGroup();
|
||||||
|
|
||||||
|
remove( "lastfm" );
|
||||||
|
|
||||||
remove( "script/resolvers" );
|
remove( "script/resolvers" );
|
||||||
remove( "script/loadedresolvers" );
|
remove( "script/loadedresolvers" );
|
||||||
|
|
||||||
@@ -892,62 +914,6 @@ TomahawkSettings::setExternalPort(int externalPort)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
|
||||||
TomahawkSettings::lastFmPassword() const
|
|
||||||
{
|
|
||||||
return value( "lastfm/password" ).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TomahawkSettings::setLastFmPassword( const QString& password )
|
|
||||||
{
|
|
||||||
setValue( "lastfm/password", password );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QByteArray
|
|
||||||
TomahawkSettings::lastFmSessionKey() const
|
|
||||||
{
|
|
||||||
return value( "lastfm/session" ).toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TomahawkSettings::setLastFmSessionKey( const QByteArray& key )
|
|
||||||
{
|
|
||||||
setValue( "lastfm/session", key );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString
|
|
||||||
TomahawkSettings::lastFmUsername() const
|
|
||||||
{
|
|
||||||
return value( "lastfm/username" ).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TomahawkSettings::setLastFmUsername( const QString& username )
|
|
||||||
{
|
|
||||||
setValue( "lastfm/username", username );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TomahawkSettings::scrobblingEnabled() const
|
|
||||||
{
|
|
||||||
return value( "lastfm/enablescrobbling", false ).toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TomahawkSettings::setScrobblingEnabled( bool enable )
|
|
||||||
{
|
|
||||||
setValue( "lastfm/enablescrobbling", enable );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TomahawkSettings::xmppBotServer() const
|
TomahawkSettings::xmppBotServer() const
|
||||||
{
|
{
|
||||||
|
@@ -165,19 +165,6 @@ public:
|
|||||||
QStringList aclEntries() const;
|
QStringList aclEntries() const;
|
||||||
void setAclEntries( const QStringList &entries );
|
void setAclEntries( const QStringList &entries );
|
||||||
|
|
||||||
/// Last.fm settings
|
|
||||||
bool scrobblingEnabled() const; /// false by default
|
|
||||||
void setScrobblingEnabled( bool enable );
|
|
||||||
|
|
||||||
QString lastFmUsername() const;
|
|
||||||
void setLastFmUsername( const QString& username );
|
|
||||||
|
|
||||||
QString lastFmPassword() const;
|
|
||||||
void setLastFmPassword( const QString& password );
|
|
||||||
|
|
||||||
QByteArray lastFmSessionKey() const;
|
|
||||||
void setLastFmSessionKey( const QByteArray& key );
|
|
||||||
|
|
||||||
/// XMPP Component Settings
|
/// XMPP Component Settings
|
||||||
QString xmppBotServer() const;
|
QString xmppBotServer() const;
|
||||||
void setXmppBotServer( const QString &server );
|
void setXmppBotServer( const QString &server );
|
||||||
|
@@ -87,11 +87,6 @@ public slots:
|
|||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
|
|
||||||
void shuffleModeChanged( bool enabled );
|
|
||||||
|
|
||||||
void trackCountChanged( unsigned int tracks );
|
|
||||||
void sourceTrackCountChanged( unsigned int tracks );
|
|
||||||
void nextTrackReady();
|
void nextTrackReady();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@@ -30,11 +30,6 @@
|
|||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QSizeGrip>
|
#include <QSizeGrip>
|
||||||
|
|
||||||
#ifdef LIBLASTFM_FOUND
|
|
||||||
#include <lastfm/ws.h>
|
|
||||||
#include <lastfm/XmlQuery>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "AtticaManager.h"
|
#include "AtticaManager.h"
|
||||||
#include "tomahawkapp.h"
|
#include "tomahawkapp.h"
|
||||||
#include "tomahawksettings.h"
|
#include "tomahawksettings.h"
|
||||||
@@ -168,21 +163,11 @@ SettingsDialog::SettingsDialog( QWidget *parent )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOW PLAYING
|
// NOW PLAYING
|
||||||
#ifdef Q_WS_MAC
|
// #ifdef Q_WS_MAC
|
||||||
ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() );
|
// ui->checkBoxEnableAdium->setChecked( s->nowPlayingEnabled() );
|
||||||
#else
|
// #else
|
||||||
ui->checkBoxEnableAdium->hide();
|
// ui->checkBoxEnableAdium->hide();
|
||||||
#endif
|
// #endif
|
||||||
|
|
||||||
// LAST FM
|
|
||||||
ui->checkBoxEnableLastfm->setChecked( s->scrobblingEnabled() );
|
|
||||||
ui->lineEditLastfmUsername->setText( s->lastFmUsername() );
|
|
||||||
ui->lineEditLastfmPassword->setText(s->lastFmPassword() );
|
|
||||||
connect( ui->pushButtonTestLastfmLogin, SIGNAL( clicked( bool) ), SLOT( testLastFmLogin() ) );
|
|
||||||
|
|
||||||
#ifdef Q_WS_MAC // FIXME
|
|
||||||
ui->pushButtonTestLastfmLogin->setVisible( false );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) );
|
connect( ui->proxyButton, SIGNAL( clicked() ), SLOT( showProxySettings() ) );
|
||||||
connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) );
|
connect( ui->checkBoxStaticPreferred, SIGNAL( toggled(bool) ), SLOT( toggleUpnp(bool) ) );
|
||||||
@@ -217,11 +202,7 @@ SettingsDialog::~SettingsDialog()
|
|||||||
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
s->setScannerTime( ui->scannerTimeSpinBox->value() );
|
||||||
s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() );
|
s->setEnableEchonestCatalogs( ui->enableEchonestCatalog->isChecked() );
|
||||||
|
|
||||||
s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
|
// s->setNowPlayingEnabled( ui->checkBoxEnableAdium->isChecked() );
|
||||||
|
|
||||||
s->setScrobblingEnabled( ui->checkBoxEnableLastfm->isChecked() );
|
|
||||||
s->setLastFmUsername( ui->lineEditLastfmUsername->text() );
|
|
||||||
s->setLastFmPassword( ui->lineEditLastfmPassword->text() );
|
|
||||||
|
|
||||||
s->applyChanges();
|
s->applyChanges();
|
||||||
s->sync();
|
s->sync();
|
||||||
@@ -265,13 +246,6 @@ SettingsDialog::createIcons()
|
|||||||
musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
|
musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
|
||||||
maxlen = qMax( fm.width( musicButton->text() ), maxlen );
|
maxlen = qMax( fm.width( musicButton->text() ), maxlen );
|
||||||
|
|
||||||
QListWidgetItem *lastfmButton = new QListWidgetItem( ui->listWidget );
|
|
||||||
lastfmButton->setIcon( QIcon( RESPATH "images/lastfm-settings.png" ) );
|
|
||||||
lastfmButton->setText( tr( "Last.fm" ) );
|
|
||||||
lastfmButton->setTextAlignment( Qt::AlignHCenter );
|
|
||||||
lastfmButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
|
|
||||||
maxlen = qMax( fm.width( lastfmButton->text() ), maxlen );
|
|
||||||
|
|
||||||
QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget );
|
QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget );
|
||||||
advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) );
|
advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) );
|
||||||
advancedButton->setText( tr( "Advanced" ) );
|
advancedButton->setText( tr( "Advanced" ) );
|
||||||
@@ -282,7 +256,6 @@ SettingsDialog::createIcons()
|
|||||||
maxlen += 15; // padding
|
maxlen += 15; // padding
|
||||||
accountsButton->setSizeHint( QSize( maxlen, 60 ) );
|
accountsButton->setSizeHint( QSize( maxlen, 60 ) );
|
||||||
musicButton->setSizeHint( QSize( maxlen, 60 ) );
|
musicButton->setSizeHint( QSize( maxlen, 60 ) );
|
||||||
lastfmButton->setSizeHint( QSize( maxlen, 60 ) );
|
|
||||||
advancedButton->setSizeHint( QSize( maxlen, 60 ) );
|
advancedButton->setSizeHint( QSize( maxlen, 60 ) );
|
||||||
|
|
||||||
#ifndef Q_WS_MAC
|
#ifndef Q_WS_MAC
|
||||||
@@ -362,78 +335,6 @@ SettingsDialog::updateScanOptionsView()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SettingsDialog::testLastFmLogin()
|
|
||||||
{
|
|
||||||
#ifdef LIBLASTFM_FOUND
|
|
||||||
ui->pushButtonTestLastfmLogin->setEnabled( false );
|
|
||||||
ui->pushButtonTestLastfmLogin->setText( "Testing..." );
|
|
||||||
|
|
||||||
QString authToken = TomahawkUtils::md5( ( ui->lineEditLastfmUsername->text().toLower() + TomahawkUtils::md5( ui->lineEditLastfmPassword->text().toUtf8() ) ).toUtf8() );
|
|
||||||
|
|
||||||
// now authenticate w/ last.fm and get our session key
|
|
||||||
QMap<QString, QString> query;
|
|
||||||
query[ "method" ] = "auth.getMobileSession";
|
|
||||||
query[ "username" ] = ui->lineEditLastfmUsername->text().toLower();
|
|
||||||
query[ "authToken" ] = authToken;
|
|
||||||
|
|
||||||
// ensure they have up-to-date settings
|
|
||||||
lastfm::setNetworkAccessManager( TomahawkUtils::nam() );
|
|
||||||
|
|
||||||
QNetworkReply* authJob = lastfm::ws::post( query );
|
|
||||||
|
|
||||||
connect( authJob, SIGNAL( finished() ), SLOT( onLastFmFinished() ) );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SettingsDialog::onLastFmFinished()
|
|
||||||
{
|
|
||||||
#ifdef LIBLASTFM_FOUND
|
|
||||||
QNetworkReply* authJob = dynamic_cast<QNetworkReply*>( sender() );
|
|
||||||
if( !authJob )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << "No auth job returned!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if( authJob->error() == QNetworkReply::NoError )
|
|
||||||
{
|
|
||||||
lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() );
|
|
||||||
|
|
||||||
if( lfm.children( "error" ).size() > 0 )
|
|
||||||
{
|
|
||||||
qDebug() << "ERROR from last.fm:" << lfm.text();
|
|
||||||
ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) );
|
|
||||||
ui->pushButtonTestLastfmLogin->setEnabled( true );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->pushButtonTestLastfmLogin->setText( tr( "Success" ) );
|
|
||||||
ui->pushButtonTestLastfmLogin->setEnabled( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch( authJob->error() )
|
|
||||||
{
|
|
||||||
case QNetworkReply::ContentOperationNotPermittedError:
|
|
||||||
case QNetworkReply::AuthenticationRequiredError:
|
|
||||||
ui->pushButtonTestLastfmLogin->setText( tr( "Failed" ) );
|
|
||||||
ui->pushButtonTestLastfmLogin->setEnabled( true );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
qDebug() << "Couldn't get last.fm auth result";
|
|
||||||
ui->pushButtonTestLastfmLogin->setText( tr( "Could not contact server" ) );
|
|
||||||
ui->pushButtonTestLastfmLogin->setEnabled( true );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SettingsDialog::accountsFilterChanged( int )
|
SettingsDialog::accountsFilterChanged( int )
|
||||||
{
|
{
|
||||||
|
@@ -86,9 +86,6 @@ private slots:
|
|||||||
void toggleUpnp( bool preferStaticEnabled );
|
void toggleUpnp( bool preferStaticEnabled );
|
||||||
void showProxySettings();
|
void showProxySettings();
|
||||||
|
|
||||||
void testLastFmLogin();
|
|
||||||
void onLastFmFinished();
|
|
||||||
|
|
||||||
void accountsFilterChanged( int );
|
void accountsFilterChanged( int );
|
||||||
|
|
||||||
void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* );
|
void createAccountFromFactory( Tomahawk::Accounts::AccountFactory* );
|
||||||
|
@@ -85,7 +85,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="accountsPage">
|
<widget class="QWidget" name="accountsPage">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
@@ -98,6 +98,9 @@
|
|||||||
<string>Internet Sources</string>
|
<string>Internet Sources</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<property name="margin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
@@ -221,119 +224,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="lastfmPage">
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
|
||||||
<property name="margin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Now Playing Information</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Applications to update with currently playing track:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="checkBoxEnableAdium">
|
|
||||||
<property name="text">
|
|
||||||
<string>Adium</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="checkBoxEnableLastfm">
|
|
||||||
<property name="layoutDirection">
|
|
||||||
<enum>Qt::LeftToRight</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Scrobble tracks to Last.fm</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Username:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditLastfmUsername"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Password:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditLastfmPassword">
|
|
||||||
<property name="echoMode">
|
|
||||||
<enum>QLineEdit::Password</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pushButtonTestLastfmLogin">
|
|
||||||
<property name="text">
|
|
||||||
<string>Test Login</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="advancedPage">
|
<widget class="QWidget" name="advancedPage">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="margin">
|
<property name="margin">
|
||||||
|
@@ -219,13 +219,13 @@ TomahawkApp::init()
|
|||||||
connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) );
|
connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tDebug() << "Init InfoSystem.";
|
||||||
|
m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( Tomahawk::InfoSystem::InfoSystem::instance() );
|
||||||
|
|
||||||
tDebug() << "Init AccountManager.";
|
tDebug() << "Init AccountManager.";
|
||||||
m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
|
m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
|
||||||
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
|
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
|
||||||
|
|
||||||
tDebug() << "Init InfoSystem.";
|
|
||||||
m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( new Tomahawk::InfoSystem::InfoSystem( this ) );
|
|
||||||
|
|
||||||
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
|
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||||
#ifndef ENABLE_HEADLESS
|
#ifndef ENABLE_HEADLESS
|
||||||
EchonestGenerator::setupCatalogs();
|
EchonestGenerator::setupCatalogs();
|
||||||
@@ -422,6 +422,7 @@ TomahawkApp::registerMetaTypes()
|
|||||||
qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" );
|
qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" );
|
||||||
qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" );
|
qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" );
|
||||||
qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" );
|
qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" );
|
||||||
|
qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" );
|
||||||
qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
|
qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
|
||||||
|
|
||||||
qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
|
qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
|
||||||
|
Reference in New Issue
Block a user