1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-07-31 03:10:12 +02:00

Merge pull request #226 from tomahawk-player/drop-qtweetlib

Drop QTweetLib and deprecated TwitterSIP
This commit is contained in:
Dominik Schmidt
2014-04-05 22:26:47 +02:00
26 changed files with 3 additions and 2427 deletions

1
.gitignore vendored
View File

@@ -12,7 +12,6 @@ Makefile*
moc_*
*~
/tomahawk
thirdparty/qtweetlib/WARNING-twitter-api-keys
.kdev4
*.kdev4
*.kate-swp

View File

@@ -269,9 +269,6 @@ if( PC_JREEN_VERSION STREQUAL "1.1.0" )
message(FATAL_ERROR "Jreen 1.1.0 has a very annoying bug that breaks accepting auth requests in Tomahawk. Please upgrade to 1.1.1 or downgrade to 1.0.5.")
endif()
macro_optional_find_package(QTweetLib)
macro_log_feature(QTWEETLIB_FOUND "QTweetLib" "Qt Twitter Library" "https://github.com/minimoog/QTweetLib" FALSE "" "QTweetLib is needed for the Twitter SIP plugin.\n")
macro_optional_find_package(LibLastFm 1.0.0)
macro_log_feature(LIBLASTFM_FOUND "liblastfm" "Qt library for the Last.fm webservices" "https://github.com/lastfm/liblastfm" TRUE "" "liblastfm is needed for scrobbling tracks to Last.fm and fetching cover artwork")

View File

@@ -1,28 +0,0 @@
# - Try to find QTweetLib
#
# QTWEETLIB_FOUND - system has QTweetLib
# QTWEETLIB_INCLUDE_DIRS - the QTweetLib include directories
# QTWEETLIB_LIBRARIES - link these to use QTweetLib
#
# (c) Dominik Schmidt <dev@dominik-schmidt.de>
#
# Include dir
find_path(QTWEETLIB_INCLUDE_DIR
NAMES QTweetLib/qtweetlib_global.h
PATHS ${KDE4_INCLUDE_DIR}
)
# Finally the library itself
find_library(QTWEETLIB_LIBRARY
NAMES QTweetLib
PATHS ${KDE4_LIB_DIR}
)
SET( QTWEETLIB_LIBRARIES ${QTWEETLIB_LIBRARY} ${QJSON_LIBRARIES} )
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(QTweetLib DEFAULT_MSG QTWEETLIB_LIBRARY QTWEETLIB_INCLUDE_DIR)
MARK_AS_ADVANCED(QTWEETLIB_LIBRARIES QTWEETLIB_INCLUDE_DIR)

View File

@@ -352,7 +352,6 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
File "${MING_BIN}\libechonest.dll"
File "${MING_BIN}\liblastfm.dll"
File "${MING_BIN}\libQTweetLib.dll"
File "${MING_BIN}\libquazip.dll"
File "${MING_BIN}\libqtkeychain.dll"

View File

@@ -53,7 +53,6 @@ Required dependencies:
The following dependencies are optional, but recommended:
* Jreen 1.0.5 (1.1.0 will fail, 1.1.1 is fine) - http://qutim.org/jreen/
* QTweetLib 0.5.0 - https://github.com/minimoog/QTweetLib/
Third party libraries that we ship with our source:

View File

@@ -202,7 +202,6 @@ QT_PLUGINS = [
TOMAHAWK_PLUGINS = [
'libtomahawk_account_xmpp.dylib',
'libtomahawk_account_google.so',
#'libtomahawk_account_twitter.so',
'libtomahawk_account_zeroconf.so',
'libtomahawk_infoplugin_adium.so',
'libtomahawk_infoplugin_charts.so',

View File

@@ -2,8 +2,7 @@
file(GLOB SUBDIRECTORIES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*")
foreach(SUBDIRECTORY ${SUBDIRECTORIES})
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/CMakeLists.txt")
if(SUBDIRECTORY STREQUAL "twitter")
elseif((SUBDIRECTORY STREQUAL "xmpp") OR (SUBDIRECTORY STREQUAL "google"))
if((SUBDIRECTORY STREQUAL "xmpp") OR (SUBDIRECTORY STREQUAL "google"))
if( JREEN_FOUND )
add_subdirectory(${SUBDIRECTORY})
endif()

View File

@@ -1,19 +0,0 @@
include_directories(${QTWEETLIB_INCLUDE_DIR})
tomahawk_add_plugin(twitter
TYPE account
EXPORT_MACRO ACCOUNTDLLEXPORT_PRO
SOURCES
TwitterAccount.cpp
TwitterInfoPlugin.cpp
TwitterConfigWidget.cpp
TomahawkOAuthTwitter.cpp
# sip/TwitterSip.cpp
UI
TwitterConfigWidget.ui
LINK_LIBRARIES
${TOMAHAWK_LIBRARIES}
${QTWEETLIB_LIBRARIES}
)

View File

@@ -1,52 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2012, Jeff Mitchell <jeff@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 "TomahawkOAuthTwitter.h"
#include "utils/Logger.h"
#include <QInputDialog>
TomahawkOAuthTwitter::TomahawkOAuthTwitter( QNetworkAccessManager *nam, QObject* parent )
: OAuthTwitter( QByteArray::fromBase64( "QzR2NFdmYTIxcmZJRGNrNEhNUjNB" ), QByteArray::fromBase64( "elhTalU2Ympydmc2VVZNSlg0SnVmcUh5amozaWV4dFkxNFNSOXVCRUFv" ), parent )
{
setNetworkAccessManager( nam );
}
const QString
TomahawkOAuthTwitter::authorizationWidget()
{
bool ok;
const QString str = QInputDialog::getText(0, tr( "Twitter PIN" ), tr( "After authenticating on Twitter's web site,\nenter the displayed PIN number here:" ), QLineEdit::Normal, QString(), &ok);
if ( ok && !str.isEmpty() )
return str;
return QString();
}
void
TomahawkOAuthTwitter::error()
{
qDebug() << Q_FUNC_INFO;
setOAuthToken( QString().toLatin1() );
setOAuthTokenSecret( QString().toLatin1() );
}

View File

@@ -1,45 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2012, Jeff Mitchell <jeff@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 TOMAHAWKOAUTHTWITTERACCOUNT
#define TOMAHAWKOAUTHTWITTERACCOUNT
#include "accounts/AccountDllMacro.h"
#include "utils/TomahawkUtils.h"
#include <QTweetLib/qtweetlib_global.h>
#include <QTweetLib/oauthtwitter.h>
class ACCOUNTDLLEXPORT TomahawkOAuthTwitter : public OAuthTwitter
{
Q_OBJECT
public:
TomahawkOAuthTwitter( QNetworkAccessManager *nam = TomahawkUtils::nam() , QObject *parent = 0 );
~TomahawkOAuthTwitter() {}
protected:
virtual const QString authorizationWidget();
private slots:
void error();
};
#endif

View File

@@ -1,247 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 "TomahawkOAuthTwitter.h"
#include "infosystem/InfoSystem.h"
#include "utils/Logger.h"
#include "sip/SipPlugin.h"
#include <QTweetLib/qtweetaccountverifycredentials.h>
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetstatus.h>
#include <QTweetLib/qtweetusershow.h>
#include <QtCore/QtPlugin>
#include <QTimer>
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 )
, m_isAuthenticating( false )
{
setAccountServiceName( "Twitter" );
setTypes( AccountTypes( StatusPushType ) );
qDebug() << "Got cached peers:" << configuration() << configuration()[ "cachedpeers" ];
m_configWidget = QPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
m_twitterAuth = QPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
m_onlinePixmap = QPixmap( ":/twitter-account/twitter-icon.png" );
m_offlinePixmap = QPixmap( ":/twitter-account/twitter-offline-icon.png" );
}
TwitterAccount::~TwitterAccount()
{
}
void
TwitterAccount::configDialogAuthedSignalSlot( bool authed )
{
tDebug() << Q_FUNC_INFO;
m_isAuthenticated = authed;
if ( !credentials()[ "username" ].toString().isEmpty() )
setAccountFriendlyName( QString( "@%1" ).arg( credentials()[ "username" ].toString() ) );
syncConfig();
emit configurationChanged();
}
Account::ConnectionState
TwitterAccount::connectionState() const
{
// if ( m_twitterSipPlugin.isNull() )
return Account::Disconnected;
// return m_twitterSipPlugin.data()->connectionState();
}
SipPlugin*
TwitterAccount::sipPlugin()
{
// if ( m_twitterSipPlugin.isNull() )
// {
// qDebug() << "CHECKING:" << configuration() << configuration()[ "cachedpeers" ];
// m_twitterSipPlugin = QPointer< TwitterSipPlugin >( new TwitterSipPlugin( this ) );
// connect( m_twitterSipPlugin.data(), SIGNAL( stateChanged( Tomahawk::Accounts::Account::ConnectionState ) ), this, SIGNAL( connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState ) ) );
// return m_twitterSipPlugin.data();
// }
// return m_twitterSipPlugin.data();
return 0;
}
Tomahawk::InfoSystem::InfoPluginPtr
TwitterAccount::infoPlugin()
{
if ( m_twitterInfoPlugin.isNull() )
m_twitterInfoPlugin = QPointer< Tomahawk::InfoSystem::TwitterInfoPlugin >( new Tomahawk::InfoSystem::TwitterInfoPlugin( this ) );
return Tomahawk::InfoSystem::InfoPluginPtr( m_twitterInfoPlugin.data() );
}
void
TwitterAccount::authenticate()
{
// Since we need to have a chance for deletion (via the infosystem) to work on the info plugin, we put this on the event loop
tDebug() << Q_FUNC_INFO;
QTimer::singleShot( 0, this, SLOT( authenticateSlot() ) );
}
void
TwitterAccount::authenticateSlot()
{
tDebug() << Q_FUNC_INFO;
if ( m_twitterInfoPlugin.isNull() )
{
if ( infoPlugin() && Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() )
{
infoPlugin().data()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin() );
}
}
if ( m_isAuthenticating )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Already authenticating";
return;
}
tDebug() << Q_FUNC_INFO << "credentials: " << credentials().keys();
if ( credentials()[ "oauthtoken" ].toString().isEmpty() || credentials()[ "oauthtokensecret" ].toString().isEmpty() )
{
tDebug() << Q_FUNC_INFO << "TwitterSipPlugin has empty Twitter credentials; not connecting";
return;
}
if ( refreshTwitterAuth() )
{
m_isAuthenticating = true;
tDebug() << Q_FUNC_INFO << "Verifying credentials";
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) );
credVerifier->verify();
}
}
void
TwitterAccount::deauthenticate()
{
tDebug() << Q_FUNC_INFO;
// if ( m_twitterSipPlugin )
// sipPlugin()->disconnectPlugin();
if ( m_twitterInfoPlugin )
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( m_twitterInfoPlugin.data() );
m_isAuthenticated = false;
m_isAuthenticating = false;
emit nowDeauthenticated();
}
bool
TwitterAccount::refreshTwitterAuth()
{
qDebug() << Q_FUNC_INFO << " begin";
if( !m_twitterAuth.isNull() )
delete m_twitterAuth.data();
Q_ASSERT( TomahawkUtils::nam() != 0 );
tDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam();
m_twitterAuth = QPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
if( m_twitterAuth.isNull() )
return false;
m_twitterAuth.data()->setOAuthToken( credentials()[ "oauthtoken" ].toString().toLatin1() );
m_twitterAuth.data()->setOAuthTokenSecret( credentials()[ "oauthtokensecret" ].toString().toLatin1() );
return true;
}
void
TwitterAccount::connectAuthVerifyReply( const QTweetUser &user )
{
m_isAuthenticating = false;
if ( user.id() == 0 )
{
qDebug() << "TwitterAccount could not authenticate to Twitter";
deauthenticate();
}
else
{
tDebug() << "TwitterAccount successfully authenticated to Twitter as user " << user.screenName();
QVariantHash config = configuration();
config[ "screenname" ] = user.screenName();
setConfiguration( config );
sync();
// sipPlugin()->connectPlugin();
m_isAuthenticated = true;
emit nowAuthenticated( m_twitterAuth, user );
}
}
QPixmap
TwitterAccount::icon() const
{
if ( connectionState() == Connected )
return m_onlinePixmap;
return m_offlinePixmap;
}
}
}
Q_EXPORT_PLUGIN2( Tomahawk::Accounts::AccountFactory, Tomahawk::Accounts::TwitterAccountFactory )

View File

@@ -1,111 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 "TwitterConfigWidget.h"
#include "TomahawkOAuthTwitter.h"
//#include "sip/TwitterSip.h"
#include "TwitterInfoPlugin.h"
#include "accounts/AccountDllMacro.h"
#include "accounts/Account.h"
#define MYNAME "ACCOUNTTWITTER"
namespace Tomahawk
{
namespace Accounts
{
class ACCOUNTDLLEXPORT TwitterAccountFactory : public AccountFactory
{
Q_OBJECT
Q_INTERFACES( Tomahawk::Accounts::AccountFactory )
public:
TwitterAccountFactory() {}
virtual ~TwitterAccountFactory() {}
QString prettyName() const { return "Twitter"; }
QString factoryId() const { return "twitteraccount"; }
QString description() const { return tr( "Send tweets from Tomahawk." ); }
QPixmap icon() const { return QPixmap( ":/twitter-account/twitter-icon.png" ); }
AccountTypes types() const { return AccountTypes( StatusPushType ); };
Account* createAccount( const QString& pluginId = QString() );
};
class ACCOUNTDLLEXPORT TwitterAccount : public Account
{
Q_OBJECT
public:
TwitterAccount( const QString &accountId );
virtual ~TwitterAccount();
QPixmap icon() const;
void authenticate();
void deauthenticate();
bool isAuthenticated() const { return m_isAuthenticated; }
ConnectionState connectionState() const;
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin();
SipPlugin* sipPlugin();
AccountConfigWidget* configurationWidget() { return m_configWidget.data(); }
QWidget* aclWidget() { return 0; }
bool refreshTwitterAuth();
TomahawkOAuthTwitter* twitterAuth() const { return m_twitterAuth.data(); }
signals:
void nowAuthenticated( const QPointer< TomahawkOAuthTwitter >&, const QTweetUser &user );
void nowDeauthenticated();
private slots:
void authenticateSlot();
void configDialogAuthedSignalSlot( bool authed );
void connectAuthVerifyReply( const QTweetUser &user );
private:
QIcon m_icon;
bool m_isAuthenticated;
bool m_isAuthenticating;
QPointer< TomahawkOAuthTwitter > m_twitterAuth;
QPointer< TwitterConfigWidget > m_configWidget;
// QPointer< TwitterSipPlugin > m_twitterSipPlugin;
QPointer< Tomahawk::InfoSystem::TwitterInfoPlugin > m_twitterInfoPlugin;
// for settings access
friend class TwitterConfigWidget;
QPixmap m_onlinePixmap;
QPixmap m_offlinePixmap;
};
};
};
#endif

View File

@@ -1,298 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 "database/DatabaseImpl.h"
#include "Source.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 ) :
AccountConfigWidget( parent ),
m_ui( new Ui::TwitterConfigWidget ),
m_account( account )
{
m_ui->setupUi( this );
connect( m_ui->twitterAuthenticateButton, SIGNAL( pressed() ),
this, SLOT( authDeauthTwitter() ) );
connect( m_ui->twitterTweetGotTomahawkButton, SIGNAL( pressed() ),
this, SLOT( startPostGotTomahawkStatus() ) );
connect( m_ui->twitterTweetComboBox, SIGNAL( currentIndexChanged( int ) ),
this, SLOT( tweetComboBoxIndexChanged( int ) ) );
m_ui->twitterTweetComboBox->setCurrentIndex( 0 );
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
QVariantHash credentials = m_account->credentials();
if ( credentials[ "oauthtoken" ].toString().isEmpty() ||
credentials[ "oauthtokensecret" ].toString().isEmpty() ||
credentials[ "username" ].toString().isEmpty() )
{
m_ui->twitterStatusLabel->setText( tr( "Status: No saved credentials" ) );
m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
m_ui->twitterSyncGroupBox->setVisible( false );
emit twitterAuthed( false );
}
else
{
m_ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( m_account->credentials()[ "username" ].toString() ) );
m_ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
//m_ui->twitterSyncGroupBox->setVisible( true );
m_ui->twitterUserTweetLineEdit->setVisible( false );
emit twitterAuthed( true );
}
m_ui->twitterSyncGroupBox->hide();
}
TwitterConfigWidget::~TwitterConfigWidget()
{
delete m_ui;
}
void
TwitterConfigWidget::authDeauthTwitter()
{
if ( m_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 );
m_ui->twitterStatusLabel->setText( tr( "Status: Credentials saved for %1" ).arg( user.screenName() ) );
m_ui->twitterAuthenticateButton->setText( tr( "De-authenticate" ) );
//m_ui->twitterSyncGroupBox->setVisible( true );
m_ui->twitterTweetComboBox->setCurrentIndex( 0 );
m_ui->twitterUserTweetLineEdit->setVisible( false );
m_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;
m_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 );
m_ui->twitterStatusLabel->setText(tr("Status: No saved credentials"));
m_ui->twitterAuthenticateButton->setText( tr( "Authenticate" ) );
m_ui->twitterSyncGroupBox->setVisible( false );
emit twitterAuthed( false );
emit sizeHintChanged();
}
void
TwitterConfigWidget::tweetComboBoxIndexChanged( int index )
{
Q_UNUSED( index );
if ( m_ui->twitterTweetComboBox->currentText() == tr( "Global Tweet" ) ) //FIXME: use data!
m_ui->twitterUserTweetLineEdit->setVisible( false );
else
m_ui->twitterUserTweetLineEdit->setVisible( true );
if ( m_ui->twitterTweetComboBox->currentText() == tr( "Direct Message" ) ) //FIXME: use data!
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Send Message!" ) );
else if ( m_ui->twitterTweetComboBox->currentText() == tr( "@Mention" ) )
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Send Mention!" ) );
else
m_ui->twitterTweetGotTomahawkButton->setText( tr( "Tweet!" ) );
}
void
TwitterConfigWidget::startPostGotTomahawkStatus()
{
qDebug() << Q_FUNC_INFO;
m_postGTtype = m_ui->twitterTweetComboBox->currentText();
if ( m_postGTtype != "Global Tweet" && ( m_ui->twitterUserTweetLineEdit->text().isEmpty() || m_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()->impl()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
if ( m_postGTtype == "@Mention" )
{
QString user = m_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()->impl()->dbid() + QString( "} (" ) + uuid.mid( 1, 8 ) + QString( ")" ) + QString( " http://gettomahawk.com" );
QString user = m_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

@@ -1,83 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 "accounts/AccountDllMacro.h"
#include <QTweetLib/qtweetstatus.h>
#include <QTweetLib/qtweetdmstatus.h>
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetnetbase.h>
#include "accounts/AccountConfigWidget.h"
namespace Ui
{
class TwitterConfigWidget;
}
namespace Tomahawk
{
namespace Accounts
{
class TwitterAccount;
class ACCOUNTDLLEXPORT TwitterConfigWidget : public AccountConfigWidget
{
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 *m_ui;
TwitterAccount *m_account;
QString m_postGTtype;
};
}
}
#endif // TWITTERCONFIGWIDGET_H

View File

@@ -1,381 +0,0 @@
<?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>380</width>
<height>180</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>380</width>
<height>180</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-account/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 post messages to your Twitter 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

@@ -1,202 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Dominik Schmidt <domme@tomahawk-player.org>
* Copyright 2012, Jeff Mitchell <jeff@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 "TwitterInfoPlugin.h"
#include "TwitterAccount.h"
#include "GlobalActionManager.h"
#include "utils/Logger.h"
#include "Source.h"
#include <QTweetLib/qtweetaccountverifycredentials.h>
#include <QTweetLib/qtweetstatusupdate.h>
namespace Tomahawk
{
namespace InfoSystem
{
TwitterInfoPlugin::TwitterInfoPlugin( Tomahawk::Accounts::TwitterAccount* account )
: m_account( account )
{
m_supportedPushTypes << InfoShareTrack << InfoLove;
}
void
TwitterInfoPlugin::init()
{
if ( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() && thread() != Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() )
{
tDebug() << "Failure: move to the worker thread before running init";
return;
}
QVariantHash credentials = m_account->credentials();
if ( credentials[ "oauthtoken" ].toString().isEmpty() || credentials[ "oauthtokensecret" ].toString().isEmpty() )
{
tDebug() << "TwitterInfoPlugin has empty Twitter credentials; not connecting";
return;
}
if ( refreshTwitterAuth() )
{
QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
connect( credVerifier, SIGNAL( parsedUser( const QTweetUser & ) ), SLOT( connectAuthVerifyReply( const QTweetUser & ) ) );
credVerifier->verify();
}
}
TwitterInfoPlugin::~TwitterInfoPlugin()
{
tDebug() << Q_FUNC_INFO;
}
bool
TwitterInfoPlugin::refreshTwitterAuth()
{
tDebug() << Q_FUNC_INFO << "begin" << this;
if ( !m_twitterAuth.isNull() )
delete m_twitterAuth.data();
Q_ASSERT( TomahawkUtils::nam() != 0 );
tDebug() << Q_FUNC_INFO << "with nam" << TomahawkUtils::nam() << this;
m_twitterAuth = QPointer< TomahawkOAuthTwitter >( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
if ( m_twitterAuth.isNull() )
return false;
m_twitterAuth.data()->setOAuthToken( m_account->credentials()[ "oauthtoken" ].toString().toLatin1() );
m_twitterAuth.data()->setOAuthTokenSecret( m_account->credentials()[ "oauthtokensecret" ].toString().toLatin1() );
return true;
}
void
TwitterInfoPlugin::connectAuthVerifyReply( const QTweetUser &user )
{
if ( user.id() == 0 )
{
tDebug() << "TwitterInfoPlugin could not authenticate to Twitter" << this;
deleteLater();
return;
}
else
{
tDebug() << "TwitterInfoPlugin successfully authenticated to Twitter" << this;
return;
}
}
void
TwitterInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
{
tDebug() << Q_FUNC_INFO;
if ( !isValid() )
{
tDebug() << Q_FUNC_INFO << "Plugin not valid, deleting and returning";
deleteLater();
return;
}
Tomahawk::InfoSystem::PushInfoPair pushInfoPair = pushData.infoPair;
if ( !pushInfoPair.second.canConvert< QVariantMap >() )
{
tLog() << Q_FUNC_INFO << "Failed to find QVariantMap!";
return;
}
QVariantMap map = pushInfoPair.second.toMap();
if ( !map.contains( "accountlist" ) || !map[ "accountlist" ].canConvert< QStringList >() )
{
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Cowardly failing to send out a message without an account list present";
return;
}
const QStringList accountList = map[ "accountlist" ].toStringList();
if ( !accountList.contains( "all" ) && !accountList.contains( m_account->accountId() ) )
{
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Our account not in the list, not tweeting out";
return;
}
if ( !map.contains( "message" ) && ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) )
{
tLog() << Q_FUNC_INFO << "Failed to find message or trackinfo";
return;
}
Tomahawk::InfoSystem::InfoStringHash info;
QString msg;
if ( !map.contains( "message" ) )
{
info = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
msg = tr( "Listening to \"%1\" by %2 and loving it! %3" )
.arg( info[ "title" ] )
.arg( info[ "artist" ] )
.arg( pushInfoPair.first.contains( "shorturl" ) ?
pushInfoPair.first[ "shorturl" ].toUrl().toString() :
GlobalActionManager::instance()->openLink( info[ "title" ], info[ "artist" ], info[ "album" ] ).toString() );
}
else
msg = map[ "message" ].toString();
QTweetStatusUpdate *statUpdate = new QTweetStatusUpdate( m_twitterAuth.data(), this );
connect( statUpdate, SIGNAL( postedStatus(const QTweetStatus &) ), SLOT( postLovedStatusUpdateReply(const QTweetStatus &) ) );
connect( statUpdate, SIGNAL( error(QTweetNetBase::ErrorCode, const QString&) ), SLOT( postLovedStatusUpdateError(QTweetNetBase::ErrorCode, const QString &) ) );
tDebug() << Q_FUNC_INFO << "Posting message:" << msg;
statUpdate->post( msg );
}
void
TwitterInfoPlugin::postLovedStatusUpdateReply( const QTweetStatus& status )
{
if ( status.id() == 0 )
tDebug() << Q_FUNC_INFO << "Failed to post loved status";
else
tDebug() << Q_FUNC_INFO << "Successfully posted loved status";
}
void
TwitterInfoPlugin::postLovedStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg )
{
tDebug() << Q_FUNC_INFO << "Error posting love message, error code is " << code << ", error message is " << errorMsg;
}
bool
TwitterInfoPlugin::isValid() const
{
return !m_twitterAuth.isNull();
}
}
}

View File

@@ -1,80 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Dominik Schmidt <domme@tomahawk-player.org>
* Copyright 2012, Jeff Mitchell <jeff@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 TWITTERINFOPLUGIN_H
#define TWITTERINFOPLUGIN_H
#include "infosystem/InfoSystem.h"
#include "TomahawkOAuthTwitter.h"
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetstatus.h>
#include <QTweetLib/qtweetnetbase.h>
namespace Tomahawk {
namespace Accounts {
class TwitterAccount;
}
namespace InfoSystem {
class TwitterInfoPlugin : public InfoPlugin
{
Q_OBJECT
public:
TwitterInfoPlugin( Tomahawk::Accounts::TwitterAccount* account );
virtual ~TwitterInfoPlugin();
public slots:
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
{
Q_UNUSED( criteria );
Q_UNUSED( requestData );
}
protected slots:
void init();
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
{
Q_UNUSED( requestData );
}
private slots:
void connectAuthVerifyReply( const QTweetUser &user );
void postLovedStatusUpdateReply( const QTweetStatus& status );
void postLovedStatusUpdateError( QTweetNetBase::ErrorCode code, const QString& errorMsg );
private:
bool refreshTwitterAuth();
bool isValid() const;
Tomahawk::Accounts::TwitterAccount* m_account;
QPointer< TomahawkOAuthTwitter > m_twitterAuth;
};
}
}
#endif // TWITTERINFOPLUGIN_H
struct A;

View File

@@ -1,6 +0,0 @@
<RCC>
<qresource prefix="/twitter-account">
<file>twitter-icon.png</file>
<file>twitter-offline-icon.png</file>
</qresource>
</RCC>

View File

@@ -1,723 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 "TwitterSip.h"
#include "utils/TomahawkUtils.h"
#include "TomahawkSettings.h"
#include "database/Database.h"
#include "database/DatabaseImpl.h"
#include "network/Servent.h"
#include "Source.h"
#include "utils/Logger.h"
#include "accounts/twitter/TomahawkOAuthTwitter.h"
#include "accounts/twitter/TwitterAccount.h"
#include <QTweetLib/qtweetaccountverifycredentials.h>
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetstatus.h>
#include <QTweetLib/qtweetusershow.h>
#include <QtPlugin>
#include <QDateTime>
#include <QRegExp>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QStringList>
static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" );
TwitterSipPlugin::TwitterSipPlugin( Tomahawk::Accounts::Account* account )
: SipPlugin( account )
, m_checkTimer( this )
, m_connectTimer( this )
, m_dmPollTimer( this )
, m_cachedFriendsSinceId( 0 )
, m_cachedMentionsSinceId( 0 )
, m_cachedDirectMessagesSinceId( 0 )
, m_cachedPeers()
, m_keyCache()
, m_state( Tomahawk::Accounts::Account::Disconnected )
{
qDebug() << Q_FUNC_INFO;
connect( account, SIGNAL( nowAuthenticated( const QPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ), SLOT( accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &, const QTweetUser & ) ) );
m_configuration = account->configuration();
qDebug() << "SIP configuration:" << m_configuration << m_configuration[ "cachedpeers" ];
if ( Database::instance()->impl()->dbid() != m_account->configuration()[ "saveddbid" ].toString() )
{
m_configuration[ "cachedpeers" ] = QVariantHash();
m_configuration[ "saveddbid" ] = Database::instance()->impl()->dbid();
syncConfig();
}
m_checkTimer.setInterval( 180000 );
m_checkTimer.setSingleShot( false );
connect( &m_checkTimer, SIGNAL( timeout() ), SLOT( checkTimerFired() ) );
m_dmPollTimer.setInterval( 60000 );
m_dmPollTimer.setSingleShot( false );
connect( &m_dmPollTimer, SIGNAL( timeout() ), SLOT( pollDirectMessages() ) );
m_connectTimer.setInterval( 180000 );
m_connectTimer.setSingleShot( false );
connect( &m_connectTimer, SIGNAL( timeout() ), SLOT( connectTimerFired() ) );
}
bool
TwitterSipPlugin::isValid() const
{
return m_account->enabled() && m_account->isAuthenticated() && !m_cachedTwitterAuth.isNull();
}
Tomahawk::Accounts::Account::ConnectionState
TwitterSipPlugin::connectionState() const
{
return m_state;
}
QString
TwitterSipPlugin::inviteString() const
{
return tr( "Enter Twitter username" );
}
void
TwitterSipPlugin::checkSettings()
{
configurationChanged();
}
void
TwitterSipPlugin::connectPlugin()
{
tDebug() << Q_FUNC_INFO;
if ( !m_account->enabled() )
{
tDebug() << Q_FUNC_INFO << "account isn't enabled";
return;
}
m_cachedPeers = m_configuration[ "cachedpeers" ].toHash();
QStringList peerList = m_cachedPeers.keys();
qStableSort( peerList.begin(), peerList.end() );
if ( !m_account->isAuthenticated() )
{
tDebug() << Q_FUNC_INFO << "account isn't authenticated, attempting";
m_account->authenticate();
}
m_state = Tomahawk::Accounts::Account::Connecting;
emit stateChanged( m_state );
}
void
TwitterSipPlugin::disconnectPlugin()
{
tDebug() << Q_FUNC_INFO;
m_checkTimer.stop();
m_connectTimer.stop();
m_dmPollTimer.stop();
if( !m_friendsTimeline.isNull() )
delete m_friendsTimeline.data();
if( !m_mentions.isNull() )
delete m_mentions.data();
if( !m_directMessages.isNull() )
delete m_directMessages.data();
if( !m_directMessageNew.isNull() )
delete m_directMessageNew.data();
if( !m_directMessageDestroy.isNull() )
delete m_directMessageDestroy.data();
m_cachedTwitterAuth = 0;
m_configuration[ "cachedpeers" ] = m_cachedPeers;
syncConfig();
m_cachedPeers.empty();
m_state = Tomahawk::Accounts::Account::Disconnected;
emit stateChanged( m_state );
}
void
TwitterSipPlugin::accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user )
{
Q_UNUSED( user );
if ( !m_account->enabled() || !m_account->isAuthenticated() )
return;
m_cachedTwitterAuth = twitterAuth;
m_friendsTimeline = QPointer<QTweetFriendsTimeline>( new QTweetFriendsTimeline( m_cachedTwitterAuth.data(), this ) );
m_mentions = QPointer<QTweetMentions>( new QTweetMentions( m_cachedTwitterAuth.data(), this ) );
m_directMessages = QPointer<QTweetDirectMessages>( new QTweetDirectMessages( m_cachedTwitterAuth.data(), this ) );
m_directMessageNew = QPointer<QTweetDirectMessageNew>( new QTweetDirectMessageNew( m_cachedTwitterAuth.data(), this ) );
m_directMessageDestroy = QPointer<QTweetDirectMessageDestroy>( new QTweetDirectMessageDestroy( m_cachedTwitterAuth.data(), this ) );
connect( m_friendsTimeline.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( friendsTimelineStatuses(const QList<QTweetStatus> &) ) );
connect( m_mentions.data(), SIGNAL( parsedStatuses(const QList< QTweetStatus > &) ), SLOT( mentionsStatuses(const QList<QTweetStatus> &) ) );
connect( m_directMessages.data(), SIGNAL( parsedDirectMessages(const QList<QTweetDMStatus> &)), SLOT( directMessages(const QList<QTweetDMStatus> &) ) );
connect( m_directMessageNew.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &)), SLOT( directMessagePosted(const QTweetDMStatus &) ) );
connect( m_directMessageNew.data(), SIGNAL( error(QTweetNetBase::ErrorCode, const QString &) ), SLOT( directMessagePostError(QTweetNetBase::ErrorCode, const QString &) ) );
connect( m_directMessageDestroy.data(), SIGNAL( parsedDirectMessage(const QTweetDMStatus &) ), SLOT( directMessageDestroyed(const QTweetDMStatus &) ) );
m_state = Tomahawk::Accounts::Account::Connected;
emit stateChanged( m_state );
QStringList peerList = m_cachedPeers.keys();
qStableSort( peerList.begin(), peerList.end() );
registerOffers( peerList );
m_connectTimer.start();
m_checkTimer.start();
m_dmPollTimer.start();
QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection );
QTimer::singleShot( 20000, this, SLOT( connectTimerFired() ) );
}
void
TwitterSipPlugin::checkTimerFired()
{
if ( !isValid() )
return;
if ( m_cachedFriendsSinceId == 0 )
m_cachedFriendsSinceId = m_configuration[ "cachedfriendssinceid" ].toLongLong();
qDebug() << "TwitterSipPlugin looking at friends timeline since id " << m_cachedFriendsSinceId;
if ( !m_friendsTimeline.isNull() )
m_friendsTimeline.data()->fetch( m_cachedFriendsSinceId, 0, 800 );
if ( m_cachedMentionsSinceId == 0 )
m_cachedMentionsSinceId = m_configuration[ "cachedmentionssinceid" ].toLongLong();
qDebug() << "TwitterSipPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId;
if ( !m_mentions.isNull() )
m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 );
}
void
TwitterSipPlugin::registerOffers( const QStringList &peerList )
{
if ( !isValid() )
return;
foreach( QString screenName, peerList )
{
QVariantHash peerData = m_cachedPeers[screenName].toHash();
if ( peerData.contains( "onod" ) && peerData["onod"] != Database::instance()->impl()->dbid() )
{
m_cachedPeers.remove( screenName );
m_configuration[ "cachedpeers" ] = m_cachedPeers;
syncConfig();
}
if ( Servent::instance()->connectedToSession( peerData["node"].toString() ) )
{
peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch();
m_cachedPeers[screenName] = peerData;
m_configuration[ "cachedpeers" ] = m_cachedPeers;
syncConfig();
qDebug() << Q_FUNC_INFO << " already connected";
continue;
}
else if ( QDateTime::currentMSecsSinceEpoch() - peerData["lastseen"].toLongLong() > 1209600000 ) // 2 weeks
{
qDebug() << Q_FUNC_INFO << " aging peer " << screenName << " out of cache";
m_cachedPeers.remove( screenName );
m_configuration[ "cachedpeers" ] = m_cachedPeers;
syncConfig();
m_cachedAvatars.remove( screenName );
continue;
}
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) )
{
qDebug() << "TwitterSipPlugin does not have host, port and/or pkey values for " << screenName << " (this is usually *not* a bug or problem but a normal part of the process)";
continue;
}
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, peerData ) );
}
}
void
TwitterSipPlugin::connectTimerFired()
{
tDebug() << Q_FUNC_INFO << " beginning";
if ( !isValid() || m_cachedPeers.isEmpty() )
{
if ( !isValid() )
tDebug() << Q_FUNC_INFO << " is not valid";
if ( m_cachedPeers.isEmpty() )
tDebug() << Q_FUNC_INFO << " has empty cached peers";
return;
}
tDebug() << Q_FUNC_INFO << " continuing";
QString myScreenName = m_configuration[ "screenname" ].toString();
QStringList peerList = m_cachedPeers.keys();
qStableSort( peerList.begin(), peerList.end() );
registerOffers( peerList );
}
void
TwitterSipPlugin::parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text )
{
QString myScreenName = m_configuration[ "screenname" ].toString();
qDebug() << "TwitterSipPlugin found an exact matching Got Tomahawk? mention or direct message from user " << screenName << ", now parsing";
regex.exactMatch( text );
if ( text.startsWith( '@' ) && regex.captureCount() >= 2 && regex.cap( 1 ) != QString( '@' + myScreenName ) )
{
qDebug() << "TwitterSipPlugin skipping mention because it's directed @someone that isn't us";
return;
}
QString node;
for ( int i = 0; i < regex.captureCount(); ++i )
{
if ( regex.cap( i ) == QString( "Got Tomahawk?" ) )
{
QString nodeCap = regex.cap( i + 1 );
nodeCap.chop( 1 );
node = nodeCap.mid( 1 );
}
}
if ( node.isEmpty() )
{
qDebug() << "TwitterSipPlugin could not parse node out of the tweet";
return;
}
else
qDebug() << "TwitterSipPlugin parsed node " << node << " out of the tweet";
if ( node == Database::instance()->impl()->dbid() )
{
qDebug() << "My dbid found; ignoring";
return;
}
QVariantHash peerData;
if( m_cachedPeers.contains( screenName ) )
{
peerData = m_cachedPeers[screenName].toHash();
//force a re-send of info but no need to re-register
peerData["resend"] = QVariant::fromValue< bool >( true );
if ( peerData["node"].toString() != node )
peerData["rekey"] = QVariant::fromValue< bool >( true );
}
peerData["node"] = QVariant::fromValue< QString >( node );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, peerData ) );
}
void
TwitterSipPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
{
tDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
{
if ( status.id() > latestHash[status.user().screenName()].id() )
latestHash[status.user().screenName()] = status;
}
}
foreach( QTweetStatus status, latestHash.values() )
{
if ( status.id() > m_cachedFriendsSinceId )
m_cachedFriendsSinceId = status.id();
tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
m_configuration[ "cachedfriendssinceid" ] = m_cachedFriendsSinceId;
syncConfig();
}
void
TwitterSipPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
{
tDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QHash< QString, QTweetStatus > latestHash;
foreach ( QTweetStatus status, statuses )
{
if ( !regex.exactMatch( status.text() ) )
continue;
if ( !latestHash.contains( status.user().screenName() ) )
latestHash[status.user().screenName()] = status;
else
{
if ( status.id() > latestHash[status.user().screenName()].id() )
latestHash[status.user().screenName()] = status;
}
}
foreach( QTweetStatus status, latestHash.values() )
{
if ( status.id() > m_cachedMentionsSinceId )
m_cachedMentionsSinceId = status.id();
tDebug() << "TwitterSipPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
parseGotTomahawk( regex, status.user().screenName(), status.text() );
}
m_configuration[ "cachedmentionssinceid" ] = m_cachedMentionsSinceId;
syncConfig();
}
void
TwitterSipPlugin::pollDirectMessages()
{
if ( !isValid() )
return;
if ( m_cachedDirectMessagesSinceId == 0 )
m_cachedDirectMessagesSinceId = m_configuration[ "cacheddirectmessagessinceid" ].toLongLong();
tDebug() << "TwitterSipPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId;
if ( !m_directMessages.isNull() )
m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 );
}
void
TwitterSipPlugin::directMessages( const QList< QTweetDMStatus > &messages )
{
tDebug() << Q_FUNC_INFO;
QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
QString myScreenName = m_configuration[ "screenname" ].toString();
QHash< QString, QTweetDMStatus > latestHash;
foreach ( QTweetDMStatus status, messages )
{
if ( !regex.exactMatch( status.text() ) )
{
QStringList splitList = status.text().split(':');
if ( splitList.length() != 5 )
continue;
if ( splitList[0] != "TOMAHAWKPEER" )
continue;
if ( !splitList[1].startsWith( "Host=" ) || !splitList[2].startsWith( "Port=" ) || !splitList[3].startsWith( "Node=" ) || !splitList[4].startsWith( "PKey=" ) )
continue;
int port = splitList[2].mid( 5 ).toInt();
if ( port == 0 )
continue;
}
if ( !latestHash.contains( status.senderScreenName() ) )
latestHash[status.senderScreenName()] = status;
else
{
if ( status.id() > latestHash[status.senderScreenName()].id() )
latestHash[status.senderScreenName()] = status;
}
}
foreach( QTweetDMStatus status, latestHash.values() )
{
qDebug() << "TwitterSipPlugin checking direct message from " << status.senderScreenName() << " with content " << status.text();
if ( status.id() > m_cachedDirectMessagesSinceId )
m_cachedDirectMessagesSinceId = status.id();
if ( regex.exactMatch( status.text() ) )
parseGotTomahawk( regex, status.sender().screenName(), status.text() );
else
{
QStringList splitList = status.text().split(':');
qDebug() << "TwitterSipPlugin found " << splitList.length() << " parts to the message; the parts are:";
foreach( QString part, splitList )
qDebug() << part;
//validity is checked above
int port = splitList[2].mid( 5 ).toInt();
QString host = splitList[1].mid( 5 );
QString node = splitList[3].mid( 5 );
QString pkey = splitList[4].mid( 5 );
QStringList splitNode = node.split('*');
if ( splitNode.length() != 2 )
{
qDebug() << "Old-style node info found, ignoring";
continue;
}
qDebug() << "TwitterSipPlugin found a peerstart message from " << status.senderScreenName() << " with host " << host << " and port " << port << " and pkey " << pkey << " and node " << splitNode[0] << " destined for node " << splitNode[1];
QVariantHash peerData = ( m_cachedPeers.contains( status.senderScreenName() ) ) ?
m_cachedPeers[status.senderScreenName()].toHash() :
QVariantHash();
peerData["host"] = QVariant::fromValue< QString >( host );
peerData["port"] = QVariant::fromValue< int >( port );
peerData["pkey"] = QVariant::fromValue< QString >( pkey );
peerData["node"] = QVariant::fromValue< QString >( splitNode[0] );
peerData["dirty"] = QVariant::fromValue< bool >( true );
QMetaObject::invokeMethod( this, "registerOffer", Q_ARG( QString, status.senderScreenName() ), Q_ARG( QVariantHash, peerData ) );
if ( Database::instance()->impl()->dbid().startsWith( splitNode[1] ) )
{
qDebug() << "TwitterSipPlugin found message destined for this node; destroying it";
if ( !m_directMessageDestroy.isNull() )
m_directMessageDestroy.data()->destroyMessage( status.id() );
}
}
}
m_configuration[ "cacheddirectmessagessinceid" ] = m_cachedDirectMessagesSinceId;
syncConfig();
}
void
TwitterSipPlugin::registerOffer( const QString &screenName, const QVariantHash &peerData )
{
qDebug() << Q_FUNC_INFO;
bool peersChanged = false;
bool needToSend = false;
bool needToAddToCache = false;
QString friendlyName = QString( '@' + screenName );
if ( !m_cachedAvatars.contains( screenName ) )
QMetaObject::invokeMethod( this, "fetchAvatar", Q_ARG( QString, screenName ) );
QVariantHash _peerData( peerData );
if ( _peerData.contains( "dirty" ) )
{
peersChanged = true;
_peerData.remove( "dirty" );
}
if ( _peerData.contains( "resend" ) )
{
needToSend = true;
peersChanged = true;
_peerData.remove( "resend" );
}
if ( !_peerData.contains( "okey" ) ||
!_peerData.contains( "onod" ) ||
( _peerData.contains( "onod" ) && _peerData["onod"] != Database::instance()->impl()->dbid() ) )
{
QString okey = QUuid::createUuid().toString().split( '-' ).last();
okey.chop( 1 );
_peerData["okey"] = QVariant::fromValue< QString >( okey );
_peerData["onod"] = QVariant::fromValue< QString >( Database::instance()->impl()->dbid() );
peersChanged = true;
needToAddToCache = true;
needToSend = true;
}
if ( _peerData.contains( "rekey" ) || !m_keyCache.contains( _peerData["okey"].toString() ) )
{
_peerData.remove( "rekey" );
needToAddToCache = true;
}
if ( !_peerData.contains( "ohst" ) || !_peerData.contains( "oprt" ) ||
_peerData["ohst"].toString() != Servent::instance()->externalAddress() ||
_peerData["oprt"].toInt() != Servent::instance()->externalPort()
)
needToSend = true;
if( needToAddToCache && _peerData.contains( "node" ) )
{
qDebug() << "TwitterSipPlugin registering offer to " << friendlyName << " with node " << _peerData["node"].toString() << " and offeredkey " << _peerData["okey"].toString();
m_keyCache << Servent::instance()->createConnectionKey( friendlyName, _peerData["node"].toString(), _peerData["okey"].toString(), false );
}
if( needToSend && _peerData.contains( "node") )
{
qDebug() << "TwitterSipPlugin needs to send and has node";
_peerData["ohst"] = QVariant::fromValue< QString >( Servent::instance()->externalAddress() );
_peerData["oprt"] = QVariant::fromValue< int >( Servent::instance()->externalPort() );
peersChanged = true;
if( !Servent::instance()->externalAddress().isEmpty() && !Servent::instance()->externalPort() == 0 )
QMetaObject::invokeMethod( this, "sendOffer", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, _peerData ) );
else
qDebug() << "TwitterSipPlugin did not send offer because external address is " << Servent::instance()->externalAddress() << " and external port is " << Servent::instance()->externalPort();
}
if ( peersChanged )
{
_peerData["lastseen"] = QString::number( QDateTime::currentMSecsSinceEpoch() );
m_cachedPeers[screenName] = QVariant::fromValue< QVariantHash >( _peerData );
m_configuration[ "cachedpeers" ] = m_cachedPeers;
syncConfig();
}
if ( m_state == Tomahawk::Accounts::Account::Connected && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, _peerData ) );
}
void
TwitterSipPlugin::sendOffer( const QString &screenName, const QVariantHash &peerData )
{
qDebug() << Q_FUNC_INFO;
QString offerString = QString( "TOMAHAWKPEER:Host=%1:Port=%2:Node=%3*%4:PKey=%5" ).arg( peerData["ohst"].toString() )
.arg( peerData["oprt"].toString() )
.arg( Database::instance()->impl()->dbid() )
.arg( peerData["node"].toString().left( 8 ) )
.arg( peerData["okey"].toString() );
qDebug() << "TwitterSipPlugin sending message to " << screenName << ": " << offerString;
if( !m_directMessageNew.isNull() )
m_directMessageNew.data()->post( screenName, offerString );
}
void
TwitterSipPlugin::makeConnection( const QString &screenName, const QVariantHash &peerData )
{
qDebug() << Q_FUNC_INFO;
if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) || !peerData.contains( "node" ) ||
peerData["host"].toString().isEmpty() || peerData["port"].toString().isEmpty() || peerData["pkey"].toString().isEmpty() || peerData["node"].toString().isEmpty() )
{
qDebug() << "TwitterSipPlugin could not find host and/or port and/or pkey and/or node for peer " << screenName;
return;
}
if ( peerData["host"].toString() == Servent::instance()->externalAddress() &&
peerData["port"].toInt() == Servent::instance()->externalPort() )
{
qDebug() << "TwitterSipPlugin asked to make connection to our own host and port, ignoring " << screenName;
return;
}
QString friendlyName = QString( '@' + screenName );
if ( !Servent::instance()->connectedToSession( peerData["node"].toString() ) )
Servent::instance()->connectToPeer( peerData["host"].toString(),
peerData["port"].toString().toInt(),
peerData["pkey"].toString(),
friendlyName,
peerData["node"].toString() );
}
void
TwitterSipPlugin::directMessagePosted( const QTweetDMStatus& message )
{
qDebug() << Q_FUNC_INFO;
qDebug() << "TwitterSipPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text();
}
void
TwitterSipPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message )
{
Q_UNUSED( errorCode );
Q_UNUSED( message );
qDebug() << Q_FUNC_INFO;
qDebug() << "TwitterSipPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage();
}
void
TwitterSipPlugin::directMessageDestroyed( const QTweetDMStatus& message )
{
qDebug() << Q_FUNC_INFO;
qDebug() << "TwitterSipPlugin destroyed message " << message.text();
}
void
TwitterSipPlugin::fetchAvatar( const QString& screenName )
{
qDebug() << Q_FUNC_INFO;
if ( !isValid() )
return;
QTweetUserShow *userShowFetch = new QTweetUserShow( m_cachedTwitterAuth.data(), this );
connect( userShowFetch, SIGNAL( parsedUserInfo( QTweetUser ) ), SLOT( avatarUserDataSlot( QTweetUser ) ) );
userShowFetch->fetch( screenName );
}
void
TwitterSipPlugin::avatarUserDataSlot( const QTweetUser &user )
{
tDebug() << Q_FUNC_INFO;
if ( !isValid() || user.profileImageUrl().isEmpty())
return;
QNetworkRequest request( user.profileImageUrl() );
QNetworkReply *reply = m_cachedTwitterAuth.data()->networkAccessManager()->get( request );
reply->setProperty( "screenname", user.screenName() );
connect( reply, SIGNAL( finished() ), this, SLOT( profilePicReply() ) );
}
void
TwitterSipPlugin::profilePicReply()
{
tDebug() << Q_FUNC_INFO;
QNetworkReply *reply = qobject_cast< QNetworkReply* >( sender() );
if ( !reply || reply->error() != QNetworkReply::NoError || !reply->property( "screenname" ).isValid() )
{
tDebug() << Q_FUNC_INFO << " reply not valid or came back with error";
return;
}
QString screenName = reply->property( "screenname" ).toString();
QString friendlyName = '@' + screenName;
QByteArray rawData = reply->readAll();
QImage image;
image.loadFromData( rawData, "PNG" );
QPixmap pixmap = QPixmap::fromImage( image );
m_cachedAvatars[screenName] = pixmap;
emit avatarReceived( friendlyName, QPixmap::fromImage( image ) );
}
void
TwitterSipPlugin::configurationChanged()
{
tDebug() << Q_FUNC_INFO;
if ( m_state != Tomahawk::Accounts::Account::Disconnected )
m_account->deauthenticate();
connectPlugin();
}
void
TwitterSipPlugin::syncConfig()
{
m_account->setConfiguration( m_configuration );
m_account->sync();
}

View File

@@ -1,132 +0,0 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@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 TWITTER_H
#define TWITTER_H
#include "accounts/AccountDllMacro.h"
#include "sip/SipPlugin.h"
#include "accounts/Account.h"
#include "accounts/twitter/TomahawkOAuthTwitter.h"
#include <QTweetLib/qtweetuser.h>
#include <QTweetLib/qtweetnetbase.h>
#include <QTweetLib/qtweetfriendstimeline.h>
#include <QTweetLib/qtweetdirectmessages.h>
#include <QTweetLib/qtweetdirectmessagenew.h>
#include <QTweetLib/qtweetdirectmessagedestroy.h>
#include <QTweetLib/qtweetmentions.h>
#include <QTweetLib/qtweetdmstatus.h>
#include <QTimer>
#include <QPointer>
#include <QSet>
class ACCOUNTDLLEXPORT TwitterSipPlugin : public SipPlugin
{
Q_OBJECT
public:
TwitterSipPlugin( Tomahawk::Accounts::Account *account );
virtual ~TwitterSipPlugin() {}
virtual bool isValid() const;
virtual Tomahawk::Accounts::Account::ConnectionState connectionState() const;
virtual QString inviteString() const;
signals:
void stateChanged( Tomahawk::Accounts::Account::ConnectionState );
public slots:
virtual void connectPlugin();
void disconnectPlugin();
void configurationChanged();
void sendMsg( const QString& peerId, const SipInfo& info )
{
Q_UNUSED( peerId );
Q_UNUSED( info );
}
void broadcastMsg( const QString &msg )
{
Q_UNUSED( msg );
}
bool addContact( const QString &peerId, AddContactOptions options, const QString& msg = QString() )
{
Q_UNUSED( peerId );
Q_UNUSED( msg );
Q_UNUSED( options );
return false;
}
void checkSettings();
private slots:
void accountAuthenticated( const QPointer< TomahawkOAuthTwitter > &twitterAuth, const QTweetUser &user );
void checkTimerFired();
void connectTimerFired();
void friendsTimelineStatuses( const QList< QTweetStatus > &statuses );
void mentionsStatuses( const QList< QTweetStatus > &statuses );
void pollDirectMessages();
void directMessages( const QList< QTweetDMStatus > &messages );
void directMessagePosted( const QTweetDMStatus &message );
void directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message );
void directMessageDestroyed( const QTweetDMStatus &message );
void registerOffers( const QStringList &peerList );
void registerOffer( const QString &screenName, const QVariantHash &peerdata );
void sendOffer( const QString &screenName, const QVariantHash &peerdata );
void makeConnection( const QString &screenName, const QVariantHash &peerdata );
void fetchAvatar( const QString &screenName );
void avatarUserDataSlot( const QTweetUser &user );
void profilePicReply();
private:
void syncConfig();
bool refreshTwitterAuth();
void parseGotTomahawk( const QRegExp &regex, const QString &screenName, const QString &text );
QPointer< TomahawkOAuthTwitter > m_cachedTwitterAuth;
QPointer< QTweetFriendsTimeline > m_friendsTimeline;
QPointer< QTweetMentions > m_mentions;
QPointer< QTweetDirectMessages > m_directMessages;
QPointer< QTweetDirectMessageNew > m_directMessageNew;
QPointer< QTweetDirectMessageDestroy > m_directMessageDestroy;
QVariantHash m_configuration;
QTimer m_checkTimer;
QTimer m_connectTimer;
QTimer m_dmPollTimer;
qint64 m_cachedFriendsSinceId;
qint64 m_cachedMentionsSinceId;
qint64 m_cachedDirectMessagesSinceId;
QVariantHash m_cachedPeers;
QHash< QString, QPixmap > m_cachedAvatars;
QSet<QString> m_keyCache;
Tomahawk::Accounts::Account::ConnectionState m_state;
};
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -72,4 +72,4 @@ private:
}
#endif // TWITTERCONFIGWIDGET_H
#endif // JABBERACCOUNTCONFIGWIDGET_H

View File

@@ -420,10 +420,8 @@ AccountDelegate::drawAccountList( QPainter* painter, QStyleOptionViewItemV4& opt
for ( int i = 0; i < accts.size(); i++ )
{
//FIXME: special case for twitter, remove for 0.8.0
if ( accts.at( i )->accountServiceName() != "Twitter" )
// draw lightbulb and text
runningRightEdge = drawStatus( painter, QPointF( rightEdge - PADDING, current), accts.at( i ) );
runningRightEdge = drawStatus( painter, QPointF( rightEdge - PADDING, current), accts.at( i ) );
const QString label = accts.at( i )->accountFriendlyName();
const QPoint textTopLeft( runningRightEdge - PADDING - painter->fontMetrics().width( label ), current);

View File

@@ -49,8 +49,6 @@ AccountModelFactoryProxy::filterAcceptsRow( int sourceRow, const QModelIndex& so
return false;
Tomahawk::Accounts::AccountFactory* factory = qobject_cast< Tomahawk::Accounts::AccountFactory* >( idx.data( Tomahawk::Accounts::AccountModel::AccountData ).value< QObject* >() );
if ( factory && factory->factoryId() == "twitteraccount" )
return false;
}
return rowType == m_filterRowType;

View File

@@ -175,11 +175,6 @@ AccountWidget::update( const QPersistentModelIndex& idx, int accountIdx )
qobject_cast< Tomahawk::Accounts::AccountFactory* >(
idx.data( Tomahawk::Accounts::AccountModel::AccountData )
.value< QObject* >() );
if ( fac->factoryId() == "twitteraccount" )
{
m_inviteContainer->setVisible( false );
m_inviteButton->setVisible( false );
}
switch ( account->connectionState() )
{