/src/sip/twitter/twitter.cpp
http://github.com/tomahawk-player/tomahawk · C++ · 1071 lines · 885 code · 167 blank · 19 comment · 149 complexity · 17d704719ce50f7dea2cda5d9f2fb07f MD5 · raw file
- /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
- *
- * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
- *
- * Tomahawk is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Tomahawk is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "twitter.h"
- #include "twitterconfigwidget.h"
- #include <QtPlugin>
- #include <QDateTime>
- #include <QRegExp>
- #include <QNetworkAccessManager>
- #include <QNetworkRequest>
- #include <QNetworkReply>
- #include <QStringList>
- #include <QTweetLib/qtweetaccountverifycredentials.h>
- #include <QTweetLib/qtweetuser.h>
- #include <QTweetLib/qtweetstatus.h>
- #include <QTweetLib/qtweetusershow.h>
- #include <utils/tomahawkutils.h>
- #include <tomahawksettings.h>
- #include <database/database.h>
- #include <network/servent.h>
- #include "utils/logger.h"
- static QString s_gotTomahawkRegex = QString( "^(@[a-zA-Z0-9]+ )?(Got Tomahawk\\?) (\\{[a-fA-F0-9\\-]+\\}) (.*)$" );
- SipPlugin*
- TwitterFactory::createPlugin( const QString& pluginId )
- {
- return new TwitterPlugin( pluginId.isEmpty() ? generateId() : pluginId );
- }
- QIcon TwitterFactory::icon() const
- {
- return QIcon( ":/twitter-icon.png" );
- }
- TwitterPlugin::TwitterPlugin( const QString& pluginId )
- : SipPlugin( pluginId )
- , m_isAuthed( false )
- , m_checkTimer( this )
- , m_connectTimer( this )
- , m_dmPollTimer( this )
- , m_cachedFriendsSinceId( 0 )
- , m_cachedMentionsSinceId( 0 )
- , m_cachedDirectMessagesSinceId( 0 )
- , m_cachedPeers()
- , m_keyCache()
- , m_state( Disconnected )
- {
- qDebug() << Q_FUNC_INFO;
- if ( Database::instance()->dbid() != twitterSavedDbid() )
- setTwitterCachedPeers( QVariantHash() );
- setTwitterSavedDbid( Database::instance()->dbid() );
- 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() ) );
- m_configWidget = QWeakPointer< TwitterConfigWidget >( new TwitterConfigWidget( this, 0 ) );
- connect( m_configWidget.data(), SIGNAL( twitterAuthed( bool ) ), SLOT( configDialogAuthedSignalSlot( bool ) ) );
- }
- void
- TwitterPlugin::configDialogAuthedSignalSlot( bool authed )
- {
- if ( !authed )
- {
- if( m_isAuthed ) {
- m_state = Disconnected;
- emit stateChanged( m_state );
- }
- setTwitterScreenName( QString() );
- setTwitterOAuthToken( QString() );
- setTwitterOAuthTokenSecret( QString() );
- }
- m_isAuthed = authed;
- }
- bool
- TwitterPlugin::isValid() const
- {
- return m_isAuthed;
- }
- const QString
- TwitterPlugin::name() const
- {
- return QString( MYNAME );
- }
- const QString
- TwitterPlugin::friendlyName() const
- {
- return tr("Twitter");
- }
- const QString
- TwitterPlugin::accountName() const
- {
- if( twitterScreenName().isEmpty() )
- return friendlyName();
- else
- return twitterScreenName();
- }
- QIcon
- TwitterPlugin::icon() const
- {
- return QIcon( ":/twitter-icon.png" );
- }
- SipPlugin::ConnectionState
- TwitterPlugin::connectionState() const
- {
- return m_state;
- }
- QWidget* TwitterPlugin::configWidget()
- {
- return m_configWidget.data();
- }
- bool
- TwitterPlugin::connectPlugin( bool startup )
- {
- Q_UNUSED( startup );
- qDebug() << Q_FUNC_INFO;
- m_cachedPeers = twitterCachedPeers();
- QStringList peerList = m_cachedPeers.keys();
- qStableSort( peerList.begin(), peerList.end() );
- registerOffers( peerList );
- if ( twitterOAuthToken().isEmpty() || twitterOAuthTokenSecret().isEmpty() )
- {
- qDebug() << "TwitterPlugin has empty Twitter credentials; not connecting";
- return m_cachedPeers.isEmpty();
- }
- if ( refreshTwitterAuth() )
- {
- QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
- connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
- credVerifier->verify();
- m_state = Connecting;
- emit stateChanged( m_state );
- }
- return true;
- }
- bool
- TwitterPlugin::refreshTwitterAuth()
- {
- qDebug() << Q_FUNC_INFO << " begin";
- if( !m_twitterAuth.isNull() )
- delete m_twitterAuth.data();
- Q_ASSERT( TomahawkUtils::nam() != 0 );
- qDebug() << Q_FUNC_INFO << " with nam " << TomahawkUtils::nam();
- m_twitterAuth = QWeakPointer<TomahawkOAuthTwitter>( new TomahawkOAuthTwitter( TomahawkUtils::nam(), this ) );
- if( m_twitterAuth.isNull() )
- return false;
- m_twitterAuth.data()->setOAuthToken( twitterOAuthToken().toLatin1() );
- m_twitterAuth.data()->setOAuthTokenSecret( twitterOAuthTokenSecret().toLatin1() );
- return true;
- }
- void
- TwitterPlugin::disconnectPlugin()
- {
- qDebug() << 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();
- if( !m_twitterAuth.isNull() )
- delete m_twitterAuth.data();
- syncConfig();
- m_cachedPeers.empty();
- m_state = Disconnected;
- emit stateChanged( m_state );
- }
- void
- TwitterPlugin::connectAuthVerifyReply( const QTweetUser &user )
- {
- if ( user.id() == 0 )
- {
- qDebug() << "TwitterPlugin could not authenticate to Twitter";
- m_isAuthed = false;
- m_state = Disconnected;
- m_connectTimer.stop();
- m_checkTimer.stop();
- m_dmPollTimer.stop();
- emit stateChanged( m_state );
- }
- else
- {
- qDebug() << "TwitterPlugin successfully authenticated to Twitter as user " << user.screenName();
- m_isAuthed = true;
- if ( !m_twitterAuth.isNull() )
- {
- setTwitterScreenName( user.screenName() );
- m_friendsTimeline = QWeakPointer<QTweetFriendsTimeline>( new QTweetFriendsTimeline( m_twitterAuth.data(), this ) );
- m_mentions = QWeakPointer<QTweetMentions>( new QTweetMentions( m_twitterAuth.data(), this ) );
- m_directMessages = QWeakPointer<QTweetDirectMessages>( new QTweetDirectMessages( m_twitterAuth.data(), this ) );
- m_directMessageNew = QWeakPointer<QTweetDirectMessageNew>( new QTweetDirectMessageNew( m_twitterAuth.data(), this ) );
- m_directMessageDestroy = QWeakPointer<QTweetDirectMessageDestroy>( new QTweetDirectMessageDestroy( m_twitterAuth.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 = Connected;
- emit stateChanged( m_state );
- m_connectTimer.start();
- m_checkTimer.start();
- m_dmPollTimer.start();
- QMetaObject::invokeMethod( this, "checkTimerFired", Qt::AutoConnection );
- QTimer::singleShot( 20000, this, SLOT( connectTimerFired() ) );
- }
- else
- {
- if ( refreshTwitterAuth() )
- {
- QTweetAccountVerifyCredentials *credVerifier = new QTweetAccountVerifyCredentials( m_twitterAuth.data(), this );
- connect( credVerifier, SIGNAL( parsedUser(const QTweetUser &) ), SLOT( connectAuthVerifyReply(const QTweetUser &) ) );
- credVerifier->verify();
- }
- else
- {
- qDebug() << "TwitterPlugin auth pointer was null!";
- m_isAuthed = false;
- m_state = Disconnected;
- m_connectTimer.stop();
- m_checkTimer.stop();
- m_dmPollTimer.stop();
- emit stateChanged( m_state );
- }
- }
- }
- }
- void
- TwitterPlugin::deletePlugin()
- {
- TomahawkSettings::instance()->remove( pluginId() );
- }
- void
- TwitterPlugin::checkTimerFired()
- {
- if ( !isValid() || m_twitterAuth.isNull() )
- return;
- if ( m_cachedFriendsSinceId == 0 )
- m_cachedFriendsSinceId = twitterCachedFriendsSinceId();
- qDebug() << "TwitterPlugin 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 = twitterCachedMentionsSinceId();
- qDebug() << "TwitterPlugin looking at mentions timeline since id " << m_cachedMentionsSinceId;
- if ( !m_mentions.isNull() )
- m_mentions.data()->fetch( m_cachedMentionsSinceId, 0, 800 );
- }
- void
- TwitterPlugin::registerOffers( const QStringList &peerList )
- {
- foreach( QString screenName, peerList )
- {
- QVariantHash peerData = m_cachedPeers[screenName].toHash();
- if ( peerData.contains( "onod" ) && peerData["onod"] != Database::instance()->dbid() )
- {
- m_cachedPeers.remove( screenName );
- syncConfig();
- }
- if ( Servent::instance()->connectedToSession( peerData["node"].toString() ) )
- {
- peerData["lastseen"] = QDateTime::currentMSecsSinceEpoch();
- m_cachedPeers[screenName] = peerData;
- 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 );
- syncConfig();
- m_cachedAvatars.remove( screenName );
- continue;
- }
- if ( !peerData.contains( "host" ) || !peerData.contains( "port" ) || !peerData.contains( "pkey" ) )
- {
- qDebug() << "TwitterPlugin 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
- TwitterPlugin::connectTimerFired()
- {
- qDebug() << Q_FUNC_INFO << " beginning";
- if ( !isValid() || m_cachedPeers.isEmpty() || m_twitterAuth.isNull() )
- {
- if ( !isValid() )
- qDebug() << Q_FUNC_INFO << " is not valid";
- if ( m_cachedPeers.isEmpty() )
- qDebug() << Q_FUNC_INFO << " has empty cached peers";
- if ( m_twitterAuth.isNull() )
- qDebug() << Q_FUNC_INFO << " has null twitterAuth";
- return;
- }
- qDebug() << Q_FUNC_INFO << " continuing";
- QString myScreenName = twitterScreenName();
- QStringList peerList = m_cachedPeers.keys();
- qStableSort( peerList.begin(), peerList.end() );
- registerOffers( peerList );
- }
- void
- TwitterPlugin::parseGotTomahawk( const QRegExp ®ex, const QString &screenName, const QString &text )
- {
- QString myScreenName = twitterScreenName();
- qDebug() << "TwitterPlugin 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() << "TwitterPlugin 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() << "TwitterPlugin could not parse node out of the tweet";
- return;
- }
- else
- qDebug() << "TwitterPlugin parsed node " << node << " out of the tweet";
- if ( node == Database::instance()->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
- TwitterPlugin::friendsTimelineStatuses( const QList< QTweetStatus > &statuses )
- {
- qDebug() << 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();
- qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
- parseGotTomahawk( regex, status.user().screenName(), status.text() );
- }
- setTwitterCachedFriendsSinceId( m_cachedFriendsSinceId );
- }
- void
- TwitterPlugin::mentionsStatuses( const QList< QTweetStatus > &statuses )
- {
- qDebug() << 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();
- qDebug() << "TwitterPlugin checking mention from " << status.user().screenName() << " with content " << status.text();
- parseGotTomahawk( regex, status.user().screenName(), status.text() );
- }
- setTwitterCachedMentionsSinceId( m_cachedMentionsSinceId );
- }
- void
- TwitterPlugin::pollDirectMessages()
- {
- if ( !isValid() )
- return;
- if ( m_cachedDirectMessagesSinceId == 0 )
- m_cachedDirectMessagesSinceId = twitterCachedDirectMessagesSinceId();
- qDebug() << "TwitterPlugin looking for direct messages since id " << m_cachedDirectMessagesSinceId;
- if ( !m_directMessages.isNull() )
- m_directMessages.data()->fetch( m_cachedDirectMessagesSinceId, 0, 800 );
- }
- void
- TwitterPlugin::directMessages( const QList< QTweetDMStatus > &messages )
- {
- qDebug() << Q_FUNC_INFO;
- QRegExp regex( s_gotTomahawkRegex, Qt::CaseSensitive, QRegExp::RegExp2 );
- QString myScreenName = twitterScreenName();
- 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() << "TwitterPlugin 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() << "TwitterPlugin 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() << "TwitterPlugin 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()->dbid().startsWith( splitNode[1] ) )
- {
- qDebug() << "TwitterPlugin found message destined for this node; destroying it";
- if ( !m_directMessageDestroy.isNull() )
- m_directMessageDestroy.data()->destroyMessage( status.id() );
- }
- }
- }
- setTwitterCachedDirectMessagesSinceId( m_cachedDirectMessagesSinceId );
- }
- void
- TwitterPlugin::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()->dbid() ) )
- {
- QString okey = QUuid::createUuid().toString().split( '-' ).last();
- okey.chop( 1 );
- _peerData["okey"] = QVariant::fromValue< QString >( okey );
- _peerData["onod"] = QVariant::fromValue< QString >( Database::instance()->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() << "TwitterPlugin 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() << "TwitterPlugin 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() << "TwitterPlugin 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 );
- syncConfig();
- }
- if ( m_state == Connected && _peerData.contains( "host" ) && _peerData.contains( "port" ) && _peerData.contains( "pkey" ) )
- QMetaObject::invokeMethod( this, "makeConnection", Q_ARG( QString, screenName ), Q_ARG( QVariantHash, _peerData ) );
- }
- void
- TwitterPlugin::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()->dbid() )
- .arg( peerData["node"].toString().left( 8 ) )
- .arg( peerData["okey"].toString() );
- qDebug() << "TwitterPlugin sending message to " << screenName << ": " << offerString;
- if( !m_directMessageNew.isNull() )
- m_directMessageNew.data()->post( screenName, offerString );
- }
- void
- TwitterPlugin::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() << "TwitterPlugin 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() << "TwitterPlugin 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
- TwitterPlugin::directMessagePosted( const QTweetDMStatus& message )
- {
- qDebug() << Q_FUNC_INFO;
- qDebug() << "TwitterPlugin sent message to " << message.recipientScreenName() << " containing: " << message.text();
- }
- void
- TwitterPlugin::directMessagePostError( QTweetNetBase::ErrorCode errorCode, const QString &message )
- {
- Q_UNUSED( errorCode );
- Q_UNUSED( message );
- qDebug() << Q_FUNC_INFO;
- qDebug() << "TwitterPlugin received an error posting direct message: " << m_directMessageNew.data()->lastErrorMessage();
- }
- void
- TwitterPlugin::directMessageDestroyed( const QTweetDMStatus& message )
- {
- qDebug() << Q_FUNC_INFO;
- qDebug() << "TwitterPlugin destroyed message " << message.text();
- }
- void
- TwitterPlugin::fetchAvatar( const QString& screenName )
- {
- qDebug() << Q_FUNC_INFO;
- if ( m_twitterAuth.isNull() )
- return;
- QTweetUserShow *userShowFetch = new QTweetUserShow( m_twitterAuth.data(), this );
- connect( userShowFetch, SIGNAL( parsedUserInfo( QTweetUser ) ), SLOT( avatarUserDataSlot( QTweetUser ) ) );
- userShowFetch->fetch( screenName );
- }
- void
- TwitterPlugin::avatarUserDataSlot( const QTweetUser &user )
- {
- qDebug() << Q_FUNC_INFO;
- if ( user.profileImageUrl().isEmpty() || m_twitterAuth.isNull() )
- return;
- QNetworkRequest request( user.profileImageUrl() );
- QNetworkReply *reply = m_twitterAuth.data()->networkAccessManager()->get( request );
- reply->setProperty( "screenname", user.screenName() );
- connect( reply, SIGNAL( finished() ), this, SLOT( profilePicReply() ) );
- }
- void
- TwitterPlugin::refreshProxy()
- {
- if ( !m_twitterAuth.isNull() )
- m_twitterAuth.data()->setNetworkAccessManager( TomahawkUtils::nam() );
- }
- void
- TwitterPlugin::profilePicReply()
- {
- qDebug() << Q_FUNC_INFO;
- QNetworkReply *reply = qobject_cast< QNetworkReply* >( sender() );
- if ( !reply || reply->error() != QNetworkReply::NoError || !reply->property( "screenname" ).isValid() )
- {
- qDebug() << 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
- TwitterPlugin::checkSettings()
- {
- if ( m_state == Disconnected )
- return;
- disconnectPlugin();
- connectPlugin( false );
- }
- void
- TwitterPlugin::setTwitterSavedDbid( const QString& dbid )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/saveddbid", dbid );
- }
- QString
- TwitterPlugin::twitterSavedDbid() const
- {
- return TomahawkSettings::instance()->value( pluginId() + "/saveddbid", QString() ).toString();
- }
- QString
- TwitterPlugin::twitterScreenName() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "ScreenName", Qt::CaseSensitive ) )
- {
- s->setValue( "screenname_tmp",
- s->value( "ScreenName" ).toString() );
- s->remove( "ScreenName" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "screenname_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "screenname",
- s->value( "screenname_tmp" ).toString() );
- s->remove( "screenname_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/screenname" ).toString();
- }
- void
- TwitterPlugin::setTwitterScreenName( const QString& screenName )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/screenname", screenName );
- }
- QString
- TwitterPlugin::twitterOAuthToken() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "OAuthToken", Qt::CaseSensitive ) )
- {
- s->setValue( "oauthtoken_tmp",
- s->value( "OAuthToken" ).toString() );
- s->remove( "OAuthToken" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "oauthtoken_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "oauthtoken",
- s->value( "oauthtoken_tmp" ).toString() );
- s->remove( "oauthtoken_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/oauthtoken" ).toString();
- }
- void
- TwitterPlugin::setTwitterOAuthToken( const QString& oauthtoken )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/oauthtoken", oauthtoken );
- }
- QString
- TwitterPlugin::twitterOAuthTokenSecret() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "OAuthTokenSecret", Qt::CaseSensitive ) )
- {
- s->setValue( "oauthtokensecret_tmp",
- s->value( "OAuthTokenSecret" ).toString() );
- s->remove( "OAuthTokenSecret" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "oauthtokensecret_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "oauthtokensecret",
- s->value( "oauthtokensecret_tmp" ).toString() );
- s->remove( "oauthtokensecret_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/oauthtokensecret" ).toString();
- }
- void
- TwitterPlugin::setTwitterOAuthTokenSecret( const QString& oauthtokensecret )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/oauthtokensecret", oauthtokensecret );
- }
- qint64
- TwitterPlugin::twitterCachedFriendsSinceId() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "CachedFriendsSinceID", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedfriendssinceid_tmp",
- s->value( "CachedFriendsSinceID" ).toLongLong() );
- s->remove( "CachedFriendsSinceID" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "cachedfriendssinceid_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedfriendssinceid",
- s->value( "cachedfriendssinceid_tmp" ).toLongLong() );
- s->remove( "cachedfriendssinceid_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/cachedfriendssinceid", 0 ).toLongLong();
- }
- void
- TwitterPlugin::setTwitterCachedFriendsSinceId( qint64 cachedId )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/cachedfriendssinceid", cachedId );
- }
- qint64
- TwitterPlugin::twitterCachedMentionsSinceId() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "CachedMentionsSinceID", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedmentionssinceid_tmp",
- s->value( "CachedMentionsSinceID" ).toLongLong() );
- s->remove( "CachedMentionsSinceID" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "cachedmentionssinceid_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedmentionssinceid",
- s->value( "cachedmentionssinceid_tmp" ).toLongLong() );
- s->remove( "cachedmentionssinceid_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/cachedmentionssinceid", 0 ).toLongLong();
- }
- void
- TwitterPlugin::setTwitterCachedMentionsSinceId( qint64 cachedId )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/cachedmentionssinceid", cachedId );
- }
- qint64
- TwitterPlugin::twitterCachedDirectMessagesSinceId() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "CachedDirectMessagesSinceID", Qt::CaseSensitive ) )
- {
- s->setValue( "cacheddirectmessagessinceid_tmp",
- s->value( "CachedDirectMessagesSinceID" ).toLongLong() );
- s->remove( "CachedDirectMessagesSinceID" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "cacheddirectmessagessinceid_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "cacheddirectmessagessinceid",
- s->value( "cacheddirectmessagessinceid_tmp" ).toLongLong() );
- s->remove( "cacheddirectmessagessinceid_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/cacheddirectmessagessinceid", 0 ).toLongLong();
- }
- void
- TwitterPlugin::setTwitterCachedDirectMessagesSinceId( qint64 cachedId )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/cacheddirectmessagessinceid", cachedId );
- }
- QVariantHash
- TwitterPlugin::twitterCachedPeers() const
- {
- TomahawkSettings* s = TomahawkSettings::instance();
- s->beginGroup( pluginId() );
- QStringList keys = s->childKeys();
- if ( keys.contains( "CachedPeers", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedpeers_tmp",
- s->value( "CachedPeers" ).toHash() );
- s->remove( "CachedPeers" );
- s->sync();
- }
- keys = s->childKeys();
- if ( keys.contains( "cachedpeers_tmp", Qt::CaseSensitive ) )
- {
- s->setValue( "cachedpeers",
- s->value( "cachedpeers_tmp" ).toHash() );
- s->remove( "cachedpeers_tmp" );
- s->sync();
- }
- s->endGroup();
- return s->value( pluginId() + "/cachedpeers", QVariantHash() ).toHash();
- }
- void
- TwitterPlugin::setTwitterCachedPeers( const QVariantHash &cachedPeers )
- {
- TomahawkSettings::instance()->setValue( pluginId() + "/cachedpeers", cachedPeers );
- TomahawkSettings::instance()->sync();
- }
- Q_EXPORT_PLUGIN2( sipfactory, TwitterFactory )