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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,7 +12,6 @@ Makefile*
|
||||
moc_*
|
||||
*~
|
||||
/tomahawk
|
||||
thirdparty/qtweetlib/WARNING-twitter-api-keys
|
||||
.kdev4
|
||||
*.kdev4
|
||||
*.kate-swp
|
||||
|
@@ -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")
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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',
|
||||
|
@@ -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()
|
||||
|
@@ -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}
|
||||
)
|
||||
|
@@ -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() );
|
||||
}
|
@@ -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
|
@@ -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 )
|
@@ -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
|
@@ -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!") );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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
|
@@ -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>
|
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
@@ -1,6 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/twitter-account">
|
||||
<file>twitter-icon.png</file>
|
||||
<file>twitter-offline-icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@@ -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 ®ex, 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();
|
||||
}
|
@@ -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 ®ex, 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 |
@@ -72,4 +72,4 @@ private:
|
||||
|
||||
}
|
||||
|
||||
#endif // TWITTERCONFIGWIDGET_H
|
||||
#endif // JABBERACCOUNTCONFIGWIDGET_H
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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() )
|
||||
{
|
||||
|
Reference in New Issue
Block a user