1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-24 14:42:53 +02:00

More account work; most of the pure-account side of a twitter account, but not yet tested

This commit is contained in:
Jeff Mitchell
2011-09-24 17:38:24 -04:00
parent c7f6144bfe
commit 88350b6a6c
19 changed files with 1200 additions and 55 deletions

View File

@@ -189,6 +189,7 @@ IF(GLOOX_FOUND)
SET( tomahawkHeaders ${tomahawkHeaders} xmppbot/xmppbot.h )
SET( tomahawkSources ${tomahawkSources} xmppbot/xmppbot.cpp )
ENDIF(GLOOX_FOUND)
ADD_SUBDIRECTORY( accounts )
ADD_SUBDIRECTORY( sip )
IF(QCA2_FOUND)

View File

@@ -0,0 +1 @@
add_subdirectory( twitter )

View File

@@ -0,0 +1,54 @@
project( tomahawk )
include( ${QT_USE_FILE} )
add_definitions( ${QT_DEFINITIONS} )
add_definitions( -DQT_PLUGIN )
add_definitions( -DQT_SHARED )
add_definitions( -DDLLEXPORT_PRO )
set( twitterAccountSources
twitteraccount.cpp
twitterconfigwidget.cpp
tomahawkoauthtwitter.cpp
)
set( twitterAccountHeaders
twitteraccount.h
twitterconfigwidget.h
tomahawkoauthtwitter.h
)
set( twitterAccountUI
twitterconfigwidget.ui
)
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
${QT_INCLUDE_DIR}
${QTWEETLIB_INCLUDE_DIR}
)
qt4_add_resources( RC_SRCS "resources.qrc" )
qt4_wrap_cpp( twitterAccountMoc ${twitterAccountHeaders} )
qt4_wrap_ui( twitterAccountUI_H ${twitterAccountUI} )
add_library( tomahawk_account_twitter SHARED ${twitterAccountUI_H} ${twitterAccountSources} ${twitterAccountMoc} ${RC_SRCS} )
IF( WIN32 )
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
"winmm.dll"
"iphlpapi.a"
)
ENDIF( WIN32 )
target_link_libraries( tomahawk_account_twitter
${TOMAHAWK_LIBRARIES}
${QTWEETLIB_LIBRARIES}
${QT_LIBRARIES}
${OS_SPECIFIC_LINK_LIBRARIES}
)
IF( APPLE )
# SET( CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-undefined dynamic_lookup" )
ENDIF( APPLE )
install( TARGETS tomahawk_account_twitter DESTINATION lib${LIB_SUFFIX} )

View File

@@ -0,0 +1,5 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>twitter-icon.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,32 @@
#include "tomahawkoauthtwitter.h"
#include <QInputDialog>
#include "utils/logger.h"
TomahawkOAuthTwitter::TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject* parent )
: OAuthTwitter( QByteArray::fromBase64( "QzR2NFdmYTIxcmZJRGNrNEhNUjNB" ), QByteArray::fromBase64( "elhTalU2Ympydmc2VVZNSlg0SnVmcUh5amozaWV4dFkxNFNSOXVCRUFv" ), parent )
{
setNetworkAccessManager( nam );
}
int
TomahawkOAuthTwitter::authorizationWidget()
{
bool ok;
int i = QInputDialog::getInt(0, tr( "Twitter PIN" ), tr( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), 0, 0, 2147483647, 1, &ok);
if (ok)
return i;
return 0;
}
void
TomahawkOAuthTwitter::error()
{
qDebug() << Q_FUNC_INFO;
setOAuthToken( QString().toLatin1() );
setOAuthTokenSecret( QString().toLatin1() );
}

View File

@@ -0,0 +1,25 @@
#ifndef TOMAHAWKOAUTHTWITTERACCOUNT
#define TOMAHAWKOAUTHTWITTERACCOUNT
#include "dllmacro.h"
#include <QTweetLib/qtweetlib_global.h>
#include <QTweetLib/oauthtwitter.h>
class DLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter
{
Q_OBJECT
public:
TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject *parent = 0 );
~TomahawkOAuthTwitter() {}
protected:
virtual int authorizationWidget();
private slots:
void error();
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,77 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.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 "twitteraccount.h"
#include "twitterconfigwidget.h"
#include <QtCore/QtPlugin>
namespace Tomahawk
{
namespace Accounts
{
Account*
TwitterAccountFactory::createAccount( const QString& accountId )
{
return new TwitterAccount( accountId.isEmpty() ? Tomahawk::Accounts::generateId( factoryId() ) : accountId );
}
TwitterAccount::TwitterAccount( const QString &accountId )
: Account( accountId )
, m_isAuthenticated( false )
{
loadFromConfig( accountId );
setAccountServiceName( "Twitter" );
QSet< AccountType > types;
types << InfoType;
setTypes( types );
m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
}
TwitterAccount::~TwitterAccount()
{
}
void
TwitterAccount::configDialogAuthedSignalSlot( bool authed )
{
m_isAuthenticated = authed;
if ( !credentials()[ "username" ].toString().isEmpty() )
setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) );
syncConfig();
emit configurationChanged();
}
}
}
#ifndef GOOGLE_WRAPPER
Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory )
#endif

View File

@@ -0,0 +1,87 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.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 TWITTERACCOUNT_H
#define TWITTERACCOUNT_H
#include "dllmacro.h"
#include "twitterconfigwidget.h"
#include "tomahawkoauthtwitter.h"
#include "accounts/account.h"
#define MYNAME "ACCOUNTTWITTER"
namespace Tomahawk
{
namespace Accounts
{
class DLLEXPORT TwitterAccountFactory : public AccountFactory
{
Q_OBJECT
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
public:
TwitterAccountFactory() {}
virtual ~TwitterAccountFactory() {}
QString prettyName() const { return "Twitter"; }
QString factoryId() const { return "twitteraccount"; }
QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
Account* createAccount( const QString& pluginId = QString() );
};
class DLLEXPORT TwitterAccount : public Account
{
Q_OBJECT
public:
TwitterAccount( const QString &accountId );
virtual ~TwitterAccount();
QIcon icon() const { return QIcon( ":/twitter-icon.png" ); }
bool canSelfAuthenticate() { return false; }
bool authenticate() { return false; }
bool isAuthenticated() { return m_isAuthenticated; }
Tomahawk::InfoSystem::InfoPlugin* infoPlugin() { return 0; }
SipPlugin* sipPlugin() { return 0; }
QWidget* configurationWidget() { return m_configWidget.data(); }
QWidget* aclWidget() { return 0; }
private slots:
void configDialogAuthedSignalSlot( bool authed );
private:
bool m_isAuthenticated;
QWeakPointer< TwitterConfigWidget > m_configWidget;
// for settings access
friend class TwitterConfigWidget;
};
};
};
#endif

View File

@@ -0,0 +1,294 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.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 "twitterconfigwidget.h"
#include "twitteraccount.h"
#include "ui_twitterconfigwidget.h"
#include "tomahawksettings.h"
#include "utils/tomahawkutils.h"
#include "database/database.h"
#include "tomahawkoauthtwitter.h"
#include <QTweetLib/qtweetaccountverifycredentials.h>
#include <QTweetLib/qtweetstatusupdate.h>
#include <QTweetLib/qtweetdirectmessagenew.h>
#include <QMessageBox>
#include "utils/logger.h"
namespace Tomahawk
{
namespace Accounts
{
TwitterConfigWidget::TwitterConfigWidget( TwitterAccount* account, QWidget *parent ) :
QWidget( parent ),
ui( new Ui::TwitterConfigWidget ),
m_account( account )
{
ui->setupUi( this );
connect( ui->twitterAuthenticateButton, SIGNAL( pressed() ),
this, SLOT( authDeauthTwitter() ) );
connect( ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ),
this, SLOT( startPostGotTomahawkStatus() ) );
connect( ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( tweetComboBoxIndexChanged( int ) ) );
ui->twitterTweetComboBox->setCurrentIndex( 0 );
ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
QVariantHash credentials = m_account->credentials();
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
credentials[ "username" ].toString().isEmpty() )
{
ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) );
ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
ui->twitterSyncGroupBox->setVisible( false );
emit twitterAuthed( false );
}
else
{
ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_account->credentials()[ "username" ].toString() ) );
ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
ui->twitterSyncGroupBox->setVisible( true );
ui->twitterUserTweetLineEdit->setVisible( false );
emit twitterAuthed( true );
}
}
TwitterConfigWidget::~TwitterConfigWidget()
{
delete ui;
}
void
TwitterConfigWidget::authDeauthTwitter()
{
if ( ui->twitterAuthenticateButton->text() == tr( "Authenticate" ) ) //FIXME: don't rely on UI strings here!
authenticateTwitter();
else
deauthenticateTwitter();
}
void
TwitterConfigWidget::authenticateTwitter()
{
qDebug() << Q_FUNC_INFO;
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
twitAuth->authorizePin();
QVariantHash credentials = m_account->credentials();
credentials[ "oauthtoken" ] = twitAuth->oauthToken();
credentials[ "oauthtokensecret" ] = twitAuth->oauthTokenSecret();
m_account->setCredentials( credentials );
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( authenticateVerifyReply( const QTweetUser & ) ) );
connect( credVerifier, SIGNAL( error( QTweetNetBase::ErrorCode, QString ) ), SLOT( authenticateVerifyError( QTweetNetBase::ErrorCode, QString ) ) );
credVerifier->verify();
}
void
TwitterConfigWidget::authenticateVerifyReply( const QTweetUser &user )
{
qDebug() << Q_FUNC_INFO;
if ( user.id() == 0 )
{
QMessageBox::critical( this, tr("Tweetin' Error"), tr("The credentials could not be verified.\nYou may wish to try re-authenticating.") );
emit twitterAuthed( false );
return;
}
QVariantHash credentials = m_account->credentials();
credentials[ "username" ] = user.screenName();
m_account->setCredentials( credentials );
QVariantHash configuration = m_account->configuration();
configuration[ "sipcachedfriendssinceid" ] = 0;
configuration[ "sipcachedmentionssinceid" ] = 0;
m_account->setConfiguration( configuration );
ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( user.screenName() ) );
ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
ui->twitterSyncGroupBox->setVisible( true );
ui->twitterTweetComboBox->setCurrentIndex( 0 );
ui->twitterUserTweetLineEdit->setVisible( false );
ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
emit twitterAuthed( true );
emit sizeHintChanged();
}
void
TwitterConfigWidget::authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg )
{
qDebug() << Q_FUNC_INFO;
qDebug() << "Error validating credentials, error code is " << code << ", error message is " << errorMsg;
ui->twitterStatusLabel->setText(tr("Status: Error validating credentials"));
emit twitterAuthed( false );
return;
}
void
TwitterConfigWidget::deauthenticateTwitter()
{
qDebug() << Q_FUNC_INFO;
QVariantHash credentials = m_account->credentials();
credentials[ "oauthtoken" ] = QString();
credentials[ "oauthtokensecret" ] = QString();
credentials[ "username" ] = QString();
m_account->setCredentials( credentials );
ui->twitterStatusLabel->setText(tr("Status: No saved credentials"));
ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
ui->twitterSyncGroupBox->setVisible( false );
emit twitterAuthed( false );
emit sizeHintChanged();
}
void
TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
{
Q_UNUSED( index );
if ( ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data!
ui->twitterUserTweetLineEdit->setVisible( false );
else
ui->twitterUserTweetLineEdit->setVisible( true );
if ( ui->twitterTweetComboBox->currentText() == tr( "Direct Message" ) ) //FIXME: use data!
ui->twitterTweetGotTomahawkButton->setText( tr( "Send Message!" ) );
else if ( ui->twitterTweetComboBox->currentText() == tr( "@Mention" ) )
ui->twitterTweetGotTomahawkButton->setText( tr( "Send Mention!" ) );
else
ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
}
void
TwitterConfigWidget::startPostGotTomahawkStatus()
{
qDebug() << Q_FUNC_INFO;
m_postGTtype = ui->twitterTweetComboBox->currentText();
if ( m_postGTtype != "Global Tweet" && ( ui->twitterUserTweetLineEdit->text().isEmpty() || ui->twitterUserTweetLineEdit->text() == "@" ) )
{
QMessageBox::critical( this, tr("Tweetin' Error"), tr("You must enter a user name for this type of tweet.") );
return;
}
qDebug() << "Posting Got Tomahawk status";
QVariantHash credentials = m_account->credentials();
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
credentials[ "username" ].toString().isEmpty() )
{
QMessageBox::critical( this, tr("Tweetin' Error"), tr("Your saved credentials could not be loaded.\nYou may wish to try re-authenticating.") );
emit twitterAuthed( false );
return;
}
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
twitAuth->setOAuthToken( credentials[ "oauthtoken" ].toString().toLatin1() );
twitAuth->setOAuthTokenSecret( credentials[ "oauthtokensecret" ].toString().toLatin1() );
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( twitAuth, this );
connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( postGotTomahawkStatusAuthVerifyReply(const QTweetUser &) ) );
credVerifier->verify();
}
void
TwitterConfigWidget::postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user )
{
qDebug() << Q_FUNC_INFO;
if ( user.id() == 0 )
{
QMessageBox::critical( this, tr("Tweetin' Error"), tr("Your saved credentials could not be verified.\nYou may wish to try re-authenticating.") );
emit twitterAuthed( false );
return;
}
TomahawkOAuthTwitter *twitAuth = new TomahawkOAuthTwitter( TomahawkUtils::nam(), this );
QVariantHash credentials = m_account->credentials();
twitAuth->setOAuthToken( credentials[ "oauthtoken" ].toString().toLatin1() );
twitAuth->setOAuthTokenSecret( credentials[ "oauthtokensecret" ].toString().toLatin1() );
if ( m_postGTtype != "Direct Message" )
{
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( twitAuth, this );
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postGotTomahawkStatusUpdateReply(const QTweetStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
QString uuid = QUuid::createUuid();
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
if ( m_postGTtype == "@Mention" )
{
QString user = ui->twitterUserTweetLineEdit->text();
if ( user.startsWith( "@" ) )
user.remove( 0, 1 );
message = QString( "@" ) + user + QString( " " ) + message;
}
statUpdate->post( message );
}
else
{
QTweetDirectMessageNew *statUpdate = new QTweetDirectMessageNew( twitAuth, this );
connect( statUpdate, SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( postGotTomahawkDirectMessageReply(const QTweetDMStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postGotTomahawkStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
QString uuid = QUuid::createUuid();
QString message = QString( "Got Tomahawk? {" ) + Database::instance()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
QString user = ui->twitterUserTweetLineEdit->text();
if ( user.startsWith( "@" ) )
user.remove( 0, 1 );
statUpdate->post( user, message );
}
}
void
TwitterConfigWidget::postGotTomahawkStatusUpdateReply( const QTweetStatus& status )
{
if ( status.id() == 0 )
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your status -- sorry!") );
else
QMessageBox::information( this, tr("Tweeted!"), tr("Your tweet has been posted!") );
}
void
TwitterConfigWidget::postGotTomahawkDirectMessageReply( const QTweetDMStatus& status )
{
if ( status.id() == 0 )
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your direct message -- sorry!") );
else
QMessageBox::information( this, tr("Tweeted!"), tr("Your message has been posted!") );
}
void
TwitterConfigWidget::postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg )
{
qDebug() << Q_FUNC_INFO;
qDebug() << "Error posting Got Tomahawk message, error code is " << code << ", error message is " << errorMsg;
QMessageBox::critical( this, tr("Tweetin' Error"), tr("There was an error posting your status -- sorry!") );
}
}
}

View File

@@ -0,0 +1,84 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.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 TWITTERACCOUNTCONFIGWIDGET_H
#define TWITTERACCOUNTCONFIGWIDGET_H
#include "dllmacro.h"
#include <QTweetLib/qtweetstatus.h>
#include <QTweetLib/qtweetdmstatus.h>
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetnetbase.h>
#include <QWidget>
class TwitterAccount;
namespace Ui
{
class TwitterConfigWidget;
}
namespace Tomahawk
{
namespace Accounts
{
class TwitterAccount;
class DLLEXPORT TwitterConfigWidget : public QWidget
{
Q_OBJECT
public:
explicit TwitterConfigWidget( TwitterAccount* account = 0, QWidget *parent = 0 );
virtual ~TwitterConfigWidget();
signals:
void twitterAuthed( bool authed );
void sizeHintChanged();
private slots:
void authDeauthTwitter();
void startPostGotTomahawkStatus();
void authenticateVerifyReply( const QTweetUser &user );
void authenticateVerifyError( QTweetNetBase::ErrorCode code, const QString &errorMsg );
void postGotTomahawkStatusAuthVerifyReply( const QTweetUser &user );
void postGotTomahawkStatusUpdateReply( const QTweetStatus &status );
void postGotTomahawkDirectMessageReply( const QTweetDMStatus &status );
void postGotTomahawkStatusUpdateError( QTweetNetBase::ErrorCode, const QString &errorMsg );
void tweetComboBoxIndexChanged( int index );
private:
void authenticateTwitter();
void deauthenticateTwitter();
Ui::TwitterConfigWidget *ui;
TwitterAccount *m_account;
QString m_postGTtype;
};
}
}
#endif // TWITTERCONFIGWIDGET_H

View File

@@ -0,0 +1,381 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TwitterConfigWidget</class>
<widget class="QWidget" name="TwitterConfigWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>390</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>580</width>
<height>390</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="resources.qrc">:/twitter-icon.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Configure this Twitter account</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="twitterInfoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>The Twitter plugin allows you to discover and play music from your Twitter friends running Tomahawk and post messages to your account.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="twitterStatusLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Status: No saved credentials</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="twitterAuthenticateButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Authenticate with Twitter</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="twitterSyncGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Twitter Connections</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="twitterInstructionsInfoLabel">
<property name="text">
<string>
If you only want to post tweets, you're done.
If you want to connect Tomahawk to your friends using Twitter, select the type of tweet and press the button below to send a sync message. You must both be following each other as Direct Messages are used. Then be (very) patient -- it can take several minutes!
You can re-send a sync message at any time simply by sending another tweet using the button.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="twitterTweetVLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<widget class="QLabel" name="twitterGlobalTweetLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select the kind of tweet you would like, then press the button to post it:</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="twitterGlobalTweetHLayout">
<item>
<widget class="QComboBox" name="twitterTweetComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Global Tweet</string>
</property>
</item>
<item>
<property name="text">
<string>@Mention</string>
</property>
</item>
<item>
<property name="text">
<string>Direct Message</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="twitterUserTweetLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="placeholderText">
<string>e.g. @tomahawk</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="twitterTweetGotTomahawkButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Send Message</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -253,6 +253,7 @@ set( libHeaders
album.h
playlist.h
accounts/account.h
accounts/accountmanager.h
sip/SipPlugin.h

View File

@@ -29,7 +29,7 @@
#include "dllmacro.h"
#include "infosystem/infosystem.h"
#include "sip/SipPlugin.h"
#include <tomahawksettings.h>
#include "tomahawksettings.h"
namespace Tomahawk
{
@@ -37,54 +37,128 @@ namespace Tomahawk
namespace Accounts
{
typedef QMap< QString, bool > ACLMap;
enum AccountType { InfoType, SipType };
inline QString generateId( const QString &factoryId )
{
QString uniq = QUuid::createUuid().toString().mid( 1, 8 );
return factoryId + "_" + uniq;
}
class DLLEXPORT Account : public QObject
{
Q_OBJECT
public:
explicit Account()
explicit Account( const QString &accountId )
: QObject()
, m_autoConnect( false )
, m_accountId( accountId ) {}
virtual ~Account() {}
virtual QString accountServiceName() const { return m_accountServiceName; } // e.g. "Twitter", "Last.fm"
virtual QString accountFriendlyName() const { return m_accountFriendlyName; } // e.g. screen name on the service, JID, etc.
virtual bool autoConnect() const { return m_autoConnect; }
virtual QString accountId() const { return m_accountId; }
virtual QVariantHash configuration() const { return m_configuration; }
virtual QWidget* configurationWidget() = 0;
virtual QVariantHash credentials() { return m_credentials; }
virtual QVariantMap acl() const { return m_acl; }
virtual QWidget* aclWidget() = 0;
virtual QIcon icon() const = 0;
virtual bool authenticate() = 0; //if none needed, just return true
virtual bool isAuthenticated() = 0;
virtual Tomahawk::InfoSystem::InfoPlugin* infoPlugin() = 0;
virtual SipPlugin* sipPlugin() = 0;
virtual QSet< AccountType > types() const
{
m_autoConnect = false;
QSet< AccountType > set;
foreach ( QString type, m_types )
{
if ( type == "InfoType" )
set << InfoType;
else if ( type == "SipType" )
set << SipType;
}
return set;
}
virtual ~Account();
QString accountServiceName() const; // e.g. "Twitter", "Last.fm"
void setAccountServiceName( const QString &serviceName );
signals:
void configurationChanged();
QString accountFriendlyName() const; // e.g. screen name on the service, JID, etc.
void setAccountFriendlyName( const QString &friendlyName );
protected:
virtual void setAccountServiceName( const QString &serviceName ) { m_accountServiceName = serviceName; }
virtual void setAccountFriendlyName( const QString &friendlyName ) { m_accountFriendlyName = friendlyName; }
virtual void setAutoConnect( bool autoConnect ) { m_autoConnect = autoConnect; }
virtual void setAccountId( const QString &accountId ) { m_accountId = accountId; }
virtual void setCredentials( const QVariantHash &credentialHash ) { m_credentials = credentialHash; }
bool autoConnect() const { return m_autoConnect; }
void setAutoConnect( bool autoConnect ) { m_autoConnect = autoConnect; }
virtual void setConfiguration( const QVariantHash &configuration ) { m_configuration = configuration; }
QHash< QString, QString > credentials() { return m_credentials; }
void setCredentials( const QHash< QString, QString > &credentialMap );
virtual void setAcl( const QVariantMap &acl ) { m_acl = acl; }
QIcon icon() const;
virtual void setTypes( const QSet< AccountType > types )
{
m_types = QStringList();
foreach ( AccountType type, types )
{
switch( type )
{
case InfoType:
m_types << "InfoType";
case SipType:
m_types << "SipType";
}
}
syncConfig();
}
QVariantMap configuration() const;
void setConfiguration( const QVariantMap &configuration );
QWidget* configurationWidget();
virtual void loadFromConfig( const QString &accountId )
{
m_accountId = accountId;
TomahawkSettings* s = TomahawkSettings::instance();
s->beginGroup( "accounts/" + m_accountId );
m_accountFriendlyName = s->value( "accountFriendlyName", QString() ).toString();
m_autoConnect = s->value( "autoConnect", false ).toBool();
m_credentials = s->value( "credentials", QVariantHash() ).toHash();
m_configuration = s->value( "configuration", QVariantHash() ).toHash();
m_acl = s->value( "acl", QVariantMap() ).toMap();
m_types = s->value( "types", QStringList() ).toStringList();
s->endGroup();
s->sync();
}
ACLMap acl() const;
void setAcl( const ACLMap &acl );
QWidget* aclWidget();
virtual void syncConfig()
{
TomahawkSettings* s = TomahawkSettings::instance();
s->beginGroup( "accounts/" + m_accountId );
s->setValue( "accountFriendlyName", m_accountFriendlyName );
s->setValue( "autoConnect", m_autoConnect );
s->setValue( "credentials", m_credentials );
s->setValue( "configuration", m_configuration );
s->setValue( "acl", m_acl );
s->setValue( "types", m_types );
s->endGroup();
s->sync();
QSet< AccountType > types() const;
void setTypes( const QSet< AccountType > types );
emit configurationChanged();
}
Tomahawk::InfoSystem::InfoPlugin* infoPlugin();
SipPlugin* sipPlugin();
private:
QString m_accountServiceName;
QString m_accountFriendlyName;
bool m_autoConnect;
QHash< QString, QString > m_credentials;
QString m_accountId;
QVariantHash m_credentials;
QVariantHash m_configuration;
QVariantMap m_acl;
QStringList m_types;
};
class DLLEXPORT AccountFactory : public QObject
@@ -103,13 +177,6 @@ public:
virtual bool isUnique() const { return false; }
virtual Account* createAccount( const QString& pluginId = QString() ) = 0;
protected:
QString generateId()
{
QString uniq = QUuid::createUuid().toString().mid( 1, 8 );
return factoryId() + "_" + uniq;
}
};
};

View File

@@ -31,9 +31,20 @@ namespace Accounts
{
AccountManager::AccountManager()
: QObject()
AccountManager* AccountManager::s_instance = 0;
AccountManager*
AccountManager::instance()
{
return s_instance;
}
AccountManager::AccountManager( QObject *parent )
: QObject( parent )
{
s_instance = this;
loadPluginFactories( findPluginFactories() );
}
@@ -70,7 +81,7 @@ AccountManager::findPluginFactories()
pluginDirs << appDir << libDir << lib64Dir << QDir( qApp->applicationDirPath() );
foreach ( const QDir& pluginDir, pluginDirs )
{
qDebug() << "Checking directory for plugins:" << pluginDir;
tDebug() << Q_FUNC_INFO << "Checking directory for plugins:" << pluginDir;
foreach ( QString fileName, pluginDir.entryList( QStringList() << "*tomahawk_account_*.so" << "*tomahawk_account_*.dylib" << "*tomahawk_account_*.dll", QDir::Files ) )
{
if ( fileName.startsWith( "libtomahawk_account" ) )
@@ -94,7 +105,7 @@ AccountManager::loadPluginFactories( const QStringList& paths )
if ( !QLibrary::isLibrary( fileName ) )
continue;
qDebug() << "Trying to load plugin:" << fileName;
tDebug() << Q_FUNC_INFO << "Trying to load plugin:" << fileName;
loadPluginFactory( fileName );
}
}
@@ -114,17 +125,17 @@ AccountManager::loadPluginFactory( const QString& path )
QObject* plugin = loader.instance();
if ( !plugin )
{
qDebug() << "Error loading plugin:" << loader.errorString();
tDebug() << Q_FUNC_INFO << "Error loading plugin:" << loader.errorString();
}
AccountFactory* accountfactory = qobject_cast<AccountFactory*>( plugin );
if ( accountfactory )
{
qDebug() << "Loaded plugin factory:" << loader.fileName() << accountfactory->factoryId() << accountfactory->prettyName();
tDebug() << Q_FUNC_INFO << "Loaded plugin factory:" << loader.fileName() << accountfactory->factoryId() << accountfactory->prettyName();
m_accountFactories[ accountfactory->factoryId() ] = accountfactory;
} else
{
qDebug() << "Loaded invalid plugin.." << loader.fileName();
tDebug() << Q_FUNC_INFO << "Loaded invalid plugin.." << loader.fileName();
}
}
@@ -162,9 +173,11 @@ AccountManager::loadPlugin( const QString& pluginId )
void
AccountManager::addAccountPlugin( Account* account )
{
m_accounts << account;
m_accounts.append( account );
//FIXME:
foreach( AccountType type, account->types() )
m_accountsByAccountType[ type ].append( account );
//TODO:
//emit pluginAdded( account );
}

View File

@@ -38,7 +38,9 @@ class DLLEXPORT AccountManager : public QObject
Q_OBJECT
public:
explicit AccountManager();
static AccountManager* instance();
explicit AccountManager( QObject *parent );
virtual ~AccountManager();
QStringList findPluginFactories();
@@ -50,12 +52,15 @@ public:
Account* loadPlugin( const QString &pluginId );
QString factoryFromId( const QString& pluginId ) const;
//QSet< Account > getAccounts( Tomahawk::Accounts::AccountType type );
QList< Account* > getAccounts() { return m_accounts; };
QList< Account* > getAccounts( Tomahawk::Accounts::AccountType type ) { return m_accountsByAccountType[ type ]; }
private:
QSet< Account* > m_accounts;
QList< Account* > m_accounts;
QHash< AccountType, QList< Account* > > m_accountsByAccountType;
QHash< QString, AccountFactory* > m_accountFactories;
static AccountManager* s_instance;
};
};

View File

@@ -86,9 +86,6 @@ TwitterPlugin::TwitterPlugin( const QString& pluginId )
m_connectTimer.setInterval( 180000 );
m_connectTimer.setSingleShot( false );
connect( &m_connectTimer, SIGNAL( timeout() ), SLOT( connectTimerFired() ) );
m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
}

View File

@@ -35,6 +35,7 @@
#include "album.h"
#include "collection.h"
#include "infosystem/infosystem.h"
#include "accounts/accountmanager.h"
#include "database/database.h"
#include "database/databasecollection.h"
#include "database/databasecommand_collectionstats.h"
@@ -212,6 +213,10 @@ TomahawkApp::init()
connect( m_shortcutHandler.data(), SIGNAL( mute() ), m_audioEngine.data(), SLOT( mute() ) );
}
tDebug() << "Init AccountManager.";
m_accountManager = QWeakPointer< Tomahawk::Accounts::AccountManager >( new Tomahawk::Accounts::AccountManager( this ) );
Tomahawk::Accounts::AccountManager::instance()->loadFromConfig();
tDebug() << "Init InfoSystem.";
m_infoSystem = QWeakPointer<Tomahawk::InfoSystem::InfoSystem>( new Tomahawk::InfoSystem::InfoSystem( this ) );
@@ -499,6 +504,12 @@ TomahawkApp::initServent()
void
TomahawkApp::initSIP()
{
foreach ( Tomahawk::Accounts::Account* account, Tomahawk::Accounts::AccountManager::instance()->getAccounts() )
{
if ( account->configurationWidget() )
account->configurationWidget()->show();
}
//FIXME: jabber autoconnect is really more, now that there is sip -- should be renamed and/or split out of jabber-specific settings
if ( !arguments().contains( "--nosip" ) )
{

View File

@@ -53,6 +53,11 @@ namespace Tomahawk
{
class InfoSystem;
}
namespace Accounts
{
class AccountManager;
}
}
#ifdef LIBLASTFM_FOUND
@@ -119,6 +124,7 @@ private:
QWeakPointer<Tomahawk::InfoSystem::InfoSystem> m_infoSystem;
QWeakPointer<XMPPBot> m_xmppBot;
QWeakPointer<Tomahawk::ShortcutHandler> m_shortcutHandler;
QWeakPointer< Tomahawk::Accounts::AccountManager > m_accountManager;
bool m_scrubFriendlyName;
#ifdef LIBLASTFM_FOUND
@@ -139,3 +145,7 @@ Q_DECLARE_METATYPE( QPersistentModelIndex );
#endif // TOMAHAWKAPP_H
struct A;
struct A;